1
votes

Is there any other functionality like always (that would only run if the sensitive signal changes and won't iterate as long as signal stays the same) which can be cascaded, separately or within the always , but is synthesizable in Verilog.

2
This would be very nice but I am not aware of any way to cascade always logic in Verilog. It would be obvious how to synthesize it but I don't think any synthesis tools are built to do it.Owen
Its a very useful logic when we want some input with human (hardware switches) speed but wanna process them with clk cycles. There should be something.Ahmad
something similar if you want to detect an edge of a signal stackoverflow.com/questions/8413661/…e19293001
@e19293001 Your provided code (Not Answer) was good and simple. Thanx! btw!! you usrname equals to infinity ... thats the point ??Ahmad

2 Answers

1
votes

While I don't think there's a construct specifically like this in Verilog, there is an easy way to do this. If you do an edge detect on the signal you want to be sensitive to, you can just "if" on that in your always block. Like such:

reg event_detected;
reg [WIDTH-1:0] sensitive_last;
always @ (posedge clk) begin
    if (sensitive_signal != sensitive_last) begin
        event_detected <= 1'b1;
    end else begin
        event_detected <= 1'b0;
    end
    sensitive_last <= sensitive_signal;
end

// Then, where you want to do things:
always @ (posedge clk) begin
    if (event_detected ) begin
        // Do things here
    end
end

The issue with doing things with nested "always" statements is that it isn't immediately obvious how much logic it would synthesize to. Depending on the FPGA or ASIC architecture you would have a relatively large register and extra logic that would be instantiated implicitly, making things like waveform debugging and gate level synthesis difficult (not to mention timing analysis). In a world where every gate/LUT counts, that sort of implicitly defined logic could become a major issue.

1
votes

The assign statement is the closest to always you you can get. assign can only be for continuous assignment. The left hand side assignment must be a wire; SystemVerilog also allows logic.

I prefer the always block over assign. I find simulations give better performance when signals that usually update at the same time are group together. I believe the optimizer in the synthesizer can does a better job with always, but this might depend on the synthesizer being used.

For synchronous logic you'll need an always block. There is no issue reading hardware switches within the always block. The fpga board may already de-bounce the input for you. If not, then send the input through a two phase pipe line before using it with your code. This helps with potential setup/hold problems.

always @(posedge clk) begin
  pre_sync_human_in <= human_in;
  sync_human_in <= pre_sync_human_in;
end
always @* begin
  //...
  case( sync_human_in )
  0 : // do this
  1 : // do that
  // ...
  endcase
  //...
end
always @(posedge clk) begin
  //...
  if ( sync_human_in==0 )  begin /* do this */ end
  else begin /* else do */ end
  //...
end

If you want to do a hand-shake having the state machine wait for a human to enter a multi-bit value, then add to states that wait for the input. One state that waits for not ready (stale bit from previous input), and the other waiting for ready :

always @(posedge clk) begin
  case(state)
  // ...
  PRE_HUMAN_IN :
    begin
      // ...
     state <= WAIT_HUMAN__FOR_NOT_READY;
    end
  WAIT_HUMAN_FOR_NOT_READY :
    begin
      // ready bit is still high for the last input, wait for not ready
      if (sync_human_in[READ_BIT])
        state <= WAIT_HUMAN_FOR_NOT_READY; 
      else
        state <= WAIT_HUMAN_FOR_READY;
    end
  WAIT_HUMAN_FOR_READY :
    begin
      // ready bit is low, wait for it to go high before proceeding
      if (sync_human_in[READ_BIT])
        state <= WORK_WITH_HUMAN_INPUT; 
      else
        state <= WAIT_HUMAN_FOR_READY;
    end
  // ...
  endcase
end