站长网seo综合查询工具,什么是网络营销和技巧,自己做的网站怎么放图片,网站域名管理权限北邮22信通一枚~
跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章
持续关注作者 迎接数电实验学习~
获取更多文章#xff0c;请访问专栏#xff1a;
北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客
目录
一.注意事项
二.按键消抖
2.1 LED_deboun…北邮22信通一枚~
跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章
持续关注作者 迎接数电实验学习~
获取更多文章请访问专栏
北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客
目录
一.注意事项
二.按键消抖
2.1 LED_debounce代码
2.2debounce.v代码 2.3管脚分配
三.流水灯
3.1 LED_flash.v代码
3.2 divide.v代码
3.3decode38.v代码
3.4管脚分配
四.呼吸灯
4.1 LED_breath.v代码 4.2管脚分配 一.注意事项
烧录之前首先检查这几个参数是否调整完毕 没调的赶紧去调
二.按键消抖
2.1 LED_debounce代码
module LED_debounce (clk,rst,key,led);input clk;input rst;input key; output reg led; wire key_pulse;//当按键按下时产生一个高脉冲翻转一次ledalways (posedge clk or negedge rst)beginif (!rst) led 1b1;else if (key_pulse)led ~led;elseled led;end //例化消抖module这里没有传递参数N采用了默认的N1 debounce u1 ( .clk (clk),.rst (rst),.key (key),.key_pulse (key_pulse));endmodule
2.2debounce.v代码
module debounce (clk,rst,key,key_pulse);parameter N 1; //要消除的按键的数量input clk;input rst;input [N-1:0] key; //输入的按键 output [N-1:0] key_pulse; //按键动作产生的脉冲 reg [N-1:0] key_rst_pre; //定义一个寄存器型变量存储上一个触发时的按键值reg [N-1:0] key_rst; //定义一个寄存器变量储存储当前时刻触发的按键值wire [N-1:0] key_edge; //检测到按键由高到低变化是产生一个高脉冲//利用非阻塞赋值特点将两个时钟触发时按键状态存储在两个寄存器变量中always (posedge clk or negedge rst)beginif (!rst) beginkey_rst {N{1b1}}; //初始化时给key_rst赋值全为1{}中表示N个1key_rst_pre {N{1b1}};endelse beginkey_rst key; //第一个时钟上升沿触发之后key的值赋给key_rst,//同时key_rst的值赋给key_rst_prekey_rst_pre key_rst; //非阻塞赋值。//相当于经过两个时钟触发//key_rst存储的是当前时刻key的值//key_rst_pre存储的是前一个时钟的key的值end endassign key_edge key_rst_pre (~key_rst);//脉冲边沿检测。//当key检测到下降沿时//key_edge产生一个时钟周期的高电平reg [17:0] cnt; //产生延时所用的计数器系统时钟12MHz//要延时20ms左右时间至少需要18位计数器 //产生20ms延时当检测到key_edge有效是计数器清零开始计数always (posedge clk or negedge rst)beginif(!rst)cnt 18h0;else if(key_edge)cnt 18h0;elsecnt cnt 1h1;end reg [N-1:0] key_sec_pre; //延时后检测电平寄存器变量reg [N-1:0] key_sec; //延时后检测key如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效always (posedge clk or negedge rst)beginif (!rst) key_sec {N{1b1}}; else if (cnt18h3ffff)key_sec key; endalways (posedge clk or negedge rst)beginif (!rst)key_sec_pre {N{1b1}};else key_sec_pre key_sec; end assign key_pulse key_sec_pre (~key_sec); endmodule2.3管脚分配 三.流水灯
3.1 LED_flash.v代码
module LED_flash(clk,rst,led);input clk,rst; output [7:0] led; reg [2:0] cnt ; //定义了一个3位的计数器输出可以作为3-8译码器的输入wire clk1h; //定义一个中间变量表示分频得到的时钟用作计数器的触发 //例化module decode38相当于调用decode38 u1 ( .sw(cnt), //例化的输入端口连接到cnt输出端口连接到led .led(led));//例化分频器模块产生一个1Hz时钟信号 divide #(.WIDTH(32),.N(12000000)) u2 ( //传递参数.clk(clk),.rst_n(rst), //例化的端口信号都连接到定义好的信号.clkout(clk1h)); //1Hz时钟上升沿触发计数器循环计数 always (posedge clk1h or negedge rst)if (!rst)cnt 0;elsecnt cnt 1;endmodule
3.2 divide.v代码
module divide ( clk,rst_n,clkout);input clk,rst_n; //输入信号其中clk连接到FPGA的C1脚频率为12MHzoutput clkout; //输出信号可以连接到LED观察分频的时钟//parameter是verilog里常数语句parameter WIDTH 3; //计数器的位数计数的最大值为 2**WIDTH-1parameter N 5; //分频系数请确保 N 2**WIDTH-1否则计数会溢出reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p为上升沿触发时的计数器cnt_n为下降沿触发时的计数器reg clk_p,clk_n; //clk_p为上升沿触发时分频时钟clk_n为下降沿触发时分频时钟//上升沿触发时计数器的控制always (posedge clk or negedge rst_n )//posedge和negedge是verilog表示信号上升沿和下降沿//当clk上升沿来临或者rst_n变低的时候执行一次always里的语句beginif(!rst_n)cnt_p0;else if (cnt_p(N-1))cnt_p0;else cnt_pcnt_p1;//计数器一直计数当计数到N-1的时候清零这是一个模N的计数器end//上升沿触发的分频时钟输出,如果N为奇数得到的时钟占空比不是50%如果N为偶数得到的时钟占空比为50%always (posedge clk or negedge rst_n)beginif(!rst_n)clk_p0;else if (cnt_p(N1)) //N1表示右移一位相当于除以2去掉余数clk_p0;else clk_p1; //得到的分频时钟正周期比负周期多一个clk时钟end//下降沿触发时计数器的控制 always (negedge clk or negedge rst_n)beginif(!rst_n)cnt_n0;else if (cnt_n(N-1))cnt_n0;else cnt_ncnt_n1;end//下降沿触发的分频时钟输出和clk_p相差半个时钟always (negedge clk)beginif(!rst_n)clk_n0;else if (cnt_n(N1)) clk_n0;else clk_n1; //得到的分频时钟正周期比负周期多一个clk时钟endassign clkout (N1)?clk:(N[0])?(clk_pclk_n):clk_p; //条件判断表达式 //当N1时直接输出clk//当N为偶数也就是N的最低位为0N00输出clk_p//当N为奇数也就是N最低位为1N01输出clk_pclk_n。//正周期多所以是相与
endmodule
3.3decode38.v代码
module decode38 (sw,led);input [2:0] sw; //开关输入信号利用了其中3个开关作为3-8译码器的输入output [7:0] led; //输出信号控制特定LEDreg [7:0] led; //定义led为reg型变量在always过程块中只能对reg型变量赋值//always过程块括号中sw为敏感变量当sw变化一次执行一次always中所有语句否则保持不变always (sw)begincase(sw) //case语句一定要跟default语句3b000: led8b0111_1111; //条件跳转其中“_”下划线只是为了阅读方便无实际意义 3b001: led8b1011_1111; //位宽进制数值是Verilog里常数的表达方法//进制可以是b、o、d、h二、八、十、十六进制3b010: led8b1101_1111;3b011: led8b1110_1111;3b100: led8b1111_0111;3b101: led8b1111_1011;3b110: led8b1111_1101;3b111: led8b1111_1110;default: ;endcaseendendmodule
3.4管脚分配 四.呼吸灯
4.1 LED_breath.v代码
module LED_breath(clk,rst,led);input clk; //系统时钟输入input rst; //复位输出output led; //led输出reg [24:0] cnt1; //计数器1reg [24:0] cnt2; //计数器2reg flag; //呼吸灯变亮和变暗的标志位//parameter CNT_NUM 2400; //计数器的最大值 period (2400^2)*2 ~ 12000000 1s由亮到暗0.5s由暗到亮0.5sparameter CNT_NUM 3464; //计数器的最大值 period (3464^2)*2 ~ 24000000 2s由亮到暗1s由暗到亮1s//产生计数器cnt1always(posedge clk or negedge rst) begin if(!rst) begincnt113d0;end else beginif(cnt1CNT_NUM-1) cnt11b0;else cnt1cnt11b1; endend//产生计数器cnt2always(posedge clk or negedge rst) begin if(!rst) begincnt213d0;flag1b0;end else beginif(cnt1CNT_NUM-1) begin //当计数器1计满时计数器2开始计数加一或减一if(!flag) begin //当标志位为0时计数器2递增计数表示呼吸灯效果由暗变亮if(cnt2CNT_NUM-1) //计数器2计满时表示亮度已最大//标志位变高之后计数器2开始递减flag1b1;elsecnt2cnt21b1;end else begin //当标志位为高时计数器2递减计数if(cnt20) //计数器2级到0表示亮度已最小标志位变低之后计数器2开始递增flag1b0;else cnt2cnt2-1b1;endendelse cnt2cnt2;//计数器1在计数过程中计数器2保持不变endend//比较计数器1和计数器2的值产生自动调整占空比输出的信号输出到led产生呼吸灯效果assign led (cnt1cnt2)?1b0:1b1;endmodule 4.2管脚分配