1
\$\begingroup\$

My Verilog code samples the input (Vin) at fixed intervals using a counter. The counter is a 2-bit register whose value increments at every positive edge of a clock (CLK). The counter takes on values from 2'b00 to 2'b11, and I want to store the value of Vin whenever the value of the counter=2'b01 in a register named u1. I have written the following code:

module inp_samp (Vin, CLK);
input Vin;
input CLK;
reg u1 = 0;
reg [1:0] counter = 2'b00;
wire CLK_inner1;
always @(posedge CLK) begin
    counter <= counter + 1'b1;      
end
assign CLK_inner1 = CLK && (counter ==2'b01);
always @ (posedge CLK_inner1)
    u1 = Vin;
endmodule

Testbench:

module testbench1(); // Testbench has no inputs, outputs
reg Vin, CLK; // Will be assigned in initial b 
inp_samp dut (.Vin(Vin), .CLK(CLK));

initial begin 
    Vin = 0;
    CLK = 0;
end
always 
    #10 CLK =!CLK;
always
    #22 Vin = !Vin;     
initial  begin
   $dumpfile ("counter.vcd"); 
   $dumpvars; 
end      
initial 
  #120  $finish; 
endmodule

The waveforms are given as follows: Waveforms I don't understand why u1 register changes its value at the highlighted instants. What should I do to fix it?

\$\endgroup\$
0

3 Answers 3

2
\$\begingroup\$

Since CLK and counter change at the same time, you get a zero-time glitch on CLK_inner1, which you can't see in waves. Since the simulator senses a change on CLK_inner1, the always block is triggered, and u1 gets the value of Vin.

You must use glitch-free clocks. You should use the same clock (CLK) for all always blocks, such as:

module inp_samp (Vin, CLK);
    input Vin;
    input CLK;
    reg u1 = 0;
    reg [1:0] counter = 2'b00;
    always @(posedge CLK) begin
        counter <= counter + 1'b1;      
    end
    always @(posedge CLK) begin
        if (counter == 2'b01) u1 <= Vin;     
    end
endmodule
\$\endgroup\$
4
  • \$\begingroup\$ Thanks for your answer but your code doesn't work perfectly. u1 changed value when counter became 2'b10. \$\endgroup\$
    – Nimit Jain
    Apr 3, 2020 at 16:26
  • \$\begingroup\$ My code matches the text description you provided in your Question. Change the counter comparison line to match the value you need, probably counter == 2'b00 \$\endgroup\$
    – toolic
    Apr 3, 2020 at 16:38
  • \$\begingroup\$ Thanks! changing the counter ==2'b00 worked. So, for knowledge, does that mean the counter value in the line "if (counter ==2'b01)" takes the value of counter before the expression "counter<=counter+1'b1" is evaluated? \$\endgroup\$
    – Nimit Jain
    Apr 3, 2020 at 16:58
  • \$\begingroup\$ Yes. That is one tricky thing about RTL simulations without explicit delays that you can see in waveforms. Think of it as the simulator sampling the signals (like counter) just before the posedge of the clock. \$\endgroup\$
    – toolic
    Apr 3, 2020 at 17:03
0
\$\begingroup\$

Missing a left arrow on the u1 statement in the second always @ block. Should be ‘u1 <= ...’ for a nonblocking assignment, which is the intention for a typical clocked block.

Also, the gated clock isn’t necessary. It’s better to use a clock-enable approach. It’s messing up your simulation in any event (that is, this is the problem.)

Finally, where is u1’s output going to? Looks like nowhere. It should be part of the module signal list.

\$\endgroup\$
3
  • \$\begingroup\$ I wasn’t done... phone died. \$\endgroup\$ Apr 3, 2020 at 16:03
  • \$\begingroup\$ Adding the left arrow doesn't change the results. I don't know what is clock enable approach. u1 is my output. I will set it as output port after resolving this bug. \$\endgroup\$
    – Nimit Jain
    Apr 3, 2020 at 16:36
  • \$\begingroup\$ To create a clock enable, add an if statement inside the always @ block with the enable logic as the expression. \$\endgroup\$ Apr 3, 2020 at 16:55
0
\$\begingroup\$

You have set up a race condition between the two clocked blocks. You don't know (and can't know) which of these blocks will be evaluated first.

If the second always block is evaluated first, then there will be a short pulse on CLK_inner1 at the point in time when CLK rises but before the counter has changed from 01 to 10.

Creating a clock like CLK_inner1 like this is a very bad practice. Instead, you should use the value of count to enable loading u1, inside a block that triggers on (posedge CLK)

\$\endgroup\$
2
  • \$\begingroup\$ I am not sure why a race condition will appear as the pos edge of CLK_inner1 will always come after pos edge of CLK. (First the Pos edge of CLK comes which will increment the counter from 0 to 1. When this happens the CLK_inner1 will become 1 from 0). \$\endgroup\$
    – Nimit Jain
    Apr 3, 2020 at 16:43
  • \$\begingroup\$ @NimitJain No, you are assuming that the counter is always incremented before u1 is updated. Suppose the counter has the value 01, then CLK rises. If the second always block is evaluated first then u1 will be updated before count changes to 10. \$\endgroup\$ Apr 3, 2020 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.