06-06-2019 08:02 AM
I'm using Vivado 2018.1 and SystemVerilog.
I have a Vivado project with two different synth/impl runs. One builds for an Artix-7 (A7) on the AC701, while the other builds for a Kintex-7 (K7) on the KC705. My SystemVerilog source code needs to do different things, depending on whether it's being built for the A7 or the K7. Does there already exist, or can I create, a macro that I can reference in the source code that will have a different value for the two different runs? With this, I could use an `ifdef to control my source code and do the right thing.
For example, they two synth runs have different values for their "PART" property. If that were accessible in my SystemVerilog source code, that would be great. But I suspect that it's not. The *only* macro I've found is something like __SYNTHESIS__ (spelling may be incorrect). That doesn't change with different runs.
06-06-2019 05:41 PM
06-06-2019 07:59 PM
As a follow up to the post that Mark referenced, you can use the same mechanism to change the RTL code.
Within the Tcl script you can change/set the value of a top level parameter used in your RTL. So if, at the top level of your RTL code you have
You can override the value of MY_PARAM through the Tcl script
set_property generic MY_PARAM=1 [current_fileset]
Since MY_PARAM is a parameter, this can be used as a value in any expression, or can be used to control a "generate if" to change the structure of the synthesized design based on the parameter.
Since parameters are scoped, you can only (directly) use it at the top level module. However, you can "pass" it into a sub-module. If your sub-module also has a parameter
module sub_mod #(parameter MY_PARAM=0) (<port list...>>
then when you instantiate sub_mod, you can pass the top level MY_PARAM into the MY_PARAM of the submod
sub_mod #(.MY_PARAM(MY_PARAM)) sub_mod_inst (<port_list...>);
Now the MY_PARAM in the sub_mod has the value of the parameter from the top level (which, in turn, had its value set from the Tcl script).
06-07-2019 04:07 AM
@avrumw , this has gotten me close, but I'm not quite there yet. Please help me get all the way. Below is what I have:
module Top_Module#( parameter TARGET_BOARD = "Undefined" )( ... ) if (TARGET_BOARD=="KC705") begin missing_module_KC705 TARGET_BOARD___equals___KC705(); end if (TARGET_BOARD=="Undefined") begin missing_module_Undefined TARGET_BOARD___equals___Undefined(); // TARGET_BOARD should be defined in constraints. Example: set_property generic TARGET_BOARD="KC705" [current_fileset] end
THEREFORE it seems like TARGET_BOARD equals "Undefined" and not "KC705" as hoped. The constraints file set is included in this run (as seen in Design Runs window). The specific constraints file is supposed to be used for synthesis. But something's not right. (Is it the "[current_fileset]"?)
Please note that I have ***not*** done any explicit TCL scripting. I've only edited my existing constraints and top module.
06-07-2019 08:17 AM
The mechanism of overriding a top level parameter cannot be placed in an XDC file - it needs to be in the project script. Specifically, it has to be executed before the line in the script that launches the synthesis run (launch_runs synth_1). The XDC files are read during synthesis (after elaboration) - at this point it is already too late (and has no effect).
When done from the GUI, this cannot be automated - the "generic" propery is set on the "fileset" not the "run", so you can have only one per fileset. The fileset is the set of RTL files, and since you have only one (and you can only have one "source" fileset), there is no way to have it set two different ways in the same project.
So, if you really want to automate it, you need to use scripted project mode (as I described in the post). This way, you create two different projects - one for one board, and one for the other board. Each one can use a the same set of source files, but different constraints as well as different "generic" settings.
There may be a "cheating" way to have to runs within the same projet have different parameters. You can change the top level parameter value in the "More Options" of the Synthesis properties, but that way, it only affects synthesis (and not, say, simulation), so it isn't recommended.
06-07-2019 09:22 AM
Thanks, @avrumw . As you might guess, I really do ***NOT*** want to change from GUI mode to scripted project mode. I see two possible chats:
I think you meant this one already. I see that synth_1, impl_1, synth_2, and impl_2, from the Properties / Options window, can get four different pre.tcl settings. So I could write one TCL script to be used for synth_1 and impl_1, and a different one to be used for synth_2 and impl_2. That should handle building the two different bitstreams.
This DOES handle more than just Synthesis. It includes Implementation. However, as you mentioned, it won't cover Synthesis. Well, does Simulation really care about the choice of FPGA? I don't think it does for most of my needs. Or I just let the sim always be fore the General Project Settings choice of FPGA. Or else I try Cheat Two.
I could instead use a tcl.pre that's configured in the Project Settings and run for all my runs. That TCL script could then in turn look at something else and internally figure out which run is active. Is that possible, for the TCL script to see which run is active? If it can, then I just put a few if/else clauses to enumerate the multiple synth/impl runs that I have, and set the TARGET_BOARD that way.
For Simulation as well, I see xsim.compile.tcl.pre. Might that script also have access to which run is active, even though those are synth/impl runs that are independent of the sim?
06-07-2019 11:02 AM - edited 06-07-2019 11:04 AM
Neither of your "cheats" will work as is.
The project mode stuff is basically a wrapper around non-project mode. When you actually "launch a run", what the tool is doing is creating a non-project script (the runme.tcl) that runs in a new copy of Vivado in the background. This background process is running in non-project mode. The pre.tcl and post.tcl are files that are executed as part of this background process. As a result, all the "project management" stuff (which is in the foreground process) doesn't exist in the context of the pre.tcl and post.tcl. So the concept of "which run am I" is gone - the non-project mode simply knows where to get its sources and constraints, the options to use for launching the process (in this case synth_design),, and where to write the results.
Similarly the properties of the "run" or the "design" also no longer mean anything. These objects are project management objects that exist in the foreground process only - by the time you get to the background process they are gone.
Finally, you cannot modify the command line options of "synth_design" in the pre.tcl script - that is just a set of tcl commands that runs before the invocation of synth_design, but the command line of synth_design itself (which is where the -generic flag has to go) is already in the runme.tcl script and can't be modified.
The way to change the command line option of synth_design is a property of the synthesis run (in the foreground process). I am not 100% certain of the format (I'm not sure if you keep the - in front of the "generic"), but it's something like
set_property STEPS.SYNTH_DESIGN.ARGS.MORE_OPTIONS "-generic MY_PARAM=1" [get_runs synth_1]
set_property STEPS.SYNTH_DESIGN.ARGS.MORE_OPTIONS "-generic MY_PARAM=2" [get_runs synth_2]
And, by the way, scripted project mode is very powerful. Once you master it, you will never go back to using the GUI to do the main builds of your design. The great thing about scripted project mode is that it is still project mode. Once the build is done, you have a project in the project directory - this project is a normal project, and hence can be opened in the GUI, and from there you can do anything in the GUI that you could have done if the project had been built through the GUI.
DO NOT CONFUSE SCRIPTED PROJECT MODE WITH NON-PROJECT MODE. They are not the same thing!