Reputation: 1
`timescale 1ns / 1ps
module StateMachine(
input [1:0] OP,
input [1:0] RESULT_COM,
input clk,
input rst,
output reg [1:0] CONTROL_AS=0,
output reg RESET_C,
output reg CONTROL_C,
output reg [1:0] state=0
);
parameter toLOWER=2'b01,toUPPER=2'b10,IDLE=0;
reg [1:0] n_state = IDLE;
//reg [1:0] state = IDLE;
reg [1:0] p_state = IDLE;
reg [1:0] prevOP = 2'b00;
reg [1:0] p_state_copy = 2'b00;
reg [15:0] count = 0;
always @ (posedge clk)
begin
if(rst == 1)
RESET_C = 1;
else
RESET_C = 0;
if(OP == 2'b01)
n_state = toLOWER;
else
if(OP == 2'b10)
n_state = toUPPER;
else
n_state = IDLE;
if(prevOP == OP)
p_state = state;
if((OP != prevOP && OP[0] != OP[1]) || (rst == 1 && (OP != 2'b00 && OP != 2'b11)))
CONTROL_C = 1;
else
CONTROL_C = 0;
if(state != n_state)
prevOP = OP;
state = n_state;
end
always @ (n_state)
begin
p_state_copy = p_state;
end
always @ (p_state)
begin
case(p_state)
toLOWER:
begin
if(RESULT_COM == 2'b10)
CONTROL_AS <= 2'b10;
else
CONTROL_AS <= 2'b00;
end
toUPPER:
begin
if(RESULT_COM == 2'b01)
CONTROL_AS <= 2'b01;
else
CONTROL_AS <= 2'b00;
end
IDLE:
begin
if(p_state_copy == toUPPER && RESULT_COM == 2'b01)
CONTROL_AS <= 2'b01;
else if(p_state_copy == toLOWER && RESULT_COM == 2'b10)
CONTROL_AS <= 2'b10;
else if(p_state_copy == toUPPER && RESULT_COM == 2'b10)
CONTROL_AS <= 2'b0;
else if(p_state_copy == toLOWER && RESULT_COM == 2'b01)
CONTROL_AS <= 2'b0;
else if(p_state_copy == toUPPER && RESULT_COM == 2'b0)
CONTROL_AS <= 2'b0;
//(p_state_copy == toLOWER && RESULT_COM == 2'b0)
else CONTROL_AS <= 2'b0;
end
endcase
end
endmodule
It is a letter converter. OP is 2 bits input. 11 and 00 means do nothing. 01 load next letter from ROM (using a counter to update the address) and convert to lower case. 10 load next letter and convert to lower case. letter won't be converted if it is not upper or lower case, or it is lower case but OP want to convert it to lower case, etc. If no input (00 or 11) or valid input always asserted (01 or 10), then output remains.
I use the p_state_copy to conserve the previous state and when next clk rising edge comes, it has some part overlap with the state. So it can check whether the previous state is IDDLE (input 00 or 11). RESULT_COM is the result from comparator, which is used to check the letter status. In the picture, hidden part in RESULT is 0 since reset is asserted.enter image description here
I can simulate, synthesize and implement it. But I can not run it on the board. May I know what the problem is? Thank you.
Upvotes: 0
Views: 280
Reputation: 1001
There's several things wrong with this code that will stop it synthesizing properly.
always @ (posedge clk)
begin
if(rst == 1)
RESET_C = 1;
should be more like
always @ (posedge clk or posedge rst)
if(rst == 1)
RESET_C = 1;
else
begin
There are several always @(...) sensitivity lists that are incomplete. e.g.
always @ (p_state)
begin
case(p_state)
toLOWER:
is missing p_state_copy and RESULT_COM that I've spotted so far. I'd suggest for maintainability either using always @(*) or even better if your tools allow always_comb
But with an incorrect sensitivity list it will almost certainly simulate incorrectly. (the simulation tool will only evaluate the block of code when the specified input changes as opposed to real combinatorial logic which won't make that restriction). For this reason many synthesis engines ignore the sensitivity list.
You're also using non-blocking assignments in a comb logic block, and blocking assignments in a comb logic block.
You're using initial statements on your variable defines. These will be ignored by the synthesis engine.
Further, (rst == 1 && (OP != 2'b00 && OP != 2'b11)) Will not synthesize correctly. You need to stick to the standard flip-flop verilog template if you want it to behave correctly.
These will all cause really wonky simulation results. I think you need to fix these issues first and check if your simulation still behaves as you expect.
Upvotes: 0
Reputation:
always @ (n_state)
begin
p_state_copy = p_state;
end
This logic can't be synthesized. There's no practical way for an FPGA to latch a value (like p_state_copy
) on the change of a logic signal (like n_state
).
Generally speaking, always
blocks in code intended for synthesis on an FPGA should be sensitive to either posedge clk
(or some other clock signal) for synchronous blocks, or *
for random logic. Specifying individual signals will only get you into trouble.
Upvotes: 0