Hacker News new | ask | show | jobs
by hrvach 2691 days ago
Thank you, I'll have to do some refactoring to avoid mixing the two assignment principles.

But it is ok to do something like:

cnt <= cnt + 1;

if (cnt > 100) cnt <= 0;

If not, how else should something like this be done?

Thanks for your help, I'm finding HDL to be anything but easy. :-)

2 comments

The usual way is simply with an else statement, so the reader can follow the logic:

  if (cnt > 100)
    cnt <= 0;
  else
    cnt <= cnt + 1;
probably not a good idea, because you are sampling cnt after think you have incremented it and you will get the wrong value

Essentially what happens is:

    tmp_cnt1 = cnt + 1;
    if (cnt > 100) tmp_cnt2 = 0;
some time later:

    cnt = tmp_cnt1;
and after that (if cnt >100)

    cnt = tmp_cnt2;
Better to say:

    if (cnt >= 99) {
        cnt <= 0;
    } else {
        cnt <= cnt+1;
    }
BTW: as an onetime verilog implementer those temporary storage locations that are made behind your back by the compiler when you use <= are potentially quite expensive, the compiler can optimise the normal case of:

   always @(posedge clk)
       r <= v;
and in some more complex cases where r is only set once in one always statement (or once in any path through an always statement) - but something like:

   always @(*) 
      r <= c;
is a nightmare that essentially means that r can have many changes scheduled in the same instant of time, more importantly it's a number of changes that can't be determined at compile time (could be 1000s of transitions) - resulting in code that's mallocing space to store all those changes - simulation can slow down if you use <= in a non-clocked place because the behaviour can't be determined statically

Also using <= a smart compiler can merge multiple always statements:

    always @(posedge clk)
        r1 <= c1;
    always @(posedge clk)
        r2 <= c2;
    ......
into a single

    always @(posedge clk) {
        r1 <= c1;
        r2 <= c2;
        ......
    }
behind your back, effectively converting 2*N simulation events into 2 (a very good thing)
Thanks for taking the time to explain it, I wish I knew all of this when I started tinkering with Verilog - it would be much easier. Btw, consider writing a FPGA related blog, you have a lot to teach and you explain well! :)
I'm afraid I've mostly worked in standard-cells rather than FPGAs, and that was a while back, I used to be the software guy in the hardware group (and the hardware guy in the software group).

These days I build embedded stuff, living on the hardware/software edge I still get to make the software/hardware tradeoffs that others often can't do

Thanks for pointing it out, I'll try to stick to a simple if-else construct in the future!
There is certainly no consensus that it's the preferred style. Some designers prefer this explicit (and more verbose) style but others prefer the less verbose one (with default first, business logic next, and reset values at the end).