|
第二篇 让FPGA跑起来
(这一篇是一边熟悉verilog一边写的,不是一天完成,前后思路可能有不连贯的地方,大家见谅~)
今天晚上一直在纠结要不要写这篇,因为是自己定义这个博客是自己的学习笔记,而不是教学博客,因为自己还没有到那个高度~但我觉得还是记录下这个过程,可以方便刚开始入门的战友们
学过单片机的应该都是从点开始的吧,然后就是各种流水灯,记得以前一个电子类的社团选拔骨干就看你能用多少中方法完成流水灯设计,确实挺有意思的。这一部分也就从流水灯开始吧,顺便自己可以逐步的熟悉verilog~
背景说明:我采用的是quarteus9.1,也就是最后一个自带仿真组件的版本(哈哈,好吧,我承认自己是懒人,没有学习modelsim…)。今天一看官网,现在的版本都已经到13了,我已经深深落伍了…
从QuartusII11.0之后的版本,可以显示中文字符,同时又能也能输入中文了,有点想换了,但这个还是算了吧O(∩_∩)O(关于Quarteus的安装破解直接掠过了,大家自行度娘。下载的话我觉得直接官网最靠谱,每当我看到那些“跪求Quarteus xx”的我都觉得挺好笑的~附上官网www.altera.com.cn)
Num1 建工程
File—New Project w…
选择存储路径,第二行输入工程名字(E文的呀)
File-new(或者Ctrl+N)----verilog HDL
File—输入语言设计
在此个例子中,我们要先分析流水灯需要有几个小模块组成。在我的开发板中的FPGA的时钟输入是50MHz,但是流水灯的闪烁频率大约是在10Hz,因此需要有分频的模块。另一个模块就是控制流水灯的模块。
下面是第一个分频模块。记得以前看过,在fpga内部,尽量设置少的时钟,否则会形成fpga内部始终满天飞,影响布局和布线。此处设计成为使能信号~
module clk_design
(
input clk,
input rst_n,
output led_en
);
reg [22:0] cnt;
parameter LED_CNT= 49999999;
always@(posedgeclkornegedgerst_n)
begin
if(!rst_n)
cnt<=23'd0;
else if (cnt< LED_CNT)
cnt<=cnt+
1'b1;
else
cnt<=23'd0;
end
assign led_en=
(cnt==23'd49_99999) ? 1'b1: 1'b0;
endmodule
在此部分设计中,讲50M时钟分频到10Hz使能信号,当计数到49999999时,给出一个时钟周期高电平,然后重新计数。(在设计中,一般模块都具有复位信号,用于模块的复位)。
第二个模块 流水灯控制模块,此部分用了case语句,实现的逐一点亮,一起熄灭的设计。
module
led_display
(
input clk,
input rst_n,
input led_en,
output reg [5:0]led_data
);
reg [5:0] num;
always@(posedge
clk or negedge rst_n)
begin
if(!rst_n)
num<=6'b0;
else if(led_en)
if (num<6'b000110)
num<=num+ 1'b1;
else
num<=1'b0;
else
num<=num;
end
always@(posedge
clk )
begin
case(num)
6'b000000: begin led_data<=6'b000000; end
6'b000001: begin led_data<=6'b000001; end
6'b000010: begin led_data<=6'b000011; end
6'b000011: begin led_data<=6'b000111; end
6'b000100: begin led_data<=6'b001111; end
6'b000101: begin led_data<=6'b011111; end
6'b000110: begin led_data<=6'b111111; end
default: begin led_data<=6'b111111; end
endcase
end
endmodule
接下来就是设计顶层文件,顶层文件我之前一直都是基于原理图输入的,在特权的书中发现,原理图在大型工程中,不适合,为了让自己能“高端,大气,上档次”,就开始学习原件的例化,用文本输入的。
module first
(
input clk,
input rst_n, //global clock reset
output [5:0]led_data//user ledi IO
);
//----generater clock
10Hz
wire led_en;
clk_design
clk_design_inst
(
.clk (clk),
.rst_n (rst_n),
.led_en (led_en)
);
//---set the display
mode
led_display
led_display_inst
(
.clk (clk),
.rst_n (rst_n),
.led_en (led_en),
.led_data (led_data)
);
Endmodule
这样一学,其实原件例化并没有那么复杂的嘛!
以上就是整个设计过程,设计之后,随之而来的就是仿真验证,9.1版本戴有仿真组件,因此就可以直接在一个软件下搞定。(不过这几天有些纠结,新东西总归是要接受的,因此也下载了11.0版本,接下来时间允许可能将9.1替换掉)
下面是步骤:
File-new(或者Ctrl+N)----Vector
Waveform File
然后在下图的空白处双击,
点击
在Filter中,可以选择要显示的类型,我一般是选择Pins:all和Registers:,在左侧框中,双击自己想要观察的管脚就可以了。
接下来是设置时钟输入频率(在实际仿真过程中,因为clk产生使能信号周期太长了,仿真时可以减小些,方便观察。个人想法,应该没有问题吧?)。最后完成时钟设置后就是保存+仿真。
点击菜单栏中的Processing—》Simulator tool
1可以选择功能仿真或者时序仿真(功能仿真需要生成Netlist,也就是要点击一下后侧的按键),然后确保4处是你要仿真的文件,点击2,提示仿真成功后,点击3,即可以看到你的仿真结果了。如下图:
到此处,一个整体的流程就算是结束了,包括了设计输入和仿真。