版权说明:未经许可,不得转载
一.目的
1.掌握复杂时序逻辑电路的设计方法
2.了解FPGA中有限状态机的工作原理和实现过程
3.学习用Verilog描述有限状态机的方法。
二.工具
1.Digilent Anvyl开发板
2.安装ISE Design Suite软件的PC机一台
3.USB数据线一根
三.简单上手实验
1.用Verilog HDL设计并实现一个10101串行序列检查器(可重叠)。
2.设计一个密码锁,检测密码为:30221。要求:以4个按钮作为输入,分别表示输入的数据0、1、2、3;当检测到有效的密码输入时,LED0被点亮。
四.实验原理
注:因为这两个实验设计到的代码量相对较多,为了方便后期修改和查看我把实验源码分为了几个部分,最后使用一个顶层文件进行调用处理。
这里给出开发板相关引脚信息和这两个实验的设计思路。
引脚信息:
五.实验步骤及结果分析
实验1
设计过程:
1.先对开发板的100Mhz时钟进行分频
2.然后对分频后的时钟进行处理,并获得一个稳定的时钟脉冲
3.画出实验的有限状态机(画的不好看,有强迫症的请不要介意):
时钟分频.v:
module clk_div(
input mclk,
input clr,
output clk190
);
reg [24:0] q;
always@(posedge mclk or posedge clr)
begin
if(clr==1)
q <= 0;
else
q <= q + 1'b1;
end
assign clk190=q[17];
endmodule
时钟脉冲.v:
module clk_pause(
input inp,
input cclk,
input clr,
output outp
);
reg delay1;
reg delay2;
reg delay3;
always@(posedge cclk or posedge clr)
begin
if(clr==1)
begin
delay1 <= 0;
delay2 <= 0;
delay3 <= 0;
end
else
begin
delay1 <= inp;
delay2 <= delay1;
delay3 <= delay2;
end
end
assign outp = delay1&delay2&~delay3;
endmodule
有限状态机.v:
module pg2(
input wire clk,
input wire clr,
input wire din,
output reg dout
);
reg [2:0] pre_state,next_state;
parameter S0=3'b000,S1=3'b001,S2=3'b010,S3=3'b011,S4=3'b100,S5=3'b101;
always@(posedge clk or posedge clr)
begin
if(clr==1)
pre_state <= S0;
else
pre_state <= next_state;
end
always@(*)
begin
case(pre_state)
S0:if(din==1)
next_state <= S1;
else
next_state <= S0;
S1:if(din==0)
next_state <= S2;
else
next_state <= S1;
S2:if(din==1)
next_state <= S3;
else
next_state <= S0;
S3:if(din==0)
next_state <= S4;
else
next_state <= S1;
S4:if(din==1)
next_state <= S5;
else
next_state <= S0;
S5:if(din==1)
next_state <= S1;
else
next_state <= S4;
default:next_state <= S0;
endcase
end
always@(*)
begin
if(pre_state==S5)
dout <= 1;
else
dout <= 0;
end
endmodule
顶层文件.v:
module clk_top(
input mclk,
input [2:0] btn,
output led
);
wire clr,clk190,clkp,btn01;
assign clr=btn[2];
assign btn01 = btn[0]|btn[1];
clk_div U1(.mclk(mclk),
.clr(clr),
.clk190(clk190)
);
clk_pause U2(.inp(btn01),
.cclk(clk190),
.clr(clr),
.outp(clkp)
);
pg2 U3(.clk(clkp),
.clr(clr),
.din(btn[1]),
.dout(led)
);
endmodule
.ucf文件:
NET mclk LOC=D11;
NET led LOC=W3;
NET btn<0> LOC=A3;
NET btn<1> LOC=AB9;
NET btn<2> LOC=E6;
实验结果截图如下:
当输入10101序列(可重叠)后,LED灯亮
实验2
设计过程和上一题一样,唯一不同的就是该实验的有限状态机,如下:
时钟分频.v:
module clk_div(
input mclk,
input clr,
output clk190
);
reg [24:0] q;
always@(posedge mclk or posedge clr)
begin
if(clr==1)
q <= 0;
else
q <= q + 1'b1;
end
assign clk190=q[17];
endmodule
时钟脉冲.v:
module clk_pause(
input inp,
input cclk,
input clr,
output outp
);
reg delay1;
reg delay2;
reg delay3;
always@(posedge cclk or posedge clr)
begin
if(clr==1)
begin
delay1 <= 0;
delay2 <= 0;
delay3 <= 0;
end
else
begin
delay1 <= inp;
delay2 <= delay1;
delay3 <= delay2;
end
end
assign outp = delay1&delay2&~delay3;
endmodule
有限状态机.v:
module pg2(
input wire clk,
input wire clr,
input wire [3:0] din,
output reg dout
);
reg [2:0] pre_state,next_state;
parameter S0=3'b000,S1=3'b001,S2=3'b010,S3=3'b011,S4=3'b100,S5=3'b101;
always@(posedge clk or posedge clr)
begin
if(clr==1)
pre_state <= S0;
else
pre_state <= next_state;
end
always@(*)
begin
case(pre_state)
S0:if(din[3]==1)
next_state <= S1;
else
next_state <= S0;
S1:if(din[0]==1)
next_state <= S2;
else
next_state <= S0;
S2:if(din[2]==1)
next_state <= S3;
else
next_state <= S0;
S3:if(din[2]==1)
next_state <= S4;
else
next_state <= S0;
S4:if(din[1]==1)
next_state <= S5;
else
next_state <= S0;
default:next_state <= S0;
endcase
end
always@(*)
begin
if(pre_state==S5)
dout <= 1;
else
dout <= 0;
end
endmodule
顶层文件.v:
module clk_top(
input mclk,
input sw,
input [3:0] btn,
output led
);
wire clr,clk190,clkp,btn01;
assign clr=sw;
assign btn01 = btn[0]|btn[1]|btn[2]|btn[3];
clk_div U1(.mclk(mclk),
.clr(clr),
.clk190(clk190)
);
clk_pause U2(.inp(btn01),
.cclk(clk190),
.clr(clr),
.outp(clkp)
);
pg2 U3(.clk(clkp),
.clr(clr),
.din(btn),
.dout(led)
);
endmodule
.ucf文件:
NET mclk LOC=D11;
NET led LOC=W3;
NET sw LOC=V5;
NET btn<0> LOC=E6;
NET btn<1> LOC=D5;
NET btn<2> LOC=A3;
NET btn<3> LOC=AB9;
实验结果截图如下:
上图为输入为30221的正确密码后,LED灯亮
六.实验总结
1.本实验的成功要点是要先对原始的100MHz的时钟进行分频和脉冲操作,这样就可以达到防抖的效果。
2.这次的实验可以用两种方法,一种是摩尔状态机,一种是米里状态机。两种方法都是没问题的,但是用不同的方法说对应的实验结果却有一些差异。前者若输入正确,LED则会一直亮着,直到下一个输入;而若后者输入正确,LED则会只闪一下就灭了。大家注意下这点就行了。
ps:这是最后一篇教程了,今天一下写完两篇,呼~~~心力憔悴啊 -----2016.12.02
pps:当志愿者去了,待会再来更 ----2016.12.02
ppps:这两天的志愿者活动太忙了,每天早起晚归,一会宿舍倒床就睡,都没来的及更新。今天终于写完啦!----2016.12.05
由于笔者的知识和水平有限,文中不足之处在所难免,恳请各位读者赐正
---------------------------------------@weekdawn 版权所有------------------------------------------------