设计一个自动售卖饮料机,设饮料售价为2.5元,可使用5角和一元硬币,有找零功能。
module drink_status_moore(clk,reset,half.one,out,cout);
input clk;
input reset;
input half;
input one;
output out;
output cout;
parameter [2:0] s0 = 3'b000, //3'd0,参数声明
s1 = 3'b001, //3'd1
s2 = 3'b010, //3'd2
s3 = 3'b011, //3'd3
s4 = 3'b100, //3'd4
s5 = 3'b101, //3'd5
s6 = 3'b110; //3'd6
reg [2:0] curr_state; //内部信号声明
reg [2:0] next_state;
//first segement: state transfer---描述状态寄存器、时序逻辑
always @(posedge clk, negedge reset) begin
if(!reset)
curr_state <= s0;
else
curr_state <= next_state;
end
//second segment: transfer condition--描述次态逻辑、组合逻辑
always @(curr_state,one,half)begin //等价 always@(*)
case(curr_state)
s0:begin
if(half) next_state = s1;
else if(one) next_state = s2;
else next_state = s0;
end
s1:begin
if(half) next_state = s2;
else if(one) next_state = s3;
else next_state = s1;
end
s2:begin
if(half) next_state = s3;
else if(one) next_state = s4;
else next_state = s2;
end
s3:begin
if(half) next_state = s4;
else if(one) next_state = s5;
else next_state = s3;
end
s4:begin
if(half) next_state = s5;
else if(one) next_state = s6;
else next_state = s4;
end
s5:begin
next_state = s0;
end
s6:begin
next_state = s0;
end
default: next_state = s0;
endcase
end
//third segement: state output---状态输出(描述输出逻辑)
assign out = ((curr_state == s5) || (curr_state == s6))?1:0;
assign cout = (curr_state == s6)?1:0; //assign可简化输出
endmodule
上述Moore FSM的Testbench:
`timescale 1ns/1ns
module drink_status_moore_tb();
reg half;
reg one;
reg clk;
reg reset;
wire out
wire cout;
initial
begin
clk = 0;
reset = 0; //初始化时钟与复位信号
#20 reset = 1; //拉起reset
end
always #20 clk = ~clk //时钟周期为40ns
initial
begin
half = 0;
one = 0;
#20;
repeat(5)begin
@(posedge clk) half = 1;
@(posedge clk) half = 0;
end
#100;
repeat(3)begin
@(posedge clk) one = 1;
@(posedge clk) one = 0;
end
#200;
$finish;
end
drink_status_moore drink_status_moore_u1(
.clk (clk),
.reset (reset),
.one (one),
.half (half),
.out (out),
.cout(cout));
endmodule
module drink_status_mealy(
input clk, //verilog-2001
input reset,
input half,
input one,
output out,
output cout);
parameter [2:0] s0 = 3'b000, //3'd0
s1 = 3'b001, //3'd1
s2 = 3'b010, //3'd2
s3 = 3'b011, //3'd3
s4 = 3'b100, //3'd4
reg [2:0] curr_state;
reg [2:0] next_state;
//first segement: state transfer---时序逻辑、描述状态寄存器
always @(posedge clk, negedge reset) begin
if(!reset)
curr_state <= s0;
else
curr_state <= next_state;
end
//second segment: transfer condition---组合逻辑、描述次态逻辑
always @(*)begin //等价 always @(curr_state,one,half)
case(curr_state)
s0:begin
if(half) next_state = s1;
else if(one) next_state = s2;
else next_state = s0;
end
s1:begin
if(half) next_state = s2;
else if(one) next_state = s3;
else next_state = s1;
end
s2:begin
if(half) next_state = s3;
else if(one) next_state = s4;
else next_state = s2;
end
s3:begin
if(half) next_state = s4;
else if(one) next_state = s0;
else next_state = s3;
end
s4:begin
if(half) next_state = s0;
else if(one) next_state = s0;
else next_state = s4;
end
default: next_state = s0;
endcase
end
//third segement: state output---状态输出(描述输出逻辑)
assign out = ((curr_state == s4) & (half|one))?1:((curr_state == s3) & (one))?1:0; //等价于if--else if--else,即条件操作符的嵌套使用
assign cout = ((curr_state == s4) & (one))?1:0;
endmodule
注意区别Moore型状态机与Mealy型状态机,一般Moore型状态机的状态数量较Mealy型要多。
设计一个序列检测器,检查的序列为“1110010”,当输入的信号依次为“1110010”时,输出信号Y输出一个高电平,否则输出信号Y为低电平。
module seq_checker_moore(
input in, clk, reset;
output out;
output [2:0] state; //000-111
parameter s0 = 'd0,
s1 = 'd1,
s2 = 'd2,
s3 = 'd3,
s4 = 'd4,
s5 = 'd5,
s6 = 'd6,
s7 = 'd7,
s8 = 'd8;
reg [2:0] curr_state;
reg [2:0] next_state;
//first segement: state transfer---时序逻辑、描述状态寄存器
always @(posedge clk, negedge reset) begin
if(!reset)
curr_state <= s0;
else
curr_state <= next_state;
end
//second segment: transfer condition---组合逻辑、描述次态逻辑
always @(*)begin //等价 always @(curr_state,in)
case(curr_state)
s0:begin
if(in==0) next_state = s0;
else next_state = s1;
end
s1:begin
if(in==0) next_state = s0;
else next_state = s2;
end
s2:begin
if(in==0) next_state = s0;
else next_state = s3;
end
s3:begin
if(in==0) next_state = s4;
else next_state = s3;
end
s4:begin
if(in==0) next_state = s5;
else next_state = s1;
end
s5:begin
if(in==0) next_state = s0;
else next_state = s6;
end
s6:begin
if(in==0) next_state = s7;
else next_state = s2;
end
s7:begin
if(in==0) next_state = s0;
else next_state = s1;
end
default: next_state = s0;
endcase
end
//third segement: state output---状态输出(描述输出逻辑)
assign out = (curr_state == s7)?1:0;
endmodule
mealy型序列检测器的状态机不再赘述。
以下为上述Moore FSM的Tsetbench:
`timescale 1ns/1ns
module seq_checker_moore_tb();
reg in;
reg clk;
reg reset;
reg [7:0] data[0:7];
wire out
wire [3:0] state;
reg i;
initial
begin
clk = 0;
reset = 0; //初始化时钟与复位信号
#20 reset = 1; //拉起reset
end
always #20 clk = ~clk //时钟周期为40ns
initial
begin
in = 0;
#30 in = 1;
#40 in = 1;
#40 in = 0;
#40 in = 0;
#40 in = 1;
#40 in = 0;
#40 in = 1;
#40 in = 0;
#40 in = 1;
#40 in = 1;
#40;
$finish;
end
initial begin //该模块与仿真无关
$readmemh("data.txt",data);
for(i=0;i<8;i=i+1)begin
#40;
$display("data=%d",data[i]);
end
#200;
$finish;
end
seq_checker_moore seq_ckecker_moore_u1(
.clk (clk),
.reset (reset),
.in (in),
.out (out),
.state(state));
endmodule