Forums

What is wrong with low level code?

Started by Kevin Simonson October 4, 2020
gnuarm.del...@gmail.com (Rick C.): "In RTL this would be something like... =
/ Out <=3D '1' when leftOp < rightOp else '0';"

I tried:

// (c) Kevin Simonson 2020

module lessThan
  #( parameter nmBits =3D 1)
  ( output              lssThn
  , input [ nmBits-1:0] leftOp
  , input [ nmBits-1:0] rightOp);

assign lssThn =3D leftOp < rightOp ? 1 : 0;

endmodule

and got the results I was looking for. So there's my low level code that I =
posted yesterday, and this very high level code that I've posted today; is =
there nothing in between? It just bugs me that with the version posted here=
 I have so little control over how the less than ("<") operator is actually=
 implemented. I think my low level code is pretty much guaranteed to do a l=
ess than comparison on any two operands with an absolute minimum of worst c=
ase time. Can I say the same for how "leftOp < rightOp" is implemented?

"Is that more clear?" Yes; thanks!

"You might try implementing something like this and compare the result to y=
our highly specified code in synthesis. So how they both turn out." Rich, I=
'd really like to do that. Unfortunately the tool I'm using to simulate is =
Icarus, and when I try to simulate it I get:

D:\Hf\Verilog\Unpacked\Src\Common>\Icarus\bin\iverilog -g2009 -o lessThan.v=
vp lessThan.sv
lessThan.sv:81: error: Unable to bind parameter `ndTypes[gnIx]' in `lessTha=
n.$gen1[1]'
lessThan.sv:81: error: Cannot evaluate genvar case expression: ndTypes[gnIx=
]
2 error(s) during elaboration.

D:\Hf\Verilog\Unpacked\Src\Common>

Any idea why Icarus is giving me these error messages?

By the way, you said, "compare the result to your highly specified code in =
synthesis." Can one synthesize with Icarus? If so, how? If not, can you rec=
ommend a tool for synthesis?
Ack! Rick, sorry for calling you Rich. It was a typo.
On Monday, October 12, 2020 at 11:18:13 PM UTC-4, Kevin Simonson wrote:
> gnuarm.del...@gmail.com (Rick C.): "In RTL this would be something like..=
. / Out <=3D '1' when leftOp < rightOp else '0';"
>=20 > I tried: >=20 > // (c) Kevin Simonson 2020 >=20 > module lessThan > #( parameter nmBits =3D 1) > ( output lssThn > , input [ nmBits-1:0] leftOp > , input [ nmBits-1:0] rightOp); >=20 > assign lssThn =3D leftOp < rightOp ? 1 : 0; >=20 > endmodule >=20 > and got the results I was looking for. So there's my low level code that =
I posted yesterday, and this very high level code that I've posted today; i= s there nothing in between? It just bugs me that with the version posted he= re I have so little control over how the less than ("<") operator is actual= ly implemented. I think my low level code is pretty much guaranteed to do a= less than comparison on any two operands with an absolute minimum of worst= case time. Can I say the same for how "leftOp < rightOp" is implemented? Sorry, what makes you think your longer version of the code will produce an= optimal result? In general, the tools take all the combinational logic an= d concatenates it into equations. Unless you place tool specific directive= s to "keep" various signals and not combine the logic into LUTs in ways tha= t eliminate those signals there is nothing to stop the tools from turning a= ll your very specific logic into a single equation for the outputs that exa= ctly matches the short version above? =20 The tools know what the target is and know that very likely the fastest sol= ution is the use of the FPGA specific primitives for adders which will exac= tly do the logic in the short equation. Because they have a fast carry cha= in, it is very unlikely the typical ASIC type optimizations will be slow on= an FPGA.=20
> "Is that more clear?" Yes; thanks!
I'm happy to try to help, but I'm not so big on wading through complex code= . It is hard enough reading my own. lol=20
> "You might try implementing something like this and compare the result to=
your highly specified code in synthesis. So how they both turn out." Rich,= I'd really like to do that. Unfortunately the tool I'm using to simulate i= s Icarus, and when I try to simulate it I get:
>=20 > D:\Hf\Verilog\Unpacked\Src\Common>\Icarus\bin\iverilog -g2009 -o lessThan=
.vvp lessThan.sv
> lessThan.sv:81: error: Unable to bind parameter `ndTypes[gnIx]' in `lessT=
han.$gen1[1]'
> lessThan.sv:81: error: Cannot evaluate genvar case expression: ndTypes[gn=
Ix]
> 2 error(s) during elaboration. >=20 > D:\Hf\Verilog\Unpacked\Src\Common> >=20 > Any idea why Icarus is giving me these error messages?
No, I've never used Icarus. But to see how efficient the result is in synt= hesis you need to use a synthesis tool. Pick an FPGA vendor and download t= heir free tools. Then you can synthesize the design and they often have an= RTL viewer which draw a schematic of the primitives allowing you to see ho= w they translated the design into LUTs, FFs, counters, etc. =20 I need to do this myself for Gowin FPGAs and soon. I like to use construct= s like... if (A - 1 < 0) then=20 -- do stuff as the counter rolls over else -- do stuff the rest of the time end if;=20 A <=3D (A - 1) mod A_modulus;=20 In previous designs the tools will pick up that I'm decrementing A in both = places and use the same adder block and use the carry out (borrow technical= ly) as the flag for the IF. I need to verify this for the Gowin parts. If= it doesn't, then I will just use=20 if (A =3D 0) then which will use some LUTs, but many less than a second adder.=20
> By the way, you said, "compare the result to your highly specified code i=
n synthesis." Can one synthesize with Icarus? If so, how? If not, can you r= ecommend a tool for synthesis? No, as i mention above you need to download a vendor's tool set. I am used= to Lattice semi tools which use Synplify as do the Gowin tools I think. L= ots of people use the Xilinx tools which are proprietary (I haven't worked = with Xilinx since they dropped Synplify many years ago). Altera/Intel has = their own tools as well, Quartus I believe. They all work pretty well or t= hey wouldn't be in business. It's as much about the tools as it is the par= ts. Altera has always had "better" tools than Xilinx, which may not be the= case any longer. =20 If you want to work with the Lattice iCE40 parts, there is an open source t= ool set, but I don't recall the name. I'm sure others here know it well. = You can test your ideas with any of these tools and might do well to try mo= re than one!=20 I didn't even notice about the name. Rick, Rich, even Dick is ok.=20 --=20 Rick C. +- Get 1,000 miles of free Supercharging +- Tesla referral code - https://ts.la/richard11209
On Monday, October 12, 2020 at 9:18:13 PM UTC-6, Kevin Simonson wrote:
> gnuarm.del...@gmail.com (Rick C.): "In RTL this would be something like..=
. / Out <=3D '1' when leftOp < rightOp else '0';"=20
>=20 > I tried: > // (c) Kevin Simonson 2020=20 >=20 > module lessThan=20 > #( parameter nmBits =3D 1)=20 > ( output lssThn=20 > , input [ nmBits-1:0] leftOp=20 > , input [ nmBits-1:0] rightOp); > assign lssThn =3D leftOp < rightOp ? 1 : 0;=20 >=20 > endmodule=20 >=20 > and got the results I was looking for. So there's my low level code that =
I posted yesterday, and this very high level code that I've posted today; i= s there nothing in between? It just bugs me that with the version posted he= re I have so little control over how the less than ("<") operator is actual= ly implemented. I think my low level code is pretty much guaranteed to do a= less than comparison on any two operands with an absolute minimum of worst= case time. Can I say the same for how "leftOp < rightOp" is implemented?= =20
>=20 > "Is that more clear?" Yes; thanks!=20 >=20 > "You might try implementing something like this and compare the result to=
your highly specified code in synthesis. So how they both turn out." Rich,= I'd really like to do that. Unfortunately the tool I'm using to simulate i= s Icarus, and when I try to simulate it I get:=20
>=20 > D:\Hf\Verilog\Unpacked\Src\Common>\Icarus\bin\iverilog -g2009 -o lessThan=
.vvp lessThan.sv=20
> lessThan.sv:81: error: Unable to bind parameter `ndTypes[gnIx]' in `lessT=
han.$gen1[1]'=20
> lessThan.sv:81: error: Cannot evaluate genvar case expression: ndTypes[gn=
Ix]=20
> 2 error(s) during elaboration.=20 >=20 > D:\Hf\Verilog\Unpacked\Src\Common>=20 >=20 > Any idea why Icarus is giving me these error messages?=20 >=20 > By the way, you said, "compare the result to your highly specified code i=
n synthesis." Can one synthesize with Icarus? If so, how? If not, can you r= ecommend a tool for synthesis? First of all, your code needs comments. To you, it might make sense (at le= ast at the moment), but you can't expect anybody to be able to help if you = publish a hundred lines of incoherence without even a 1-line comment of wha= t it's supposed to be.=20 If all you want is a comparator, you don't even need the ?: operator. It's= just: wire less_than =3D left_op < right_op; I don't even know why you'd want to put this in a separate module; just use= it where you need it, or in an if-clause: if (left_op < right_op) do_stuff; Sometimes the synthesizer will not do a great job with abstract code. This= is not such a case. You do not need to write low-level code for a subtrac= tor. In an FPGA, for example, the line I wrote above will be synthesized u= sing a built-in carry chain logic. Your code, in which you instantiate pri= mitives, will end up with poorer results, because it won't use the fast car= ry chain. Some notes: - Use lots of comments. - Don't instantiate any primitives unless absolutely necessary for performa= nce. - Avoid unnecessary hierarchy and "generate" blocks. I have not used it much but I recently found a site called "EDA Playground"= in which you can simulate using various simulators and also synthesize usi= ng Mentor Questa, a commercial synthesizer. I'm not familiar with Questa, = but here is a link with a simple example. You could set up your own "playg= round" and synthesize. I don't know if you can view the resulting schemati= cs, but you can at least get resulting utilization statistics: https://www.edaplayground.com/x/2BmJ
On Tuesday, October 13, 2020 at 10:41:12 AM UTC-6, Kevin Neilson wrote:
> On Monday, October 12, 2020 at 9:18:13 PM UTC-6, Kevin Simonson wrote:=20 > > gnuarm.del...@gmail.com (Rick C.): "In RTL this would be something like=
... / Out <=3D '1' when leftOp < rightOp else '0';"=20
> >=20 > > I tried:=20 > > // (c) Kevin Simonson 2020=20 > >=20 > > module lessThan=20 > > #( parameter nmBits =3D 1)=20 > > ( output lssThn=20 > > , input [ nmBits-1:0] leftOp=20 > > , input [ nmBits-1:0] rightOp);=20 > > assign lssThn =3D leftOp < rightOp ? 1 : 0;=20 > >=20 > > endmodule=20 > >=20 > > and got the results I was looking for. So there's my low level code tha=
t I posted yesterday, and this very high level code that I've posted today;= is there nothing in between? It just bugs me that with the version posted = here I have so little control over how the less than ("<") operator is actu= ally implemented. I think my low level code is pretty much guaranteed to do= a less than comparison on any two operands with an absolute minimum of wor= st case time. Can I say the same for how "leftOp < rightOp" is implemented?= =20
> >=20 > > "Is that more clear?" Yes; thanks!=20 > >=20 > > "You might try implementing something like this and compare the result =
to your highly specified code in synthesis. So how they both turn out." Ric= h, I'd really like to do that. Unfortunately the tool I'm using to simulate= is Icarus, and when I try to simulate it I get:=20
> >=20 > > D:\Hf\Verilog\Unpacked\Src\Common>\Icarus\bin\iverilog -g2009 -o lessTh=
an.vvp lessThan.sv=20
> > lessThan.sv:81: error: Unable to bind parameter `ndTypes[gnIx]' in `les=
sThan.$gen1[1]'=20
> > lessThan.sv:81: error: Cannot evaluate genvar case expression: ndTypes[=
gnIx]=20
> > 2 error(s) during elaboration.=20 > >=20 > > D:\Hf\Verilog\Unpacked\Src\Common>=20 > >=20 > > Any idea why Icarus is giving me these error messages?=20 > >=20 > > By the way, you said, "compare the result to your highly specified code=
in synthesis." Can one synthesize with Icarus? If so, how? If not, can you= recommend a tool for synthesis?
> First of all, your code needs comments. To you, it might make sense (at l=
east at the moment), but you can't expect anybody to be able to help if you= publish a hundred lines of incoherence without even a 1-line comment of wh= at it's supposed to be.=20
>=20 > If all you want is a comparator, you don't even need the ?: operator. It'=
s just:=20
>=20 > wire less_than =3D left_op < right_op;=20 >=20 > I don't even know why you'd want to put this in a separate module; just u=
se it where you need it, or in an if-clause:=20
>=20 > if (left_op < right_op) do_stuff;=20 >=20 > Sometimes the synthesizer will not do a great job with abstract code. Thi=
s is not such a case. You do not need to write low-level code for a subtrac= tor. In an FPGA, for example, the line I wrote above will be synthesized us= ing a built-in carry chain logic. Your code, in which you instantiate primi= tives, will end up with poorer results, because it won't use the fast carry= chain. Some notes:=20
>=20 > - Use lots of comments.=20 > - Don't instantiate any primitives unless absolutely necessary for perfor=
mance.=20
> - Avoid unnecessary hierarchy and "generate" blocks.=20 >=20 > I have not used it much but I recently found a site called "EDA Playgroun=
d" in which you can simulate using various simulators and also synthesize u= sing Mentor Questa, a commercial synthesizer. I'm not familiar with Questa,= but here is a link with a simple example. You could set up your own "playg= round" and synthesize. I don't know if you can view the resulting schematic= s, but you can at least get resulting utilization statistics:=20
>=20 > https://www.edaplayground.com/x/2BmJ
Sorry; I meant the Mentor *Precision* synthesizer. Questa (n=C3=A9e Models= im) is the simulator.