33# ## SPDX short identifier: ADIBSD
44# ##############################################################################
55
6- proc spi_engine_create {{name " spi_engine" } {data_width 32} {async_spi_clk 1} {num_cs 1} {num_sdi 1} {num_sdo 1} {sdi_delay 0} {echo_sclk 0} {sdo_streaming 0} {cmd_mem_addr_width 4} {data_mem_addr_width 4} {sdi_fifo_addr_width 5} {sdo_fifo_addr_width 5} {sync_fifo_addr_width 4} {cmd_fifo_addr_width 4}} {
7- puts " echo_sclk: $echo_sclk "
6+ # # Unified SPI Engine generation script
7+ # # This script provides a single implementation that works for both Xilinx and Intel
8+ # # by using the vendor-agnostic ad_* procedures from adi_board.tcl or <intel_carrier>_system_qsys.tcl
89
9- create_bd_cell -type hier $name
10- current_bd_instance /$name
11-
12- if {$async_spi_clk == 1} {
13- create_bd_pin -dir I -type clk spi_clk
10+ proc ad_detect_vendor {} {
11+ if {[info commands get_bd_cells] != " " } {
12+ return " xilinx"
1413 }
15- if {$echo_sclk == 1 } {
16- create_bd_pin -dir I -type clk echo_sclk
14+ if {[ info commands add_instance] != " " } {
15+ return " intel "
1716 }
18- create_bd_pin -dir I -type clk clk
19- create_bd_pin -dir I -type rst resetn
20- create_bd_pin -dir I trigger
21- create_bd_pin -dir O irq
22- create_bd_intf_pin -mode Master -vlnv analog.com:interface:spi_engine_rtl:1.0 m_spi
23- create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_sample
24- if {$sdo_streaming == 1} {
25- create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 s_axis_sample
17+ # Default to xilinx for backward compatibility
18+ return " xilinx"
19+ }
20+
21+ proc optional_param {param_list index default_value} {
22+ if {[llength $param_list ] > $index } {
23+ return [lindex $param_list $index ]
24+ } else {
25+ return $default_value
2626 }
27+ }
2728
29+ proc spi_engine_create {args} {
30+
31+ set vendor [ad_detect_vendor]
32+
33+ # Parse arguments based on vendor expectations
34+ if {$vendor == " xilinx" } {
35+ # Xilinx: name + optional parameters
36+ set name [lindex $args 0]
37+ set data_width [optional_param $args 1 32]
38+ set async_spi_clk [optional_param $args 2 1]
39+ set num_cs [optional_param $args 3 1]
40+ set num_sdi [optional_param $args 4 1]
41+ set num_sdo [optional_param $args 5 1]
42+ set sdi_delay [optional_param $args 6 0]
43+ set echo_sclk [optional_param $args 7 0]
44+ set sdo_streaming [optional_param $args 8 0]
45+ set cmd_mem_addr_width [optional_param $args 9 4]
46+ set data_mem_addr_width [optional_param $args 10 4]
47+ set sdi_fifo_addr_width [optional_param $args 11 5]
48+ set sdo_fifo_addr_width [optional_param $args 12 5]
49+ set sync_fifo_addr_width [optional_param $args 13 4]
50+ set cmd_fifo_addr_width [optional_param $args 14 4]
51+
52+ } elseif {$vendor == " intel" } {
53+ # Intel: name + clocks & resets + optional parameters
54+ if {[llength $args ] < 4} {
55+ error " ERROR: Intel implementation requires at least: name, axi_clk, axi_reset, spi_clk"
56+ }
57+ set name [lindex $args 0]
58+ set axi_clk [lindex $args 1]
59+ set axi_reset [lindex $args 2]
60+ set spi_clk [lindex $args 3]
61+ set data_width [optional_param $args 4 32]
62+ set async_spi_clk [optional_param $args 5 1]
63+ set num_cs [optional_param $args 6 1]
64+ set num_sdi [optional_param $args 7 1]
65+ set num_sdo [optional_param $args 8 1]
66+ set sdi_delay [optional_param $args 9 0]
67+ set echo_sclk [optional_param $args 10 0]
68+ set sdo_streaming [optional_param $args 11 0]
69+ set cmd_mem_addr_width [optional_param $args 12 4]
70+ set data_mem_addr_width [optional_param $args 13 4]
71+ set sdi_fifo_addr_width [optional_param $args 14 5]
72+ set sdo_fifo_addr_width [optional_param $args 15 5]
73+ set sync_fifo_addr_width [optional_param $args 16 4]
74+ set cmd_fifo_addr_width [optional_param $args 17 4]
75+ }
76+
77+ # Component instance names
2878 set execution " ${name} _execution"
2979 set axi_regmap " ${name} _axi_regmap"
3080 set offload " ${name} _offload"
3181 set interconnect " ${name} _interconnect"
3282
83+ if {$vendor == " xilinx" } {
84+ # Create hierarchy for Xilinx only
85+ create_bd_cell -type hier $name
86+ current_bd_instance /$name
87+ if {$async_spi_clk == 1} {
88+ create_bd_pin -dir I -type clk spi_clk
89+ }
90+ if {$echo_sclk == 1} {
91+ create_bd_pin -dir I -type clk echo_sclk
92+ }
93+ create_bd_pin -dir I -type clk clk
94+ create_bd_pin -dir I -type rst resetn
95+ create_bd_pin -dir I trigger
96+ create_bd_pin -dir O irq
97+ create_bd_intf_pin -mode Master -vlnv analog.com:interface:spi_engine_rtl:1.0 m_spi
98+ create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_sample
99+ if {$sdo_streaming == 1} {
100+ create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 s_axis_sample
101+ }
102+ }
103+
104+
105+ # IP instances
33106 ad_ip_instance spi_engine_execution $execution
34107 ad_ip_parameter $execution CONFIG.DATA_WIDTH $data_width
35108 ad_ip_parameter $execution CONFIG.NUM_OF_CS $num_cs
@@ -39,6 +112,7 @@ proc spi_engine_create {{name "spi_engine"} {data_width 32} {async_spi_clk 1} {n
39112 ad_ip_parameter $execution CONFIG.ECHO_SCLK $echo_sclk
40113
41114 ad_ip_instance axi_spi_engine $axi_regmap
115+ ad_ip_parameter $axi_regmap CONFIG.MM_IF_TYPE 0
42116 ad_ip_parameter $axi_regmap CONFIG.DATA_WIDTH $data_width
43117 ad_ip_parameter $axi_regmap CONFIG.NUM_OFFLOAD 1
44118 ad_ip_parameter $axi_regmap CONFIG.NUM_OF_SDI $num_sdi
@@ -57,51 +131,97 @@ proc spi_engine_create {{name "spi_engine"} {data_width 32} {async_spi_clk 1} {n
57131 ad_ip_parameter $offload CONFIG.CMD_MEM_ADDRESS_WIDTH $cmd_mem_addr_width
58132 ad_ip_parameter $offload CONFIG.SDO_MEM_ADDRESS_WIDTH $data_mem_addr_width
59133 ad_ip_parameter $offload CONFIG.SDO_STREAMING $sdo_streaming
134+ ad_ip_parameter $offload CONFIG.ASYNC_TRIG 0
60135
61136 ad_ip_instance spi_engine_interconnect $interconnect
62137 ad_ip_parameter $interconnect CONFIG.DATA_WIDTH $data_width
63138 ad_ip_parameter $interconnect CONFIG.NUM_OF_SDI $num_sdi
64139
65- ad_connect $axi_regmap /spi_engine_offload_ctrl0 $offload /spi_engine_offload_ctrl
66- ad_connect $offload /m_interconnect_ctrl $interconnect /s_interconnect_ctrl
67- ad_connect $offload /spi_engine_ctrl $interconnect /s0_ctrl
68- ad_connect $axi_regmap /spi_engine_ctrl $interconnect /s1_ctrl
69- ad_connect $interconnect /m_ctrl $execution /ctrl
70- ad_connect $offload /offload_sdi m_axis_sample
71- ad_connect $offload /trigger trigger
72-
73- ad_connect $execution /spi m_spi
74-
75- if {$sdo_streaming == 1} {
76- ad_connect $offload /s_axis_sdo s_axis_sample
77- }
78-
79- ad_connect clk $axi_regmap /s_axi_aclk
80-
81- if {$async_spi_clk == 1} {
82- ad_connect spi_clk $offload /spi_clk
83- ad_connect spi_clk $offload /ctrl_clk
84- ad_connect spi_clk $execution /clk
85- ad_connect spi_clk $axi_regmap /spi_clk
86- ad_connect spi_clk $interconnect /clk
87- } else {
88- ad_connect clk $offload /spi_clk
89- ad_connect clk $offload /ctrl_clk
90- ad_connect clk $execution /clk
91- ad_connect clk $axi_regmap /spi_clk
92- ad_connect clk $interconnect /clk
140+ # Connections based on vendor
141+ if {$vendor == " xilinx" } {
142+
143+ # Clock connections
144+ ad_connect clk $axi_regmap /s_axi_aclk
145+
146+ if {$async_spi_clk == 1} {
147+ ad_connect spi_clk $offload /spi_clk
148+ ad_connect spi_clk $offload /ctrl_clk
149+ ad_connect spi_clk $execution /clk
150+ ad_connect spi_clk $axi_regmap /spi_clk
151+ ad_connect spi_clk $interconnect /clk
152+ } else {
153+ ad_connect clk $offload /spi_clk
154+ ad_connect clk $offload /ctrl_clk
155+ ad_connect clk $execution /clk
156+ ad_connect clk $axi_regmap /spi_clk
157+ ad_connect clk $interconnect /clk
158+ }
159+
160+ if {$echo_sclk == 1} {
161+ ad_connect echo_sclk $execution /echo_sclk
162+ }
163+
164+ # Reset connections
165+ ad_connect $axi_regmap /spi_resetn $offload /spi_resetn
166+ ad_connect $axi_regmap /spi_resetn $execution /resetn
167+ ad_connect $axi_regmap /spi_resetn $interconnect /resetn
168+ ad_connect resetn $axi_regmap /s_axi_aresetn
169+ ad_connect irq $axi_regmap /irq
170+
171+ # Data path connections
172+ ad_connect $axi_regmap /spi_engine_offload_ctrl0 $offload /spi_engine_offload_ctrl
173+ ad_connect $offload /m_interconnect_ctrl $interconnect /s_interconnect_ctrl
174+ ad_connect $offload /spi_engine_ctrl $interconnect /s0_ctrl
175+ ad_connect $axi_regmap /spi_engine_ctrl $interconnect /s1_ctrl
176+ ad_connect $interconnect /m_ctrl $execution /ctrl
177+ ad_connect $offload /offload_sdi m_axis_sample
178+ ad_connect $offload /trigger trigger
179+ ad_connect $execution /spi m_spi
180+
181+ if {$sdo_streaming == 1} {
182+ ad_connect $offload /s_axis_sdo s_axis_sample
183+ }
184+
185+
186+ # Exit hierarchy
187+ current_bd_instance /
188+
189+ } elseif {$vendor == " intel" } {
190+ # Intel connection style (flat with different interface naming)
191+
192+ # Clock connections
193+ ad_connect $axi_clk $axi_regmap .s_axi_clock
194+ ad_connect $spi_clk $axi_regmap .if_spi_clk
195+ ad_connect $spi_clk $execution .if_clk
196+ ad_connect $spi_clk $interconnect .if_clk
197+ ad_connect $spi_clk $offload .if_ctrl_clk
198+ ad_connect $spi_clk $offload .if_spi_clk
199+
200+ # Reset connections
201+ ad_connect $axi_reset $axi_regmap .s_axi_reset
202+ ad_connect $axi_regmap .if_spi_resetn $execution .if_resetn
203+ ad_connect $axi_regmap .if_spi_resetn $interconnect .if_resetn
204+ ad_connect $axi_regmap .if_spi_resetn $offload .if_spi_resetn
205+
206+ # Data path connections
207+ ad_connect $interconnect .m_cmd $execution .cmd
208+ ad_connect $execution .sdi_data $interconnect .m_sdi
209+ ad_connect $interconnect .m_sdo $execution .sdo_data
210+ ad_connect $execution .sync $interconnect .m_sync
211+ ad_connect $axi_regmap .cmd $interconnect .s1_cmd
212+ ad_connect $interconnect .s1_sdi $axi_regmap .sdi_data
213+ ad_connect $axi_regmap .sdo_data $interconnect .s1_sdo
214+ ad_connect $interconnect .s1_sync $axi_regmap .sync
215+ ad_connect $offload .cmd $interconnect .s0_cmd
216+ ad_connect $interconnect .s0_sdi $offload .sdi_data
217+ ad_connect $offload .sdo_data $interconnect .s0_sdo
218+ ad_connect $interconnect .s0_sync $offload .sync
219+ ad_connect $offload .m_interconnect_ctrl $interconnect .s_interconnect_ctrl
220+ ad_connect $offload .ctrl_cmd_wr $axi_regmap .offload0_cmd
221+ ad_connect $offload .ctrl_sdo_wr $axi_regmap .offload0_sdo
222+ ad_connect $offload .if_ctrl_enable $axi_regmap .if_offload0_enable
223+ ad_connect $offload .if_ctrl_enabled $axi_regmap .if_offload0_enabled
224+ ad_connect $offload .if_ctrl_mem_reset $axi_regmap .if_offload0_mem_reset
225+ ad_connect $offload .status_sync $axi_regmap .offload_sync
93226 }
94-
95- if {$echo_sclk == 1} {
96- ad_connect echo_sclk $execution /echo_sclk
97- }
98-
99- ad_connect $axi_regmap /spi_resetn $offload /spi_resetn
100- ad_connect $axi_regmap /spi_resetn $execution /resetn
101- ad_connect $axi_regmap /spi_resetn $interconnect /resetn
102-
103- ad_connect resetn $axi_regmap /s_axi_aresetn
104- ad_connect irq $axi_regmap /irq
105-
106- current_bd_instance /
107- }
227+ }
0 commit comments