一、complex_fsm
相较于上一篇文章状态机--可乐机售卖,增加输入与输出,增加状态机复杂度,以练习状态机
系统框图
- 输入端 1. 时钟输入 2. 复位信号 3. pi_money_half:是否投入5毛 4.pi_money_one:是否投入1元钱
- 输出端:(三种情况)①出找零、出可乐②出可乐、不找零③不找零、不出可乐
- 状态:0 0.5 1 1.5 2 2.5 3 ;
二、波形图绘制
使用wavedrom editor
{signal: [
{name: 'clk', wave: 'p.........|............'},
{name: 'rerset', wave: 'lh......|..............'},
{name: 'pi_money_half', wave: 'l.....hl....h.l..h..l..'},
{name: 'pi_money_one', wave: 'l.h..l.hlhl...h.l....hl'},
{name: "pi_data", wave: "=.=..======.=.=.==..===", data: ["2'b00", "2'b10","2'b00","2'b01","2'b10","2'b00", "2'b10", "2'b00", "2'b01","2'b10","2'b00","2'b01","2'b00","2'b10","2'b00"] },
{name: "state", wave: "=..===.==.=..====.===.=", data: ["IDEL", "ONE", "TWO", "IDEL","HALF","ONE_HALF","IDLE","HALF","ONE","TWO","IDLE","HALF","ONE","ONE_HALF","IDLE"] },
{name: 'po_cola', wave: 'l....hl...hl....hl....hl'},
{name: 'po_money', wave: 'l....hl.........hl......'},
],
config: { hscale: 2,
skin: "narrow"
}
}
绘制完成啦。
三、程序编写
complex_fsm.v
module complex_fsm(
clk,
reset,
pi_money_half,
pi_money_one,
po_cola,
po_money);
//---Ports declearation: generated by Robei---
input clk;
input reset;
input pi_money_half;
input pi_money_one;
output po_cola;
output [1:0] po_money;
wire clk;
wire reset;
wire pi_money_half;
wire pi_money_one;
reg po_cola;
reg [1:0] po_money;
//----Code starts here: integrated by Robei-----
parameter IDLE = 5'b00001;
parameter HALF = 5'b00010;
parameter ONE = 5'b00100;
parameter ONE_HALF = 5'b01000;
parameter TWO = 5'b10000;
wire [1:0]pi_money;
reg [4:0]state;
assign pi_money = {pi_money_one,pi_money_half};
always@(posedge clk or negedge reset)
if(reset == 0)
state <= IDLE;
else begin
case(state)
IDLE:begin
if(pi_money == 2'b01) state <= HALF;
else if(pi_money == 2'b10)state <= ONE;
else if(pi_money == 2'b11)state <= ONE_HALF;
else state <= IDLE;
end
HALF:begin
if(pi_money == 2'b01) state <= ONE;
else if(pi_money == 2'b10)state <= ONE_HALF;
else if(pi_money == 2'b11)state <= TWO;
else state <= HALF;
end
ONE:begin
if(pi_money == 2'b01) state <= ONE_HALF;
else if(pi_money == 2'b10)state <= TWO;
else if(pi_money == 2'b11)state <= IDLE;
else state <= ONE;
end
ONE_HALF:begin
if(pi_money == 2'b01) state <= TWO;
else if(pi_money == 2'b10)state <= IDLE;
else if(pi_money == 2'b11)state <= IDLE;
else state <= ONE_HALF;
end
TWO:begin
if(pi_money == 2'b01) state <= IDLE;
else if(pi_money == 2'b10)state <= IDLE;
else if(pi_money == 2'b11)state <= IDLE;
else state <= TWO;
end
default :state <= IDLE;
endcase
end
always@(posedge clk or negedge reset)
if(reset == 0)begin
po_cola <= 0;
po_money <= 0;
end
else begin
case(state)
ONE:begin
if(pi_money == 2'b11) begin
po_cola <= 1;
po_money <= 2'b00;
end
else begin
po_cola <= 0;
po_money <= 2'b00;
end
end
ONE_HALF:begin
if(pi_money == 2'b11) begin
po_cola <= 1;
po_money <= 2'b01;
end
else if(pi_money == 2'b10)begin
po_cola <= 1;
po_money <= 2'b00;
end
else begin
po_cola <= 0;
po_money <= 2'b00;
end
end
TWO:begin
if(pi_money == 2'b01)begin
po_cola <= 1;
po_money <= 2'b00;
end
else if(pi_money == 2'b10)begin
po_cola <= 1;
po_money <= 2'b01;
end
else begin
po_cola <= 0;
po_money <= 2'b00;
end
end
default:begin
po_cola <= 0;
po_money <= 2'b00;
end
endcase
end
/*
always@(posedge clk or negedge reset)
if(reset == 0)
begin
po_cola <= 0;
po_money <= 0;
end
else begin
if(state == IDLE && pi_money_half == 1)
begin
po_cola <= 1;
po_money <= 0;
end
else if(state == IDLE && pi_money_one == 1)
begin
po_cola <= 1;
po_money <= 1;
end
else begin
po_cola <= 0;
po_money <= 0;
end
end
*/
endmodule //complex_fsm
complex_fsm_tb.v
module complex_fsm_tb();
reg clk;
reg reset;
reg pi_money_half;
reg pi_money_one;
wire po_cola;
wire [1:0] po_money;
//----Code starts here: integrated by Robei-----
initial clk = 1;
always#1 clk = ~clk;
initial begin
reset = 0;
pi_money_half = 0;
pi_money_one = 0;
#2
reset = 1;
#2
pi_money_half = 1;
#4
pi_money_half = 0;
pi_money_one = 1;
#2
pi_money_one = 0;
#8;
pi_money_one = 1;
#6
pi_money_one = 0;
#2
pi_money_one = 1;
pi_money_half = 0;
#2
pi_money_one = 0;
pi_money_half = 0;
#2
pi_money_one = 1;
pi_money_half = 1;
#2
pi_money_one = 0;
pi_money_half = 0;
$finish;
end
initial begin
$dumpfile ("D:/Robei_project/Robei_study_complex_fsm/complex_fsm_tb.vcd");
$dumpvars;
end
//---Module instantiation---
complex_fsm complex_fsm1(
.clk(clk),
.reset(reset),
.pi_money_half(pi_money_half),
.pi_money_one(pi_money_one),
.po_cola(po_cola),
.po_money(po_money));
endmodule //complex_fsm_tb
四、反思与总结
本身这个可乐机设计不完整,存在缺陷,不过感谢野火的教程--状态机!!