From c90d5141acd9a6cbe16b46b61647da4349eb5c77 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 14 Nov 2014 22:11:49 -0800 Subject: [PATCH] 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