1# Hierarchical cell: tx
2proc create_hier_cell_tx_dma { parentCell nameHier numPorts } {
3
4  if { $parentCell eq "" || $nameHier eq "" || $numPorts eq "" } {
5     puts "ERROR: create_hier_cell_tx() - Empty argument(s)!"
6     return
7  }
8
9  # Get object for parentCell
10  set parentObj [get_bd_cells $parentCell]
11  if { $parentObj == "" } {
12     puts "ERROR: Unable to find parent cell <$parentCell>!"
13     return
14  }
15
16  if { $numPorts < 1 } {
17     puts "ERROR: numPorts invalid: $numPorts"
18     return
19  }
20
21  # Make sure parentObj is hier blk
22  set parentType [get_property TYPE $parentObj]
23  if { $parentType ne "hier" } {
24     puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."
25     return
26  }
27
28  # Save current instance; Restore later
29  set oldCurInst [current_bd_instance .]
30
31  # Set parent object as current
32  current_bd_instance $parentObj
33
34  # Create cell and set as current instance
35  set hier_obj [create_bd_cell -type hier $nameHier]
36  current_bd_instance $hier_obj
37
38  #########################
39  # Pin list
40  #########################
41  create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M_AXIS_DMA
42  create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_TX_DMA
43  create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi_tx_dmac
44
45  create_bd_pin -dir I bus_clk
46  create_bd_pin -dir I bus_rstn
47  create_bd_pin -dir I clk40
48  create_bd_pin -dir I clk40_rstn
49  create_bd_pin -dir O -from [expr $numPorts - 1] -to 0 irq
50
51  #########################
52  # Instantiate IPs
53  #########################
54  set axi_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_0 ]
55  set_property -dict [ list \
56     CONFIG.NUM_MI $numPorts \
57 ] $axi_interconnect_0
58
59  set axi_crossbar_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_crossbar:2.1 axi_crossbar_0 ]
60  set_property -dict [ list \
61     CONFIG.NUM_MI {1} \
62     CONFIG.NUM_SI $numPorts
63 ] $axi_crossbar_0
64
65  set axis_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_interconnect:2.1 axis_interconnect_0 ]
66  set_property -dict [ list \
67     CONFIG.ARB_ON_TLAST {1} \
68     CONFIG.ARB_ON_MAX_XFERS {0} \
69     CONFIG.ENABLE_ADVANCED_OPTIONS {1} \
70     CONFIG.M00_HAS_REGSLICE {1} \
71     CONFIG.NUM_MI {1} \
72     CONFIG.NUM_SI $numPorts \
73  ] $axis_interconnect_0
74
75  set xlconcat_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_0 ]
76  set_property -dict [ list \
77     CONFIG.NUM_PORTS $numPorts \
78  ] $xlconcat_0
79
80  set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ]
81  set_property -dict [ list \
82CONFIG.CONST_VAL {0} \
83 ] $xlconstant_0
84
85  #########################
86  # Wiring
87  #########################
88  connect_bd_net -net bus_clk \
89     [get_bd_pins bus_clk] \
90     [get_bd_pins axis_interconnect_0/ACLK] \
91     [get_bd_pins axis_interconnect_0/M00_AXIS_ACLK]
92  connect_bd_net -net bus_rstn \
93     [get_bd_pins bus_rstn] \
94     [get_bd_pins axis_interconnect_0/ARESETN] \
95     [get_bd_pins axis_interconnect_0/M00_AXIS_ARESETN]
96  connect_bd_net -net clk40 \
97     [get_bd_pins clk40] \
98     [get_bd_pins axi_crossbar_0/aclk] \
99     [get_bd_pins axi_interconnect_0/ACLK] \
100     [get_bd_pins axi_interconnect_0/S00_ACLK]
101  connect_bd_net -net clk40_rstn \
102     [get_bd_pins clk40_rstn] \
103     [get_bd_pins axi_crossbar_0/aresetn] \
104     [get_bd_pins axi_interconnect_0/ARESETN] \
105     [get_bd_pins axi_interconnect_0/S00_ARESETN]
106
107  connect_bd_net -net xlconstant_0_dout \
108     [get_bd_pins xlconstant_0/dout]
109  connect_bd_net -net xlconcat_0_dout \
110     [get_bd_pins irq] \
111     [get_bd_pins xlconcat_0/dout]
112
113  connect_bd_intf_net -intf_net M_AXI_TX_DMAC_1 \
114     [get_bd_intf_pins s_axi_tx_dmac] \
115     [get_bd_intf_pins axi_interconnect_0/S00_AXI]
116  connect_bd_intf_net -intf_net axi_crossbar_0_M00_AXI \
117     [get_bd_intf_pins M_AXI_TX_DMA] \
118     [get_bd_intf_pins axi_crossbar_0/M00_AXI]
119  connect_bd_intf_net -intf_net axis_interconnect_0_M00_AXIS \
120     [get_bd_intf_pins M_AXIS_DMA] \
121     [get_bd_intf_pins axis_interconnect_0/M00_AXIS]
122
123  #########################
124  # Per-port Section
125  #########################
126  for {set i 0} {$i < $numPorts} {incr i} {
127     # Configure each port on axi_crossbar and axis_interconnect
128     puts "Creating TX dma port ${i}"
129     set_property [format "CONFIG.S%02d_SINGLE_THREAD" ${i}] {1} $axi_crossbar_0
130     set_property -dict [ list \
131        [format "CONFIG.S%02d_HAS_REGSLICE" ${i}] {1} \
132     ] $axis_interconnect_0
133
134     set axi_tx_dmac [ create_bd_cell -type ip -vlnv analog.com:user:axi_dmac:1.0 axi_tx_dmac_$i ]
135     set_property -dict [ list \
136        CONFIG.DMA_TYPE_DEST {1} \
137        CONFIG.DMA_TYPE_SRC {0} \
138     ] $axi_tx_dmac
139
140     # Add a tuser signal indicating which DMA channel originated the packet
141     # Hard-coded to handle up to 16 DMA channels
142     # Convert i (in decimal) to 4-bit binary:
143     binary scan [binary format c ${i}] B* i_binary
144     set i_binary [string range ${i_binary} end-3 end]
145
146     set tuser_appender [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_subset_converter:1.1 axis_subset_converter_${i} ]
147     set_property -dict [ list \
148        CONFIG.M_TUSER_WIDTH.VALUE_SRC USER \
149     ] $tuser_appender
150     set_property -dict [ list \
151        CONFIG.M_TUSER_WIDTH {4} \
152        CONFIG.TUSER_REMAP 4'b${i_binary} \
153     ] $tuser_appender
154
155     connect_bd_intf_net -intf_net [format "axis_subset_converter_%d_S_AXIS" ${i}] \
156        [get_bd_intf_pins $axi_tx_dmac/m_axis] \
157        [get_bd_intf_pins ${tuser_appender}/S_AXIS]
158     connect_bd_intf_net -intf_net [format "S%02d_AXIS_1" ${i}] \
159        [get_bd_intf_pins ${tuser_appender}/M_AXIS] \
160        [get_bd_intf_pins [format "axis_interconnect_0/S%02d_AXIS" ${i}]]
161     connect_bd_intf_net -intf_net axi_dmac_${i}_m_src_axi \
162        [get_bd_intf_pins [format "axi_crossbar_0/S%02d_AXI" ${i}]] \
163        [get_bd_intf_pins $axi_tx_dmac/m_src_axi]
164     connect_bd_intf_net -intf_net [format "axi_interconnect_0_M%02d_AXI" ${i}] \
165        [get_bd_intf_pins [format "axi_interconnect_0/M%02d_AXI" ${i}]] \
166        [get_bd_intf_pins $axi_tx_dmac/s_axi]
167
168     connect_bd_net [get_bd_pins $axi_tx_dmac/irq] [get_bd_pins xlconcat_0/In${i}]
169
170     connect_bd_net -net clk40 \
171        [get_bd_pins [format "axi_interconnect_0/M%02d_ACLK" ${i}]]\
172        [get_bd_pins $axi_tx_dmac/m_axis_aclk] \
173        [get_bd_pins $axi_tx_dmac/m_src_axi_aclk] \
174        [get_bd_pins $axi_tx_dmac/s_axi_aclk] \
175	[get_bd_pins $tuser_appender/aclk] \
176        [get_bd_pins [format "axis_interconnect_0/S%02d_AXIS_ACLK" ${i}]]
177
178     connect_bd_net -net clk40_rstn \
179        [get_bd_pins [format "axi_interconnect_0/M%02d_ARESETN" ${i}]] \
180        [get_bd_pins $axi_tx_dmac/m_src_axi_aresetn] \
181        [get_bd_pins $axi_tx_dmac/s_axi_aresetn] \
182	[get_bd_pins $tuser_appender/aresetn] \
183        [get_bd_pins [format "axis_interconnect_0/S%02d_AXIS_ARESETN" ${i}]]
184
185     connect_bd_net -net xlconstant_0_dout \
186        [get_bd_pins [format "axis_interconnect_0/S%02d_ARB_REQ_SUPPRESS" ${i}]]
187  }
188
189  # Restore current instance
190  current_bd_instance $oldCurInst
191}
192
193
194