状态机:贩卖机
1.简单情况
module ztj_fmj(
clk,
rst,
money_in,
kele
);
parameter IDLE=2'b00;
parameter ONE=2'b01;
parameter TWO=2'b10;
input clk;
input rst;
input money_in;
output kele;
reg[1:0] state;
reg kele;
always@(posedge clk or negedge rst)
begin
if(rst==0)
state<=IDLE;
else
case(state)
IDLE:
if(money_in==0)
state<=IDLE;
else
state<=ONE;
ONE:
if(money_in==0)
state<=ONE;
else
state<=TWO;
TWO:
if(money_in==0)
state<=TWO;
else
state<=IDLE ;
default:
state<=IDLE;
endcase
end
always@(posedge clk or negedge rst)
begin
if(rst==0)
kele<=0;
else if((state==TWO)&&(money_in==1))
kele<=1;
else
kele<=0;
end
endmodule
2.仿真代码
module ztj_fmj_tb();
reg clk;
reg rst;
reg money_in;
wire kele;
wire[1:0] state=u0.state;//关注该用法
ztj_fmj u0(
.clk(clk),
.rst(rst),
.money_in(money_in),
.kele(kele)
);
initial
begin
clk=0;rst<=0;
money_in<=0;
#25 rst<=1;
/*
#30 money_in<=1;
#40 money_in<=0;
#40 money_in<=1;
#80 money_in<=0;*/
#300 $stop;
end
always@(posedge clk or negedge rst)
begin
if(rst==0)
money_in<=0;
else
money_in<={$random}%2;
end
initial begin
$timeformat(-9,0,"ns",6);
$monitor ("@time %t:money_in= %b,state= %b,kele= %b",$time,money_in,state,kele);
end
always #10 clk<=~clk;
endmodule
2.复杂情况
module ztj_fmj(
clk,
rst,
money_in_half,
money_in_one,
kele,
po_money
);
parameter IDLE=5'b00000;
parameter HALF=5'b00010;
parameter ONE=5'b00100;
parameter ONE_HALF=5'b01000;
parameter TWO=5'b10000;
input clk;
input rst;
input money_in_half;
input money_in_one;
output kele;
output po_money;
reg[4:0] state;
reg[1:0] pi_money;
reg kele;
reg po_money;
always@(posedge clk or negedge rst)
begin
if(rst==0)
pi_money<=2'b00;
else
pi_money<={money_in_one,money_in_half};
end
always@(posedge clk or negedge rst)
begin
if(rst==0)
state<=IDLE;
else
case(state)
IDLE: if(pi_money==2'b00) state<=IDLE; else if(pi_money==2'b01) state<=HALF; else if(pi_money==2'b10) state<=ONE;
HALF: if(pi_money==2'b00) state<=HALF; else if(pi_money==2'b01) state<=ONE; else if(pi_money==2'b10) state<=ONE_HALF;
ONE: if(pi_money==2'b00) state<=ONE; else if(pi_money==2'b01) state<=ONE_HALF; else if(pi_money==2'b10) state<=TWO;
ONE_HALF: if(pi_money==2'b00) state<=ONE_HALF; else if(pi_money==2'b01) state<=TWO; else if(pi_money==2'b10) state<=IDLE;
TWO: if(pi_money==2'b00) state<=TWO; else if(pi_money==2'b01) state<=IDLE; else if(pi_money==2'b10) state<=IDLE;
default: state<=IDLE;
endcase
end
always@(posedge clk or negedge rst)
begin
if(rst==0)
kele<=0;
else if(((state==TWO&&(money_in_one==1||money_in_half==1)))||(state==ONE_HALF&&money_in_one))
kele<=1;
else
kele<=0;
end
always@(posedge clk or negedge rst)
begin
if(rst==0)
po_money<=0;
else if((state==TWO)&&(money_in_one==1)&&(money_in_half==0))
po_money<=1;
else
po_money<=0;
end
endmodule
module ztj_fmj_tb();
reg clk;
reg rst;
reg money_in_half ;
reg money_in_one;
wire kele;
ztj_fmj u0(
.clk(clk),
.rst(rst),
.money_in_half(money_in_half),
.money_in_one(money_in_one),
.kele(kele)
);
initial
begin
clk=0;rst<=0;
money_in_half<=0;
money_in_one<=0;
#25 rst<=1;
#300 $stop;
end
always@(posedge clk or negedge rst)
begin
if(rst==0)
begin money_in_half<=0; money_in_one<=0;end
else
begin
money_in_half<={$random}%2;
money_in_one<={$random}%2;
end
end
/* initial begin
$timeformat(-9,0,"ns",6);
$monitor ("@time %t:money_in= %b,state= %b,kele= %b",$time,money_in,state,kele);
end */
always #10 clk<=~clk;
endmodule