Author Topic: [Verilog] Using non-blocking assignments reduces LE's by half!?  (Read 11758 times)

0 Members and 1 Guest are viewing this topic.

Offline vortexnlTopic starter

  • Contributor
  • Posts: 40
I just got into SystemVerilog, and I made a simple led blinker that looks like this:

Code: [Select]
module CPLD(input CLK, input BTN, output LED);

reg [24:0] counter;

always @ (posedge CLK)
begin
counter <= counter+1;
if(BTN)
LED <= counter[23];
else
LED <= counter[22];
end

endmodule

When I compile this, Quartus II says it uses 25 logic elements of the CPLD. However:

When I replace all non-blocking assignments with blocking assignments, like this, I use 48 LE's, but it functions exactly the same:
Code: [Select]
module CPLD(input CLK, input BTN, output LED);

reg [24:0] counter;

always @ (posedge CLK)
begin
counter = counter+1;
if(BTN)
LED = counter[23];
else
LED = counter[22];
end

endmodule

I thought blocking and non-blocking assignments only affected simulation?

Here is the generated schematic for the non-blocking version that uses 25 LE's (I use the Quartus II RTL viewer):



And here is the schematic for the blocking version:



As you can see, the counter gets swapped with the adder, but functionality remains the same.

Please note that I am extremely new to all of this, so I hope some of you HDL guru's can enlighten me.  :-+

- Nick
 

Offline cyr

  • Frequent Contributor
  • **
  • Posts: 252
  • Country: se
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #1 on: July 03, 2014, 04:41:01 pm »
They are not quite the same (as you can see from the schematic).

One results in you taking the output of the adder, one takes the output of the register. The LE:s probably have internal connections from the logic array to a register, but not the other way around. So in one case the register and adder get put in the same LE, and in the other case they require one each.

Edit:

No, actually I was right. :)

Basically, in one case your LED is connected to one bit of "counter" (the current value of the register), but in the other case you are connecting it to one bit of "counter+1" (the new value / the output of the adder). The only difference in the end is that your LED is updated one clock cycle earlier.
« Last Edit: July 03, 2014, 04:55:52 pm by cyr »
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #2 on: July 03, 2014, 11:10:06 pm »
I've never done any Verilog (or RTL) work, but what's with the +1 representation in those diagrams? h1000000, and not h0000001 ???
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #3 on: July 04, 2014, 06:31:39 am »
Yep, it's all about timing as you've been shown. I didn't really understand the difference until I found some problems in a CPU design which had timing problems because blocking assignment was used where non-blocking was needed. See http://www.arctic.umn.edu/vespa/index.html and compare dff.v in vespa.tar and BWAT.tar.gz on that site.

I can recommend the book of which this is the companion website. I like how they constructed the CPU, doing a single cycle RTL Verilog design first, then pipelining the datapath and making the Verilog more structural.
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #4 on: July 04, 2014, 08:44:07 am »
I've never done any Verilog (or RTL) work, but what's with the +1 representation in those diagrams? h1000000, and not h0000001 ???
25'h1000000 is a 25-bit number in hex notation, as in 0x1000000. So that's the MSB set to 1.

As for the OP, as you've noticed there are definitely differences between blocking and non-blocking. See for example: http://www.asic-world.com/tidbits/blocking.html
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #5 on: July 04, 2014, 11:12:00 am »

25'h1000000 is a 25-bit number in hex notation, as in 0x1000000. So that's the MSB set to 1.


Yes, but the counter is supposed to increment by 1, not 2^24

Code: [Select]

counter <= counter+1;


 

Offline vortexnlTopic starter

  • Contributor
  • Posts: 40
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #6 on: July 04, 2014, 05:25:32 pm »
So to verify:

Blocking and non-blocking assignments actually change the hardware as well? I don't really understand it. Because people say you are supposed to use blocking assignments with combinational logic, but I would assume that combinational logic would have to run in parallel right? I don't see logic being sequential. I'm still reading up on all of this, so I hope to understand all of this soon.
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #7 on: July 04, 2014, 05:50:51 pm »
So to verify:

Blocking and non-blocking assignments actually change the hardware as well? I don't really understand it. Because people say you are supposed to use blocking assignments with combinational logic, but I would assume that combinational logic would have to run in parallel right? I don't see logic being sequential. I'm still reading up on all of this, so I hope to understand all of this soon.
I don't think parallel is a good way of thinking about things. My definitions here: sequential logic and combinational logic.
A sequential logic circuit has the transparency between its inputs and outputs broken. See D flip-flop for an example circuit.

If you look at the two designs from the Quartus II translator you gave earlier, you'll see the hardware is different. In the first one, the input to the multiplexer is the last clock period's sum. In the second it is the current period's sum. Note both are sequential circuits.


"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline pigtwo

  • Regular Contributor
  • *
  • Posts: 137
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #8 on: July 05, 2014, 03:36:45 am »

25'h1000000 is a 25-bit number in hex notation, as in 0x1000000. So that's the MSB set to 1.


Yes, but the counter is supposed to increment by 1, not 2^24

It is incrementing my one.  If you notice in the schematic it says '[24:0]' instead of '[0:24]', that pretty much means that it is reversed.  So 10000...000 is 1 in that case. 
   counter <= counter+1;
   
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #9 on: July 05, 2014, 04:59:00 am »
bit 0 usually is the one denominating 1 as in 2^0, so bit 24 would be 2^24.

For some reason RTL values are LSB first?
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #10 on: July 05, 2014, 05:40:39 am »
@miguelvp
Exactly! In my ~50 years of design work, I don't recall any serious system that has written numbers like that. So where did it come from??
Actually, I think there was one, but I can't remember what it was...

[edit] Oh, ok. I just read a bit more on defining vectors in Verilog. It seems that you can number your element sequence left-to-right or right-to-left, so you can define a vector A[24:0] or A[0:24]. In the first case (which I would *always* consider the norm) A[24] is the most significant bit of the vector, and in the second case A[0] is the most significant bit. In the OP's code he has defined his register in the 'normal' manner, so the question remains: why does the RTL viewer represent a value of one in the manner that we have seen?

It would be interesting to change the original code to define

Code: [Select]
reg [0:24] counter;

and then see what the viewer generates.


@OP
Here's an extract from Ciletti (Digital Design - With an Introduction to the Verilog HDL) that sums up blocking and non-blocking behaviour, and which you can see exactly in the two schematics in your original post.

Quote
Blocking assignment statements are executed sequentially in the order they are listed
in a block of statements. Nonblocking assignments are executed concurrently by evaluating
the set of expressions on the right-hand side of the list of statements; they do not
make assignments to their left-hand sides until all of the expressions are evaluated. The
two types of assignments may be better understood by means of an illustration. Consider
these two procedural blocking assignments:
     B = A
     C = B + 1
The first statement transfers the value of Ainto B. The second statement increments the
value of Band transfers the new value to C. At the completion of the assignments, C
contains the value of A+1 .
Now consider the two statements as nonblocking assignments:
     B <= A
     C <= B + 1
When the statements are executed, the expressions on the right-hand side are evaluated
and stored in a temporary location. The value of Ais kept in one storage location and
the value of B+1 in another. After all the expressions in the block are evaluated and
stored, the assignment to the targets on the left-hand side is made. In this case, C will
contain the original value of B,plus 1. A general rule is to use blocking assignments when
sequential ordering is imperative and in cyclic behavior that is level sensitive(i.e., in
combinational logic). Use nonblocking assignments when modeling concurrent execution(e.g.,
edge-sensitive behavior such as synchronous, concurrent register transfers)
and when modeling latched behavior .Nonblocking assignments are imperative in dealing with
register transfer level design, as shown in Chapter 8 . They model the concurrent
operations of physical hardware synchronized by a common clock.
« Last Edit: July 05, 2014, 06:19:55 am by Sailor »
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #11 on: July 05, 2014, 06:48:06 am »
If that RTL view is for a +1 value then that is indeed a bit curious. You could change it to  counter <= counter + 4'b1101;  and see if the bit pattern shows up in reverse in the RTL view.

If so that would be a Bad Thing [tm] IMO, because vortexnl did define counter in the usual MSB:LSB notation.
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #12 on: July 05, 2014, 07:41:46 am »
@bwat

I've just had a look at the website you recommended. The concept (design, test, compiler, etc) sounds interesting, especially if it hangs together and works as advertised. :-+

 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #13 on: July 05, 2014, 07:50:32 am »
@bwat

I've just had a look at the website you recommended. The concept (design, test, compiler, etc) sounds interesting, especially if it hangs together and works as advertised. :-+

You mean the VESPA website? (I've linked to two different websites in this thread, I think you mean the VESPA one and not my own, right?)
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline cyr

  • Frequent Contributor
  • **
  • Posts: 252
  • Country: se
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #14 on: July 05, 2014, 08:42:16 am »
So to verify:

Blocking and non-blocking assignments actually change the hardware as well? I don't really understand it. Because people say you are supposed to use blocking assignments with combinational logic, but I would assume that combinational logic would have to run in parallel right? I don't see logic being sequential. I'm still reading up on all of this, so I hope to understand all of this soon.

One thing to realize is that Quartus will evaluate the block of code you have written, figure out what the end result is, and then synthesize the netlist to realize what you have described in the available hardware. It does *not* take every line of code and translate to one specific type of hardware element.

See what happens if you alter your code so that the LED is assigned first and the counter second. The blocking and non-blocking versions should then be equivalent.
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #15 on: July 05, 2014, 08:51:55 am »

@bwat
Yes, it was the VESPA site. But I just had a look at your site. The Everyman Kernel also sounds interesting. Have you ever put it onto a micro, say NXP or ST?
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #16 on: July 05, 2014, 09:07:11 am »

@bwat
Yes, it was the VESPA site.
I think the book is good for someone who knows Verilog and just wants to see a "perfect" design method for a simple pipelined CPU. I say perfect because nobody gets it right first time but it does seem so much simpler the way they do it.

But I just had a look at your site. The Everyman Kernel also sounds interesting. Have you ever put it onto a micro, say NXP or ST?
I remember being sent on some Renesas one day course where you got  a development board to take home. I put my kernel on it within an hour of walking through my front door. I ran through their wizard to create the boot sequence and just linked in my code. I think that was a 32-bit microcontroller, though it was a while ago. I usually just run boot it from a PC. In the future it will be ported to run on a homebrew CPU which will have other hard real-time friendly functions.
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #17 on: July 05, 2014, 09:13:16 am »
@cyr
Yes, I guess it would, because you are then forcing the (sequential) blocking code to evaluate the LED (which is dependent on the counter state) before the counter is incremented. The point in all of this being that (a) you need to know exactly what you want your hardware to do, and (b) you need to understand the consequences (and the reasons for those consequences) of using the different types of assignment.

Again, it would be interesting to see the two RTL viewer diagrams after altering the sequence in the blocking version, and seeing how the LE consumption varies.

I might have to install Quartus and have a play around...

 

Offline free_electron

  • Super Contributor
  • ***
  • Posts: 8549
  • Country: us
    • SiliconValleyGarage
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #18 on: July 05, 2014, 09:51:56 am »


Since you wrote counter =counter +1 first,
And later wanted to pick a bit from counter (which is now actually equal to itself +1) the synthesizer wires into the logic after the adder.
Essentially the +1 MUST be executed before you pick the signal off (that is why this is called blocking)

With non blocking statements they occur concurrently.
You increment but you also pick off the current value. The count value only really changes an infinitesimal amount later (the delay inside the flipflop)

Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #19 on: July 06, 2014, 09:13:28 am »
Hmmmm, well, strange...

I installed Quartus II Web Edition 13.1 this afternoon, and ran the OPs code. I selected a Cyclone IV device. Not only does it use the same number of LEs (25) in both blocking and non-blocking form, the output of the RTL viewer is identical to the OPs EXCEPT that the +1 is correctly indicated i.e. 25'h1 (not 25'h1000000).

@vortexnl
What version are you running?
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #20 on: July 06, 2014, 09:41:45 am »
You might also want to check what options were used for synthesis. Presumably default options, but you never know if the OP has been experimenting with shiney buttons in the preferences.
 

Offline Sailor

  • Regular Contributor
  • *
  • Posts: 170
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #21 on: July 06, 2014, 09:45:02 am »
Yes, and all pots, inductor cores, etc are just *meant* to be twiddled  ::)
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #22 on: July 06, 2014, 10:02:06 am »
Actually I was serious. :P Have had it happen often enough that some clever soul had been mucking about with the options, and it could not possibly have affected the undesired result ... except that it did. ;)
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8627
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #23 on: July 06, 2014, 10:03:59 am »
Hmmmm, well, strange...

I installed Quartus II Web Edition 13.1 this afternoon, and ran the OPs code. I selected a Cyclone IV device. Not only does it use the same number of LEs (25) in both blocking and non-blocking form, the output of the RTL viewer is identical to the OPs EXCEPT that the +1 is correctly indicated i.e. 25'h1 (not 25'h1000000).

@vortexnl
What version are you running?
OP mentioned CPLD, not FPGA, so try something like a Max/Max II instead?

Also you should be able to use the Chip Planner to look at how the LEs were used, which should show the difference more clearly compared to RTL.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: [Verilog] Using non-blocking assignments reduces LE's by half!?
« Reply #24 on: July 06, 2014, 10:07:37 am »
Might be more device dependent than version dependent.

So Cyclone IV (DE0-Nano) on Quartus II 13.1 gives me the OP's hex representation but it adds a carry bit of 0?


But original Cyclone (I) on Quartus II 10.1 gives me Sailor's representation
« Last Edit: July 06, 2014, 10:13:44 am by miguelvp »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf