Verilog Finite State Machine [closed]
Question
I'm trying to create a Finite state machine in verilog. The system has 4 1-bit
inputs rst
, clk
, A
, B
and one output, Z
.
Z is equal to 1 if either: A had same value on last two clock edges.
or B has been high (1) on every clock edge since the last rule was true.
Otherwise z=0
;
I don't have the tools to simulate my attempt atm. So I'm wondering if this is the correct method and if i'm on the right track?
module StateMachine( R, A, B, clk, Z);
input R, A, B, clk;
output reg Z;
reg ATemp;
reg state;
always @ (posedge clk or A)
if (A == 1'b1)
/////////////////
begin
if (ATemp == 1'b1) state <= 1'b1;
else ATemp <= A;
end
////////////////
else
////////////
begin
if (ATemp == 1'b0) state <= 1'b1;
else ATemp <= A;
end
always @ (state)
case(state)
1'b0: Z=0;
1'b1: Z=1;
default: Z=0;
endcase
endmodule
Solution
You can use the following tools:
GHDL is an open-source simulator for the VHDL language ( User Guide )
Additionally these are the most popular simulation tools:
Further resources:
There is also the stackexchange electronics community and codereview.
- Overmapped: a forum on VHDL topics
Additionally, heed the C to HDL compiler tool
(.. I doubt many can review your code in 3 minutes, nor would I want them too )
OTHER TIPS
You have no next state logic so state will never change, and there's no reset so state will start as 1'bz. I recommend starting with Xilinx guidelines when coding state machines.
Your definition of a flipflop is slightly wrong. You have always @ (posedge clk or A)
. You should not combine edge triggers and non-edge triggers. It might work in simulation but you will not get what you want in synthesis.
If you only want the value to change on a clock edge then use always @( posedge clk)
or for a combinatorial input, that is output changes with input use always @( A )
or the more modern version always @*
. @* will trigger for any changes. Missing items from the sensitivity list use to be a main reason for synthesised code not simulating the same as the RTL.
Saying that if you are building a flip flop you should include a reset. always @ (posedge clk or negedge rst_n)
Also note the state is never set to 0, so first impression is that this will lock up into to a particular state/output. It is hard for me to see how the code implements the question being asked. My solution would be some thing like:
module statemachine(
input rst,
input A,
input B,
input clk,
output reg Z
);
reg [1:0] a_last_two;
wire rule_one;
always @ (posedge clk or negedge rst) begin
if (~rst) begin
a_last_two <= 2'b0;
end
else begin
a_last_two <= {a_last_two[0] ,A};
end
end
assign rule_one = (a_last_two[1] == a_last_two[0]);
//rule one could be written as ~^a_last_two (xnor reduction operator)
reg rule_two;
always @ (posedge clk or negedge rst) begin
if (~rst) begin
rule_two <= 1'b0 ;
end
else begin
//rule 2 resets when rule_one is true
if (rule_one) begin
rule_two <= 1'b1 ;
end
else begin
rule_two <= rule_two & B ;
end
end
end
assign Z = rule_one | rule_two ;
endmodule