Verilog: keep value in register (assign to same register)

3k views Asked by At

I want to keep the value in a register for arbitrary amount of clock cycles. Basically I want to do it similar like the treatment of a state machine:

always@ (posedge Clock ) begin
if ( Reset ) CurrentState <= STATE_Initial ;
else CurrentState <= NextState ;
end

always@ ( * ) begin
NextState = CurrentState ;
  case ( CurrentState )
  STATE_Initial : begin
  NextState = STATE_1 ;
  end
  STATE_1 : begin
  NextState = STATE_2 ;
  end
  endcase
end

My problem is now that I want to proceed in addition to that and similarly with a standard register of 24 bits:

always@ (posedge Clock ) begin
if ( Reset )
  CurrentState <= STATE_Initial ;
  curReg <= 24'd0;
else 
  CurrentState <= NextState ;
  curReg <= nextReg;
end

always@ ( * ) begin
NextState = CurrentState ;
nextReg = curReg;
  case ( CurrentState )
  STATE_Initial : begin
  NextState = STATE_1 ;
  nextReg = 24'd2048;
  end
  STATE_1 : begin
  NextState = STATE_2 ;
  nextReg = 24'd211;
  end
  endcase
end

For me it seems to be treated the same way, but I always receive some errors that the timing constraints are not met. So, why is that a problem?

1

There are 1 answers

3
Greg On

Yo are missing begin-end in the if-else statement

always @(posedge Clock) begin
  if ( Reset ) begin // <---- HERE
    CurrentState <= STATE_Initial ;
    curReg <= 24'd0;
  end // <---- HERE
  else begin // <---- HERE
    CurrentState <= NextState ;
    curReg <= nextReg;
  end // <---- HERE
end

For improved timing, you can direct the synthesizer to perform parallel case. This will increase area. IEEE Std 1364-2001 (aka Verilog-2001) added attributes to verilog for synthesis as described in section 2.8. However I have not seen may tools utilize this feature, most have gone to a more SystemVerilog approach and continually supporting their custom keywords in comments

IEEE Std 1364-2001 and above suggestions from the LRM:

(* parallel_case *)
case(CurrentState)
  ...
endcase

IEEE Std 1800-2005 (SystemVerilog) and above solution: (recommended)

unique case(CurrentState)
  ...
default: begin end // blank default for parallel only, else unique means parallel+full
endcase

IEEE Std 1800-2009 (SystemVerilog) and above solution: (best if supported)

unique0 case(CurrentState) // unqiue0 is explicit parallel case
  ...
endcase

Typical vendor specific syntax. Refer to the synthesis manual for exact syntax:

case(CurrentState) // synthesis parallel_case
  ...
endcase

Parallelism will help with your next state calculation. Your synthesizer may already be doing it if it smart enough and timing aware. You may still running into timing issues at 500MHz depending on your standard cells and routing.

If all else fails, you will need to slow down your clock or not update all your flops on every clock cycle. For example an tiny update counter:

always @(posedge Clock) begin
  if ( Reset ) begin
    CurrentState <= STATE_Initial ;
    curReg <= 24'd0;
    tiny_update_counter <= 0;
  end
  else begin // <---- HERE
    if(tinly_update_counter == 0) begin
      CurrentState <= NextState ;
      curReg <= nextReg;
      tiny_update_counter <= next_tiny_update_counter;
    end
    else begin
      tiny_update_counter <= tiny_update_counter - 1;
    end
  end
end