FPGA预科实习项目总结_csdm fpga实训报告
parameter MAX_NUM = 9;
parameter CYCLE = 20;
always #(CYCLE/2) clk = ~clk;
initial begin
clk = 1'b0;
rst_n = 1'b0;//开始复位
#(CYCLE);
rst_n = 1'b1;//结束复位
key = 4'b1111;
#((MAX_NUM)\*CYCLE\*4);
key = 4'b1110;
#((MAX_NUM)\*CYCLE\*4);
key = 4'b1101;
#((MAX_NUM)\*CYCLE\*4);
key = 4'b1011;
#((MAX_NUM)\*CYCLE\*4);
key = 4'b0111;
#((MAX_NUM)\*CYCLE\*4);
$stop;
end
key_led #(.TIME0_2S(MAX_NUM)) u_key_led(
.clk (clk),
.rst_n (rst_n),
.key (key),
.led (led)
);
endmodule
### 3.按键消抖
#### 1.消抖原理
![在这里插入图片描述]()
#### 2.系统框图
![在这里插入图片描述]()
#### 3.项目代码
//按键消抖
module key_debounce(
input clk ,
input rst_n ,
input wire [3:0] key_in,
output wire [3:0] key_out
);
变量名称MAX20赋值为二进制数值16'df4;//触发下降沿事件
触发下降沿事件;//用于记录时间段的计数模块
reg [15..8] cnt_20ms;//用于记录时间段的计数模块
reg start;//倒计时启动标志
reg [3..7] key_r[8..15];//按键消抖寄存器组
reg [3..7] key_r[8..15];//按键消抖寄存器组
reg flag;//用于检测按钮状态
reg [3..7] key_on;//中间按键存储单元
//计时器设置为持续时间
always @(posedge clk, negedge rst_n)
begin
when (!rst_n)
count_time := 5;
when nedge
count_time := max_count;
when start
if (count_time == 1'd1)
then count_time :=5;
else count_time -- := count_time -1'd1;
default
count_time := count_time;
end
end
/* 下降沿检测 */
always @posedge(clk) or negedge(rst_n) block
if (!rst_n)
begin
rKeyR0 = 4'bFFFF;
rKeyR1 = 4'bFFFF;
end
else
begin
rKeyR0 = key_in;
rKeyR1 = rKeyR0;
end
end
assign nEdge = (
(rKeyR0 & rKeyR1)[3]
| (rKeyR0 & rKeyR2)[2]
| (rKeyR3 & rKeyR4)[5]
);
//约束start
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
start <= 1’b0;
end
else if (nedge) begin
start <= 1’b1;
end
else if (cnt_20ms == 1’d0) begin
start <= 1’b0;
end
else begin
start <= start;
end
end
// 记录标志位
always @posedge(clk) or negedge(rst_n)
begin
if(!rst_n)
flag = 4'b0_ _ _ ;
end
elseif(cnt_2_ 2ms == #1'd') // cnt_2 2ms等于1'd
flag = ~key_r;
endif
else
flag = 4'b0_ _ _ _;
endif
$end
//设置key_out的值
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
key_on <= 4’b1111;
end
else if (flag[0]== 1’b1) begin
key_on <= 4’b1110;
end
else if (flag[1]== 1’b1) begin
key_on <= 4’b1101;
end
else if (flag[2]== 1’b1) begin
key_on <= 4’b1011;
end
else if (flag[3]== 1’b1) begin
key_on <= 4’b0111;
end
else begin
key_on <= key_on;
end
end
assign key_out = key_on ;
endmodule
### 4.数码管显示
#### 1.显示原理
![在这里插入图片描述]()
#### 2.系统框图
![在这里插入图片描述]()
#### 3.源码显示
module time_count(//计时0.5s,计满后输出高电平
input clk ,
input rst_n ,
output reg flag
);
parameter MAX_NUM = 26’d24_999_999;
reg [25:0] cnt;
always @(posedge clk or negedge rst_n) begin
else if (!rst_n) begin
cnt = 0;
flag = 0;
end
else if (cnt == MAX_NUM) begin
cnt = 0;
flag = 1;
end
else begin
cnt = cnt + 1;
flag = 0;
end
end
endmodule
module seg_led_static(
input clk ,
input rst_n ,
input flag ,//计满0.5秒后,标志
output reg [5:0] sel ,//六位位选信号
output reg [7:0] seg //八位段选信号
);
reg [3:0] num;
//受控选择位低电平有效
always (posedge(clk) or negedge(rst_n)) when rst_n ?
sel <= 6'b111111;
:
sel <= 6'b000000;
end
该计数器在flag处于高电平状态时递增
总是发生在posedgeclk和negedgest rn事件下的门控块
当rstn等于低电平时
将计数值设为零
当flag等于高电平时
计数值增加一位二进制位
否则保持不变
//段选信号控制数码管显示
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
seg <= 8’b0;
end
else case (num)
4’h0: seg <= 8’b1100_0000;//匹配到后参考共阳极真值表
4’h1: seg <= 8’b1111_1001;
4’h2: seg <= 8’b1010_0100;
4’h3: seg <= 8’b1011_0000;
4’h4: seg <= 8’b1001_1001;
4’h5: seg <= 8’b1001_0010;
4’h6: seg <= 8’b1000_0010;
4’h7: seg <= 8’b1111_1000;
4’h8: seg <= 8’b1000_0000;
4’h9: seg <= 8’b1001_0000;
4’ha: seg <= 8’b1000_1000;
4’hb: seg <= 8’b1000_0011;
4’hc: seg <= 8’b1100_0110;
4’hd: seg <= 8’b1010_0001;
4’he: seg <= 8’b1000_0110;
4’hf: seg <= 8’b1000_1110;
default: seg <= 8’b1111_1111;
endcase
end
endmodule
module top_seg_led_static(
input clk ,
input rst_n ,
output wire [5:0] sel ,
output wire [7:0] seg
);
$wire flag ;
parameter MAX_NUM = 26'd24_999_999;
time_count #(.MAX_NUM(MAX_NUM))time_count_inst(//持续0.5秒后将输出高电平信号
.clk(clk),
.rst_n(rst_n),
.flag(flag)
);
led_static segmented interface named seg_led_static, which accepts the following inputs: a clock signal, a reset signal, a flag indicating completion of 0.5 seconds, and two selection control signals for segment and data input respectively;
#### 4.测试文件
`timescale 1ns/1ns
module top_seg_led_static_tb();
reg clk;
reg rst_n;
wire [5:0] sel ;
wire [7:0] seg ;
parameter MAX_NUM = 9;
parameter CYCLE = 20 ;
always #(CYCLE/2)clk = ~clk;
initial begin
clk = 1’b0;
rst_n = 1’b0;
#(CYCLE);
rst_n = 1’b1;
#(16*(MAX_NUM + 1)*CYCLE);
$stop;
end
u_top_seg LED static (#(.MAX NUM MAX NUM))(top seg LED static (.MAX NUM MAX NUM))(clk(clk),rstn(rstn),sel(sel),seg(seg));
endmodule
### 5.呼吸灯
#### 1.项目源码
module breath_led(
input clk ,
input rst_n ,
output reg [3:0] led
);
parameter CNT_US = 6’d49;//1us
parameter CNT_MS = 10’d999;//1ms
parameter CNT_S = 10’d999;//1s
定义为cnt_us的寄存器。
标记add_cnt_us为开始计数器的信号。
标记end_cnt_us为结束计数器的信号。
reg [9:0] cnt_ms;
wire add_cnt_ms;
wire end_cnt_ms;
reg [9:0] cnt_s;
wire add_cnt_s;
wire end_cnt_s;
reg flag ;//亮灭标志
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt_us <= 6’d0;
end
else if (add_cnt_us) begin
if (end_cnt_us) begin
cnt_us <= 6’d0;
end
else begin
cnt_us <= cnt_us + 1’b1;
end
end
else begin
cnt_us <= cnt_us ;
end
end
assign add_cnt_us = 1’b1;
assign end_cnt_us = add_cnt_us && cnt_us == CNT_US;
每当posedgeclk或negedge rst_n时开始
如果rst_n为真则
cnt.ms等于十进制度零
否则如果add_cnt.ms则
如果end_cnt.ms则
cnt.ms等于十进制度零
否则
cnt.ms增加一倍的一次方即变为当前值加一
否则
cnt.ms保持当前值不变结束
结束
结束开始时cnt.ms等于当前值结束结束
assign add_cnt_ms = end_cnt_us ;
assign end_cnt_ms = add_cnt_ms && cnt_ms == CNT_MS ;
always @(posedgeclk或者negedgestn事件触发)begin
当rstn为低电平有效时进入第一个分支
系统计数器cnts被初始化为十进制零;
否则如果add_cnts成立
如果end_cnts成立则将cnts重置为十进制零;
否则将cnts递增一个计数单位;
否则继续维持当前状态;
结束\
assign add_cnt_s = end_cnt_ms ;
assign end_cnt_s = add_cnt_s && cnt_s == CNT_S ;
//约束标志
posedge clock或negedge rst_n时开始
if (!rst_n)时开始
标志等于1’b0;
否则如果end_cnt_s时开始
标志反向;
否则begin
标志等于自身;
end
/* led控制 */
always clock.posedge or rst_n.negedgebegin
if (not rst_n)
assign led = 4'b0;
else-if(flag)
assign led = { four times cnt_s > cnt_ms };
else
assign led = { four times cnt_s < cnt_ms };
end
endmodule
#### 2.测试文件
`timescale 1ns/1ns
module breath_led_tb();
reg clk ;
reg rst_n ;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
大多数嵌入式工程师在提升技能时通常会自主学习或参加培训课程。高昂的学费确实带来了不少困扰。缺乏系统性的自主学习效果不佳且耗时长。容易被技术瓶颈所限制。
因此收集整理了这套《2024年嵌入式与物联网开发全套学习资料》,其初心也很单纯——就是为了帮助那些想自学提升却不知道该怎么开始的朋友,并且希望能减轻大家的学习负担。



涵盖从新手到初学者的基础知识和专业内容,并根据学习者的不同阶段提供相应的课程资源;同时提供给有3年以上相关经验的专业人士进一步深化的专业课程;系统性地覆盖了超过95%嵌入式与物联网开发的核心知识点,并真正实现了全面且系统的知识体系!


因为文件较大,在此处仅对目录大纲进行了截取展示,并列出了每个节点中均包含的大厂面经、学习笔记、源码资料以及实战项目等具体内容,并承诺后续将持续更新
如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

最后
资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!
45047797)]
涵盖从入门到进阶的学习资源
[外链图片转存中…(img-PJmc3s1y-1712245047797)]
[外链图片转存中…(img-GP54kPY6-1712245047798)]
因为文件较大,在此处仅对部分目录大纲进行了截图展示。其中每个节点中均包含大厂面经、学习笔记等资源,并非全部展示完毕。此外,在线预览页面上点击某个选项后会跳转至对应的内容页面
如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

最后
资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!
