简单的可乐贩卖机,实现找零
代码中注意的点:
实现不同时投入1元和0.5元先定义一个随机数,再赋值给 pi_money_half,而pi_money_one取反
只能实现01,10
pi_money_half <= random_data;
pi_money_one <= ~random_data;
或者,可以实现10,01,00
random_data <= {$random} % 3;
{pi_money_one,pi_money_half} = random_data;
1. 状态机
2. 时序图
3. 代码
complex_fsm_fire.v文件
module complex_fsm_fire
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire pi_money_half,
input wire pi_money_one,
output reg po_cola,
output reg po_half
);
parameter IDEL = 5'b0_0001,
HALF = 5'b0_0010,
ONE = 5'b0_0100,
ONE_HALF = 5'b0_1000,
TWO = 5'b1_0000;
wire [1:0] pi_money;
reg [4:0] state;
assign pi_money = {pi_money_one,pi_money_half};
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDEL;
else case(state)
IDEL: case(pi_money)
2'b00: state <= IDEL;
2'b01: state <= HALF;
2'b10: state <= ONE;
2'b11: state <= IDEL;
endcase
HALF: case(pi_money)
2'b00: state <= HALF;
2'b01: state <= ONE;
2'b10: state <= ONE_HALF;
2'b11: state <= IDEL;
endcase
ONE: case(pi_money)
2'b00: state <= ONE;
2'b01: state <= ONE_HALF;
2'b10: state <= TWO;
2'b11: state <= IDEL;
endcase
ONE_HALF: case(pi_money)
2'b00: state <= ONE_HALF;
2'b01: state <= TWO;
2'b10: state <= IDEL;
2'b11: state <= IDEL;
endcase
TWO: case(pi_money)
2'b00: state <= TWO;
2'b01: state <= IDEL;
2'b10: state <= IDEL;
2'b11: state <= IDEL;
endcase
endcase
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) begin
po_cola <= 1'b0;
po_half <= 1'b0;
end
else if((state == ONE_HALF) && (pi_money == 2'b10))
po_cola <= 1'b1;
else if((state == TWO) && (pi_money == 2'b01))
po_cola <= 1'b1;
else if((state == TWO) && (pi_money == 2'b10)) begin
po_cola <= 1'b1;
po_half <= 1'b1;
end
else begin
po_cola <= 1'b0;
po_half <= 1'b0;
end
endmodule
tb_complex_fsm_fire.v文件
`timescale 1ns/1ns
module tb_complex_fsm_fire();
//声明变量
reg sys_clk;
reg sys_rst_n;
reg pi_money_half;
reg pi_money_one;
reg random_data;
wire po_cola;
wire po_half;
//初始化
initial
begin
sys_clk = 1'b0;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
random_data <= 1'b0;
else
random_data <= {$random} % 2;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pi_money_half <= 1'b0;
else
pi_money_half <= random_data;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pi_money_one <= 1'b0;
else
pi_money_one <= ~random_data;
//系统时钟初始化,周期为20ns
always #10 sys_clk = ~sys_clk;
wire [1:0] pi_money = complex_fsm_fire_inst.pi_money;
wire [4:0] state = complex_fsm_fire_inst.state;
//初始化显示
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("$time %t:pi_money_half=%b,pi_money_one=%b,pi_money=%b,state=%b,po_cola=%b,po_half=%b",$time,pi_money_half,pi_money_one,pi_money,state,po_cola,po_half);
end
//实例化
complex_fsm_fire complex_fsm_fire_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.pi_money_half (pi_money_half),
.pi_money_one (pi_money_one),
.po_cola (po_cola),
.po_half (po_half)
);
endmodule