当前位置: 首页 > news >正文

Verilog 利用伪随机,时序,按键消抖等,实现一个(打地鼠)游戏

简介

这里使用Verilog实现了一个“打地鼠”游戏,规则如下:

1.灯的亮灭由伪随机数生成,按下对应按钮,可以将灯按灭

2.当所有灯灭掉后,视为胜利,等待0.3s进入下一关

3.当3s内没有完成或者按灭本身就是灭掉的灯,视为失败,所有灯会灭-亮-灭闪烁一次,然后进入下一关。

        整个项目以len_on为顶层,含有lfsr_4bit(伪随机生成),button_on(按键消抖),clear_led(游戏灭灯主逻辑)为子模块。

        由于各个板子不同,可能部分代码需要修改

这里面,按钮和LED灯,以及复位,都是低电平有效,按钮低电平表示按下,LED灯低电平点亮。时钟频率为50MHz

全部代码

len_on.v(顶层)

顶层模块,包含游戏正确,失败的部分处理。

module len_on(input  wire 		clk		,input  wire	[3:0]	buf_4	,input  wire 		rst_n	,output reg  [3:0]	led
);parameter CLK_FREQ = 50_000_000;    // 50MHz
parameter LED_TIME_MS = 300;// 300ms-0.3s 爆闪
parameter LED_CYCLES = (CLK_FREQ / 1000) * LED_TIME_MS;// 爆闪所经历周期reg  [1:0] now_state;// 当前状态,00正常 ,01灭10亮11灭 (失败闪灯)reg  [31:0] counter;  // 闪灯时间计数器wire [3:0] buf_on_4;	// 消抖后的信号reg  random_enable;	// 随机亮灯的使能信号wire [3:0] random_out;// 随机4位数字信号reg  clear_led_enable;	// 按灯器的使能信号wire [3:0] clear_out_led;	// 按灯器输出的led信号wire [1:0] clear_out_state;	// 按灯器状态always @(posedge clk or negedge rst_n) beginif (!rst_n) begin// 复位时初始化counter <= 0;// 计数器初始化led <= 4'b1111;// 全灭now_state <= 2'b00;// 随时开始clear_led_enable <= 1'b0;random_enable<= 1'b0;endelse beginif (now_state == 2'b00)	begin// 正常开始状态case (clear_out_state)//00开始重置,01重置完成,10正常进行,11失败2'b00	:begin//开始重置led <= 4'b1111;	// 全灭clear_led_enable <= 1'b0;	// 按灯器不使能random_enable<= 1'b1;		// 随机器使能end2'b01	:begin//重置完成led <= clear_out_led;	// 输出按灯器信号clear_led_enable <= 1'b1;	// 按灯器正常使能random_enable<= 1'b0;		// 随机器不使能end2'b10	:begin//正常进行led <= clear_out_led;	// 输出按灯器信号clear_led_enable <= 1'b1;	// 按灯器正常使能random_enable<= 1'b0;		// 随机器不使能end2'b11	:begin//失败led <= 4'b1111;	// 全灭clear_led_enable <= 1'b0;	// 按灯器不使能random_enable<= 1'b0;		// 随机器不使能now_state <= 2'b01;	// 进入闪灯状态counter <= 0;// 重置计时器enddefault :	beginnow_state <= now_state;// 保持当前状态end// 没有内容,结束endcaseendelse beginif(counter>LED_CYCLES) beginnow_state <= now_state+1;	// 进入下一状态counter <= 0;// 重置计时器endelsecounter <= counter + 1 ;if(now_state==2'b10)led <= 4'b0000;	// 全亮elseled <= 4'b1111;	// 全灭endend
end// 生成随机数lfsr_4bit get_4(.clk		(clk),.rst_n		(rst_n),.enable    	(random_enable) ,   	// 使能信号.random_out (random_out)		// 4位随机数输出
);// 按键消抖button_on button_on_0(.clk	(clk)		,.rst_n	(rst_n)		,.but_in	(buf_4[0])	,.but_on (buf_on_4[0])
);button_on button_on_1(.clk	(clk)		,.rst_n	(rst_n)		,.but_in	(buf_4[1])	,.but_on (buf_on_4[1])
);button_on button_on_2(.clk	(clk)		,.rst_n	(rst_n)		,.but_in	(buf_4[2])	,.but_on (buf_on_4[2])
);button_on button_on_3(.clk	(clk)		,.rst_n	(rst_n)		,.but_in	(buf_4[3])	,.but_on (buf_on_4[3])
);clear_led clear_led(.clk				(clk),.buf_on_4			(buf_on_4),	// 消抖后的信号.rst_n				(rst_n),.clear_led_enable	(clear_led_enable),	// 该模块使能信号.led_in				(random_out),.led_out			(clear_out_led),.next_state			(clear_out_state)//下次状态,0不变1重置,2失败);endmodule

button_on.v(按键消抖)

按键消抖部分,注意按键低电平有效,,消抖时间5ms

module button_on(// 按键消抖input  wire clk,input  wire rst_n,input  wire but_in,output reg  but_on
);parameter CLK_FREQ = 50_000_000;    // 50MHz
parameter DEBOUNCE_TIME_MS = 5;     // 5ms消抖时间
parameter DEBOUNCE_CYCLES = (CLK_FREQ / 1000) * DEBOUNCE_TIME_MS;  // 100,000reg [31:0] counter;
reg but_in_prev;always @(posedge clk or negedge rst_n) beginif (!rst_n) beginbut_on <= 1;but_in_prev <= 1;counter <= 0;endelse beginbut_in_prev <= but_in;if (but_in != but_in_prev) begin        // 检测到变化counter <= DEBOUNCE_CYCLES;         // 重新开始计时endelse if (counter > 0) begin             // 正在计时counter <= counter - 1;if (counter == 1) begin             // 计时结束but_on <= but_in;               // 更新输出endendend
endendmodule

lfsr_4bit.v (四位伪随机数生成器)

如果全0或者全1会重新随机。

module lfsr_4bit (input wire clk,input wire rst_n,input wire enable,        // 使能信号output reg [3:0] random_out  // 4位随机数输出
);// LFSR反馈多项式:x^4 + x^3 + 1
wire feedback = random_out[3] ^ random_out[2];
wire is_all_zero = (random_out == 4'b0000);  // 检测全0
wire is_all_one = (random_out == 4'b1111);   // 检测全1always @(posedge clk or negedge rst_n) beginif (!rst_n) beginrandom_out <= 4'b0001;  // 初始种子,不能全为0end else if (enable) begin// 如果下一个状态是全0或全1,则重新加载种子if ({random_out[2:0], feedback} == 4'b0000 || {random_out[2:0], feedback} == 4'b1111) beginrandom_out <= 4'b1001;  // 重新加载种子end else beginrandom_out <= {random_out[2:0], feedback};endend
endendmodule

clear_led.v(游戏主逻辑)

由于按钮是低电平按下,所以检测下降沿。

module clear_led(input   wire        clk             ,input   wire [3:0]  buf_on_4        ,input   wire        rst_n           ,input   wire        clear_led_enable,// 使能信号input   wire [3:0]  led_in          ,// 随机四位信号output  reg  [3:0]  led_out         ,output  reg  [1:0]  next_state      
);parameter CLK_FREQ = 50_000_000;
parameter OVER_TIME_MS = 3000;// 失败时间3s
parameter OVER_CYCLES = (CLK_FREQ / 1000) * OVER_TIME_MS;
parameter SUCCESS_DELAY_MS = 300;  // 成功后延时300ms
parameter SUCCESS_DELAY_CYCLES = (CLK_FREQ / 1000) * SUCCESS_DELAY_MS;reg [31:0] counter;
reg [3:0] buf_old_4;
wire [3:0] buf_falling_edge;assign buf_falling_edge = (~buf_on_4) & buf_old_4;parameter STATE_SUCCESS  = 2'b00;	// 上一次成功,开始重置
parameter STATE_READY    = 2'b01;	// 重置完成
parameter STATE_NORMAL   = 2'b10;	// 正常运行
parameter STATE_FAIL     = 2'b11;	// 失败
// 注意:STATE_SUCCESS_DELAY 可以用 STATE_SUCCESS 的计数器实现,不需要新状态reg [3:0] led_temp;
reg [3:0] led_next;
reg fail_detected;
reg success_delay_done;  // 成功延时完成标志always @(posedge clk or negedge rst_n) beginif (!rst_n) begin// 复位counter     <= 0;buf_old_4   <= 4'b1111;led_out     <= 4'b1111;  // 全灭next_state  <= STATE_READY;led_temp    <= 4'b1111;fail_detected <= 0;success_delay_done <= 0;endelse if (!clear_led_enable) begin// 不使能led_out     <= 4'b1111;	// 全灭next_state  <= STATE_READY;	//重置完成状态counter     <= 0;led_temp    <= 4'b1111;fail_detected <= 0;success_delay_done <= 0;endelse beginbuf_old_4 <= buf_on_4;	// 记录上次按键case (next_state)STATE_READY: beginif (clear_led_enable) begin// 如果刚从成功状态过来且延时未完成,保持READY状态if (!success_delay_done && counter < SUCCESS_DELAY_CYCLES) begincounter <= counter + 32'd1;led_out <= 4'b1111;  // 保持全灭endelse begin// 延时完成或不需要延时,进入正常流程led_temp <= led_in;led_out <= led_in;counter <= 32'd1;next_state <= STATE_NORMAL;fail_detected <= 0;success_delay_done <= 0;  // 重置延时标志endendendSTATE_NORMAL: beginif (counter >= OVER_CYCLES) beginnext_state <= STATE_FAIL;endelse begincounter <= counter + 32'd1;// 预先计算下一个LED状态led_next = led_temp;fail_detected = 0;// 检查每个按键的下降沿if (buf_falling_edge[0]) beginif (led_temp[0] == 1'b1) begin  // 如果已经是灭的状态fail_detected = 1;endelse beginled_next[0] = 1'b1;  // 灭掉LEDendendif (buf_falling_edge[1]) beginif (led_temp[1] == 1'b1) begin  // 如果已经是灭的状态fail_detected = 1;endelse beginled_next[1] = 1'b1;  // 灭掉LEDendendif (buf_falling_edge[2]) beginif (led_temp[2] == 1'b1) begin  // 如果已经是灭的状态fail_detected = 1;endelse beginled_next[2] = 1'b1;  // 灭掉LEDendendif (buf_falling_edge[3]) beginif (led_temp[3] == 1'b1) begin  // 如果已经是灭的状态fail_detected = 1;endelse beginled_next[3] = 1'b1;  // 灭掉LEDendend// 更新状态if (fail_detected) beginnext_state <= STATE_FAIL;endelse if (led_next != led_temp) beginled_temp <= led_next;led_out <= led_next;if (led_next == 4'b1111) begin  // 所有LED都灭了next_state <= STATE_SUCCESS;counter <= 0;endendendendSTATE_SUCCESS: beginled_out <= 4'b1111;  // 保持全灭// 设置成功延时标志,并重置计数器用于延时success_delay_done <= 0;counter <= 32'd1;  // 开始计数next_state <= STATE_READY;  // 立即转到READY状态,在READY中完成延时endSTATE_FAIL: begincounter <= 0;success_delay_done <= 0;  // 失败时重置延时标志// 保持失败状态,等待外部重置if (!clear_led_enable) beginnext_state <= STATE_READY;endenddefault: beginnext_state <= STATE_READY;endendcaseend
endendmodule

结果视频

Verilog 实现一个类似(打地鼠)游戏

http://www.dtcms.com/a/605738.html

相关文章:

  • 【音视频】均衡器(Equalizer)技术详解
  • win11安装mysql社区版数据库
  • 菏泽定制网站建设推广花艺企业网站建设规划
  • 哪些网站可以做推广婚庆公司网站源码
  • LVS负载均衡群集(一) -- NAT模式
  • 【ZeroRnge WebRTC】RFC 8445:ICE 协议规范(中文整理与译注)
  • librtp 实现详解:仓颉语言中的 RTP和RTCP 协议库开发实践
  • Android http网络请求的那些事儿
  • 两台 centos 7.9 部署 pbs version 18.1.4 集群
  • 【动手学深度学习】8.1. 序列模型
  • 【AI软件开发】从文献管理到知识编织:构建AI驱动的学术研究工作流
  • 网站上面图片上传尺寸建设部二级结构工程师注销网站
  • PostIn从初级到进阶(3) - 如何对接口快速设计并管理接口文档
  • 按键精灵安卓/ios脚本开发辅助工具:yolo转换教程
  • 人工智能驱动下的OCR API技术演进与实践应用
  • 昆明网站建设介绍湛江专业雷剧全集
  • 网站到期时间营销型网站服务公司
  • 常用设计模式:工厂方法模式
  • 视频矩阵哪个品牌好?2025 视频矩阵品牌标杆出炉
  • MongoDB 分片
  • 网站访客qq获取苏州建网站公司
  • Vue 3与 Vue 2响应式的区别
  • 自主建站平台怎样在百度建网站
  • 开源白板工具(SaaS),一体化白板,包含思维导图、流程图、自由画等
  • 九、InnoDB引擎-MVCC
  • Cesium 性能优化:从常识到深入实践
  • 购物网站的排版番禺品牌型网站建设
  • 想学习网站建设网络公司起名大全最新
  • claude 国内注册方法(2025 年 11 月更新)
  • 研究生看文献笔记总记不好?