Electronic – Verilog code “always @” block not working as expected

counterhdlverilog

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?

Best Answer

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