掌握有限状态机的设计。实现并仿真:
1)基于mealy状态机进行序列“1101”的检测;
2)基于moore或mealy状态机的按键消抖电路设计。
(1)基于mealy状态机进行序列“1101”的检测;
(2)基于moore或mealy状态机的按键消抖电路设计。
(3)按照本模版撰写实验报告,版面排版要求及评分标准:
(1)设计代码
`timescale 1ns / 1ps
module Seq_det_mealy(Clk,Rst_,din,y);
input Clk,Rst_,din;
output reg y;
//状态符号声明
localparam [1:0] s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;
//状态信号声明
reg [2:0] cs,nst;
//现态
always @(posedge Clk)
if(!Rst_) cs<=s0;
else cs<=nst;
//次态
always @*
begin
case(cs)
s0: if(din) nst=s1;
else nst=s0;
s1: if(din) nst=s2;
else nst=s0;
s2: if(din) nst=s2;
else nst=s3;
s3: nst=s0;
default:nst=s0;
endcase
end
//输出
always @*
begin
if((cs==s3)&&(din==1)) y=1;
else y=0;
end
endmodule
(3)testbench代码
`timescale 1ns / 1ps
module testbench_Seq_det_mealy();
reg Clk,Rst_;
reg din;
wire y;
localparam N=5, M=2*N;
initial
begin
Clk=0;
Rst_=0;
#7 Rst_=1;
end
always #N Clk=~Clk;
initial
begin
din=1;
#(2*M) din=0;
#M din=1;
#(3*M) din=0;
#M din=1;
end
initial #100 $finish;
Seq_det_mealy unit1(Clk,Rst_,din,y);
endmodule
(1)设计代码
`timescale 1ns / 1ps
module Key_debounce #(parameter N=19)(sw,Clk,Rst_,out);
input sw,Clk,Rst_;
output reg out;
//状态声明
localparam [2:0] zero=3'b000,zero1=3'b001,zero2=3'b010,one=3'b100,one1=3'b101,one2=3'b110;
//信号声明
reg[2:0] cs,nst;
//利用计数器产生tick信号
wire tick;
reg [N-1:0] regN;
always @(posedge Clk)//设计同步异步都行
begin
if(!Rst_) regN<=0; //看书本上P117页代码有什么问题?
else regN<=regN+1;
end
assign tick=(regN==0)?1'b1:1'b0;
//状态机设计部分-现态逻辑-时序电路
always @(posedge Clk )
begin
if(!Rst_) cs=zero;
else cs=nst;
end
//状态机设计部分--次态逻辑-组合电路
always @*
begin
nst=cs;
//组合电路开始就给输出赋初值,这样后面状态不转移的情况就不用写
case(cs)
zero: if(sw) nst=zero1;
zero1: if(!sw) nst=zero;
else if(tick) nst=zero2;
zero2: if(!sw) nst=zero;
else if(tick) nst=one;
one: if(!sw) nst=one1;
one1: if(sw) nst=one;
else if(tick) nst=one2;
one2: if(sw) nst=one;
else if(tick) nst=zero;
endcase
end
//状态机设计部分--输出逻辑-组合电路
always @*
begin
out=1'b0;//赋初值
case (cs)
one,one1,one2:out=1'b1;
zero2:
begin
if(sw&tick) out=1'b1;
end
endcase
end
endmodule
(3)testbench代码
`timescale 1ns / 1ps
module tb_Key_debounce;
reg Clk,sw_in,Rst_;
wire sw_out;
Key_debounce #(.N(2)) unit (.sw(sw_in),.Clk(Clk),.Rst_(Rst_),.out(sw_out));
always #2 Clk=~Clk;
initial
begin
sw_in=0;Clk=0;
#5 sw_in=1;
#1 sw_in=0;
#1 sw_in=1;
#1 sw_in=0;
#2 sw_in=1;
#100 sw_in=0;
#1 sw_in=1;
#1 sw_in=0;
#2 sw_in=1;
#1 sw_in=0;
end
initial
begin
Rst_=1;
#2 Rst_=0;
#2 Rst_=1;
end
initial #300 $finish;
endmodule