前言:
刚接触FPGA开发,尝试做一个流水灯,用的是比较老的Altera DE0开发板,简介如下:
DE0 FPGA教育开发板是一套轻薄型的开发板,必要的开发工具、参考设计和相关配件均一应俱全,相当简单、容易上手,非常适合初学者用来学习FPGA逻辑设计与计算机架构。DE0搭载了Altera Cyclone III 系列中的EP3C16 FPGA,可提供15,408 LEs(逻辑单元)以及346 I/O,此外,DE0开发版还搭配了丰富的周边装置,可适用于大学或专科学校的教学课程,并足供开发复杂的数位系统。
新建文件
打开quartus,新建一个工程项目flow_led
Altera DE0 搭载的是Altera Cyclone III EP3C16 选择后创建
代码编写
添加.v文件开始编写
module flow_led(
input sys_clk , //时钟信号
input sys_rst_n , //复位信号
output reg [9:0] led //板子有0-9 共十个led灯 故定义10个位宽
);
reg [25:0] cnt; //定义一个26位宽的计数器
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n) //复位有效 计数器清零
cnt <= 26'd0;
else if(cnt == 50_000_000 - 1) //计数到1s 计数器清零
cnt <= 26'd0;
else
cnt <= cnt + 1'd1; //反之 继续计数
end
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
led <= 10'b0000000001; //复位有效 第一个灯亮
else if(cnt == 50_000_000 - 1)
led <= {led[8:0],led[9]}; //复位无效时, 如果计数器满1s 用拼接运算符换位
else
led <= led; //不满1s 保持
end
endmodule
几个需要注意的点:
1、定义led的位数需根据有多少个led灯来定。
2、为什么计数器要设计成26位宽?50MHZ的时钟信号,T= 1/f = 20ns,也就是说跑够1s需要50M个时钟周期,计数器从0开始,一直计数到50M - 1 刚好1s,50M换算为二进制刚好是26位数。
3、由于本例运用的是拼接运算符,所以不要将复位时所有的led置为全高或者全低,否则会导致全亮或者全灭,如果想加快流水灯速度,可以对计数器做调整
接下来做波形仿真
波形仿真
`timescale 1 ns/ 1 ns
module flow_led_vlg_tst();
reg eachvec;
reg sys_clk;
reg sys_rst_n;
wire [9:0] led;
flow_led i1 (
.led(led),
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n)
);
initial
begin
sys_clk = 1'b0; //初始时钟信号为0
sys_rst_n <= 1'b0; //初始复位信号为0
#50
sys_rst_n <= 1'b1; //50个时间单位后反转
$display("Running testbench");
end
always
begin
# 10 sys_clk = ~ sys_clk ; // 20ns为周期的时钟信号
end
endmodule
注意一点:
自动生成的testbench文件中会有eachvea语句,如果要自行添加时钟信号需将此语句删除。
运行modelsim进行波形仿真
至此文件编译和波形都符合预期,接下来准备上板验证。
上板验证
首先找到DE0的说明书,找到管脚分配部分
打开 Pin Planner 分配管脚
分配管脚完成,关闭Pin Planner,进行全编译。 编译完成后,点击Programmer
点击Hardware Setup 选择USB-Blaster (注意此时应该连接好并打开板子)如果没有USB选项,在设备管理器安装,路径通常在quartus下的drivers文件夹
点击start 进行程序的录入。
成功