Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

Passing parameter/generic to the top level in Quartus/tcl?

I'm trying to pass a git sha1 as a parameter to the top level in Quartus tcl

I added a source probe:

   gits
     u_gits
       (.probe (160'habbaface000000000000000000000000acdcbabe));
Which I can read with a small script:

./read-gits.sh 
GIT_SHA1: ABBAFACE000000000000000000000000ACDCBABE
Then I do:

module top
 # ( parameter GIT_SHA1 = 160'h0)
   ( input wire        pad_clk_50m_fpga,
...
   gits
     u_gits
       (.probe (GIT_SHA1));

./read-gits.sh 
GIT_SHA1: 3462636237316231396130366135366562373434
Which seem to be the ascii representation of the last 160 bits of the sha1

Inside the project file I have:

grep GIT_SHA1 project.qsf 
set_parameter -name GIT_SHA1 160'ha26916cc5fa8d5dbda994bcb71b19a06a56eb744
Then I tried to pass it as an integer

grep GIT_SHA1 project.qsf 
set_parameter -name GIT_SHA1 927200069134354371996170413995076949976682510148
But then I just got:

./read-gits.sh 
GIT_SHA1: 00000000000000000000000000000000FFFFFFFF

So what is the recommended way to pass a 160 bit vector to the top level as a parameter or generic using tcl in Quartus? Passing it as a string would result in control characters and would require some quoting of tcl delimiters

10 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'm not sure what you are trying to do here. If you are talking about synthesis, the parameter must be a set value at compile time. What does "read-gits.sh" actually look at and do? Are you talking about the In-System Sources & Probes debugging feature? It's a little confusing what's happening here.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes it's synthesis in Quartus (17.0.2), it's a constant known at synthesis time, and it's a probe as in-system sources & probes. The script is using a quartus_stp tcl script which is simply calling "start_insystem_source_probe" and "read_probe_data -value_in_hex".

    To me it seems like Quartus can only pass 32-bit integers as parameters to the top level.

    I can use pre processor defines in verilog, but in vhdl I would have to generate vhdl code containing the constants unless Quartus can handle the vhdl number syntax better. This is quite cumbersome, and I would expect parameters/generics to work in Quartus. It works fine in simulation (modelsim, ncsim, and vcs) as well as in Xilinx Vivado where I can write (where $sha1 is a tcl variable holding the 160-bit value):

    set_property generic "GIT_SHA1=160'h$sha1" 
    

    My question is if there is a way to pass a parameter/generic of a given size larger than 32-bit?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Either if larger generics than 32 bit integer can be passed or not, isn't it much easier to generate a VHDL package or Verilog include file holding the parameters?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It's not difficult to generate rtl code, but to me it's much simpler to put

    set_parameter -name GIT_SHA1 160'h$sha1
    

    into my build script. It's actually already there. It just doesn't work. I already have the same structure in my other scripts for simulation and build for other vendors.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The answer is no. The passing of generics to top levels in quartus has been fairly limited for a long time. You're limited to strings, integers, booleans.

    You could probably pass it in as a string and have the HDL parse the string into a sensible value. The annoying part you'll find though, is that Quartus doesnt support textio during synthesis, so you'll probably have to write your own conversion function.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Up to 32-bit integers... I find it a bit odd. They have a parser capable of parsing Verilog numbers so why not use this to parse the expression passed by the set_parameter tcl command.

    In Verilog it's possible to use the pre-processor as a work around:

    module top
    `ifdef M_GIT_SHA1
     # ( parameter GIT_SHA1 = `M_GIT_SHA1)
    `else
     # ( parameter GIT_SHA1 = {20{8'h42}})
    `endif
       ( input wire        pad_clk_50m_fpga,
    

    And then set:

    set_global_assignment -name VERILOG_MACRO "M_GIT_SHA1=160'h$sha1"
    

    in the build script, which yields:

    $./read-gits.sh 
    GIT_SHA1: 1B15850CADD9D969468FEE6669D86837E7B19239
    $git rev-parse HEAD
    1b15850cadd9d969468fee6669d86837e7b19239
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Verilog numbers are not integers. Integers in Verilog are 32 bit 4 state values (0,1,X,Z). Reg can be any length, but it is not an integer.

    I guess the restrictions come from system. And most people dont pass a lot into the top level.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes I know Verilog regs/wires/logic types can have other values than integers/0/1 and are arrays/vectors. I expected scalar constants to work as it works in all the other tools mentioned, and since Quartus has a parser which presumably can parse Verilog constants witch could be re-used to parse parameters/generics. But again Quartus seem to support only up to 32-bit integers which I tried as a work around for the git SHA1 I tried to pass (160-bit vectors). Things could of course get ugly when you start to pass enums, packed arrays, structs, and combinations of these (even though not so common in synthesis).

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I think most tools are pretty consistant in what they support.

    Modelsim and ActiveHDL only support basic top level generics - integers, strings, booleans, logic_vectors (as a string). They do not support passing in arrays or records/structs
    • zener's avatar
      zener
      Icon for Occasional Contributor rankOccasional Contributor

      According to:

      https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/mapIdTopics/jka1465598325723.htm

      Quartus should support different data types in parameters.

      A 160-bit parameter as a hex value can be set by using the following constant:

      set_parameter GIT_SHA1 H"88fdebee854eea5898f7daa7b87dbc4e6acb3986"

      If I pass this in Quartus Prime Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition using a Cyclone V device as a target it works as expected:

      In project.map.rpt I observe:

      ; Parameter Settings for User Entity Instance: Top-level Entity: |top ;
      +----------------+------------------------------------------+----------------------+
      ; Parameter Name ; Value ; Type ;
      +----------------+------------------------------------------+----------------------+
      ; GIT_SHA1 ; ec2a02b93595351d1cf538d44a3cf19fb441e311 ; Unsigned Hexadecimal ;
      +----------------+------------------------------------------+----------------------+

      Also if it's passed down to other parameters I see it as:

      ; Parameter Name ; Value ; Type ;
      +----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------+
      ; SHA1 ; 1110110000101010000000101011100100110101100101010011010100011101000111001111010100111000110101000100101000111100111100011001111110110100010000011110001100010001 ; Unsigned Binary ;

      Also inserting this parameter into a read only register reads it back correctly.


      However, if I move to Quartus Prime Version 20.4.0 Build 72 12/14/2020 SC Pro Edition using a Cyclone 10 GX target:

      In project.syn.rpt I observe:

      +--------------------------------------------------------+
      ; Synthesis Default Parameter Settings ;
      +----------+---------------------------------------------+
      ; Name ; Setting ;
      +----------+---------------------------------------------+
      ; GIT_SHA1 ; H"ec2a02b93595351d1cf538d44a3cf19fb441e311" ;
      +----------+---------------------------------------------+

      +-----------------------------------------------------------------------------------------------------------------------------------------------------+
      ; Parameter Settings for Top-Level Entity ;
      +----------------+------------------------------------------------------------------------------------------------------------------+-----------------+
      ; Parameter Name ; Value ; Type ;
      +----------------+------------------------------------------------------------------------------------------------------------------+-----------------+
      ; GIT_SHA1 ; 0000000000100000000000100000100100110101100101010011010100010000000100000000010100111000000001000100 <truncated> ; Unsigned Binary ;
      +----------------+------------------------------------------------------------------------------------------------------------------+-----------------+


      It appears that the synthesis engine used by the two versions/devices handles this differently.