Synthesizable verilog code

  always @(posedge pclk or negedge presetn) begin
    if (~presetn)
      cnt <= 8'h00;
    else begin

      if (posedge_detector_load_tdr) begin
        cnt = tdr_reg;
      end else begin
        cnt = cnt;
      end
      
      if (enable && posedge_detector_clk_in) begin
        if (up_down) begin
          cnt <= cnt + 8'h01;
        end else
          cnt <= cnt - 8'h01;
      end else cnt <= cnt;
    end

  end

My intention is that I want to check if load_tdr is triggered then load tdr_reg into cnt and starts counting. Otherwise, keep the value of cnt and starts couting.

I want to ask if this blocking statement is synthesizable? Is is a good practice?

if (posedge_detector_load_tdr) begin
        cnt = tdr_reg;
      end else begin
        cnt = cnt;
      end

Because when I ask Chatgpt, it tells me that

There are multiple rules in play here.

The primary rule is:

Inside an always @(posedge clk) block, you should never use a blocking assignment to a variable that will be read outside that block.

Blocking assignments here are a significant cause of simulation race conditions. If another block attempts to read cnt, you do not know the order in which blocks are executed, resulting in the retrieval of either the old or updated value.

The secondary rule is:

You should not mix blocking and non-blocking assignments to the same variable.

The real problem comes in when you make a non-blocking assignment first, followed by a blocking assignment. The non-blocking assignment overrides the blocking assignment.

A better practice would be to use a temporary variable.

always @(posedge pclk or negedge presetn)
    if (~presetn)
      cnt <= 8'h00;
    else begin
      if (posedge_detector_load_tdr)
        temp_cnt = tdr_reg;
     else
        temp_cnt = cnt;
      if (enable && posedge_detector_clk_in)
        if (up_down) 
          cnt <= temp_cnt + 8'h01;
       else
          cnt <= temp_cnt - 8'h01;
end
1 Like

Hi @dave_59, do we always need to have else in if-else block ? You miss

else cnt <= cnt;

It is redundant and unnecessary.

1 Like