我是靠谱客的博主 爱听歌大侠,最近开发中收集的这篇文章主要介绍前仿真和后仿真的区别,按键消抖设计思想、PLL使用、ODDR2的原语使用 --2020/10/29工作总结前仿真和后仿真的区别按键消抖设计思想PLL使用ODDR2的原语使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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的原语使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部