fpga学习 01状态机-爱代码爱编程
状态机
实现一个可乐机,规定只能投入一元硬币,投入三元可以出一瓶可乐,否则不出
状态转移图:
功能代码:
module simple_fsm
(
input wire sys_clk,
input wire sys_rst_n,
input wire pi_money,//投入硬币
output reg po_cola //出可乐 使用always语句控制的都需要用reg
);
reg [2:0] state;//定义中间变量状态state
//使用独热码定义状态
parameter IDLE=3'b100;
parameter ONE=3'b010;
parameter TWO=3'b001;
//使用always语句控制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;//投入硬币,状态跳转到1
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语句控制po_cola
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'b0;
sys_rst_n<=1'b0;
#20
sys_rst_n<=1'b1;
end
//使用always语句控制时钟翻转
always #10 sys_clk=~sys_clk; //时钟周期为50MHz
//使用always语句给pi_money赋随机值
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;//simple_fsm_inst.state读取state内部的state
//实例化simpel_fsm
simple_fsm simple_fsm_inst
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n),
.pi_money (pi_money ),
.po_cola (po_cola )
);
Endmodule
使用modelsim的仿真结果:
如果有错误请指正!