// Sequential always block.
always @(posedge clk or posedge rst)
begin
if (rst)
state <= STATE_IDLE;
else
state <= next;
end
// Combinational always block.
always @(state or input1 or input2 ... or inputN)
begin
next = STATE_IDLE;
outputs = OUTPUT_IDLE:
case (state)
STATE_IDLE:
begin
... // the logic to determine the next state.
next = STATE_?????;
end
STATE_?????:
begin
... // the logic to determine the next state.
next = STATE_?????;
outputs = ?????; // The output of this state.
end
endcase
end
针对simplified one-hot encoding的FSM范例:
// Sequential always block.
always @(posedge clk or posedge rst)
begin
if (rst)
state <= n'b0;
state[STATE_DEFAULT] <= 1'b0;
else
state <= next;
end
// Combinational always block.
always @(state or input1 or input2 ... or inputN)
begin
next = n'b0;
outputs = OUTPUT_DEFAULT:
case (1'b1) // synopsys full_case parallel_case
state[STATE_DEFAULT]:
begin
... // the logic to determine the next state.
next[STATE_?????] = 1'b1;
end
state[STATE_?????]:
begin
... // the logic to determine the next state.
next[STATE_?????] = 1'b1;
outputs = ?????; // The output of this state.
end
// synopsys translate_off
default:
$display("Bad state!!");
// synopsys translate_on
endcase
end
针对simplified one-hot with zero-idle encoding的FSM:
// Sequential always block.
always @(posedge clk or posedge rst)
begin
if (rst)
state <= n'b0;
else
state <= next;
end
// Combinational always block.
always @(state or input1 or input2 ... or inputN)
begin
next = n'b0;
outputs = OUTPUT_DEFAULT:
case (1'b1) // synopsys full_case parallel_case
~|state: // IDLE
begin
... // the logic to determine the next state.
next[STATE_?????] = 1'b1;
end
state[STATE_?????]:
begin
... // the logic to determine the next state.
next[STATE_?????] = 1'b1;
outputs = ?????; // The output of this state.
end
// synopsys translate_off
default:
$display("Bad state!!");
// synopsys translate_on
endcase
end
input signed [7:0] a, b;
output signed [15:0] o;
assign o = a * b;
or
input [7:0] a, b;
output [15:0] o;
wire signed [15:0] o_sgn;
assugb o_sgn = $signed(a) * $signed(b);
assign o = $unsigned(o_sgn);
正负号的扩展:应多加利用Verilog的implicity signed extension,避免手动进行转换。
input signed [7:0] a, b;
input signed [8:0] o;
assign o = a + b; // Verilog会自动进行符号的扩展。