aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils/rfnoc_blocktool/templates/modules
diff options
context:
space:
mode:
authorLars Amsel <lars.amsel@ni.com>2019-04-26 15:51:42 +0200
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:14 -0800
commit752fdd269215a606212fb97e909b08707bf54507 (patch)
treee8fe3eb901e2740641ac34f580f456592286f148 /host/utils/rfnoc_blocktool/templates/modules
parent384a94d1b6e3a980c19df70f8a1a95ec9f52eb6e (diff)
downloaduhd-752fdd269215a606212fb97e909b08707bf54507.tar.gz
uhd-752fdd269215a606212fb97e909b08707bf54507.tar.bz2
uhd-752fdd269215a606212fb97e909b08707bf54507.zip
rfnoc: add eRFNoC block builder to generate boiler plate Verilog
This is an initial generator for eRFNoC block. The script generates the top level block, the shell module, a testbench, and a Makefile as well as a Makefile.srcs. To build a block from a yml file one has to invoke python -c <config> -d <destination folder> destination folder should be an in tree module folder located in uhd-fpga/usrp3/lib/erfnoc/blocks The build tool supports all interface types for control as well as data. For each interface type there are three templates to generate the variable block in the top level block and the shell * declare the wires * connect the wires * instantiate the modules The first two are used in the shell module as well as in the top level block. The last is for the shell only.
Diffstat (limited to 'host/utils/rfnoc_blocktool/templates/modules')
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_chdr_connect_template.mako15
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_chdr_modules_template.mako41
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_chdr_wires_template.mako30
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_connect_template.mako8
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_modules_template.mako28
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_wires_template.mako23
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_raw_connect_template.mako31
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_raw_modules_template.mako78
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/axis_raw_wires_template.mako50
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/ctrlport_connect_template.mako41
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/ctrlport_modules_template.mako47
-rw-r--r--host/utils/rfnoc_blocktool/templates/modules/ctrlport_wires_template.mako58
12 files changed, 450 insertions, 0 deletions
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_connect_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_connect_template.mako
new file mode 100644
index 000000000..ff619b6d9
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_connect_template.mako
@@ -0,0 +1,15 @@
+<%page args="num_inputs, num_outputs"/>
+
+%for idx, input in enumerate(config['data']['inputs']):
+ .m_${input}_chdr_tdata(${input}_chdr_tdata),
+ .m_${input}_chdr_tlast(${input}_chdr_tlast),
+ .m_${input}_chdr_tvalid(${input}_chdr_tvalid),
+ .m_${input}_chdr_tready(${input}_chdr_tready)${"," if (idx < num_inputs -1) or (num_outputs > 0) else ""}
+%endfor
+
+%for idx, output in enumerate(config['data']['outputs']):
+ .s_${output}_chdr_tdata(${output}_chdr_tdata),
+ .s_${output}_chdr_tlast(${output}_chdr_tlast),
+ .s_${output}_chdr_tvalid(${output}_chdr_tvalid),
+ .s_${output}_chdr_tready(${output}_chdr_tready)${"," if (idx < num_outputs -1) else ""}
+%endfor
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_modules_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_modules_template.mako
new file mode 100644
index 000000000..bcb23dff6
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_modules_template.mako
@@ -0,0 +1,41 @@
+%for idx, input in enumerate(config['data']['inputs']):
+ chdr_to_chdr_data #(
+ .CHDR_W(CHDR_W)
+ ) chdr_to_chdr_data_i${idx} (
+ .axis_chdr_clk(rfnoc_chdr_clk),
+ .axis_chdr_rst(rfnoc_chdr_rst),
+ .s_axis_chdr_tdata(s_rfnoc_chdr_tdata[(${idx}*CHDR_W)+:CHDR_W]),
+ .s_axis_chdr_tlast(s_rfnoc_chdr_tlast[${idx}]),
+ .s_axis_chdr_tvalid(s_rfnoc_chdr_tvalid[${idx}]),
+ .s_axis_chdr_tready(s_rfnoc_chdr_tready[${idx}]),
+ .m_axis_chdr_tdata(m_${input}_chdr_tdata),
+ .m_axis_chdr_tlast(m_${input}_chdr_tlast),
+ .m_axis_chdr_tvalid(m_${input}_chdr_tvalid),
+ .m_axis_chdr_tready(m_${input}_chdr_tready),
+ .flush_en(data_i_flush_en),
+ .flush_timeout(data_i_flush_timeout),
+ .flush_active(data_i_flush_active[${idx}]),
+ .flush_done(data_i_flush_done[${idx}])
+ );
+%endfor
+
+%for idx, output in enumerate(config['data']['outputs']):
+ chdr_to_chdr_data #(
+ .CHDR_W(CHDR_W)
+ ) chdr_to_chdr_data_o${idx} (
+ .axis_chdr_clk(rfnoc_chdr_clk),
+ .axis_chdr_rst(rfnoc_chdr_rst),
+ .m_axis_chdr_tdata(m_rfnoc_chdr_tdata[(${idx}*CHDR_W)+:CHDR_W]),
+ .m_axis_chdr_tlast(m_rfnoc_chdr_tlast[${idx}]),
+ .m_axis_chdr_tvalid(m_rfnoc_chdr_tvalid[${idx}]),
+ .m_axis_chdr_tready(m_rfnoc_chdr_tready[${idx}]),
+ .s_axis_chdr_tdata(s_${output}_chdr_tdata),
+ .s_axis_chdr_tlast(s_${output}_chdr_tlast),
+ .s_axis_chdr_tvalid(s_${output}_chdr_tvalid),
+ .s_axis_chdr_tready(s_${output}_chdr_tready),
+ .flush_en(data_o_flush_en),
+ .flush_timeout(data_o_flush_timeout),
+ .flush_active(data_o_flush_active[${idx}]),
+ .flush_done(data_o_flush_done[${idx}])
+ );
+%endfor
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_wires_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_wires_template.mako
new file mode 100644
index 000000000..9453c8fd1
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_chdr_wires_template.mako
@@ -0,0 +1,30 @@
+<%page args="mode, num_inputs, num_outputs"/>\
+
+<%
+ if mode == "shell":
+ sl_pre = "s_"
+ ma_pre = "m_"
+ in_wire = "input "
+ out_wire = "output "
+ term = ","
+ elif mode == "block":
+ sl_pre = ""
+ ma_pre = ""
+ in_wire = ""
+ out_wire = ""
+ term=";"
+%>\
+%for idx, port in enumerate(config['data']['inputs']):
+ // Payload Stream to User Logic: ${port}
+ ${out_wire}wire [CHDR_W-1:0] ${ma_pre}${port}_chdr_tdata${term}
+ ${out_wire}wire ${ma_pre}${port}_chdr_tlast${term}
+ ${out_wire}wire ${ma_pre}${port}_chdr_tvalid${term}
+ ${in_wire}wire ${ma_pre}${port}_chdr_tready${term if (term == ";") or (idx < num_inputs -1) or (num_outputs > 0) else ""}
+%endfor
+
+%for idx, port in enumerate(config['data']['outputs']):
+ ${in_wire}wire [CHDR_W-1:0] ${sl_pre}${port}_chdr_tdata${term}
+ ${in_wire}wire ${sl_pre}${port}_chdr_tlast${term}
+ ${in_wire}wire ${sl_pre}${port}_chdr_tvalid${term}
+ ${out_wire}wire ${sl_pre}${port}_chdr_tready${term if (term == ";") or (idx < num_outputs -1) else ""}
+%endfor
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_connect_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_connect_template.mako
new file mode 100644
index 000000000..cefc97a22
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_connect_template.mako
@@ -0,0 +1,8 @@
+ .m_axis_ctrl_tdata(m_axis_ctrl_tdata),
+ .m_axis_ctrl_tlast(m_axis_ctrl_tlast),
+ .m_axis_ctrl_tvalid(m_axis_ctrl_tvalid),
+ .m_axis_ctrl_tready(m_axis_ctrl_tready),
+ .s_axis_ctrl_tdata(s_axis_ctrl_tdata),
+ .s_axis_ctrl_tlast(s_axis_ctrl_tlast),
+ .s_axis_ctrl_tvalid(s_axis_ctrl_tvalid),
+ .s_axis_ctrl_tready(s_axis_ctrl_tready),
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_modules_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_modules_template.mako
new file mode 100644
index 000000000..4c349b11b
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_modules_template.mako
@@ -0,0 +1,28 @@
+<%!
+import math
+%>
+ axis_ctrl_endpoint #(
+ .SYNC_CLKS(${1 if config['control']['clk_domain'] == "rfnoc_ctrl" else 0}),
+ .SLAVE_FIFO_SIZE(${math.ceil(math.log2(config['control']['fifo_depth']))})
+ ) axis_ctrl_endpoint_i (
+ .rfnoc_ctrl_clk(rfnoc_ctrl_clk),
+ .rfnoc_ctrl_rst(rfnoc_ctrl_rst),
+ .axis_ctrl_clk(axis_ctrl_clk),
+ .axis_ctrl_rst(axis_ctrl_rst),
+ .s_rfnoc_ctrl_tdata(s_rfnoc_ctrl_tdata),
+ .s_rfnoc_ctrl_tlast(s_rfnoc_ctrl_tlast),
+ .s_rfnoc_ctrl_tvalid(s_rfnoc_ctrl_tvalid),
+ .s_rfnoc_ctrl_tready(s_rfnoc_ctrl_tready),
+ .m_rfnoc_ctrl_tdata(m_rfnoc_ctrl_tdata),
+ .m_rfnoc_ctrl_tlast(m_rfnoc_ctrl_tlast),
+ .m_rfnoc_ctrl_tvalid(m_rfnoc_ctrl_tvalid),
+ .m_rfnoc_ctrl_tready(m_rfnoc_ctrl_tready),
+ .s_axis_ctrl_tdata(s_axis_ctrl_tdata),
+ .s_axis_ctrl_tlast(s_axis_ctrl_tlast),
+ .s_axis_ctrl_tvalid(s_axis_ctrl_tvalid),
+ .s_axis_ctrl_tready(s_axis_ctrl_tready),
+ .m_axis_ctrl_tdata(m_axis_ctrl_tdata),
+ .m_axis_ctrl_tlast(m_axis_ctrl_tlast),
+ .m_axis_ctrl_tvalid(m_axis_ctrl_tvalid),
+ .m_axis_ctrl_tready(m_axis_ctrl_tready)
+ );
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_wires_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_wires_template.mako
new file mode 100644
index 000000000..dd15bd100
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_ctrl_wires_template.mako
@@ -0,0 +1,23 @@
+<%page args="mode"/>\
+<%
+ if mode == "shell":
+ sl_pre = "s_"
+ ma_pre = "m_"
+ in_wire = "input "
+ out_wire = "output "
+ term = ","
+ elif mode == "block":
+ sl_pre = "s_"
+ ma_pre = "m_"
+ in_wire = ""
+ out_wire = ""
+ term = ";"
+%>\
+ ${out_wire}wire [31:0] ${ma_pre}axis_ctrl_tdata${term}
+ ${out_wire}wire ${ma_pre}axis_ctrl_tlast${term}
+ ${out_wire}wire ${ma_pre}axis_ctrl_tvalid${term}
+ ${in_wire}wire ${ma_pre}axis_ctrl_tready${term}
+ ${in_wire}wire [31:0] ${sl_pre}axis_ctrl_tdata${term}
+ ${in_wire}wire ${sl_pre}axis_ctrl_tlast${term}
+ ${in_wire}wire ${sl_pre}axis_ctrl_tvalid${term}
+ ${out_wire}wire ${sl_pre}axis_ctrl_tready${term}
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_raw_connect_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_raw_connect_template.mako
new file mode 100644
index 000000000..c78946289
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_raw_connect_template.mako
@@ -0,0 +1,31 @@
+<%page args="num_inputs, num_outputs"/>\
+\
+%for idx, input in enumerate(config['data']['inputs']):
+ // Payload Stream to User Logic: ${input}
+ .m_${input}_payload_tdata(${input}_payload_tdata),
+ .m_${input}_payload_tkeep(${input}_payload_tkeep),
+ .m_${input}_payload_tlast(${input}_payload_tlast),
+ .m_${input}_payload_tvalid(${input}_payload_tvalid),
+ .m_${input}_payload_tready(${input}_payload_tready),
+ // Context Stream to User Logic: ${input}
+ .m_${input}_context_tdata(${input}_context_tdata),
+ .m_${input}_context_tuser(${input}_context_tuser),
+ .m_${input}_context_tlast(${input}_context_tlast),
+ .m_${input}_context_tvalid(${input}_context_tvalid),
+ .m_${input}_context_tready(${input}_context_tready)${"," if (idx < num_inputs - 1) or (num_outputs > 0) else ""}
+%endfor
+
+%for idx, output in enumerate(config['data']['outputs']):
+ // Payload Stream from User Logic: ${output}
+ .s_${output}_payload_tdata(${output}_payload_tdata),
+ .s_${output}_payload_tkeep(${output}_payload_tkeep),
+ .s_${output}_payload_tlast(${output}_payload_tlast),
+ .s_${output}_payload_tvalid(${output}_payload_tvalid),
+ .s_${output}_payload_tready(${output}_payload_tready),
+ // Context Stream from User Logic: ${output}
+ .s_${output}_context_tdata(${output}_context_tdata),
+ .s_${output}_context_tuser(${output}_context_tuser),
+ .s_${output}_context_tlast(${output}_context_tlast),
+ .s_${output}_context_tvalid(${output}_context_tvalid),
+ .s_${output}_context_tready(${output}_context_tready)${"," if (idx < num_outputs -1) else ""}
+%endfor
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_raw_modules_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_raw_modules_template.mako
new file mode 100644
index 000000000..c181eeedd
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_raw_modules_template.mako
@@ -0,0 +1,78 @@
+
+%for idx, input in enumerate(config['data']['inputs']):
+ <%
+ port_tmp = config['data']['inputs'][input]
+ %>
+ chdr_to_axis_raw_data #(
+ .CHDR_W(CHDR_W),
+ .ITEM_W(${port_tmp['item_width']}),
+ .NIPC(${port_tmp['nipc']}),
+ .SYNC_CLKS(${1 if config['data']['clk_domain'] == "rfnoc_chdr" else 0}),
+ .CONTEXT_FIFO_SIZE(${port_tmp['context_fifo_depth']}),
+ .PAYLOAD_FIFO_SIZE(${port_tmp['payload_fifo_depth']}),
+ .CONTEXT_PREFETCH_EN(1)
+ ) chdr_to_axis_raw_data_i${idx} (
+ .axis_chdr_clk(rfnoc_chdr_clk),
+ .axis_chdr_rst(rfnoc_chdr_rst),
+ .axis_data_clk(axis_data_clk),
+ .axis_data_rst(axis_data_rst),
+ .s_axis_chdr_tdata(s_rfnoc_chdr_tdata[(${idx}*CHDR_W)+:CHDR_W]),
+ .s_axis_chdr_tlast(s_rfnoc_chdr_tlast[${idx}]),
+ .s_axis_chdr_tvalid(s_rfnoc_chdr_tvalid[${idx}]),
+ .s_axis_chdr_tready(s_rfnoc_chdr_tready[${idx}]),
+ .m_axis_payload_tdata(m_${input}_payload_tdata),
+ .m_axis_payload_tkeep(m_${input}_payload_tkeep),
+ .m_axis_payload_tlast(m_${input}_payload_tlast),
+ .m_axis_payload_tvalid(m_${input}_payload_tvalid),
+ .m_axis_payload_tready(m_${input}_payload_tready),
+ .m_axis_context_tdata(m_${input}_context_tdata),
+ .m_axis_context_tuser(m_${input}_context_tuser),
+ .m_axis_context_tlast(m_${input}_context_tlast),
+ .m_axis_context_tvalid(m_${input}_context_tvalid),
+ .m_axis_context_tready(m_${input}_context_tready),
+ .flush_en(data_i_flush_en),
+ .flush_timeout(data_i_flush_timeout),
+ .flush_active(data_i_flush_active[${idx}]),
+ .flush_done(data_i_flush_done[${idx}])
+ );
+%endfor
+
+%for idx, output in enumerate(config['data']['outputs']):
+ <%
+ port_tmp = config['data']['outputs'][output]
+ %>
+ axis_raw_data_to_chdr #(
+ .CHDR_W(CHDR_W),
+ .ITEM_W(${port_tmp['item_width']}),
+ .NIPC(${port_tmp['nipc']}),
+ .SYNC_CLKS(${1 if config['data']['clk_domain'] == "rfnoc_chdr" else 0}),
+ .CONTEXT_FIFO_SIZE(${port_tmp['context_fifo_depth']}),
+ .PAYLOAD_FIFO_SIZE(${port_tmp['payload_fifo_depth']}),
+ .CONTEXT_PREFETCH_EN(1),
+ .MTU(MTU)
+ ) axis_raw_data_to_chdr_i${idx} (
+ .axis_chdr_clk(rfnoc_chdr_clk),
+ .axis_chdr_rst(rfnoc_chdr_rst),
+ .axis_data_clk(axis_data_clk),
+ .axis_data_rst(axis_data_rst),
+ .m_axis_chdr_tdata(m_rfnoc_chdr_tdata[(${idx}*CHDR_W)+:CHDR_W]),
+ .m_axis_chdr_tlast(m_rfnoc_chdr_tlast[${idx}]),
+ .m_axis_chdr_tvalid(m_rfnoc_chdr_tvalid[${idx}]),
+ .m_axis_chdr_tready(m_rfnoc_chdr_tready[${idx}]),
+ .s_axis_payload_tdata(s_${output}_payload_tdata),
+ .s_axis_payload_tkeep(s_${output}_payload_tkeep),
+ .s_axis_payload_tlast(s_${output}_payload_tlast),
+ .s_axis_payload_tvalid(s_${output}_payload_tvalid),
+ .s_axis_payload_tready(s_${output}_payload_tready),
+ .s_axis_context_tdata(s_${output}_context_tdata),
+ .s_axis_context_tuser(s_${output}_context_tuser),
+ .s_axis_context_tlast(s_${output}_context_tlast),
+ .s_axis_context_tvalid(s_${output}_context_tvalid),
+ .s_axis_context_tready(s_${output}_context_tready),
+ .framer_errors(),
+ .flush_en(data_o_flush_en),
+ .flush_timeout(data_o_flush_timeout),
+ .flush_active(data_o_flush_active[${idx}]),
+ .flush_done(data_o_flush_done[${idx}])
+ );
+%endfor
diff --git a/host/utils/rfnoc_blocktool/templates/modules/axis_raw_wires_template.mako b/host/utils/rfnoc_blocktool/templates/modules/axis_raw_wires_template.mako
new file mode 100644
index 000000000..abb8ef5e0
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/axis_raw_wires_template.mako
@@ -0,0 +1,50 @@
+<%page args="mode, num_inputs, num_outputs"/>\
+<%
+ if mode == "shell":
+ sl_pre = "s_"
+ ma_pre = "m_"
+ in_wire = "input "
+ out_wire = "output "
+ term = ","
+ elif mode == "block":
+ sl_pre = ""
+ ma_pre = ""
+ in_wire = ""
+ out_wire = ""
+ term = ";"
+%>\
+%for idx, port in enumerate(config['data']['inputs']):
+ <%
+ port_tmp = config['data']['inputs'][port]
+ %>\
+ // Payload Stream to User Logic: ${port}
+ ${out_wire}wire [${port_tmp['item_width']*port_tmp['nipc']-1}:0] ${ma_pre}${port}_payload_tdata${term}
+ ${out_wire}wire [${port_tmp['nipc']-1}:0] ${ma_pre}${port}_payload_tkeep${term}
+ ${out_wire}wire ${ma_pre}${port}_payload_tlast${term}
+ ${out_wire}wire ${ma_pre}${port}_payload_tvalid${term}
+ ${in_wire}wire ${ma_pre}${port}_payload_tready${term}
+ // Context Stream to User Logic: ${port}
+ ${out_wire}wire [CHDR_W-1:0] ${ma_pre}${port}_context_tdata${term}
+ ${out_wire}wire [3:0] ${ma_pre}${port}_context_tuser${term}
+ ${out_wire}wire ${ma_pre}${port}_context_tlast${term}
+ ${out_wire}wire ${ma_pre}${port}_context_tvalid${term}
+ ${in_wire}wire ${ma_pre}${port}_context_tready${term if (term == ";") or (idx < num_inputs - 1) or (num_outputs > 0) else ""}
+%endfor
+
+%for idx, port in enumerate(config['data']['outputs']):
+ <%
+ port_tmp = config['data']['outputs'][port]
+ %>\
+ // Payload Stream from User Logic: ${port}
+ ${in_wire}wire [${port_tmp['item_width'] * port_tmp['nipc'] - 1}:0] ${sl_pre}${port}_payload_tdata${term}
+ ${in_wire}wire [${port_tmp['nipc'] - 1}:0] ${sl_pre}${port}_payload_tkeep${term}
+ ${in_wire}wire ${sl_pre}${port}_payload_tlast${term}
+ ${in_wire}wire ${sl_pre}${port}_payload_tvalid${term}
+ ${out_wire}wire ${sl_pre}${port}_payload_tready${term}
+ // Context Stream from User Logic: ${port}
+ ${in_wire}wire [CHDR_W-1:0] ${sl_pre}${port}_context_tdata${term}
+ ${in_wire}wire [3:0] ${sl_pre}${port}_context_tuser${term}
+ ${in_wire}wire ${sl_pre}${port}_context_tlast${term}
+ ${in_wire}wire ${sl_pre}${port}_context_tvalid${term}
+ ${out_wire}wire ${sl_pre}${port}_context_tready${term if (term == ";") or (idx < num_outputs -1) else ""}
+%endfor
diff --git a/host/utils/rfnoc_blocktool/templates/modules/ctrlport_connect_template.mako b/host/utils/rfnoc_blocktool/templates/modules/ctrlport_connect_template.mako
new file mode 100644
index 000000000..944f4af16
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/ctrlport_connect_template.mako
@@ -0,0 +1,41 @@
+ // Control Port Master
+ .m_ctrlport_req_wr(m_ctrlport_req_wr),
+ .m_ctrlport_req_rd(m_ctrlport_req_rd),
+ .m_ctrlport_req_addr(m_ctrlport_req_addr),
+ .m_ctrlport_req_data(m_ctrlport_req_data),
+%if config['control']['ctrlport']['byte_mode']:
+ .m_ctrlport_req_byte_en(m_ctrlport_req_byte_en),
+%endif
+%if config['control']['ctrlport']['timed']:
+ .m_ctrlport_req_has_time(m_ctrlport_req_has_time),
+ .m_ctrlport_req_time(m_ctrlport_req_time),
+%endif
+ .m_ctrlport_resp_ack(m_ctrlport_resp_ack),
+%if config['control']['ctrlport']['has_status']:
+ .m_ctrlport_resp_status(m_ctrlport_resp_status),
+%endif
+ .m_ctrlport_resp_data(m_ctrlport_resp_data),
+%if config['control']['interface_direction'] != "slave":
+ // Control Port Slave
+ .s_ctrlport_req_wr(s_ctrlport_req_wr),
+ .s_ctrlport_req_rd(s_ctrlport_req_rd),
+ .s_ctrlport_req_addr(s_ctrlport_req_addr),
+ .s_ctrlport_req_portid(s_ctrlport_req_portid),
+ %if config['control']['interface_direction'] == "remote_master_slave":
+ .s_ctrlport_req_rem_epid(s_ctrlport_req_rem_epid),
+ .s_ctrlport_req_rem_portid(s_ctrlport_req_rem_portid),
+ %endif
+ .s_ctrlport_req_data(s_ctrlport_req_data),
+ %if config['control']['ctrlport']['byte_mode']:
+ .s_ctrlport_req_byte_en(s_ctrlport_req_byte_en),
+ %endif
+ %if config['control']['ctrlport']['timed']:
+ .s_ctrlport_req_has_time(s_ctrlport_req_has_time),
+ .s_ctrlport_req_time(s_ctrlport_req_time),
+ %endif
+ .s_ctrlport_resp_ack(s_ctrlport_resp_ack),
+ %if config['control']['ctrlport']['has_status']:
+ .s_ctrlport_resp_status(s_ctrlport_resp_status),
+ %endif
+ .s_ctrlport_resp_data(s_ctrlport_resp_data),
+%endif
diff --git a/host/utils/rfnoc_blocktool/templates/modules/ctrlport_modules_template.mako b/host/utils/rfnoc_blocktool/templates/modules/ctrlport_modules_template.mako
new file mode 100644
index 000000000..9aecc2b80
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/ctrlport_modules_template.mako
@@ -0,0 +1,47 @@
+<%!
+import math
+%>
+ ctrlport_endpoint #(
+ .THIS_PORTID(THIS_PORTID),
+ .SYNC_CLKS(${1 if config['control']['clk_domain'] == "rfnoc_ctrl" else 0}),
+ .AXIS_CTRL_MST_EN(${int(config['control']['interface_direction'] != "slave")}),
+ .AXIS_CTRL_SLV_EN(1),
+ .SLAVE_FIFO_SIZE(${math.ceil(math.log2(config['control']['fifo_depth']))})
+ ) ctrlport_endpoint_i (
+ .rfnoc_ctrl_clk(rfnoc_ctrl_clk),
+ .rfnoc_ctrl_rst(rfnoc_ctrl_rst),
+ .ctrlport_clk(ctrlport_clk),
+ .ctrlport_rst(ctrlport_rst),
+ .s_rfnoc_ctrl_tdata(s_rfnoc_ctrl_tdata),
+ .s_rfnoc_ctrl_tlast(s_rfnoc_ctrl_tlast),
+ .s_rfnoc_ctrl_tvalid(s_rfnoc_ctrl_tvalid),
+ .s_rfnoc_ctrl_tready(s_rfnoc_ctrl_tready),
+ .m_rfnoc_ctrl_tdata(m_rfnoc_ctrl_tdata),
+ .m_rfnoc_ctrl_tlast(m_rfnoc_ctrl_tlast),
+ .m_rfnoc_ctrl_tvalid(m_rfnoc_ctrl_tvalid),
+ .m_rfnoc_ctrl_tready(m_rfnoc_ctrl_tready),
+ .m_ctrlport_req_wr(m_ctrlport_req_wr),
+ .m_ctrlport_req_rd(m_ctrlport_req_rd),
+ .m_ctrlport_req_addr(m_ctrlport_req_addr),
+ .m_ctrlport_req_data(m_ctrlport_req_data),
+ .m_ctrlport_req_byte_en(${"m_ctrlport_req_byte_en" if config['control']['ctrlport']['byte_mode'] else ""}),
+ .m_ctrlport_req_has_time(${"m_ctrlport_req_has_time" if config['control']['ctrlport']['timed'] else ""}),
+ .m_ctrlport_req_time(${"m_ctrlport_req_time" if config['control']['ctrlport']['timed'] else ""}),
+ .m_ctrlport_resp_ack(m_ctrlport_resp_ack),
+ .m_ctrlport_resp_status(${"m_ctrlport_resp_status" if config['control']['ctrlport']['has_status'] else "'h0"}),
+ .m_ctrlport_resp_data(m_ctrlport_resp_data),
+ .s_ctrlport_req_wr(${"s_ctrlport_req_wr" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_rd(${"s_ctrlport_req_rd" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_addr(${"s_ctrlport_req_addr" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_portid(${"s_ctrlport_req_portid" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_rem_epid(${"s_ctrlport_req_rem_epid" if config['control']['interface_direction'] == "remote_master_slave" else "'h0"}),
+ .s_ctrlport_req_rem_portid(${"s_ctrlport_req_rem_portid" if config['control']['interface_direction'] == "remote_master_slave" else "'h0"}),
+ .s_ctrlport_req_data(${"s_ctrlport_req_data" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_byte_en(${"s_ctrlport_req_byte_en" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_has_time(${"s_ctrlport_req_has_time" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_req_time(${"s_ctrlport_req_time" if config['control']['interface_direction'] != "slave" else "'h0"}),
+ .s_ctrlport_resp_ack(${"s_ctrlport_resp_ack" if config['control']['interface_direction'] != "slave" else ""}),
+ .s_ctrlport_resp_status(${"s_ctrlport_resp_status" if config['control']['interface_direction'] != "slave" else ""}),
+ .s_ctrlport_resp_data(${"s_ctrlport_resp_data" if config['control']['interface_direction'] != "slave" else ""})
+ );
+ \ No newline at end of file
diff --git a/host/utils/rfnoc_blocktool/templates/modules/ctrlport_wires_template.mako b/host/utils/rfnoc_blocktool/templates/modules/ctrlport_wires_template.mako
new file mode 100644
index 000000000..6d149ae6b
--- /dev/null
+++ b/host/utils/rfnoc_blocktool/templates/modules/ctrlport_wires_template.mako
@@ -0,0 +1,58 @@
+<%page args="mode"/>\
+\
+<%
+ if mode == "shell":
+ sl_pre = "s_"
+ ma_pre = "m_"
+ sl_wire = "input "
+ ma_wire = "output "
+ term = ","
+ elif mode == "block":
+ sl_pre = "s_"
+ ma_pre = "m_"
+ sl_wire = ""
+ ma_wire = ""
+ term = ";"
+%>\
+ // Control Port Master
+ ${ma_wire}wire ${ma_pre}ctrlport_req_wr${term}
+ ${ma_wire}wire ${ma_pre}ctrlport_req_rd${term}
+ ${ma_wire}wire [19:0] ${ma_pre}ctrlport_req_addr${term}
+ ${ma_wire}wire [31:0] ${ma_pre}ctrlport_req_data${term}
+%if config['control']['ctrlport']['byte_mode']:
+ ${ma_wire}wire [3:0] ${ma_pre}ctrlport_req_byte_en${term}
+%endif
+%if config['control']['ctrlport']['timed']:
+ ${ma_wire}wire ${ma_pre}ctrlport_req_ha${sl_pre}time${term}
+ ${ma_wire}wire [63:0] ${ma_pre}ctrlport_req_time${term}
+%endif
+ ${sl_wire}wire ${ma_pre}ctrlport_resp_ack${term}
+%if config['control']['ctrlport']['has_status']:
+ ${sl_wire}wire [1:0] ${ma_pre}ctrlport_resp_status${term}
+%endif
+ ${sl_wire}wire [31:0] ${ma_pre}ctrlport_resp_data${term}
+
+%if config['control']['interface_direction'] != "slave":
+ // Control Port Slave
+ ${sl_wire}wire ${sl_pre}ctrlport_req_wr${term}
+ ${sl_wire}wire ${sl_pre}ctrlport_req_rd${term}
+ ${sl_wire}wire [19:0] ${sl_pre}ctrlport_req_addr${term}
+ ${sl_wire}wire [9:0] ${sl_pre}ctrlport_req_portid${term}
+ %if config['control']['interface_direction'] == "remote_master_slave":
+ ${sl_wire}wire [15:0] ${sl_pre}ctrlport_req_rem_epid${term}
+ ${sl_wire}wire [9:0] ${sl_pre}ctrlport_req_rem_portid${term}
+ %endif
+ ${sl_wire}wire [31:0] ${sl_pre}ctrlport_req_data${term}
+ %if config['control']['ctrlport']['byte_mode']:
+ ${sl_wire}wire [3:0] ${sl_pre}ctrlport_req_byte_en${term}
+ %endif
+ %if config['control']['ctrlport']['timed']:
+ ${sl_wire}wire ${sl_pre}ctrlport_req_has_time${term}
+ ${sl_wire}wire [63:0] ${sl_pre}ctrlport_req_time${term}
+ %endif
+ ${ma_wire}wire ${sl_pre}ctrlport_resp_ack${term}
+ %if config['control']['ctrlport']['has_status']:
+ ${ma_wire}wire [1:0] ${sl_pre}ctrlport_resp_status${term}
+ %endif
+ ${ma_wire}wire [31:0] ${sl_pre}ctrlport_resp_data${term}
+%endif