aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/vivado_ipi/axi_dmac/bd
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/vivado_ipi/axi_dmac/bd')
-rw-r--r--fpga/usrp3/lib/vivado_ipi/axi_dmac/bd/bd.tcl115
1 files changed, 115 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/vivado_ipi/axi_dmac/bd/bd.tcl b/fpga/usrp3/lib/vivado_ipi/axi_dmac/bd/bd.tcl
new file mode 100644
index 000000000..d67f5134c
--- /dev/null
+++ b/fpga/usrp3/lib/vivado_ipi/axi_dmac/bd/bd.tcl
@@ -0,0 +1,115 @@
+
+proc init {cellpath otherInfo} {
+ set ip [get_bd_cells $cellpath]
+
+ bd::mark_propagate_override $ip \
+ "ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ"
+
+ # On ZYNQ the core is most likely connected to the AXI3 HP ports so use AXI3
+ # as the default.
+ set family [string tolower [get_property FAMILY [get_property PART [current_project]]]]
+ if {$family == "zynq"} {
+ set axi_protocol 1
+ } else {
+ set axi_protocol 0
+ }
+
+ foreach dir {SRC DEST} {
+ # This is a bit of a hack, but we can't change the protocol if the type
+ # is not AXI MM
+ set old [get_property "CONFIG.DMA_TYPE_${dir}" $ip]
+ set_property "CONFIG.DMA_TYPE_${dir}" "0" $ip
+ set_property "CONFIG.DMA_AXI_PROTOCOL_${dir}" $axi_protocol $ip
+ set_property "CONFIG.DMA_TYPE_${dir}" $old $ip
+ }
+}
+
+proc post_config_ip {cellpath otherinfo} {
+ set ip [get_bd_cells $cellpath]
+
+ # Update AXI interface properties according to configuration
+ set max_bytes_per_burst [get_property "CONFIG.MAX_BYTES_PER_BURST" $ip]
+ set fifo_size [get_property "CONFIG.FIFO_SIZE" $ip]
+
+ foreach dir {"SRC" "DEST"} {
+ set type [get_property "CONFIG.DMA_TYPE_$dir" $ip]
+ if {$type != 0} {
+ continue
+ }
+
+ set data_width [get_property "CONFIG.DMA_DATA_WIDTH_$dir" $ip]
+ set max_beats_per_burst [expr {int(ceil($max_bytes_per_burst * 8.0 / $data_width))}]
+
+ set intf [get_bd_intf_pins [format "%s/m_%s_axi" $cellpath [string tolower $dir]]]
+ set_property CONFIG.MAX_BURST_LENGTH $max_beats_per_burst $intf
+
+ # The core issues as many requests as the amount of data the FIFO can hold
+ if {$dir == "SRC"} {
+ set_property CONFIG.NUM_WRITE_OUTSTANDING 0 $intf
+ set_property CONFIG.NUM_READ_OUTSTANDING $fifo_size $intf
+ } else {
+ set_property CONFIG.NUM_WRITE_OUTSTANDING $fifo_size $intf
+ set_property CONFIG.NUM_READ_OUTSTANDING 0 $intf
+ }
+ }
+}
+
+proc axi_dmac_detect_async_clk { cellpath ip param_name clk_a clk_b } {
+ set param_src [get_property "CONFIG.$param_name.VALUE_SRC" $ip]
+ if {[string equal $param_src "USER"]} {
+ return;
+ }
+
+ set clk_domain_a [get_property CONFIG.CLK_DOMAIN $clk_a]
+ set clk_domain_b [get_property CONFIG.CLK_DOMAIN $clk_b]
+ set clk_freq_a [get_property CONFIG.FREQ_HZ $clk_a]
+ set clk_freq_b [get_property CONFIG.FREQ_HZ $clk_b]
+ set clk_phase_a [get_property CONFIG.PHASE $clk_a]
+ set clk_phase_b [get_property CONFIG.PHASE $clk_b]
+
+ # Only mark it as sync if we can make sure that it is sync, if the
+ # relationship of the clocks is unknown mark it as async
+ if {$clk_domain_a != {} && $clk_domain_b != {} && \
+ $clk_domain_a == $clk_domain_b && $clk_freq_a == $clk_freq_b && \
+ $clk_phase_a == $clk_phase_b} {
+ set clk_async 0
+ } else {
+ set clk_async 1
+ }
+
+ set_property "CONFIG.$param_name" $clk_async $ip
+
+# if {$clk_async == 0} {
+# bd::send_msg -of $cellpath -type INFO -msg_id 1 -text "$clk_a and $clk_b are synchronous"
+# } else {
+# bd::send_msg -of $cellpath -type INFO -msg_id 1 -text "$clk_a and $clk_b are asynchronous"
+# }
+}
+
+proc propagate {cellpath otherinfo} {
+ set ip [get_bd_cells $cellpath]
+ set src_type [get_property CONFIG.DMA_TYPE_SRC $ip]
+ set dest_type [get_property CONFIG.DMA_TYPE_DEST $ip]
+
+ set req_clk [get_bd_pins "$ip/s_axi_aclk"]
+
+ if {$src_type == 2} {
+ set src_clk [get_bd_pins "$ip/fifo_wr_clk"]
+ } elseif {$src_type == 1} {
+ set src_clk [get_bd_pins "$ip/s_axis_aclk"]
+ } else {
+ set src_clk [get_bd_pins "$ip/m_src_axi_aclk"]
+ }
+
+ if {$dest_type == 2} {
+ set dest_clk [get_bd_pins "$ip/fifo_rd_clk"]
+ } elseif {$dest_type == 1} {
+ set dest_clk [get_bd_pins "$ip/m_axis_aclk"]
+ } else {
+ set dest_clk [get_bd_pins "$ip/m_dest_axi_aclk"]
+ }
+
+ axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_REQ_SRC" $req_clk $src_clk
+ axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_SRC_DEST" $src_clk $dest_clk
+ axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_DEST_REQ" $dest_clk $req_clk
+}