我是靠谱客的博主 传统舞蹈,最近开发中收集的这篇文章主要介绍verilog实现状态机一、使用工具二、要求三、需求分析四、时序切换五、检测10010串六、总结,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
如愿
- 一、使用工具
- 二、要求
- 三、需求分析
- 四、时序切换
- 五、检测10010串
- 六、总结
一、使用工具
Quartus 18.1
二、要求
1、根据以下描述功能用verilog编写一段代码, 并用状态机来实现该功能。
(1)状态机:实现一个测试过程,该过程包括启动准备状态、启动测试、停止测试、查询测试结果、显示测试结果、测试结束返回初始化6个状态;用时间来控制该过程,90秒内完成该过程;
(2)描述状态跳转时间;
(3)编码实现。
2. 画出可以检测10010串的状态图, 并用verilog编程实现之。
三、需求分析
对于第一个要求,是实现六个状态,并且用时间来控制这个过程,说简单一点,就是根据时间切换六个状态
对于第二个要求,需要检测10010的数据串,只有当10010依次输入时,才能通过检测,而实现这个功能,可以通过按键来模拟0和1的值,并且使用6个状态,只有当输入的值正确之后,才能进入下一个状态,不然就会回到出事状态
四、时序切换
- 状态切换代码
module six_state (//90s内六个状态切换
input wire clk, //时钟,50M
input wire rst_n, //复位信号
output wire [3:0] led //1s脉冲信号
);
//6个切换状态
parameter s1= 1;
parameter s2= 2;
parameter s3= 3;
parameter s4= 4;
parameter s5= 5;
parameter s6= 6;
//切换时间状态为1s
parameter MAX_NUM=26'd50_000_000;
reg [3:0] led_r;
reg [2:0] cstate;//现在的状态
reg [25:0] cnt;
//计数模块
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 26'd0;
else if (cnt == MAX_NUM)
cnt <= 26'd0;
else
cnt <= cnt + 1'd1;
end
//状态切换模块
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cstate <= 3'b0;
else if (cnt == MAX_NUM) begin
if (cstate == 3'd6) begin
cstate <= 3'b0;
end else begin
cstate <= cstate + 1'b1;
end
end
else
cstate <= cstate ;
end
//状态输出模块
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
led_r <= 4'b0;
else begin
case (cstate)
s1: led_r <= 4'b0001;
s2: led_r <= 4'b0010;
s3: led_r <= 4'b0100;
s4: led_r <= 4'b1000;
s5: led_r <= 4'b0011;
s6: led_r <= 4'b0111;
default : led_r <= led_r ;
endcase
end
end
assign led = led_r ;
endmodule
- 效果
五、检测10010串
- 按键消抖模块
module key_debounce( //按键消抖模块
input wire clk,
input wire rst_n,
input wire key,
output wire key_value, //按键稳定信号
output wire flag //按键稳定标志
);
parameter delay_time = 1_000_000;
reg [22:0] delay_cnt;
reg key_reg;
reg flag_r;
reg key_value_r;
//0.2ms计时器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
key_reg <= 1'b0;
else begin
key_reg <= key;
if(key_reg == 1'b1 && key == 1'b0)begin
delay_cnt <= delay_time;
end
else if (delay_cnt == 20'd0)
delay_cnt <= 20'd0;
else if (key_reg == 1'b0 && key == 1'b0)
delay_cnt <= delay_cnt -1'd1;
end
end
//控制flag
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
flag_r <= 1'b0;
else if (delay_cnt == 20'd1)
flag_r <= 1'b1;
else
flag_r <= 1'b0;
end
assign flag = flag_r;
//得到输出值
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
key_value_r <= 1'b0;
else if (delay_cnt == 20'd1)
key_value_r <= ~key ;
else
key_value_r <= key_value_r;
end
assign key_value =key_value_r;
endmodule
- 密码模块
/* 密码:10010 */
module password(
input wire clk,
input wire rst_n,
input wire [1:0] key,
output wire [3:0] led
);
//转态空间
parameter IDLE = 3'd0;
parameter S1 = 3'd1;//按对一个
parameter S2 = 3'd2;//按对两个
parameter S3 = 3'd3;//按对三个
parameter S4 = 3'd4;//按对四个
parameter S5 = 3'd5;//按对五个
parameter MAX_NUM=26'd49_999_999;
reg [2:0] cstate;
reg [3:0] led_r;
reg [25:0] cnt;
//1s计时器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 26'd0;
else if (cnt == MAX_NUM)
cnt <= 26'd0;
else
cnt <= cnt + 1'd1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) begin
cstate <= IDLE;
end
else begin
case(cstate)
IDLE:begin
if(key[1])begin
cstate <= S1;
end
else if(key[0])
cstate <= IDLE;
else
cstate <= cstate;
end
S1:begin
if(key[0])begin
cstate <= S2;
end
else if(key[1])
cstate <= IDLE;
else
cstate <= cstate;
end
S2:begin
if(key[0])begin
cstate <= S3;
end
else if(key[1])
cstate <= IDLE;
else
cstate <= cstate;
end
S3:begin
if(key[1])begin
cstate <= S4;
end
else if(key[0])
cstate <= IDLE;
else
cstate <= cstate;
end
S4:begin
if(key[0])begin
cstate <= S5;
end
else if(key[1])
cstate <= IDLE;
else
cstate <= cstate;
end
default:cstate <= cstate;
endcase
end
end
//状态输出
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
led_r <= 4'b0;
else begin
case(cstate)
IDLE: led_r <= 4'b0001;
S1: led_r <= 4'b0010;
S2: led_r <= 4'b0100;
S3: led_r <= 4'b1000;
S4: led_r <= 4'b1110;
S5: led_r <= 4'b1111;
default led_r <= led_r;
endcase
end
end
assign led =led_r;
endmodule
- 状态检测顶层模块
module state_judge_top(
input wire clk,
input wire rst_n,
input wire [1:0] key,
output wire [3:0] led
);
wire [1:0] key_value;
wire [1:0] flag;
key_debounce i0_key_debounce(
.clk (clk),
.rst_n (rst_n),
.key (key[0]),
.key_value (key_value[0]), //按键稳定信号
.flag (flag[0])//按键稳定标志
);
key_debounce i1_key_debounce(
.clk (clk),
.rst_n (rst_n),
.key (key[1]),
.key_value (key_value[1]), //按键稳定信号
.flag (flag[1])//按键稳定标志
);
password i_password(
.clk (clk),
.rst_n (rst_n),
.key ({key_value[1]&&flag[1],key_value[0]&&flag[0]}),
.led (led)
);
endmodule
- 效果
六、总结
- 在序列串较短的时候,用状态切换不仅思路清晰,而且比较简单,但是在序列串比较长的时候,这种方法就不适用了,是否可以考虑存储之后再进行比较,但这样又怎么发挥FPGA并行的优势呢。
最后
以上就是传统舞蹈为你收集整理的verilog实现状态机一、使用工具二、要求三、需求分析四、时序切换五、检测10010串六、总结的全部内容,希望文章能够帮你解决verilog实现状态机一、使用工具二、要求三、需求分析四、时序切换五、检测10010串六、总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复