概述
2020/10/29工作总结
- 前仿真和后仿真的区别
- 前仿真
- 综合后仿真
- 后仿真
- synthesize和implement、generate bitstream
- 参考链接
- 按键消抖设计思想
- PLL使用
- DCM模块
- ODDR2的原语使用
- 参考链接:
前仿真和后仿真的区别
初学者学习FPGA,必定会被它的各种仿真弄的晕头转向。比如,前仿真、后仿真、功能仿真、时序仿真、行为级仿真、RTL级仿真、综合后仿真、门级仿真、布局布线后仿真等。
前仿真
前仿真=功能仿真=行为级仿真=RTL级仿真
前仿真,也称为功能仿真或行为级仿真。是指仅对逻辑功能进行测试模拟,以了解其实现的功能是否满足原设计的要求,仿真过程没有加入时序信息,不涉及具体器件的硬件特性,如延时特性;
综合后仿真
综合后仿真把综合生成的标准延时文件反标注到综合仿真模型中去,可估计门延时对电路带来的影响。
后仿真
后仿真=时序仿真=布局布线后仿真=门级仿真
后仿真,也称为布局布线后仿真或时序仿真。是指提取有关的器件延迟、连线延时等时序参数,并在此基础上进行的仿真,它是非常接近真实器件运行情况的仿真。
synthesize和implement、generate bitstream
synthesize代表综合。
implement代表布局布线
generate bitstream代表生成二进制文件(二进制文件是用来下载到开发板上)
参考链接
https://blog.csdn.net/i13919135998/article/details/52458685
按键消抖设计思想
1.每隔20ms读一次按键值.(这相当于打第一拍)
2.对读取的按键值再打一拍,然后检测下降沿。
代码如下
//===========================================================================
// Module name: key_test.v
// 描述: 检测开发板上的四个按键KEY1~KEY4, 当检测到按键按下时,相应的LED灯翻转
//===========================================================================
`timescale 1ns / 1ps
module key_test (
clk, // 开发板上输入时钟: 50Mhz
rst_n, // 开发板上输入复位按键
key_in, // 输入按键信号(KEY1~KEY4)
led_out // 输出LED灯,用于控制开发板上四个LED(LED1~LED4)
);
//===========================================================================
// PORT declarations
//===========================================================================
input clk;
input rst_n;
input [3:0] key_in;
output [3:0] led_out;
//寄存器定义
reg [19:0] count;
reg [3:0] key_scan; //按键扫描值KEY
//===========================================================================
// 采样按键值,20ms扫描一次,采样频率小于按键毛刺频率,相当于滤除掉了高频毛刺信号。
//===========================================================================
always @(posedge clk or negedge rst_n) //检测时钟的上升沿和复位的下降沿
begin
if(!rst_n) //复位信号低有效
count <= 20'd0; //计数器清0
else
begin
if(count ==20'd999_999) //20ms扫描一次按键,20ms计数(50M/50-1=999_999)
begin
count <= 20'b0; //计数器计到20ms,计数器清零
key_scan <= key_in; //采样按键输入电平
end
else
count <= count + 20'b1; //计数器加1
end
end
//===========================================================================
// 按键信号锁存一个时钟节拍
//===========================================================================
reg [3:0] key_scan_r;
always @(posedge clk)
key_scan_r <= key_scan;
wire [3:0] flag_key = key_scan_r[3:0] & (~key_scan[3:0]); //当检测到按键有下降沿变化时,代表该按键被按下,按键有效
//===========================================================================
// LED灯控制,按键按下时,相关的LED输出翻转
//===========================================================================
reg [3:0] temp_led;
always @ (posedge clk or negedge rst_n) //检测时钟的上升沿和复位的下降沿
begin
if (!rst_n) //复位信号低有效
temp_led <= 4'b1111; //LED灯控制信号输出为低, LED灯全灭
else
begin
if ( flag_key[0] ) temp_led[0] <= ~temp_led[0]; //按键KEY1值变化时,LED1将做亮灭翻转
if ( flag_key[1] ) temp_led[1] <= ~temp_led[1]; //按键KEY2值变化时,LED2将做亮灭翻转
if ( flag_key[2] ) temp_led[2] <= ~temp_led[2]; //按键KEY3值变化时,LED3将做亮灭翻转
if ( flag_key[3] ) temp_led[3] <= ~temp_led[3]; //按键KEY4值变化时,LED4将做亮灭翻转
end
end
assign led_out[0] = temp_led[0];
assign led_out[1] = temp_led[1];
assign led_out[2] = temp_led[2];
assign led_out[3] = temp_led[3];
endmodule
PLL使用
PLL,即锁相环。是 FPGA 中的重要资源。PLL可以进行分频、倍频。
PLL可以通过例化IP核来容易实现。
在sparten6开发板中,PLL通过例化后,生成的脉冲不能直接输出,需要通过ODDR2,使得BUFG输出的时钟信号能够输出到FPGA的普通IO。
注意这里ODDR2不是IP核,是原语。
`timescale 1ns / 1ps
//
// Module Name: pll_test
//
module pll_test(
input clk,
input rst_n,
output clk_out //pll clock output
);
wire locked;
wire pll_clk_o;
/PLL IP 调用
pll_ip pll_ip_inst
(// Clock in ports
.CLK_IN1(clk), // IN 50Mhz
// Clock out ports
.CLK_OUT1(pll_clk_o), // OUT 25Mhz
.CLK_OUT2(), // OUT 50Mhz
.CLK_OUT3(), // OUT 75Mhz
.CLK_OUT4(), // OUT 100Mhz
// Status and control signals
.RESET(~rst_n),// IN
.LOCKED(locked)); // OUT
///调用ODDR2使时钟信号通过普通IO输出//
ODDR2 #(
.DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" set/reset
) ODDR2_inst (
.Q(clk_out), // 1-bit DDR output data
.C0(pll_clk_o), // 1-bit clock input
.C1(~pll_clk_o), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(1'b1), // 1-bit data input (associated with C0)
.D1(1'b0), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
endmodule
DCM模块
数 字时钟管理模块(Digital Clock Manager,DCM)是基于Xilinx的其他系列器件所采用的数字延迟锁相环(DLL,Delay Locked Loop)模块。
DCM和PLL一样,均可实现分频和倍频。不过如果相移是必需的,就应该明确地选择DCM。
ODDR2的原语使用
原语,英文名称primitive,是FPGA软件集成开发环境所提供的一系列底层逻辑功能单元。由于是底层逻辑功能单元,所以它们往往跟目标FPGA芯片以及芯片厂商紧密相关,因此不同厂商、不同器件的原语往往不能通用。当编译器对我们的HDL代码进行编译时,其中间环节的一些输出往往就是由原语组成的逻辑网表。因此,原语往往是不参与综合过程的,而使用原语描述的逻辑往往也不会被综合工具所优化。
一般来说,在进行HDL代码编写时,不需要直接或间接的进行原语调用,因为随着FPGA设计规模的越来越庞杂,人脑应该集中于抽象层次较高的工作中去,而将这些具体实现细节交给编译器来完成。不过有些时候,原语或者库中底层模块的调用还是十分必要的。(通过原语可以调用底层逻辑单元)
例如:
// Verilog example
wire innerclk, gclk;
BUFG onToGlobalClockTree(.I (innerclk),
.O (gclk));
always@(posedge gclk)
begin
……
end
如果时钟信号不是由FPGA芯片的专用时钟pin(或pad)引入FPGA的,那么它通常就需要在FPGA内部被显式的连接到时钟树资源上,否则,直接使用这种不经过时钟树的时钟信号,会给FPGA设计的时序带来非常麻烦的问题,进而导致逻辑行为失败。
可是HDL代码仅仅描述功能,无法向编译器表达“希望将某一时钟信号连接到时钟树资源”这样的一层意思,那么此时,就需要使用类似BUFG这样的库里提供的底层模块来进行指示。
那么,像上例这样,通过显式调用BUFG这样一个库中的底层模块,就可以告诉编译器,我们希望将innerclk信号引入全局时钟树,而其经过全局时钟树后的名字就改为gclk。后续HDL代码便可以放心的基于gclk编写逻辑。
参考链接:
https://blog.csdn.net/Reborn_Lee/article/details/105020930?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242
最后
以上就是爱听歌大侠为你收集整理的前仿真和后仿真的区别,按键消抖设计思想、PLL使用、ODDR2的原语使用 --2020/10/29工作总结前仿真和后仿真的区别按键消抖设计思想PLL使用ODDR2的原语使用的全部内容,希望文章能够帮你解决前仿真和后仿真的区别,按键消抖设计思想、PLL使用、ODDR2的原语使用 --2020/10/29工作总结前仿真和后仿真的区别按键消抖设计思想PLL使用ODDR2的原语使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复