什么是状态机?
输出不仅和输入有关还和系统本身的状态相关,或者只与本身的状态相关
module simple_fsm (
input wire sys_clk,
input wire sys_rst_n,
input wire pi_money,
output reg po_cola
);
reg [2:0] state;
// always @(posedge sys_clk or negedge sys_rst_n)
// if(sys_rst_n == 1'b0)
// state <= 1'b0;
// else if(pi_money ==1'b1)
// state <= state + 2'd1;
// else
// state <= state;
parameter IDLE = 3'b001 ;
parameter ONE = 3'b010 ;
parameter TWO = 3'b100 ;
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;
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;
//将 RTL 模块中的内部信号引入到 Testbench 模块中进行观察
//没有这一步后面的窗口函数无法观察state的大小
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
仿真符合预期