December 18, 2024

Vivado and Tcl - example 1

The following blog gives a great introduction to Zynq, and in part 3 transitions to using Tcl to do a project in non-project (Tcl) mode. These posts were done in 2021. I am going to work through his first blog posts here and make various notes, and will use other pages for subsequent posts of his.

Lesson 1

He mentions that if you run linux on a Zynq board, you may be able to attach a USB Wifi dongle. He uses a development board called the "Red Pitaya STEMLab 125-14" -- which I have never heard of. This sells for $420 and has some fast ADC and DAC chips.

He does not install board files or talk about them. He selects the part -- xc7z010clg400-1 both when working with the Vivado GUI and when working with Tcl. I kind of like this, as it avoids yet another "black box".

His example bumps the FCLK-0 up to 125 Mhz -- I just leave it at 50. He claims that Vivado needs to know the clock frequencies. I am doubtful -- they need to get set by code in the PS, and I think that values set in these fields will only be used by Vivado when it generates code for the SDK (which I don't use).

He also disables the M_AXI_GP0. I observe the actions this triggers in the Tcl Console.
I set the FCLK-0 to 100, then back to 50 so I could see the Tcl code to do that.

create_project s9_blink_example /u1/home/tom/bin/s9_blink_example -part xc7z010clg400-1
set_property  ip_repo_paths  /u1/home/tom/vivado/ip_repo [current_project]
update_ip_catalog
create_bd_design "blinky"
update_compile_order -fileset sources_1
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0
endgroup
set_property CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} [get_bd_cells processing_system7_0]
set_property CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {50} [get_bd_cells processing_system7_0]
set_property CONFIG.PCW_USE_M_AXI_GP0 {0} [get_bd_cells processing_system7_0]
apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" Master "Disable" Slave "Disable" }  [get_bd_cells processing_system7_0]
Now he adds two blocks that are new to me -- "binary counter" and "slice". Then he configures the counter to 27 bits wide and makes the slice pull bit 27.
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:c_counter_binary:12.0 c_counter_binary_0
endgroup
startgroup
create_bd_cell -type ip -vlnv xilinx.com:ip:xlslice:1.0 xlslice_0
endgroup
set_property CONFIG.Output_Width {27} [get_bd_cells c_counter_binary_0]
set_property -dict [list \
  CONFIG.DIN_FROM {26} \
  CONFIG.DIN_TO {26} \
  CONFIG.DIN_WIDTH {27} \
] [get_bd_cells xlslice_0]
Now we create a port using the background menu, name it "led" and make it an output.
create_bd_port -dir O led
Now we connect things up (no automation).
startgroup
connect_bd_net [get_bd_ports led] [get_bd_pins xlslice_0/Dout]
endgroup
connect_bd_net [get_bd_pins xlslice_0/Din] [get_bd_pins c_counter_binary_0/Q]
connect_bd_net [get_bd_pins c_counter_binary_0/CLK] [get_bd_pins processing_system7_0/FCLK_CLK0]
regenerate_bd_layout

Wrap the design

Go to the "sources" tab, expand "design sources" to find "blinky" and use the menu to create HDL wrapper.
make_wrapper -files [get_files /u1/home/tom/bin/s9_blink_example/s9_blink_example.srcs/sources_1/bd/blinky/blinky.bd] -top
add_files -norecurse /u1/home/tom/bin/s9_blink_example/s9_blink_example.gen/sources_1/bd/blinky/hdl/blinky_wrapper.v

Add constraints

We only have one signal to characterize. He does it like so:
set_property IOSTANDARD LVCMOS33 [get_ports {led}]
set_property SLEW SLOW [get_ports {led}]
set_property DRIVE 8 [get_ports {led}]

#set_property PACKAGE_PIN F16 [get_ports {led}]
set_property PACKAGE_PIN M19 [get_ports {led}]
I have only ever set IOSTANDARD and PACKAGE_PIN -- it is interesting to see these other items. I change the package pin to M19, which is an onboard LED on my s9 board. I add the constraint file, electing to "create file". Then I relocate the file, open it, and add the above as contents.

Generate Bitstream

He now presents a nice shortcut. Go right to the bottom of "flow navigator" and select "generate bitstream". Tell it that it is OK to launch synthesis and implementation and away you go.
file mkdir /u1/home/tom/bin/s9_blink_example/s9_blink_example.srcs/constrs_1
file mkdir /u1/home/tom/bin/s9_blink_example/s9_blink_example.srcs/constrs_1/new
close [ open /u1/home/tom/bin/s9_blink_example/s9_blink_example.srcs/constrs_1/new/constraints.xdc w ]
add_files -fileset constrs_1 /u1/home/tom/bin/s9_blink_example/s9_blink_example.srcs/constrs_1/new/constraints.xdc
launch_runs impl_1 -to_step write_bitstream -jobs 4
This will take several minutes. When it is done it always wants to "open implemented design" by default. He points out that it is good to check here that timing values don't have troubles (such as negative slack timing and non-zero total timing).

Test the bitstream

I wasn't paying attention and the project got dumped into my "bin" directory.
So I do this:
mv s9_blink_example ../vivado/s9_blink_example1
Then the bitstream is here:
/home/tom/vivado/s9_blink_example1/s9_blink_example.runs/impl_1/blinky_wrapper.bit
I compile this into Kyu, boot the board and indeed the D5 LED blinks, somewhat slower than the 1 Hz the example aimed at because I gave it a 50 Mhz clock rather than a 125.
Feedback? Questions? Drop me a line!

Tom's Computer Info / [email protected]