Synthesizable Verilog from behavioral constructs - 5

Delay statements, e.g. @(posedge clock), require careful attention if there are several in a row. If there are only delays on the positive edge of the clock you can implement them with a state machine:

Behavioural:

forever
begin
command1;
@(posedge clock);
command2;
@(posedge clock);
command3;
@(posedge clock);
end

Synthesizable:

always @(posedge clock or posedge reset)
if (reset) // reset the state machine when reset is high
begin
state <= 0;
end
else
begin
case (state)
0 : begin
command1;
state <= 1;
end

1 : begin
command2;
state <= 2;
end

2 : begin
command3;
state <= 0;
end
endcase
end

If both clock edges are present, then you could implement it in synthesizable Verilog with a state machine changing values on both clock edges:

Behavioural:

forever
begin
command1;
@(posedge clock);
command2;
@(negedge clock);
command3;
@(posedge clock);
@(posedge clock);
command4;
@(negedge clock);
end

Synthesizable:

always @(posedge clock or negedge clock or posedge reset)
if (reset) // reset the state machine when reset is high
begin
state <= 0;
end
else
begin
case (state)
0 : begin
command1;
state <= 1;
end

1 : if (clock == 1) // wait for the positive edge
begin
command2;
state <= 2;
end

2 : begin // this will definitely begin at the negative edge as state 1 precedes it
command3;
state <= 3;
end

3 : state <= 4; // we arrive at the positive edge of the clock, but need to wait a clock cycle

4 : if (clock == 1) // wait for the positive edge
begin
command4;
state <= 0;
end // we'll get back to state 0 at the negative clock edge, the right time for command1
endcase
end

As you can see, multiple clock edges requires care to implement in synthesizable Verilog.

Note: in general commandi refers to a block of commands. It is assumed there is an appropriate clock for the case statement state machines. Care is required in setting appropriate reset states, initialization, and completion of use of a state machine:

* Is there a signal to tell the state machine to begin?
* Does a done signal go high, signalling the state machine has finished?
* When it is not in operation, does the state machine idle correctly? Does it change signal values shared with other code? Does it set outputs from it to appropriate idling values?
* Is the state machine reset to the idle state by a reset signal?
* Ensure that you initialize all registers.
* Ensure that your state register has the correct bit width - if it is too small, assigning a larger state value will just return it to an earlier state.

1. 