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