我想我已经写了 switch 和 if 的所有情况,但我不明白为什么在综合过程中会出现以下消息。
该模块执行BCD码转换为余3码的操作。 在行为模拟中,它是可操作的。但在综合后模拟中,它工作错误。
`timescale 1ns/1ps
module fsm_ex3 (
input sw1,
input sw2,
input clk,
input reset_n,
output reg [3:0] LED
);
localparam S_0 = 3'b000;
localparam S_1 = 3'b001;
localparam S_2 = 3'b010;
localparam S_3 = 3'b011;
localparam S_4 = 3'b100;
localparam S_5 = 3'b101;
localparam S_6 = 3'b110;
reg sw1_signal1,sw1_signal2,sw2_signal1,sw2_signal2;
wire o_sw1, o_sw2;
always @(posedge clk) begin
sw1_signal1 <= sw1;
sw2_signal1 <= sw2;
sw1_signal2 <= sw1_signal1;
sw2_signal2 <= sw2_signal1;
end
assign o_sw1 = sw1_signal1 && ~sw1_signal2;
assign o_sw2 = sw2_signal1 && ~sw2_signal2;
reg [2:0] c_state;
reg [2:0] n_state;
always @(posedge clk, negedge reset_n) begin
if(!reset_n) begin
c_state <= S_0;
end
else
c_state <= n_state;
end
always @(*) begin
case (c_state)
S_0:begin
if(o_sw1&&~o_sw2) begin
n_state <= S_1;
LED <= 4'b0001;
end
else if(~o_sw1&&o_sw2) begin
n_state <= S_2;
LED <= 4'b0000;
end
else begin
n_state <= S_0;
LED <= LED;
end
end
S_1:begin
if(o_sw1&&~o_sw2) begin
n_state <= S_3;
LED[1] <= 1;
end
else if(~o_sw1&&o_sw2) begin
n_state <= S_4;
LED[1] <= 0;
end
else begin
n_state <= S_1;
LED <= LED;
end
end
S_2:begin
if(o_sw1&&~o_sw2) begin
LED[1] <= 0;
n_state <= S_4;
end
else if(~o_sw1&&o_sw2) begin
LED[1] <= 1;
n_state <= S_4;
end
else begin
n_state <= S_2;
LED <= LED;
end
end
S_3:begin
if(o_sw1&&~o_sw2) begin
LED[2] <= 0;
n_state <= S_5;
end
else if(~o_sw1&&o_sw2) begin
LED[2] <= 1;
n_state <= S_5;
end
else begin
n_state <= S_3;
LED <= LED;
end
end
S_4:begin
if(o_sw1&&~o_sw2) begin
n_state <= S_5;
LED[2] <= 1;
end
else if(~o_sw1&&o_sw2) begin
n_state <= S_6;
LED[2] <= 0;
end
else begin
n_state <= S_4;
LED <= LED;
end
end
S_5:begin
if(o_sw1&&~o_sw2) begin
LED[3] <= 0;
n_state <= S_0;
end
else if(~o_sw1&&o_sw2) LED[3] <= 1;
else begin
n_state <= S_5;
LED <= LED;
end
end
S_6:begin
if(o_sw1&&~o_sw2) begin
n_state <= S_0;
LED[3] <= 1;
end
else begin
n_state <= n_state;
LED <= LED;
end
end
default: begin
n_state <= n_state;
LED <= LED;
end
endcase
end
endmodule
我使用always(*)并写出所有情况,但没有任何改变。
如果将设计分成 2 个块,更新和评估,代码可能如下所示:
// Updating phase
reg [3:0] n_LED;
always @( posedge clk or negedge reset_n )
if ( ~reset_n )
{ c_state, LED } <= { S_0, 4'b0000 };
else
{ c_state, LED } <= { n_state, n_LED };
// Evaluation phase
always @*
begin
{ n_state, n_LED } = { c_state, LED }; // Default
case ( c_state )
...
S_5: begin
if ( o_sw1 && ( ~o_sw2 ) ) begin
n_LED[3] = 0;
n_state = S_0;
end
else if ( ( ~o_sw1 ) && o_sw2 )
n_LED[3] = 1;
else
n_state = S_5;
end
...
endcase
end
在更新阶段,下一个状态被分配给当前状态(DFF D -> Q)。
在评估阶段,下一个状态是从当前状态或其他变量导出的(DFF Q -> D)。使用“=”代替“<=" because this block comprises combinational logic. There is a default assignment at the beginning of this block. So if some variables are not assigned in the case branches, that would be no problem since all variables have already got their default values.