Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
09/21/07 21:07
Read: times


 
Msg Score: +1
 +1 Good Answer/Helpful
#144897 - block vs nonblocking
Responding to: ???'s previous message
Russ Cooper said:
reg [15:0] clockDivider;                // A 16-bit counter
    reg outputBit;                          // 1 KHz, 20% duty cycle signal

    always @(posedge clock50Mhz) begin      // On 50 MHz clock rising edge
        clockDivider = clockDivider + 1;    // Bump the counter
        if (clockDivider == 50000) begin    // One millisecond has gone by
            clockDivider = 0;               // Reset the counter
        end                             // End 'one msec has gone by'
        outputBit =                         // Assert the output for 20%
            (clockDivider < 10000) ? 1 : 0; //  of the one ms period
    end                                 // End 'on 50MHz rising edge'



This works fine; the waveform on the physical output pin looks exactly as expected. However, I realized as I was fiddling around that you could get the same result in many, many, many different ways.


One note: you used blocking assignments. For synchronous descriptions you should use non-blocking assignments. There is a significant difference. A blocking assignment is evaluated and the left-hand-side is updated immediately, while a non-blocking assignment is scheduled such that all of its right-hand side is evaluated immediately but the assignment to the LHS occurs at the end of the simulation cycle.

Your code is a really good example of this. At the rising edge of the clock, the register clockDivider is incremented. THEN the comparison is executed, possibly resetting the counter. THEN the counter is tested to drive the state of outputBit. When you simulate this, you'll get something that "looks" correct but isn't.

Look closer. Consider the case where clockDivider is 49999. After the rising edge of the clock, clockDivider will be immediately incremented and it will be 50000. The next statement, the comparison of clockDivider to 50000, will then evaluate to true, and then the counter will immediately clear. The next statement tests if clockDivider is less than 10000, which evaluates to true, because clockDivider was just cleared.

But that's not how the hardware actually works. In real hardware, all three of the statements in that always block are executed in parallel. At the rising edge of the clock:

a) clockDivider is incremented.

b) The current value of clockDivider (BEFORE the increment) is compared to 50000. If the comparison is true, then clockDivider is supposed to be cleared. But wait: that conflicts with a)! So the second assignment overrides the first.

So your simulation will show clockDivider changing from 49998 to 49999 to 0, where in reality the hardware will change from 49998 to 49999 to 50000 to 0.

c) The current value of clockDivider (BEFORE the increment) is compared to 10000. If clockDivider is less than 10000, then outputBit is set, otherwise, it is cleared. Your simulation with blocking assignments will show outputBit being cleared simultaneously with the value of clockDivider changing to 10000. However, in reality, that can't happen because it's comparing the wrong value of clockDivider.

Basically, the non-blocking assignment properly models synchronous processes, and the rule is simple: a synchronous process block MUST use non-blocking assignments, and combinatorial processes MUST use blocking assignments. Google for "Coding Styles That Kill." BTW, it's worth noting that VHDL does not give you the choice of blocking vs non-blocking assignments, as it only has non-blocking. (Yes, VHDL has variables, to which assignments ARE blocking, but they can only be used within a process and as such their utility is rightfully limited.)

BTW: when you count starting at zero, comparing against 50000 gives you 50001 counts in each cycle. So you should compare against 49999 for your rollover. (Same for the deassertion of outputBit when compared to 10000; you should really test for 9999.) For example:
    always @(posedge clock50Mhz or negedge rst_l) begin
	if (~rst_l) begin
	    clockDividerNB  <= 0;
	    outputBitNB	    <= 1'b0;
	end else begin	    
	    if (clockDividerNB == 49999) begin
		clockDividerNB 	 <= 0;
	    end else begin
		clockDividerNB 	 <= clockDividerNB + 1;
	    end
	    outputBitNB 	 <= (clockDividerNB < 9999) ? 1 : 0;
	end // else: !if(~rst_l)
    end // always @ (posedge clock50Mhz or negedge rst_l)

Notice how I first test for 49999 and if true then I reset clockDivider, otherwise I count. This is the standard way to code a counter that can roll over.

Yes, there is a subtle difference between rolling over at 50000 and rolling over at 49999, and in this example it's trivial. You didn't see anything out-of-sorts on your 'scope because you don't have the counter available at the pins. However, in other cases this can be a show-stopper.

You should simulate this as it is illuminating. (In fact, stop futzing with your board and learn about how to write a good Verilog test bench and how to simulate your code. You will spend a lot less time scratching your head.) If you simulate this, you will notice something interesting about the assertion of outputBitNB ...

good luck,
-a

List of 147 messages in thread
TopicAuthorDate
Getting Started With FPGAs, Part II            01/01/70 00:00      
   I didn't find it too big a job ... YMMV, of course            01/01/70 00:00      
   when it doesnt work            01/01/70 00:00      
      I'd guess...            01/01/70 00:00      
         Curses            01/01/70 00:00      
   OP Update 1 of ???            01/01/70 00:00      
      On your way ...            01/01/70 00:00      
         Not windows this time?            01/01/70 00:00      
            Not Windows every time, anyway            01/01/70 00:00      
      re: OP Update            01/01/70 00:00      
         what might be helpful before you get too far along            01/01/70 00:00      
   OP Update 2 of ???            01/01/70 00:00      
      re: update            01/01/70 00:00      
         The Verilog == C trap            01/01/70 00:00      
            re: The Verilog == C trap            01/01/70 00:00      
               Thinking hardware            01/01/70 00:00      
                  I read somewhere ...            01/01/70 00:00      
                  re: Thinking Hardware            01/01/70 00:00      
               One reason why HDL isnt the same as software            01/01/70 00:00      
                  Have I got this right?            01/01/70 00:00      
                     re: Have I got this right?            01/01/70 00:00      
                        re: re: Have I got this right?            01/01/70 00:00      
                           re: OT            01/01/70 00:00      
                        Nothing\'s perfect            01/01/70 00:00      
                        The thing to watch with FPGA's            01/01/70 00:00      
   OP Update 3 of ?            01/01/70 00:00      
      have you looked at the resource utilization?            01/01/70 00:00      
         Just a little bit            01/01/70 00:00      
            On a slightly different note..            01/01/70 00:00      
               the lesson ...            01/01/70 00:00      
               HDL coding to "help" the synthesizer            01/01/70 00:00      
         Please clarify            01/01/70 00:00      
            think hardware            01/01/70 00:00      
               this sounds like...            01/01/70 00:00      
                  re: this sounds like            01/01/70 00:00      
               Please clarify again            01/01/70 00:00      
                  for purpose of understanding ... YES            01/01/70 00:00      
                  answer            01/01/70 00:00      
      double assignment            01/01/70 00:00      
         Good catch, I think            01/01/70 00:00      
            re: Good Catch            01/01/70 00:00      
      block vs nonblocking            01/01/70 00:00      
         I have unplugged my eval board            01/01/70 00:00      
            re: Unplugged            01/01/70 00:00      
   OP Update 4 of ?            01/01/70 00:00      
      Another question about the counter            01/01/70 00:00      
         what's wrong            01/01/70 00:00      
            \'initial\' block            01/01/70 00:00      
               general Verilog coding advice            01/01/70 00:00      
                  Wow            01/01/70 00:00      
            Where does "reset" come from?            01/01/70 00:00      
   OP Dumb Question 1 of ?            01/01/70 00:00      
      look at it in the other way            01/01/70 00:00      
         But isn\'t it out of spec?            01/01/70 00:00      
            If you look more closely at the spec ...            01/01/70 00:00      
         which tools?            01/01/70 00:00      
            fanout exceeded            01/01/70 00:00      
               device dependence            01/01/70 00:00      
      newer data sheet?            01/01/70 00:00      
      Metastability            01/01/70 00:00      
         ... and contact bounce            01/01/70 00:00      
            That might not be a worry ...            01/01/70 00:00      
               Thanks            01/01/70 00:00      
   OP Update 5 of ?            01/01/70 00:00      
      do you mean, adaptive threshold?            01/01/70 00:00      
         Yes            01/01/70 00:00      
            PicoBlaze            01/01/70 00:00      
               Andy ... about that PicoBlaze ...            01/01/70 00:00      
                  re: about picoblaze            01/01/70 00:00      
         the boundary is quite arbitrary            01/01/70 00:00      
            Yes            01/01/70 00:00      
   OP Update 6 of ?            01/01/70 00:00      
      a better way            01/01/70 00:00      
   OP Update 7 of ?            01/01/70 00:00      
      OP Update 7.01            01/01/70 00:00      
         excessive skew warning            01/01/70 00:00      
            Offensive code here            01/01/70 00:00      
               On a slightly different note            01/01/70 00:00      
                  whatizit?            01/01/70 00:00      
                  free vs paid-for ModelSim            01/01/70 00:00      
               reason for the skew warning            01/01/70 00:00      
                  error            01/01/70 00:00      
                  I\\\'m drinking from a fire hose!            01/01/70 00:00      
                     fIREHOSE            01/01/70 00:00      
                        Faucet            01/01/70 00:00      
                           faucet            01/01/70 00:00      
                              Slow drip            01/01/70 00:00      
                                 I have no particular interest in this - but            01/01/70 00:00      
                                    Famous last words...            01/01/70 00:00      
                                       sure, I take your point - but            01/01/70 00:00      
                                 What libraries you use in VHDL            01/01/70 00:00      
                                    std_logic_arith vs numeric_std            01/01/70 00:00      
                              I found the FM!            01/01/70 00:00      
                                 Development System Reference Guide            01/01/70 00:00      
                           Another slow drip            01/01/70 00:00      
                              doubts            01/01/70 00:00      
                              I am not surprised it doesn\'t find that            01/01/70 00:00      
                              I was surprised            01/01/70 00:00      
                              If you want to see how the logic was synthesized            01/01/70 00:00      
                                 Don't cares worked for me            01/01/70 00:00      
                                    Not quite what I meant            01/01/70 00:00      
                                       Bummer            01/01/70 00:00      
                                          I wouldn't worry about minimizing            01/01/70 00:00      
                                             Thanks            01/01/70 00:00      
                              re: drip            01/01/70 00:00      
                                 re: re: drip            01/01/70 00:00      
                                    huh?            01/01/70 00:00      
                                       re: huh?            01/01/70 00:00      
                                          defaults?            01/01/70 00:00      
                                             re: defaults?            01/01/70 00:00      
                                             ***** Interesting result! ******            01/01/70 00:00      
                                          challenge            01/01/70 00:00      
                                             unknown is not don't care            01/01/70 00:00      
                                                A noob question            01/01/70 00:00      
                                                   similar noob question            01/01/70 00:00      
                                                      re: what happens            01/01/70 00:00      
                                                   You should get a latch            01/01/70 00:00      
                                                   re: a noob question            01/01/70 00:00      
                                                      Not really answered            01/01/70 00:00      
                                                         I'd guess...            01/01/70 00:00      
                           Simulator question            01/01/70 00:00      
                              what you are seeing            01/01/70 00:00      
                                 Thanks, Jez            01/01/70 00:00      
                                    check the logic!            01/01/70 00:00      
                                       That's good news            01/01/70 00:00      
                                          this might make the key difference            01/01/70 00:00      
                                             Two flavors of \"big\"            01/01/70 00:00      
                                                drop the comments :-)            01/01/70 00:00      
                                             as has been recommended ...            01/01/70 00:00      
                                          My confidence in XILINX' simulator is low            01/01/70 00:00      
                                             Xilinx vs. ModelSim            01/01/70 00:00      
                                                It's worth using ModelSim just for the features            01/01/70 00:00      
                                          behavioral is good,kind of            01/01/70 00:00      
                                             re: behavioral is good, kind of            01/01/70 00:00      
                                       Double post. Oops.            01/01/70 00:00      
                                 not so simple            01/01/70 00:00      
                              re: Simulator Question: ANSWER            01/01/70 00:00      
                                 re: ANSWER            01/01/70 00:00      
                                 re: ANSWER, Part II            01/01/70 00:00      
                        Long time            01/01/70 00:00      
      one more comment            01/01/70 00:00      
   OP Update 8 of ?            01/01/70 00:00      
      its supposed to make things easier to debug            01/01/70 00:00      
      one way vs the other way            01/01/70 00:00      
         re: Them two ways            01/01/70 00:00      
   OP Update 9 of ?            01/01/70 00:00      
   OP Update 10 of 10            01/01/70 00:00      

Back to Subject List