文章目录
一、Verilog基础
有关更多细节,请参考:
二、Quantus基础
1. 如何新建一个项目
1.1 新建文件夹用来存放项目文件,请注意你的文件夹路径不要有中文,不过系统自带的桌面和文档这些路径除外。
1.2 新建项目文件
prj 项目文件
rtl 寄存器转换级,用来描述各级寄存器,用来存放.v文件
tb 仿真文件
tcl tool command language,用来存放引脚的脚本
1.3 打开Quantus
File——New——new project wizard
点击“…”选择文件夹,一直到prj路径。
命名项目名称,但是上下两个名称可以不一样。
选择空模板。
选择芯片
设置仿真界面。
一般来说我们可以选择。
最后一步,界面总览。
当然,你也可以选择编写程序自动生成项目文件。New_project.bat
如何设置顶层文件
右键设置顶层文件
如何选择常规引脚
记得在nCEO选项双击
界面介绍
- 引脚设置,引脚设置可以导出,导出时需要将默认导出的后缀.csv改成.tcl,tool——tcl script添加运行脚本。
- 全编译,当项目准备完成后可以选择。
- 分析综合,当未设置引脚时编译可以选择此处
- 编译日志
- 芯片设计
- 烧录运行
如何使用quantus生成波形图
确保你已经连接上了板子。
双击空白处
修改值
二、简易流水灯设计
点亮LED
提供复制
module led (
output wire[3:0] led_on
);
assign led_on = 4'b1111;
endmodule
原理图:
间隔1s使LED闪烁
注意:FPGA只有双分支和多分支结构没有单分支结构,代码不严谨将导致系统产生毛刺
原理:设计一个计数器,每当时钟数到1s时,灯就会改变一次状态。
module led (
input wire [0:0] clk,//时钟信号50mhz
input wire rst_n,//复位信号下降沿有效
output wire[3:0] led_on
);
parameter MAX = 26'd50_000_000;
reg [3:0] led_r; //led信号寄存器
reg [25:0] cnt; //计数寄存器
//记录1s计数器设计
always @(posedge clk or negedge rst_n) begin //只会在上升沿或者下降沿的时候进入always模块
if(!rst_n)begin //取反代表下降沿
cnt <=26'd0;
end
else if (cnt == MAX - 1'd1)begin//记到最大数
cnt <=26'd0;
end
else begin //FPGA只有双分支和多分枝结构没有单分支结构,代码不严谨将导致系统产生毛刺
cnt <= cnt+1'd1;
end
end //计数观察
//并行数据块
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
led_r <= 4'b0000;//4个led全灭
end
else if (cnt == MAX-1'd1)begin
led_r <= ~led_r; //取反,有记忆性
end
else begin
led_r <= led_r;
end
end
assign led_on = led_r;
endmodule
拓展,若要间隔0.5s则取MAX=25‘d25_000_000;
点亮跑马灯
注意,代码不严谨,仅供算法参考,此版本可能通不过编译。
原理:设计一个0.5s计数器
module led (
input wire [0:0] clk,//时钟信号50mhz
input wire rst_n,//复位信号下降沿有效
output wire[3:0] led_on
);
parameter MAX = 25'd25_000_000;
reg [3:0] led_r; //led信号寄存器
reg [24:0] cnt; //计数寄存器
//记录0.5s计数器设计
always @(posedge clk or negedge rst_n) begin //只会在上升沿或者下降沿的时候进入always模块
if(!rst_n)begin //取反代表下降沿
cnt <=25'd0;
end
else if (cnt == MAX - 1'd1)begin//记到最大数
cnt <=25'd0;
end
else begin //FPGA只有双分支和多分枝结构没有单分支结构,代码不严谨将导致系统产生毛刺
cnt <= cnt+1'd1;
end
end //计数观察
//并行数据块
/*
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
led_r <= 4'b0000;//4个led全灭
end
else if (cnt == MAX-1'd1)begin
led_r <= ~led_r; //取反,有记忆性
end
else begin
led_r <= led_r;
end
end
*/
//跑马灯0001,0011,0111,1111,1110,1100,1000,0000
//从左向右0.5s点亮流水灯
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
led_r <= 4'b0001;//4个led全灭
end
else if (cnt == MAX-1'd1)begin
//led_r <= {led_r[2:0],led_r[3]}; //从左往右
//led_r <= {led_r[2:0],~led_r[3]}; //从左往右跑马灯
//led_r <= {led_r[0],led_r[3:1]}; //从右向左
//led_r <= {~led_r[0],led_r[3:1]}; //从右向左跑马灯跑马灯
end
else begin
led_r <= led_r;
end
end
assign led_on = led_r;//顺序无所谓
endmodule
本文基于个人理解撰写,仅供参考。