Search code examples
verilogsystem-veriloghdl

Verilog blocking assignment not blocking


I have a problem with Verilog blocking assignment, in the simulation it seems that it is not blocking. Espessialy in the second always@ block. I need the rst to go "1"only forv1 unit (clock cycle?), but it simultaneosly goes "1" and "0". When i replace bothrst = 1'b0; with rst = #10 1'b0; then in the simulation I can see the rst goes "1" for 10 units of time. Can anybody help me?

module testled(
input clk,
output reg out
);
 reg [23:0] counter;
 reg rst;


 initial begin
    out = 1'b0;
    rst = 1'b0;
    counter = 24'b000000000000000000000000;
end
always @(posedge clk, posedge rst) begin
    if(rst) begin
        counter = 24'b000000000000000000000000;
    end
    else begin
        counter = counter + 1;
    end
end

always @(posedge clk) begin
    case (out)
        1'b1 : begin
            if (counter[5]) begin
                rst = 1'b1;
                out = 1'b0;
                rst =1'b0;
            end
            else begin
                out = out;
            end             
        end
        1'b0 : begin
            if (counter[3]) begin
                rst = 1'b1;
                out = 1'b1;
                rst = 1'b0;
            end
            else begin
                out = out;
            end             
        end         
    endcase
end

endmodule


Solution

  • For simulation purposes you could do:

    initial begin
      out = 1'b1;
      #10ns out = 1'b0;
      #20ns out = 1'b1;
      #30ns out = 1'b0;
    end
    

    But that is not synthesizable so will not help in your final application.

    For sequential (clocked) logic the time high or low must be an integer number of clock cycles. Using Counter as an state and combinatorially decoding this for out.

    always @(posedge clk,  rst) begin
      if(rst) begin
        counter <= 'b0;
      end
      else begin
        counter <= counter + 1;
      end
    end
    
    always @* begin
      if (counter < 10) begin
        out = 1'b0;
      end 
      else if (counter < 30) begin
        out = 1'b1;
      end
      else if (counter < 50) begin
        out = 1'b0;
      end
      else if (counter < 90) begin
        out = 1'b1;
      end
      else begin
        out = 1'b0;
      end
    end