module simple_fsm
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire pi_money ,
output reg po_cola
);
parameter IDLE = 3'b001;
parameter ONE = 3'b010;
parameter TWO = 3'b100;
reg [2:0] state;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE;
else case(state)
IDLE:if(pi_money == 1'b1)
state <= ONE;
else
state <= IDLE;
ONE:if(pi_money == 1'b1)
state <= TWO;
else
state <= ONE;
TWO:if(pi_money == 1'b1)
state <= IDLE;
else
state <= TWO;
default: state <= IDLE;
endcase
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
po_cola <= 1'b0;
else if((state == TWO)&&(pi_money == 1'b1))
po_cola <= 1'b1;
else
po_cola <= 1'b0;
endmodule
`timescale 1ns/1ns
module tb_simple_fsm();
reg sys_clk;
reg sys_rst_n;
reg pi_money;
wire po_cola;
initial
begin
sys_clk <=1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pi_money <= 1'b0;
else
pi_money <= {$random}%2;
wire [2:0] state = simple_fsm_inst.state;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t:pi_money = %b,state = %b,po_cola = %b",$time,pi_money,state,po_cola);
end
simple_fsm simple_fsm_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.pi_money (pi_money ),
.po_cola (po_cola )
);
endmodule
Moore状态机:输出只和当前状态有关和输入无关
Mealy状态机:输出和当前状态和输入有关
module state
(
input wire sys_clk,
input wire sys_rst_n,
input wire pi_money,
output reg po_cola
);
parameter IDLE=4'b0001;
parameter ONE=4'b0010;
parameter TWO=4'b0100;
parameter THREE =4'b1000;
reg [3:0] state;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE;
else case(state)
IDLE:if(pi_money == 1'b1)
state <= ONE;
else
state <= IDLE;
ONE:if(pi_money == 1'b1)
state <= TWO;
else
state <= ONE;
TWO:if(pi_money == 1'b1)
//po_cola <= 1'b1;
state <= THREE;
else
state <= TWO;
THREE:if(pi_money == 1'b1)
state <= ONE;
else if(pi_money == 1'b0)
state <= IDLE;
else
state <= IDLE;
default:state <= state;
endcase
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
po_cola <= 1'b0;
else if (state == THREE)
po_cola <= 1'b1;
else
po_cola <= 1'b0;
endmodule
`timescale 1ns/1ns
module tb_state();
reg sys_clk;
reg sys_rst_n;
reg pi_money;
wire po_cola;
initial
begin
sys_clk <= 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk <= ~sys_clk;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pi_money <= 1'b0;
else
pi_money <= {$random}%2;
wire [3:0] state = state_inst.state;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t: pi_money=%b state=%b po_cola =%b",$time,pi_money,state,po_cola);
end
state state_inst
(
.sys_clk (sys_clk ),
.sys_rst_n(sys_rst_n),
.pi_money (pi_money ),
.po_cola (po_cola )
);
endmodule