10010序列检测
对串行输入的数据流进行检测,只要发现
10010 码型会立即输出一个高位的电平
module seqdet( x, z, clk, rst);
input x,clk, rst;
output z;
reg [2:0] state;//状态寄存器
wire z;
parameter IDLE = 3 'd0,
A = 3 'd1,
B = 3 'd2,
C = 3 'd3,
D = 3 'd4,
E = 3 'd5,
F = 3 'd6,
G = 3 'd7;
assign z =(state==D && x==0) ? 1 :0;//状态为 D 时又收到了 0,表明 10010 收到应有输出 Z 为高
always @(posedge clk or negedge rst)
if(!rst)
begin
state<=IDLE;
end
else
casex( state)
IDLE: if(x==1)
state<=A; //用状态变量记住高电平(x==1)来过
else state<= IDLE; //输入的是低电平,不符合要求,所以状态保留不变
A: if (x==0)
state<=B; //用状态变量记住第二位正确低电平(x==0)来过
else state<= A; //输入的是高电平,不符合要求,所以状态保留不变
B: if (x==0)
state<=C; //用状态变量记住第三位正确低电平(x==0)来过
else state<=F; //输入的是高电平,不符合要求,记住只有一位曾经对过
C: if(x==1)
state<=D; //用状态变量记住第四位正确高电平(x==1)来过
else state<=G; //输入的是低电平,不符合要求,记住没有一位曾经对过
D: if(x==0)
state<=E; //用状态变量记住第五位正确低电平(x==0)来过
else state<=A; //输入的是高电平,不符合要求,
E: if(x==0)
state<=C; //用状态变量记住 1 0 0 曾经来过,此状态为 C
else state<=A; //输入的是高电平,只有 1 位正确,该状态是 A
F: if(x==1)
state<=A; //输入的是高电平,只有 1 位正确,该状态是 A
else
state<=B; //输入的是低电平,已有 2 位正确,该状态是 B
G: if(x==1)
state<=F; //输入的又是高电平,只有 1 位正确,记该状态 F
else state <=B; //输入的是低电平,已有 2 位正确,该状态是 B
default: state<=IDLE;
endcase
endmodule
自动售卖机状态机
module drink_machine(
//input
clk,
rst_n,
nickel_in,//5 美分
dime_in, //10 美分
quarter_in,//25 美分
//output
collect, //投币者提货信号
dispense, //同时机器发货信号
nickel_out,//退回投币者 5 美分
dime_out //退回投币者 10 美 分
);
input nickel_in,dime_in,quarter_in;
input clk,rst_n;
output collect,dispense;
output nickel_out,dime_out;
reg collect;
reg dispense;
reg nickel_out;
reg dime_out;
parameter IDLE =0;
parameter FIVE =1;
parameter TEN =2;
parameter FIFTEEN =3;
parameter TWENTY =4;
parameter TWENTY_FIVE =5;
parameter THIRTY =6;
parameter ONE_DIME =7;
reg [2:0] state;
always@(posedge clk or negedge rst_n)
begin
if(rst_n==1'b0)
begin
nickel_out <=0;
dime_out <=0;
dispense <=0;
collect <=0;
state <= IDLE;
end
else
begin
nickel_out <=0;
dime_out <=0;
dispense <=0;
collect <=0;
case(state)
IDLE: begin
if(nickel_in)
state <= FIVE;
else if(dime_in)
state <= TEN;
else if(quarter_in)
state <= TWENTY_FIVE;
end
FIVE: begin
if(nickel_in)
state <= TEN;
else if(dime_in)
state <= FIFTEEN;
else if(quarter_in)
state <= THIRTY;
end
TEN: begin
if(nickel_in)
state <= FIFTEEN;
else if(dime_in)
state <= TWENTY;
else if(quarter_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
end
end
FIFTEEN:begin
if(nickel_in)
state <= TWENTY;
else if(dime_in)
state <= TWENTY_FIVE;
else if(quarter_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
nickel_out <=1'b1;
end
end
TWENTY:begin
if(nickel_in)
state <= TWENTY_FIVE;
else if(dime_in)
state <= THIRTY;
else if(quarter_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
dime_out <=1'b1;
end
end
TWENTY_FIVE:begin
if(nickel_in)
state <= THIRTY;
else if(dime_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
end
else if(quarter_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
dime_out <=1'b1;
nickel_out <=1'b1;
end
end
THIRTY:begin
if(nickel_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
end
else if(dime_in)
begin
state <= IDLE;
dispense<=1'b1;
collect <=1'b1;
nickel_out <=1'b1;
end
else if(quarter_in)
begin
state <= ONE_DIME;
dispense<=1'b1;
collect <=1'b1;
dime_out <=1'b1;
end
end
ONE_DIME:begin
state <= IDLE;
dime_out <=1'b1;
end
endcase
end
end
endmodule