Reply by Kevin Neilson October 13, 20202020-10-13
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.
Reply by Kevin Neilson October 13, 20202020-10-13
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
Reply by Rick C October 13, 20202020-10-13
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
Reply by Kevin Simonson October 13, 20202020-10-13
Ack! Rick, sorry for calling you Rich. It was a typo.
Reply by Kevin Simonson October 13, 20202020-10-13
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?
Reply by Rick C October 12, 20202020-10-12
On Monday, October 12, 2020 at 7:30:21 PM UTC-4, Kevin Simonson wrote:
> // (c) Kevin Simonson 2020 > > module lessThan > #( parameter nmBits = 1) > ( output lssThn > , input [ nmBits-1:0] leftOp > , input [ nmBits-1:0] rightOp); > > typedef enum { CORNER, E_LEAF, N_LEAF, SIDE, E_INTERIOR, N_INTERIOR } nodeType; > > localparam integer nmNodes = (nmBits << 1) - 1; > localparam integer lvLimit = $clog2( nmBits); > localparam integer nmRships = (nmNodes << 1) - lvLimit - 1; > > nodeType ndTypes [ nmNodes:1]; > integer inLows [ nmNodes:1]; > integer inHighs [ nmBits-1:1]; > integer outs [ nmNodes:1]; > integer bases [ lvLimit:0]; > wire rss [ nmRships:1]; > wire ntRght; > genvar gnIx; > > function automatic integer fillSubtree ( input integer vrtcl > , input integer hrzntl > , input bit equal); > integer ndIx; > integer rlIx; > integer vr; > integer hz; > integer twice; > integer nxVr; > bit nxEq; > begin > ndIx = (1 << vrtcl) + (hrzntl << vrtcl + 1); > vr = vrtcl; > hz = hrzntl; > while (nmNodes < ndIx) > begin > vr = vr - 1; > hz <<= 1; > ndIx = (1 << vr) + (hz << vr + 1); > end > rlIx = bases[ vr] + (hz << 1); > fillSubtree = rlIx; > if (0 < vr) > begin > nxVr = vr - 1; > twice = hz << 1; > nxEq = 0 == hz || ! equal; > ndTypes[ ndIx] = 0 < hz ? equal ? E_INTERIOR : N_INTERIOR : SIDE; > inLows[ ndIx] = fillSubtree( nxVr, twice , nxEq); > inHighs[ ndIx >> 1] = fillSubtree( nxVr, twice + 1, nxEq); > end > else > begin > ndTypes[ ndIx] = 0 < hz ? equal ? E_LEAF : N_LEAF : CORNER; > inLows[ ndIx] = hz; > end > outs[ ndIx] = rlIx; > end > endfunction > > initial > begin > integer lvl; > bases[ 0] = 1; > for (lvl = 0; lvl < lvLimit; lvl = lvl + 1) > begin > bases[ lvl + 1] = bases[ lvl] + ((nmNodes >> lvl) + 1 >> 1 << 1) - 1; > end > fillSubtree( lvLimit, 0, 1); > end > > generate > for (gnIx = 1; gnIx <= nmNodes; gnIx = gnIx + 1) > begin > integer inLow = inLows[ gnIx]; > integer inHigh = inHighs[ gnIx + 1 >> 1]; > integer out = outs[ gnIx]; > case (ndTypes[ gnIx]) > E_INTERIOR > : begin > nor2 pio( rss[ out - 1], rss[ inLow - 1], rss[ inHigh - 1]); > mplex pim( rss[ out], rss[ inHigh - 1], rss[ inHigh], rss[ inLow]); > end > N_INTERIOR > : begin > nand2 mia( rss[ out - 1], rss[ inLow - 1], rss[ inHigh - 1]); > mplex mim( rss[ out], rss[ inHigh - 1], rss[ inLow], rss[ inHigh]); > end > SIDE > : mplex sm( rss[ out], rss[ inHigh - 1], rss[ inLow], rss[ inHigh]); > E_LEAF > : begin > equ2 ple( rss[ out], leftOp[ inLow], rightOp[ inLow]); > assign rss[ out - 1] = rightOp[ inLow]; > end > N_LEAF > : begin > xor2 mlx( rss[ out], leftOp[ inLow], rightOp[ inLow]); > assign rss[ out - 1] = rightOp[ inLow]; > end > CORNER > : begin > nt1 cn( ntRght, rightOp[ inLow]); > nor2 co( rss[ out], leftOp[ inLow], ntRght); > end > endcase > end > endgenerate > assign lssThn = rss[ bases[ lvLimit]]; > > endmodule
I found the top level module declaration (third line, duh!) and it looks like you are implementing a subtraction, I'm guessing the carry out is the flag. In RTL this would be something like... Out <= '1' when leftOp < rightOp else '0'; No need to even define a function/module. At least in VHDL this is built into the language and I'm pretty sure something equivalent is provided as well. From what I recall, you were specifying all the details to provide a speed optimized solution. That is probably counter productive in an FPGA and may or may not be in something like a gate array. I don't know so much about fully synthesized ASICs. Is that more clear? You might try implementing something like this and compare the result to your highly specified code in synthesis. So how they both turn out. -- Rick C. -+ Get 1,000 miles of free Supercharging -+ Tesla referral code - https://ts.la/richard11209
Reply by Rick C October 12, 20202020-10-12
On Monday, October 12, 2020 at 7:27:49 PM UTC-4, Kevin Simonson wrote:
> On Tuesday, October 6, 2020 at 5:22:11 PM UTC-7, gnuarm.del...@gmail.com =
wrote:
> > So wiring together such things as gates is very uncommon these days. It=
is well worth the while to learn how to describe your design in HDL rather= than instantiating gates and such.=20
> >=20 > > --=20 > >=20 > > Rick C.=20 >=20 > Okay, I'm willing to learn how to describe my design in HDL, preferably V=
erilog, since that's what I've concentrated on. How would I go about learni= ng how to write higher level Verilog, rather "than instantiating gates and = such"? I'll include my source code as it stands right now in my next post. = I guess I'd just like to know how to code it at a higher level. Sorry, it is too painful for me to read that sort of code. I don't say tha= t as an insult, simply that Verilog is a second language to me so I'm not c= lear what all the operators are, etc. =20 If you want to add two numbers, you write=20 A <=3D B + C;=20 That's it in VHDL anyway. I think in this case Verilog is the same. =20 But your code below is not instantiating gates that I can see.=20 Let's try this. How about showing what your code does with a simple math s= tatement if that is possible? Not HDL, just an explanation, a spec like so= meone might give you to indicate what the calculation would do without spec= ifying any of the implementation details. =20 --=20 Rick C. -- Get 1,000 miles of free Supercharging -- Tesla referral code - https://ts.la/richard11209
Reply by Kevin Simonson October 12, 20202020-10-12
// (c) Kevin Simonson 2020

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

typedef enum { CORNER, E_LEAF, N_LEAF, SIDE, E_INTERIOR, N_INTERIOR } nodeType;

localparam integer nmNodes  = (nmBits << 1) - 1;
localparam integer lvLimit  = $clog2( nmBits);
localparam integer nmRships = (nmNodes << 1) - lvLimit - 1;

nodeType ndTypes [  nmNodes:1];
integer  inLows  [  nmNodes:1];
integer  inHighs [ nmBits-1:1];
integer  outs    [  nmNodes:1];
integer  bases   [  lvLimit:0];
wire     rss     [ nmRships:1];
wire     ntRght;
genvar   gnIx;

function automatic integer fillSubtree ( input integer vrtcl
                                       , input integer hrzntl
                                       , input     bit equal);
    integer ndIx;
    integer rlIx;
    integer vr;
    integer hz;
    integer twice;
    integer nxVr;
    bit nxEq;
  begin
    ndIx = (1 << vrtcl) + (hrzntl << vrtcl + 1);
    vr   = vrtcl;
    hz   = hrzntl;
    while (nmNodes < ndIx)
    begin
      vr   = vr - 1;
      hz <<= 1;
      ndIx = (1 << vr) + (hz << vr + 1);
    end
    rlIx        = bases[ vr] + (hz << 1);
    fillSubtree = rlIx;
    if (0 < vr)
    begin
      nxVr                = vr - 1;
      twice               = hz << 1;
      nxEq                = 0 == hz || ! equal;
      ndTypes[ ndIx]      = 0 < hz ? equal ? E_INTERIOR : N_INTERIOR : SIDE;
      inLows[ ndIx]       = fillSubtree( nxVr, twice    , nxEq);
      inHighs[ ndIx >> 1] = fillSubtree( nxVr, twice + 1, nxEq);
    end
    else
    begin
      ndTypes[ ndIx] = 0 < hz ? equal ? E_LEAF : N_LEAF : CORNER;
      inLows[ ndIx]  = hz;
    end
    outs[ ndIx] = rlIx;
  end
endfunction

initial
begin
  integer lvl;
  bases[ 0] = 1;
  for (lvl = 0; lvl < lvLimit; lvl = lvl + 1)
  begin
    bases[ lvl + 1] = bases[ lvl] + ((nmNodes >> lvl) + 1 >> 1 << 1) - 1;
  end
  fillSubtree( lvLimit, 0, 1);
end

generate
  for (gnIx = 1; gnIx <= nmNodes; gnIx = gnIx + 1)
  begin
    integer inLow  = inLows[ gnIx];
    integer inHigh = inHighs[ gnIx + 1 >> 1];
    integer out    = outs[ gnIx];
    case (ndTypes[ gnIx])
      E_INTERIOR
    : begin
        nor2 pio( rss[ out - 1], rss[ inLow - 1], rss[ inHigh - 1]);
        mplex pim( rss[ out], rss[ inHigh - 1], rss[ inHigh], rss[ inLow]);
      end
      N_INTERIOR
    : begin
        nand2 mia( rss[ out - 1], rss[ inLow - 1], rss[ inHigh - 1]);
        mplex mim( rss[ out], rss[ inHigh - 1], rss[ inLow], rss[ inHigh]);
      end
      SIDE
    : mplex sm( rss[ out], rss[ inHigh - 1], rss[ inLow], rss[ inHigh]);
      E_LEAF
    : begin
        equ2 ple( rss[ out], leftOp[ inLow], rightOp[ inLow]);
        assign rss[ out - 1] = rightOp[ inLow];
      end
      N_LEAF
    : begin
        xor2 mlx( rss[ out], leftOp[ inLow], rightOp[ inLow]);
        assign rss[ out - 1] = rightOp[ inLow];
      end
      CORNER
    : begin
        nt1 cn( ntRght, rightOp[ inLow]);
        nor2 co( rss[ out], leftOp[ inLow], ntRght);
      end
    endcase
  end
endgenerate
assign lssThn = rss[ bases[ lvLimit]];

endmodule
Reply by Kevin Simonson October 12, 20202020-10-12
On Tuesday, October 6, 2020 at 5:22:11 PM UTC-7, gnuarm.del...@gmail.com wr=
ote:
> So wiring together such things as gates is very uncommon these days. It i=
s well worth the while to learn how to describe your design in HDL rather t= han instantiating gates and such.=20
>=20 > --=20 >=20 > Rick C.=20
Okay, I'm willing to learn how to describe my design in HDL, preferably Ver= ilog, since that's what I've concentrated on. How would I go about learning= how to write higher level Verilog, rather "than instantiating gates and su= ch"? I'll include my source code as it stands right now in my next post. I = guess I'd just like to know how to code it at a higher level.
Reply by Rick C October 6, 20202020-10-06
On Tuesday, October 6, 2020 at 7:04:31 PM UTC-4, Mike Perkins wrote:
> On 05/10/2020 01:02:03, Kevin Simonson wrote: > > I recently posted a Verilog module to this forum, and someone > > responded that I was coding at a very low level, which was true; I > > was referring to XOR gates, NAND gates, NOR gates, and NOT gates. Is > > there something wrong with writing my code at such a low level? If I > > have a fairly good understanding of how my algorithm needs to run at > > such a low level, then what is wrong with writing that kind of low > > level code? >=20 > As others have said readability is everything. >=20 > One time when I wrote at a low level was when trying to maximise speed=20 > when pipe-lining numerical algorithms. >=20 > There are times when it's appropriate.
If not in this thread I may have mentioned a former poster here who used sc= hematics for hierarchical construction allowing specification of relative a= nd absolute positioning within a layout. He only converted to VHDL when he= was able to do the same specification of location attributes. Then he nev= er looked back. He was essentially designing at the LUT level and simplify= ing the design process by using hierarchical constructs eliminating much of= the detail design process. =20 This was largely practical for his work because he was designing similar ci= rcuits repeatedly, but mostly because he was being paid to do designs no on= e else could pull off really. The combination of speed and density was har= d to achieve. Today the tools are better and the parts are MUCH bigger mak= ing large, fast designs easier to do without massive libraries of hand hewn= designs much less common.=20 So wiring together such things as gates is very uncommon these days. It is= well worth the while to learn how to describe your design in HDL rather th= an instantiating gates and such.=20 --=20 Rick C. + Get 1,000 miles of free Supercharging + Tesla referral code - https://ts.la/richard11209