Author Topic: How to feed an int to a third party module which wants a parameter in "Quotes"?  (Read 2642 times)

0 Members and 1 Guest are viewing this topic.

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8076
  • Country: ca
(Verilog/SystemVerilog)

Ok, dealing with a stupid problem which I hope someone has a neat solution to....

One of Altera's functions, 'altpll' has a bunch of parameters to make it work.  I have no trouble feeding most of them with computed 'localparams int xxxx=123;'.  But, there is this stupid 1 important parameter which demands it's input to be defined in quotes like a string, eg:

Code: [Select]

localparam int    PHASE_ps = (((1000000 / ( CLK_KHZ_IN/1000 * CLK_IN_MULT / CLK_IN_DIV )) * PHASE_degree / 360) -1) ;
localparam string PHASE_ps_s1 = "499" ;
localparam PHASE_ps_s2 = "499" ;


altpll #(
HPLL1.clk1_phase_shift = "0"     -> OK, 0ps phase shift accepted.
HPLL1.clk1_phase_shift = "499"   -> OK, 499ps phase shift accepted.
HPLL1.clk1_phase_shift = PHASE_ps   -> BAD, always renders 0ps phase shift even though the PHASE_ps is 499.
HPLL1.clk1_phase_shift = PHASE_ps_s1   -> BAD, says Override of parameter 'clk1_phase_shift' from '****' has an incompatible value.
HPLL1.clk1_phase_shift = PHASE_ps_s2   -> Good, but, I cannot make the PHASE_ps_s2 = my computed integer.
)

Is there any way to make the 'HPLL1.clk1_phase_shift =' see 'PHASE_ps' as if it were a string number in quotes like 'PHASE_ps_s2' so I can get my PLL .sv code to auto generate the phase depending on the input parameters?  Every other 'altpll' parameter filled with localparam ints already works fine, it's this ONE bugger which for some reason beyond me needs it's integer in quotes...  WTH?

« Last Edit: March 06, 2021, 04:35:39 am by BrianHG »
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
I don't feel like researching the details on how to do this... ok, I did anyway.  You need to convert your integer to a string with... an attribute.  It might work.  Not certain.  Try

blah := T'IMAGE(X);    is a string representation of X that is of type T.

Where T is the type integer or the subtype you are  using and X is your integer.  So....
localparam string PHASE_ps_s1 = integer'image(499);

I don't know anything about localparam so not sure this will work, but a string is a a string, no?

Oh crap!  I didn't see this was Verilog.   Does Verilog have something like attributes? 

I was wondering why it was an equal and not <= or :=
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8076
  • Country: ca
localparam is the same as parameter, except that when you instantiate your module, you cannot externally set a value for the internal localparam's 'constant'.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
I don't know Verilog, so that doesn't mean much to me.  The issue is do you have a way of turning an integer into a string like VHDL does?  I did a little Verilog some years back and I seem to recall generating strings, but it may have only been in the context of writing to a file. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15250
  • Country: fr
(Verilog/SystemVerilog)

Ok, dealing with a stupid problem which I hope someone has a neat solution to....

One of Altera's functions, 'altpll' has a bunch of parameters to make it work.  I have no trouble feeding most of them with computed 'localparams int xxxx=123;'.  But, there is this stupid 1 important parameter which demands it's input to be defined in quotes like a string, eg:

Code: [Select]

localparam int    PHASE_ps = (((1000000 / ( CLK_KHZ_IN/1000 * CLK_IN_MULT / CLK_IN_DIV )) * PHASE_degree / 360) -1) ;
localparam string PHASE_ps_s1 = "499" ;
localparam PHASE_ps_s2 = "499" ;


altpll #(
HPLL1.clk1_phase_shift = "0"     -> OK, 0ps phase shift accepted.
HPLL1.clk1_phase_shift = "499"   -> OK, 499ps phase shift accepted.
HPLL1.clk1_phase_shift = PHASE_ps   -> BAD, always renders 0ps phase shift even though the PHASE_ps is 499.
HPLL1.clk1_phase_shift = PHASE_ps_s1   -> BAD, says Override of parameter 'clk1_phase_shift' from '****' has an incompatible value.
HPLL1.clk1_phase_shift = PHASE_ps_s2   -> Good, but, I cannot make the PHASE_ps_s2 = my computed integer.
)

Is there any way to make the 'HPLL1.clk1_phase_shift =' see 'PHASE_ps' as if it were a string number in quotes like 'PHASE_ps_s2' so I can get my PLL .sv code to auto generate the phase depending on the input parameters?  Every other 'altpll' parameter filled with localparam ints already works fine, it's this ONE bugger which for some reason beyond me needs it's integer in quotes...  WTH?

I'm not a SystemVerilog user, but it looks like you need an integer-to-string conversion function here. I'm pretty sure constants in quotes in SV are strings?
(Why Altera uses string parameters here, I have no clue.)

I've seen there is a itoa() function in SV.
So something like this, if I got it right:

string PHASE_ps_s1;
PHASE_ps_s1.itoa(PHASE_ps);

Problem is, the itoa() function kind of acts like a method and has no return value. So I don't know if the above would be usable in the context of 'localparam'. Something to investigate though.
 
The following users thanked this post: BrianHG

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8076
  • Country: ca
Yes, there is a round about way of including a 'dummy into to string.vh' file to do the conversion through a lookup table to trick the compiler.

Next, it's Lattice Diamond's EHXPLLL function.  See the attached photo.  Everything will compile until the last step where is wants those red arrows, the top 2 in particular, as ASCII numbers in quotes.  And it must be the right number there, or the final fitter reports that the PLL is running at an illegal 0MHz.



Why do these companies do this?  It's a poor piggyback solution where they have prevented any programming flexibility at compile time.  I need to generate a new source file for every possible PLL configuration with the right text by the red arrow, green comments to solve this problem.

Lattice solution, just re-run their wizard.  My problem, there are around 5-10 calculations to get right, and fill in the correct fields every-time I want to make a change in video mode & source crystal oscillator when my code works out all the problems ahead of time automatically.
« Last Edit: March 06, 2021, 09:48:11 pm by BrianHG »
 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8076
  • Country: ca
Well, solved in the stupidest way....
Ohhh Altera..  :palm:  I'm embarrassed to post this as even Intel's tech forum still has no proper solution...
Code: [Select]
localparam  DDR3_WDQ_PHASE_ps = (((1000000 / ( PLL1_in_KHz/1000 * CLK_IN_MULT / CLK_IN_DIV )) * DDR3_WDQ_PHASE / 360) -1) ;
localparam  DDR3_RDQ_PHASE_ps = (((1000000 / ( PLL1_in_KHz/1000 * CLK_IN_MULT / CLK_IN_DIV )) * DDR3_RDQ_PHASE / 360) -1) ;

localparam  int Altera_Dummy_String [0:399] = '{ // Seriously, this is the only way...  I feel like an idiot making this public...
"0000","0010","0020","0030","0040","0050","0060","0070","0080","0090","0100","0110","0120","0130","0140","0150","0160","0170","0180","0190",
"0200","0210","0220","0230","0240","0250","0260","0270","0280","0290","0300","0310","0320","0330","0340","0350","0360","0370","0380","0390",
"0400","0410","0420","0430","0440","0450","0460","0470","0480","0490","0500","0510","0520","0530","0540","0550","0560","0570","0580","0590",
"0600","0610","0620","0630","0640","0650","0660","0670","0680","0690","0700","0710","0720","0730","0740","0750","0760","0770","0780","0790",
"0800","0810","0820","0830","0840","0850","0860","0870","0880","0890","0900","0910","0920","0930","0940","0950","0960","0970","0980","0990",
"1000","1010","1020","1030","1040","1050","1060","1070","1080","1090","1100","1110","1120","1130","1140","1150","1160","1170","1180","1190",
"1200","1210","1220","1230","1240","1250","1260","1270","1280","1290","1300","1310","1320","1330","1340","1350","1360","1370","1380","1390",
"1400","1410","1420","1430","1440","1450","1460","1470","1480","1490","1500","1510","1520","1530","1540","1550","1560","1570","1580","1590",
"1600","1610","1620","1630","1640","1650","1660","1670","1680","1690","1700","1710","1720","1730","1740","1750","1760","1770","1780","1790",
"1800","1810","1820","1830","1840","1850","1860","1870","1880","1890","1900","1910","1920","1930","1940","1950","1960","1970","1980","1990",
"2000","2010","2020","2030","2040","2050","2060","2070","2080","2090","2100","2110","2120","2130","2140","2150","2160","2170","2180","2190",
"2200","2210","2220","2230","2240","2250","2260","2270","2280","2290","2300","2310","2320","2330","2340","2350","2360","2370","2380","2390",
"2400","2410","2420","2430","2440","2450","2460","2470","2480","2490","2500","2510","2520","2530","2540","2550","2560","2570","2580","2590",
"2600","2610","2620","2630","2640","2650","2660","2670","2680","2690","2700","2710","2720","2730","2740","2750","2760","2770","2780","2790",
"2800","2810","2820","2830","2840","2850","2860","2870","2880","2890","2900","2910","2920","2930","2940","2950","2960","2970","2980","2990",
"3000","3010","3020","3030","3040","3050","3060","3070","3080","3090","3100","3110","3120","3130","3140","3150","3160","3170","3180","3190",
"3200","3210","3220","3230","3240","3250","3260","3270","3280","3290","3300","3310","3320","3330","3340","3350","3360","3370","3380","3390",
"3400","3410","3420","3430","3440","3450","3460","3470","3480","3490","3500","3510","3520","3530","3540","3550","3560","3570","3580","3590",
"3600","3610","3620","3630","3640","3650","3660","3670","3680","3690","3700","3710","3720","3730","3740","3750","3760","3770","3780","3790",
"3800","3810","3820","3830","3840","3850","3860","3870","3880","3890","3900","3910","3920","3930","3940","3950","3960","3970","3980","3990" };

localparam  DDR3_WDQ_PHASE_pss = Altera_Dummy_String[DDR3_WDQ_PHASE_ps/10] ;
localparam  DDR3_RDQ_PHASE_pss = Altera_Dummy_String[DDR3_RDQ_PHASE_ps/10] ;
My god.....

Anyways, the bottom 'DDR3_W/RDQ_PHASE_pss' work perfectly except its only 10ps precision...
« Last Edit: March 12, 2021, 08:17:40 am by BrianHG »
 

Offline Daixiwen

  • Frequent Contributor
  • **
  • Posts: 367
  • Country: no
I have the same problem with Microsemi. Companies just assume that you want to use their stupid Megawizard thing each time you want to change a parameter, and make it impossible to make more generic designs.
I feel for you but I'm afraid that the look up table is the only solution. Just hide it deep in a 5000-lines file and never open it again :D

I haven't been on Intel's forum for at least one year. Last time I checked it was still totally unusable.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
I'm no Verilog wizard, but can't you just construct the string in your own code like you would in any other programming language?  If the value you want in a string is in an integer you can do a few simple steps to get each digit and assign that digit to the appropriate character in the string, no?  It would be cleaner if you defined a function to get the quotient and remainder from dividing by ten.  Then another function to convert a single digit to ASCII, if nothing else in a case statement.  String them together and assign the character to the string variable.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8076
  • Country: ca
I'm no Verilog wizard, but can't you just construct the string in your own code like you would in any other programming language?  If the value you want in a string is in an integer you can do a few simple steps to get each digit and assign that digit to the appropriate character in the string, no?  It would be cleaner if you defined a function to get the quotient and remainder from dividing by ten.  Then another function to convert a single digit to ASCII, if nothing else in a case statement.  String them together and assign the character to the string variable.
Unfortunately no.  For some reason, this one parameter wants a 'Quoted' string number inside an 'INT' which cannot be replicated using the string functions which require a true 'string'.  Yes, for normal function modules who use strings this would actually work:

localparam DDR3_WDQ_PHASE_pss = string'(DDR3_WDQ_PHASE_ps);
or
localparam string DDR3_WDQ_PHASE_pss = int'(DDR3_WDQ_PHASE_ps);

But noooooo, this throws out errors in modelsim that I cannot feed a parameter expecting a string an actual string...
I've used and passed strings parameters elsewhere in my code with no problems, but this stupid 'altpll' is a special beast where only this stupidity needs a:

parameter/localparam int DDR3_WDQ_PHASE_pss = "1234";

WTF?  It's like Altera is decoding the 4 characters as ascii bytes within that 32 bit 'INT' parameter holding the string.

Oh, and the table you see above I did generate with some cheap basic code... I have the mind to extend the table's resolution to 1ps just to have pages of code to get that 1 right number...
« Last Edit: March 12, 2021, 02:55:24 pm by BrianHG »
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
I have the same problem with Microsemi. Companies just assume that you want to use their stupid Megawizard thing each time you want to change a parameter, and make it impossible to make more generic designs.

PREACH.

And the whole wizard thing makes standalone simulation (that is, not driven from Libero) damn near impossible. And it makes source-code control difficult, too. "Do I check this whole inscrutable project into the repo, and then have to commit a change every time I open the thing to look at it?"

For a previous ProASIC-3 project I was able to work out using Synplify and the Libero "designer" program standalone, not part of a Libero project. I created a dummy project to create the handful of things that needed to be generated by wizards and copied the black box component instances into my design. I'm doing a PolarFire thing now and the wizards spew so much shit that it's difficult to keep straight. And the libraries guide doesn't have component definitions for the higher-level stuff like the transceivers or even the deserializers built into the I/O. And there's no simplified component for a DDR input flop, it's all just the big IOD nonsense. It's painful.

MicroSemi wants you to use their "SmartDesign" for all of this. There are so many non-obvious things about the user interface that are maddening. Like: your job is engineering, so you write HDL modules that implement the special sauce for your product design. You need to somehow add your modules to the "smart design." So you have to put them in the hdl directory so the tools can find it. But then try dragging the file to the canvas to create a "module." Umm, nope, can't do that, even thought the documents say that's what you do. You have to click the "build hierarchy" button which analyzes all of the sources, and once that happens, your new source is in the work directory, and only then can you add it to the canvas.

I hate doing drawing-based HDL design. It's bullshit. And MicroSemi still drags along the ViewLogic bullshit that we had to use for FPGA designs in the early 90s. Jeebus Henry Tapdancing Christmas.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
I hate doing drawing-based HDL design. It's bullshit. And MicroSemi still drags along the ViewLogic bullshit that we had to use for FPGA designs in the early 90s. Jeebus Henry Tapdancing Christmas.

And THAT sir, is why you get the big bucks!
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15250
  • Country: fr
parameter/localparam int DDR3_WDQ_PHASE_pss = "1234";

Ah I see. I don't know much of Verilog, but how can the above even be allowed? And what does it actually mean? Can a quoted literal be anything else than a string (apparently so)? And if so, what's the benefit of using quotes? And why would the thing whine if you're actually passing an (non-quoted) integer for an int parameter?
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
parameter/localparam int DDR3_WDQ_PHASE_pss = "1234";

Ah I see. I don't know much of Verilog, but how can the above even be allowed? And what does it actually mean? Can a quoted literal be anything else than a string (apparently so)? And if so, what's the benefit of using quotes? And why would the thing whine if you're actually passing an (non-quoted) integer for an int parameter?

If this is actual Verilog syntax, I'm just gonna say that VHDL isn't this stupid.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3881
  • Country: us
parameter/localparam int DDR3_WDQ_PHASE_pss = "1234";

Ah I see. I don't know much of Verilog, but how can the above even be allowed? And what does it actually mean? Can a quoted literal be anything else than a string (apparently so)? And if so, what's the benefit of using quotes? And why would the thing whine if you're actually passing an (non-quoted) integer for an int parameter?

If this is actual Verilog syntax, I'm just gonna say that VHDL isn't this stupid.

I'm not sure if it is actual Verilog syntax or not, but from experience quartus will let you compile almost anything that looks vaguely like verilog.  You may not know what it will do, but it will pick *something* and run with it.
 
The following users thanked this post: BrianHG

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15250
  • Country: fr
parameter/localparam int DDR3_WDQ_PHASE_pss = "1234";

Ah I see. I don't know much of Verilog, but how can the above even be allowed? And what does it actually mean? Can a quoted literal be anything else than a string (apparently so)? And if so, what's the benefit of using quotes? And why would the thing whine if you're actually passing an (non-quoted) integer for an int parameter?

If this is actual Verilog syntax, I'm just gonna say that VHDL isn't this stupid.

Well, hopefully someone knowledgeable in Verilog can answer those questions.

Now it's for certain that Verilog has a much weaker type system than VHDL. "parameter" and "localparameter" don't actually take an explicit type AFAIK (remember I know little Verilog though). Is the explicit type in parameters something from a later version of Verilog, or strictly for SystemVerilog?

And VHDL is definitely NOT stupid. It's very strict with type checking, and regarding constants and generics in particular, there's very little you can't do. I do not doubt SystemVerilog has added a lot of similar features, but unfortunately, it's still not widely used, and most IPs from vendors are still written in very lousy Verilog. As someone said, they don't even care as they focus on getting it right using their IP generators, and pretty much ignore what you may want to do outside of them.

 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8076
  • Country: ca
parameter/localparam int DDR3_WDQ_PHASE_pss = "1234";

Ah I see. I don't know much of Verilog, but how can the above even be allowed? And what does it actually mean? Can a quoted literal be anything else than a string (apparently so)? And if so, what's the benefit of using quotes? And why would the thing whine if you're actually passing an (non-quoted) integer for an int parameter?

If this is actual Verilog syntax, I'm just gonna say that VHDL isn't this stupid.

Well, hopefully someone knowledgeable in Verilog can answer those questions.

Now it's for certain that Verilog has a much weaker type system than VHDL. "parameter" and "localparameter" don't actually take an explicit type AFAIK (remember I know little Verilog though). Is the explicit type in parameters something from a later version of Verilog, or strictly for SystemVerilog?

And VHDL is definitely NOT stupid. It's very strict with type checking, and regarding constants and generics in particular, there's very little you can't do. I do not doubt SystemVerilog has added a lot of similar features, but unfortunately, it's still not widely used, and most IPs from vendors are still written in very lousy Verilog. As someone said, they don't even care as they focus on getting it right using their IP generators, and pretty much ignore what you may want to do outside of them.
No, this is a load of crap related 'specifically' to 'altpll' from Altera and ModelSim & Quartus.  Like I said, I've used string parameters in my modules to pass parameters between them and they work fine.  This is an exclusive 'altpll' BS with that 1 single 'PHASE' setting.  Everything else works fine with normal ints for the numbers and normal strings for the strings.

Altera's position is just use their megawizard and accept that fixed number in quotes.  Regenerate every time you need a change.  Risk entering a mistake during calculations where my code can do all that work for me.

I got the same story from Lattice when I emailed their tech support with their 'EHXPLLL' and those ascii quoted numbers which need to be inside the stupid /* */ and // comments.  You bet I'm gonna make my little basic software generate 1000s of their EHXPLLL definition and comments which will be 'generate / endgenerate' inserted into a module having nothing but the same PLL with all possible iterations.  Unless I find a smarter solution trick like what I did with Altera, it will probably be a megabyte source file.  Though with lattice, the phase works, however, it just wont even compile unless I specify the frequency in those /* .... */ comments.

So, this BS isn't Altera specific.  Others have made such blundering un-checked inflexible crap as well.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf