aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils/rfnoc/templates
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils/rfnoc/templates')
-rw-r--r--host/utils/rfnoc/templates/CMakeLists.txt16
-rw-r--r--host/utils/rfnoc/templates/modules/CMakeLists.txt24
-rw-r--r--host/utils/rfnoc/templates/modules/chdr_xb_sep_transport.v.mako23
-rw-r--r--host/utils/rfnoc/templates/modules/connect_clk_domains.v.mako12
-rw-r--r--host/utils/rfnoc/templates/modules/connect_io_ports.v.mako20
-rw-r--r--host/utils/rfnoc/templates/modules/ctrl_crossbar.v.mako39
-rw-r--r--host/utils/rfnoc/templates/modules/device_io_ports.v.mako9
-rw-r--r--host/utils/rfnoc/templates/modules/device_transport.v.mako13
-rw-r--r--host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako37
-rw-r--r--host/utils/rfnoc/templates/modules/rfnoc_block.v.mako84
-rw-r--r--host/utils/rfnoc/templates/modules/sep_xb_wires.v.mako12
-rw-r--r--host/utils/rfnoc/templates/modules/static_router.v.mako15
-rw-r--r--host/utils/rfnoc/templates/modules/stream_endpoints.v.mako92
-rw-r--r--host/utils/rfnoc/templates/rfnoc_image_core.v.mako159
14 files changed, 555 insertions, 0 deletions
diff --git a/host/utils/rfnoc/templates/CMakeLists.txt b/host/utils/rfnoc/templates/CMakeLists.txt
new file mode 100644
index 000000000..88c5e3bd4
--- /dev/null
+++ b/host/utils/rfnoc/templates/CMakeLists.txt
@@ -0,0 +1,16 @@
+#
+# Copyright 2019 Ettus Research, A National Instrument Brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+set(RFNOC_PKG_FILES ${RFNOC_PKG_FILES})
+set(RFNOC_PKG_TOP_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_image_core.v.mako
+)
+list(APPEND RFNOC_PKG_FILES ${RFNOC_PKG_TOP_FILES})
+add_subdirectory(modules)
+set(RFNOC_PKG_FILES ${RFNOC_PKG_FILES} PARENT_SCOPE)
diff --git a/host/utils/rfnoc/templates/modules/CMakeLists.txt b/host/utils/rfnoc/templates/modules/CMakeLists.txt
new file mode 100644
index 000000000..ee69b63b5
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/CMakeLists.txt
@@ -0,0 +1,24 @@
+#
+# Copyright 2017 Ettus Research, National Instruments Company
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+set(RFNOC_PKG_FILES ${RFNOC_PKG_FILES})
+set(RFNOC_PKG_TOP_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/chdr_xb_sep_transport.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/connect_io_ports.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/ctrl_crossbar.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/device_io_ports.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/device_transport.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/drive_unused_ports.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_block.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/sep_xb_wires.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/static_router.v.mako
+ ${CMAKE_CURRENT_SOURCE_DIR}/stream_endpoints.v.mako
+)
+list(APPEND RFNOC_PKG_FILES ${RFNOC_PKG_TOP_FILES})
+set(RFNOC_PKG_FILES ${RFNOC_PKG_FILES} PARENT_SCOPE)
diff --git a/host/utils/rfnoc/templates/modules/chdr_xb_sep_transport.v.mako b/host/utils/rfnoc/templates/modules/chdr_xb_sep_transport.v.mako
new file mode 100644
index 000000000..0862a1ac1
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/chdr_xb_sep_transport.v.mako
@@ -0,0 +1,23 @@
+<%page args="seps, transports"/>\
+\
+<%
+ import re
+ sep2xb = ""
+ xb2sep = ""
+ for sep in reversed(list(seps.keys())):
+ sep2xb += "%s_to_xb_wire, " % sep
+ xb2sep += "xb_to_%s_wire, " % sep
+ for transport in reversed(transports):
+ sep2xb += "s_%s_wire, " % transport["name"]
+ xb2sep += "m_%s_wire, " % transport["name"]
+ sep2xb = sep2xb[:-2]
+ xb2sep = xb2sep[:-2]
+%>\
+ .s_axis_tdata ({${re.sub("wire", "tdata", sep2xb)}}),
+ .s_axis_tlast ({${re.sub("wire", "tlast", sep2xb)}}),
+ .s_axis_tvalid ({${re.sub("wire", "tvalid", sep2xb)}}),
+ .s_axis_tready ({${re.sub("wire", "tready", sep2xb)}}),
+ .m_axis_tdata ({${re.sub("wire", "tdata", xb2sep)}}),
+ .m_axis_tlast ({${re.sub("wire", "tlast", xb2sep)}}),
+ .m_axis_tvalid ({${re.sub("wire", "tvalid", xb2sep)}}),
+ .m_axis_tready ({${re.sub("wire", "tready", xb2sep)}}),
diff --git a/host/utils/rfnoc/templates/modules/connect_clk_domains.v.mako b/host/utils/rfnoc/templates/modules/connect_clk_domains.v.mako
new file mode 100644
index 000000000..df055645c
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/connect_clk_domains.v.mako
@@ -0,0 +1,12 @@
+<%page args="connections, clocks"/>\
+\
+%for connection in connections:
+<%
+ src_name = connection["srcblk"] # Should always be "_device_"
+ src = clocks[(src_name, connection["srcport"])]
+ dst_name = connection["dstblk"]
+ dst = clocks[(dst_name, connection["dstport"])]
+%>\
+ assign ${dst_name}_${dst["name"]}_clk = ${src["name"]}_clk;
+%endfor
+
diff --git a/host/utils/rfnoc/templates/modules/connect_io_ports.v.mako b/host/utils/rfnoc/templates/modules/connect_io_ports.v.mako
new file mode 100644
index 000000000..c37697d88
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/connect_io_ports.v.mako
@@ -0,0 +1,20 @@
+<%page args="connections, io_ports, names"/>\
+\
+%for connection in connections:
+<%
+ src_name = connection["srcblk"]
+ src = io_ports[(src_name, connection["srcport"], names[0])]
+ dst_name = connection["dstblk"]
+ dst = io_ports[(dst_name, connection["dstport"], names[1])]
+%>\
+ %for src_wire, dst_wire in zip(src["wires"], dst["wires"]):
+<%
+ swire = src_wire["name"] if src_name == "_device_" else "%s_%s" % (src_name, src_wire["name"])
+ dwire = dst_wire["name"] if dst_name == "_device_" else "%s_%s" % (dst_name, dst_wire["name"])
+ if src_wire["direction"] == "output":
+ swire, dwire = dwire, swire
+%>\
+ assign ${dwire} = ${swire};
+ %endfor
+
+%endfor
diff --git a/host/utils/rfnoc/templates/modules/ctrl_crossbar.v.mako b/host/utils/rfnoc/templates/modules/ctrl_crossbar.v.mako
new file mode 100644
index 000000000..5872e270e
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/ctrl_crossbar.v.mako
@@ -0,0 +1,39 @@
+<%page args="seps, blocks"/>\
+\
+<%
+ import re
+ axisstr = ""
+ for block in reversed(list(blocks.keys())):
+ axisstr += "{0}_%s_ctrl_{1}, " % block
+ for sep in reversed(list(seps.keys())):
+ axisstr += "{0}_%s_ctrl_{1}, " % sep
+ axisstr += "{0}_core_ctrl_{1}"
+%>\
+%for block in blocks:
+ wire [31:0] m_${block}_ctrl_tdata , s_${block}_ctrl_tdata ;
+ wire m_${block}_ctrl_tlast , s_${block}_ctrl_tlast ;
+ wire m_${block}_ctrl_tvalid, s_${block}_ctrl_tvalid;
+ wire m_${block}_ctrl_tready, s_${block}_ctrl_tready;
+%endfor
+
+ axis_ctrl_crossbar_nxn #(
+ .WIDTH (32),
+ .NPORTS (${len(seps) + len(blocks) + 1}),
+ .TOPOLOGY ("TORUS"),
+ .INGRESS_BUFF_SIZE(5),
+ .ROUTER_BUFF_SIZE (5),
+ .ROUTING_ALLOC ("WORMHOLE"),
+ .SWITCH_ALLOC ("PRIO")
+ ) ctrl_xb_i (
+ .clk (rfnoc_ctrl_clk),
+ .reset (rfnoc_ctrl_rst),
+ .s_axis_tdata ({${axisstr.format("m", "tdata ")}}),
+ .s_axis_tvalid ({${axisstr.format("m", "tvalid")}}),
+ .s_axis_tlast ({${axisstr.format("m", "tlast ")}}),
+ .s_axis_tready ({${axisstr.format("m", "tready")}}),
+ .m_axis_tdata ({${axisstr.format("s", "tdata ")}}),
+ .m_axis_tvalid ({${axisstr.format("s", "tvalid")}}),
+ .m_axis_tlast ({${axisstr.format("s", "tlast ")}}),
+ .m_axis_tready ({${axisstr.format("s", "tready")}}),
+ .deadlock_detected()
+ );
diff --git a/host/utils/rfnoc/templates/modules/device_io_ports.v.mako b/host/utils/rfnoc/templates/modules/device_io_ports.v.mako
new file mode 100644
index 000000000..abfb86c98
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/device_io_ports.v.mako
@@ -0,0 +1,9 @@
+<%page args="io_ports"/>\
+<%import six%>\
+//// IO ports //////////////////////////////////
+%for name, io_port in six.iteritems(io_ports):
+// ${name}
+ %for wire in io_port["wires"]:
+ ${wire["direction"]} wire [${"%3d" % wire["width"]}-1:0] ${wire["name"]},
+ %endfor
+%endfor
diff --git a/host/utils/rfnoc/templates/modules/device_transport.v.mako b/host/utils/rfnoc/templates/modules/device_transport.v.mako
new file mode 100644
index 000000000..3d752ce13
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/device_transport.v.mako
@@ -0,0 +1,13 @@
+<%page args="transports"/>\
+\
+%for i, transport in enumerate(transports):
+ // Transport ${i} (${transport["name"]} ${transport["type"]})
+ input wire [${transport["width"]}-1:0] s_${transport["name"]}_tdata,
+ input wire s_${transport["name"]}_tlast,
+ input wire s_${transport["name"]}_tvalid,
+ output wire s_${transport["name"]}_tready,
+ output wire [${transport["width"]}-1:0] m_${transport["name"]}_tdata,
+ output wire m_${transport["name"]}_tlast,
+ output wire m_${transport["name"]}_tvalid,
+ input wire m_${transport["name"]}_tready${"," if i < len(transports) - 1 else ""}
+%endfor
diff --git a/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako b/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako
new file mode 100644
index 000000000..e6df532f0
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/drive_unused_ports.v.mako
@@ -0,0 +1,37 @@
+<%page args="connections, blocks, block_descs, seps"/>\
+\
+<%
+ sources = []
+ destinations = []
+ for connection in connections:
+ sources.append((connection["srcblk"], connection["srcport"]))
+ destinations.append((connection["dstblk"], connection["dstport"]))
+%>\
+%for sep in seps:
+ %for input in range(seps[sep]["num_data_i"]):
+ %if not (sep, "in%d" % (input)) in destinations:
+ assign s_${sep}_in${input}_tdata = 'h0;
+ assign s_${sep}_in${input}_tlast = 1'b0;
+ assign s_${sep}_in${input}_tvalid = 1'b0;
+ %endif
+ %endfor
+ %for output in range(seps[sep]["num_data_o"]):
+ %if not (sep, "out%d" % (output)) in sources:
+ assign m_${sep}_out${output}_tready = 1'b1;
+ %endif
+ %endfor
+%endfor
+%for block in blocks:
+ %for input in block_descs[blocks[block]["block_desc"]].data["inputs"]:
+ %if not (block, input) in destinations:
+ assign s_${block}_${input}_tdata = ${block_descs[blocks[block]["block_desc"]].chdr_width}'h0;
+ assign s_${block}_${input}_tlast = 1'b0;
+ assign s_${block}_${input}_tvalid = 1'b0;
+ %endif
+ %endfor
+ %for output in block_descs[blocks[block]["block_desc"]].data["outputs"]:
+ %if not (block, output) in sources:
+ assign m_${block}_${output}_tready = 1'b1;
+ %endif
+ %endfor
+%endfor
diff --git a/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako b/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako
new file mode 100644
index 000000000..061e4dc8e
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/rfnoc_block.v.mako
@@ -0,0 +1,84 @@
+<%page args="block_id, block_number, block_name, block, block_params"/>\
+\
+<%
+ import re
+ import six
+ axis_inputs = ""
+ axis_outputs = ""
+ for input in list(block.data["inputs"].keys()):
+ axis_inputs = "{0}_%s_%s_{1}, " % (block_name, input) + axis_inputs
+ axis_inputs = axis_inputs[:-2]
+ for output in list(block.data["outputs"].keys()):
+ axis_outputs = "{0}_%s_%s_{1}, " % (block_name, output) + axis_outputs
+ axis_outputs = axis_outputs[:-2]
+%>\
+
+ // ----------------------------------------------------
+ // ${block_name}
+ // ----------------------------------------------------
+%for clock in block.clocks:
+ %if not clock["name"] in ["rfnoc_chdr", "rfnoc_ctrl"]:
+ wire ${block_name}_${clock["name"]}_clk;
+ %endif
+%endfor
+ wire [CHDR_W-1:0] ${axis_inputs.format("s", "tdata ")};
+ wire ${axis_inputs.format("s", "tlast ")};
+ wire ${axis_inputs.format("s", "tvalid")};
+ wire ${axis_inputs.format("s", "tready")};
+ wire [CHDR_W-1:0] ${axis_outputs.format("m", "tdata ")};
+ wire ${axis_outputs.format("m", "tlast ")};
+ wire ${axis_outputs.format("m", "tvalid")};
+ wire ${axis_outputs.format("m", "tready")};
+
+%if hasattr(block, "io_ports"):
+ %for name, io_port in six.iteritems(block.io_ports):
+ // ${name}
+ %for wire in io_port["wires"]:
+ wire [${"%3d" % wire["width"]}-1:0] ${block_name}_${wire["name"]};
+ %endfor
+ %endfor
+%endif
+
+ rfnoc_block_${block.module_name} #(
+ .THIS_PORTID(${block_id}),
+ .CHDR_W(CHDR_W),
+%for name, value in six.iteritems(block_params):
+ .${name}(${value}),
+%endfor
+ .MTU(MTU)
+ ) b_${block_name}_${block_number} (
+ .rfnoc_chdr_clk (rfnoc_chdr_clk),
+ .rfnoc_ctrl_clk (rfnoc_ctrl_clk),
+%for clock in block.clocks:
+ %if not clock["name"] in ["rfnoc_chdr", "rfnoc_ctrl"]:
+ .${clock["name"]}_clk(${block_name}_${clock["name"]}_clk),
+ %endif
+%endfor
+ .rfnoc_core_config (rfnoc_core_config[512*${block_number + 1}-1:512*${block_number}]),
+ .rfnoc_core_status (rfnoc_core_status[512*${block_number + 1}-1:512*${block_number}]),
+
+%if hasattr(block, "io_ports"):
+ %for name, io_port in six.iteritems(block.io_ports):
+ %for wire in io_port["wires"]:
+ .${wire["name"]}(${block_name}_${wire["name"]}),
+ %endfor
+ %endfor
+%endif
+
+ .s_rfnoc_chdr_tdata ({${axis_inputs.format("s", "tdata ")}}),
+ .s_rfnoc_chdr_tlast ({${axis_inputs.format("s", "tlast ")}}),
+ .s_rfnoc_chdr_tvalid({${axis_inputs.format("s", "tvalid")}}),
+ .s_rfnoc_chdr_tready({${axis_inputs.format("s", "tready")}}),
+ .m_rfnoc_chdr_tdata ({${axis_outputs.format("m", "tdata ")}}),
+ .m_rfnoc_chdr_tlast ({${axis_outputs.format("m", "tlast ")}}),
+ .m_rfnoc_chdr_tvalid({${axis_outputs.format("m", "tvalid")}}),
+ .m_rfnoc_chdr_tready({${axis_outputs.format("m", "tready")}}),
+ .s_rfnoc_ctrl_tdata (s_${block_name}_ctrl_tdata ),
+ .s_rfnoc_ctrl_tlast (s_${block_name}_ctrl_tlast ),
+ .s_rfnoc_ctrl_tvalid(s_${block_name}_ctrl_tvalid),
+ .s_rfnoc_ctrl_tready(s_${block_name}_ctrl_tready),
+ .m_rfnoc_ctrl_tdata (m_${block_name}_ctrl_tdata ),
+ .m_rfnoc_ctrl_tlast (m_${block_name}_ctrl_tlast ),
+ .m_rfnoc_ctrl_tvalid(m_${block_name}_ctrl_tvalid),
+ .m_rfnoc_ctrl_tready(m_${block_name}_ctrl_tready)
+ );
diff --git a/host/utils/rfnoc/templates/modules/sep_xb_wires.v.mako b/host/utils/rfnoc/templates/modules/sep_xb_wires.v.mako
new file mode 100644
index 000000000..4aa7d56bb
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/sep_xb_wires.v.mako
@@ -0,0 +1,12 @@
+<%page args="seps"/>\
+\
+%for sep in seps:
+ wire [CHDR_W-1:0] xb_to_${sep}_tdata ;
+ wire xb_to_${sep}_tlast ;
+ wire xb_to_${sep}_tvalid;
+ wire xb_to_${sep}_tready;
+ wire [CHDR_W-1:0] ${sep}_to_xb_tdata ;
+ wire ${sep}_to_xb_tlast ;
+ wire ${sep}_to_xb_tvalid;
+ wire ${sep}_to_xb_tready;
+%endfor
diff --git a/host/utils/rfnoc/templates/modules/static_router.v.mako b/host/utils/rfnoc/templates/modules/static_router.v.mako
new file mode 100644
index 000000000..3649c278b
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/static_router.v.mako
@@ -0,0 +1,15 @@
+<%page args="connections"/>\
+\
+%for connection in connections:
+<%
+ srcblk = connection["srcblk"]
+ dstblk = connection["dstblk"]
+ srcport = "in" if connection["srcport"] == None else connection["srcport"]
+ dstport = "out" if connection["dstport"] == None else connection["dstport"]
+%>\
+ assign s_${dstblk}_${dstport}_tdata = m_${srcblk}_${srcport}_tdata ;
+ assign s_${dstblk}_${dstport}_tlast = m_${srcblk}_${srcport}_tlast ;
+ assign s_${dstblk}_${dstport}_tvalid = m_${srcblk}_${srcport}_tvalid;
+ assign m_${srcblk}_${srcport}_tready = s_${dstblk}_${dstport}_tready;
+
+%endfor \ No newline at end of file
diff --git a/host/utils/rfnoc/templates/modules/stream_endpoints.v.mako b/host/utils/rfnoc/templates/modules/stream_endpoints.v.mako
new file mode 100644
index 000000000..f8ecccb77
--- /dev/null
+++ b/host/utils/rfnoc/templates/modules/stream_endpoints.v.mako
@@ -0,0 +1,92 @@
+<%page args="seps"/>\
+<%
+ import math
+ import re
+ import six
+
+ axis_inputs = {}
+ axis_outputs = {}
+ for i, sep in enumerate(seps):
+ inputs = ""
+ outputs = ""
+ for data_i in range(0,seps[sep]["num_data_i"]):
+ inputs = "s_{0}_in%d_{1}, " % (data_i) + inputs
+ axis_inputs[sep] = inputs[:-2]
+ for data_o in range(0,seps[sep]["num_data_o"]):
+ outputs = "m_{0}_out%d_{1}, " % (data_o) + outputs
+ axis_outputs[sep] = outputs[:-2]
+%>\
+\
+%for i, sep in enumerate(seps):
+<%
+# If buff_size == 0, then we assume that we will never transmit through this SEP
+buff_size = seps[sep]["buff_size"]
+if buff_size > 0:
+ buff_size = int(math.ceil(math.log(buff_size, 2)))
+ # FIXME MTU assumed to be 10 here -- forcing to at least accommodate 2 pkts
+ buff_size = max(buff_size, 10+1)
+else:
+ buff_size = 5
+%>\
+ wire [CHDR_W-1:0] ${axis_outputs[sep].format(sep,"tdata")};
+ wire ${axis_outputs[sep].format(sep,"tlast")};
+ wire ${axis_outputs[sep].format(sep,"tvalid")};
+ wire ${axis_outputs[sep].format(sep,"tready")};
+ wire [CHDR_W-1:0] ${axis_inputs[sep].format(sep,"tdata")};
+ wire ${axis_inputs[sep].format(sep,"tlast")};
+ wire ${axis_inputs[sep].format(sep,"tvalid")};
+ wire ${axis_inputs[sep].format(sep,"tready")};
+ wire [31:0] m_${sep}_ctrl_tdata , s_${sep}_ctrl_tdata ;
+ wire m_${sep}_ctrl_tlast , s_${sep}_ctrl_tlast ;
+ wire m_${sep}_ctrl_tvalid, s_${sep}_ctrl_tvalid;
+ wire m_${sep}_ctrl_tready, s_${sep}_ctrl_tready;
+
+ chdr_stream_endpoint #(
+ .PROTOVER (PROTOVER),
+ .CHDR_W (CHDR_W),
+ .AXIS_CTRL_EN (${int(seps[sep]["ctrl"])}),
+ .AXIS_DATA_EN (${int(seps[sep]["data"])}),
+ .NUM_DATA_I (${int(seps[sep]["num_data_i"])}),
+ .NUM_DATA_O (${int(seps[sep]["num_data_o"])}),
+ .INST_NUM (${i}),
+ .CTRL_XBAR_PORT (${i+1}),
+ .INGRESS_BUFF_SIZE (${buff_size}),
+ .MTU (MTU),
+ .REPORT_STRM_ERRS (1)
+ ) ${sep}_i (
+ .rfnoc_chdr_clk (rfnoc_chdr_clk ),
+ .rfnoc_chdr_rst (rfnoc_chdr_rst ),
+ .rfnoc_ctrl_clk (rfnoc_ctrl_clk ),
+ .rfnoc_ctrl_rst (rfnoc_ctrl_rst ),
+ .device_id (device_id ),
+ .s_axis_chdr_tdata (xb_to_${sep}_tdata ),
+ .s_axis_chdr_tlast (xb_to_${sep}_tlast ),
+ .s_axis_chdr_tvalid (xb_to_${sep}_tvalid ),
+ .s_axis_chdr_tready (xb_to_${sep}_tready ),
+ .m_axis_chdr_tdata (${sep}_to_xb_tdata ),
+ .m_axis_chdr_tlast (${sep}_to_xb_tlast ),
+ .m_axis_chdr_tvalid (${sep}_to_xb_tvalid ),
+ .m_axis_chdr_tready (${sep}_to_xb_tready ),
+ .s_axis_data_tdata ({${axis_inputs[sep].format(sep,"tdata")}}),
+ .s_axis_data_tlast ({${axis_inputs[sep].format(sep,"tlast")}}),
+ .s_axis_data_tvalid ({${axis_inputs[sep].format(sep,"tvalid")}}),
+ .s_axis_data_tready ({${axis_inputs[sep].format(sep,"tready")}}),
+ .m_axis_data_tdata ({${axis_outputs[sep].format(sep,"tdata")}}),
+ .m_axis_data_tlast ({${axis_outputs[sep].format(sep,"tlast")}}),
+ .m_axis_data_tvalid ({${axis_outputs[sep].format(sep,"tvalid")}}),
+ .m_axis_data_tready ({${axis_outputs[sep].format(sep,"tready")}}),
+ .s_axis_ctrl_tdata (s_${sep}_ctrl_tdata ),
+ .s_axis_ctrl_tlast (s_${sep}_ctrl_tlast ),
+ .s_axis_ctrl_tvalid (s_${sep}_ctrl_tvalid),
+ .s_axis_ctrl_tready (s_${sep}_ctrl_tready),
+ .m_axis_ctrl_tdata (m_${sep}_ctrl_tdata ),
+ .m_axis_ctrl_tlast (m_${sep}_ctrl_tlast ),
+ .m_axis_ctrl_tvalid (m_${sep}_ctrl_tvalid),
+ .m_axis_ctrl_tready (m_${sep}_ctrl_tready),
+ .strm_seq_err_stb ( ),
+ .strm_data_err_stb ( ),
+ .strm_route_err_stb ( ),
+ .signal_data_err (1'b0 )
+ );
+
+%endfor
diff --git a/host/utils/rfnoc/templates/rfnoc_image_core.v.mako b/host/utils/rfnoc/templates/rfnoc_image_core.v.mako
new file mode 100644
index 000000000..57b70ece3
--- /dev/null
+++ b/host/utils/rfnoc/templates/rfnoc_image_core.v.mako
@@ -0,0 +1,159 @@
+<%
+ import datetime
+%>//
+// Copyright ${datetime.datetime.now().year} ${config.copyright}
+//
+// ${config.license}
+//
+
+// Module: rfnoc_image_core (for ${config.device.type})
+// This file was autogenerated by UHD's image builder tool (rfnoc_image_builder)
+// Re-running that tool will overwrite this file!
+// File generated on: ${datetime.datetime.now().isoformat()}
+% if source:
+// Source: ${source}
+% endif
+% if source_hash:
+// Source SHA256: ${source_hash}
+% endif
+
+module rfnoc_image_core #(
+ parameter [15:0] PROTOVER = {8'd1, 8'd0}
+)(
+ // Clocks
+ input wire chdr_aclk,
+ input wire ctrl_aclk,
+ input wire core_arst,
+%for clock in config.device.clocks:
+ input wire ${clock["name"]}_clk,
+%endfor
+ // Basic
+ input wire [15:0] device_id,
+<%include file="/modules/device_io_ports.v.mako" args="io_ports=config.device.io_ports"/>\
+<%include file="/modules/device_transport.v.mako" args="transports=config.device.transports"/>\
+);
+
+ localparam CHDR_W = 64;
+ localparam MTU = 10;
+ localparam EDGE_TBL_FILE = `"`RFNOC_EDGE_TBL_FILE`";
+
+ wire rfnoc_chdr_clk, rfnoc_chdr_rst;
+ wire rfnoc_ctrl_clk, rfnoc_ctrl_rst;
+
+ // ----------------------------------------------------
+ // CHDR Crossbar
+ // ----------------------------------------------------
+<%include file="/modules/sep_xb_wires.v.mako" args="seps=config.stream_endpoints"/>\
+
+ chdr_crossbar_nxn #(
+ .CHDR_W (CHDR_W),
+ .NPORTS (${len(config.stream_endpoints) + len(config.device.transports)}),
+ .DEFAULT_PORT (0),
+ .MTU (MTU),
+ .ROUTE_TBL_SIZE (6),
+ .MUX_ALLOC ("ROUND-ROBIN"),
+ .OPTIMIZE ("AREA"),
+ .NPORTS_MGMT (${len(config.device.transports)}),
+ .EXT_RTCFG_PORT (0),
+ .PROTOVER (PROTOVER)
+ ) chdr_xb_i (
+ .clk (rfnoc_chdr_clk),
+ .reset (rfnoc_chdr_rst),
+ .device_id (device_id),
+<%include file="/modules/chdr_xb_sep_transport.v.mako" args="seps=config.stream_endpoints, transports=config.device.transports"/>\
+ .ext_rtcfg_stb (1'h0),
+ .ext_rtcfg_addr (16'h0),
+ .ext_rtcfg_data (32'h0),
+ .ext_rtcfg_ack ()
+ );
+
+ // ----------------------------------------------------
+ // Stream Endpoints
+ // ----------------------------------------------------
+
+<%include file="/modules/stream_endpoints.v.mako" args="seps=config.stream_endpoints"/>\
+
+<%
+ from collections import OrderedDict
+ ctrl_seps = OrderedDict((k, v) for k, v in config.stream_endpoints.items() if v.get('ctrl'))
+%>
+ // ----------------------------------------------------
+ // Control Crossbar
+ // ----------------------------------------------------
+
+ wire [31:0] m_core_ctrl_tdata , s_core_ctrl_tdata ;
+ wire m_core_ctrl_tlast , s_core_ctrl_tlast ;
+ wire m_core_ctrl_tvalid, s_core_ctrl_tvalid;
+ wire m_core_ctrl_tready, s_core_ctrl_tready;
+<%include file="/modules/ctrl_crossbar.v.mako" args="seps=ctrl_seps, blocks=config.noc_blocks"/>\
+
+ // ----------------------------------------------------
+ // RFNoC Core Kernel
+ // ----------------------------------------------------
+ wire [(512*${len(config.noc_blocks)})-1:0] rfnoc_core_config, rfnoc_core_status;
+
+ rfnoc_core_kernel #(
+ .PROTOVER (PROTOVER),
+ .DEVICE_TYPE (16'h${config.device.type_id}),
+ .DEVICE_FAMILY ("${config.device.family}"),
+ .SAFE_START_CLKS (0),
+ .NUM_BLOCKS (${len(config.noc_blocks)}),
+ .NUM_STREAM_ENDPOINTS(${len(config.stream_endpoints)}),
+ .NUM_ENDPOINTS_CTRL (${len(ctrl_seps)}),
+ .NUM_TRANSPORTS (${len(config.device.transports)}),
+ .NUM_EDGES (${len(config.block_con)}),
+ .CHDR_XBAR_PRESENT (1),
+ .EDGE_TBL_FILE (EDGE_TBL_FILE)
+ ) core_kernel_i (
+ .chdr_aclk (chdr_aclk),
+ .chdr_aclk_locked (1'b1),
+ .ctrl_aclk (ctrl_aclk),
+ .ctrl_aclk_locked (1'b1),
+ .core_arst (core_arst),
+ .core_chdr_clk (rfnoc_chdr_clk),
+ .core_chdr_rst (rfnoc_chdr_rst),
+ .core_ctrl_clk (rfnoc_ctrl_clk),
+ .core_ctrl_rst (rfnoc_ctrl_rst),
+ .s_axis_ctrl_tdata (s_core_ctrl_tdata ),
+ .s_axis_ctrl_tlast (s_core_ctrl_tlast ),
+ .s_axis_ctrl_tvalid (s_core_ctrl_tvalid),
+ .s_axis_ctrl_tready (s_core_ctrl_tready),
+ .m_axis_ctrl_tdata (m_core_ctrl_tdata ),
+ .m_axis_ctrl_tlast (m_core_ctrl_tlast ),
+ .m_axis_ctrl_tvalid (m_core_ctrl_tvalid),
+ .m_axis_ctrl_tready (m_core_ctrl_tready),
+ .device_id (device_id),
+ .rfnoc_core_config (rfnoc_core_config),
+ .rfnoc_core_status (rfnoc_core_status)
+ );
+
+ // ----------------------------------------------------
+ // Blocks
+ // ----------------------------------------------------
+%for i, name in enumerate(config.noc_blocks):
+<%include file="/modules/rfnoc_block.v.mako" args="block_id=i + len(config.stream_endpoints) + 1, block_number=i, block_name=name, block=config.blocks[config.noc_blocks[name]['block_desc']], block_params=config.noc_blocks[name]['parameters']"/>
+%endfor
+
+ // ----------------------------------------------------
+ // Static Router
+ // ----------------------------------------------------
+<%include file="/modules/static_router.v.mako" args="connections=config.block_con"/>\
+
+ // ----------------------------------------------------
+ // Unused Ports
+ // ----------------------------------------------------
+<%include file="/modules/drive_unused_ports.v.mako" args="connections=config.block_con, blocks=config.noc_blocks, block_descs=config.blocks, seps=config.stream_endpoints"/>\
+
+ // ----------------------------------------------------
+ // Clock Domains
+ // ----------------------------------------------------
+<%include file="/modules/connect_clk_domains.v.mako" args="connections=config.clk_domain_con, clocks=config.clocks"/>\
+
+ // ----------------------------------------------------
+ // IO Port Connection
+ // ----------------------------------------------------
+ // Master/Slave Connections:
+<%include file="/modules/connect_io_ports.v.mako" args="connections=config.io_port_con_ms, io_ports=config.io_ports, names=('master', 'slave')"/>\
+ // Broadcaster/Listener Connections:
+<%include file="/modules/connect_io_ports.v.mako" args="connections=config.io_port_con_bl, io_ports=config.io_ports, names=('broadcaster', 'listener')"/>\
+endmodule