aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/vivado_ipi/axi_dmac/bd/bd.tcl
blob: d67f5134c10f7b08f6a4d6b703938c94a04f5c1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
}