I think I've written all the cases for switch and if, but I don't understand why following message occur in synthesis process.
This module performs the operation of converting BCD code into excess-3 code. In behavior simulation, it works operately. but in post synthesis simulation, it works wrong.
`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
i using always(*) and write all cases but nothing change.
If you separate the design into 2 blocks, updating and evaluation, the code may look like this:
// 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
In the updating phase, the next state is assigned to current state (DFF D -> Q).
In the evaluation phase, the next state is derived from current state or other variables (DFF Q -> D). Use "=" instead of "<=" 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.