zoukankan      html  css  js  c++  java
  • FPGA大疆考试准备内容

    1.寄存器与锁存器

    锁存器:电平触发的存储单元,在有效电平时间里可以多次改变数据。
    优点:    占触发器资源少,缺点是容易产生毛刺。(附上去毛刺的方法:格雷码计数器(*https://blog.csdn.net/qp314/article/details/5147695*)代替二进制码计数器,或者用D触发器同步。)
     在FPGA中用的很少,因为FPGA中触发器的资源非常丰富。
     寄存器:边沿触发的存储单元,在上升或下降沿数据变化,一个周期里只能变化一次。(寄存器是有DFF(D触发器)构成的,它起的只是暂时存储数据的作用;内存储器有MOS门和TTL门两种构成,有ROM和RAM两种。)

    flip-flop:触发器,是时钟边沿触发,可存储1 bit data,是register的基本组成单位,结构图如下:

    register:寄存器,a hardware register stores bits of information in such a way that systems can write to or read out all the bits simultaneously.就是时钟边沿触发的存储结构,是由多个flip-flop组成,可以构成register file, SRAM等,结构如下:

    时序逻辑结构

    latch:锁存器,是由电平触发,结构图如下:

    组合逻辑结构

    2.FPGA实现的verilog编码流程:文本编辑→功能仿真→逻辑综合→布局布线→时序仿真
    3.对于同步接口的设计,同步输入信号需要约束——input delay————,同步输出信号需要约束——output delay——分别关联到同步时钟上
    4.逻辑设计中的同步电路有源同步,系统同步,自同步三种,传统并行接口采用的是源同步或者系统同步的方法来实现的,serdes接口—SerDes(Serializer-Deserializer)是串行器和解串器的简称http://blog.sina.com.cn/s/blog_aec06aac01013m5g.html—均衡和数据时钟相位检测——GMII接口(是8bit并行同步收发接口,采用8位接口数据,工作时钟125MHz,因此传输速率可达1000Mbps。同时兼容MII所规定的10/100 Mbps工作方式。)
    5.关于FPGA的仿真:
    主要有功能仿真,门级仿真和时序仿真,其中功能仿真知识进行代码功能验证的仿真,门级仿真则是在综合过后,加入了器件库的延时信息的情况下进行的,
    时序仿真在设计流程中的最后一个仿真是时序仿真。在设计布局布线完成以后可以提供一个时序仿真模型,这种模型中也包括了器件的一些信息,同时还会提供一个SDF时序标注文件(Standard Delay format Timing Anotation)。SDF时序标注最初使用在Verilog语言的设计中,现在VHDL语言的设计中也引用了这个概念。对于一般的设计者来说并不需知道SDF文件的详细细节,因为这个文件一般由器件厂家提供给设计者,xilinx公司使用SDF作为时序标注文件扩展名,Altera公司使用SDO作为时序标注文件的扩展名。在SDF时序标注文件中对每一个底层逻辑门提供了3种不同的延时值,分别是典型延时值、最小延时值和最大延时值,在对SDF标注文件进行实例化说明时必须指定使用了那一种延时。虽然在设计的最初阶段就已经定义了设计的功能,但是只有当设计布局布线到一个器件中后,才会得到精确的延时信息,在这个阶段才可以模拟到比较接近实际电路的行为。
     
    6.关于FPGA实现定点数的浮点化
    首先明确浮点数的表示方法:

    那么其在FPGA上的实现方法:

    但是为什么这样的方法就可以实现FPGA的浮点输的转化呢?表示比较疑惑

     7.状态机设计:实现序列检测:

    根据要检测的序列的长度决定状态的个数,然后设计好状态转移图:根据三段式的设计方案,即可以实现状态机的编写:

    三段式序列检测"10010"
    
    module seqdet(din,clk,rst,dout);
    input din;    //输入
    input clk;
    input rst;
    output dout;  //输出
    reg dout;
    
    reg [4:0] CS;  //现态寄存器
    reg [4:0] NS;  //次态寄存器
    
    parameter [4:0] IDLE = 5'b00000,  //独热码
                      A  = 5'b00001,
                      B  = 5'b00010,
                      C  = 5'b00100,
                      D  = 5'b01000,
                      E  = 5'b10000;
    
    always @ (posedge clk or negedge rst)
      if (!rst)
        CS <= IDLE;
      else
        CS <= NS ;
    
    always @ ( CS or din ) begin
      NS = 5'bx;
      case (CS)
        IDLE : NS = din ? A : IDLE;
               A : NS = din ? A : B;
               B : NS = din ? A : C;
              C : NS = din ? D : IDLE;
              D : NS = din ? A : E;
              E : NS = din ? A : C;
    
          default: NS = IDLE;   
       endcase
     end
    
    always @ ( posedge clk or negedge rst)
       if (!rst)
           dout <= 1'b0;
       else
           begin
               dout <= 1'b0;
               if (NS == E)
               dout <= 1'b1;
           end  
    endmodule

    状态机之并行数据串行化:

    //并行数据串行化
    module b2c(din8,clk,slr,din);
    input clk,clr;
    input [7:0]din8;
    output din;
    reg [2:0]cs,ns;
    reg dout;
    always@(posedge clk or posedge clr)
    begin
        if(clr) cs<=0;
        else cs<=ns;
    end
    
    always@(clk or din8 or dout)
    begin
         case(cs)
         3'b0:
         begin 
          din<din8[7];
          ns<=3'b1;
         end
         3'b1:
         begin 
          din<din8[6];
          ns<=3'b2;
         end
         3'b2:
         begin 
          din<din8[5];
          ns<=3'b3;
         end
         3'b3:
         begin 
          din<din8[4];
          ns<=3'b4;
         end
         3'b4:
         begin 
          din<din8[3];
          ns<=3'b5;
         end
         3'b5:
         begin 
          din<din8[2];
          ns<=3'b6;
         end
         3'b6:
         begin 
          din<din8[1];
          ns<=3'b7;
         end
         3'b7:
         begin 
          din<din8[0];
          ns<=3'b0;
         end
         default:
         begin
           din<=1'b0;
           ns<=0;
         end
         endcase
    end
    endmodule

    8.FIFO深度计算,原来这也是一个神奇的问题啊,首先需要了解其应用的场景,FIFO主要用于数据的缓存,在写快但是读慢的情形下,主要考虑到读写时钟的不一致性问题,主要的计算公式:depth of fifo=FIFO被填满的时间*(w_clk - r_clk)大于数据包的传送时间=数据量 / 写入速度。

    以下是网上整理到的资料:

    首先,一定要理解清楚FIFO的应用场景,这个会直接关系到FIFO深度的计算,如果是面试官抛出的问题,那么有不清楚的地方,就应该进行询问。如果是笔试或者工程中需要计算FIFO深度的话,那么就需要自己考虑清楚。

    其次,异步FIFO,读写时钟不同频,那么FIFO主要用于数据缓存,我们选择的FIFO深度应该能够保证在最极端的情况下,仍然不会溢出。因此考虑的前提一般都是写时钟频率大于读时钟频率,但是若写操作是连续的数据流,那么再大的FIFO都无法保证数据不溢出。因此可以认为这种情况下写数据的传输是“突发Burst”的,即写操作并不连续,设计者需要根据满标志控制或者自己来控制写操作的起止。

    宏观地,从整个时间域上看,"写数据=读数据",这个条件必须要满足,如果这个大条件不满足的话,用FIFO是没有效果的。但是在发送方"突发"发送数据的时间T内,是很有可能写数据>读数据的,因此FIFO的深度要能够保证,在这段时间T内,如果接收方未能将发送方发送的数据接收完毕的话,剩下的数据都是可以存储在FIFO内部而且不会溢出的,那么在发送方停止发送数据的"空闲时隙"内,接收方可以从容地接收剩下来的数据。

    写时钟周期w_clk, 
    读时钟周期r_clk, 
    写时钟周期里,每B个时钟周期会有A个数据写入FIFO 
    读时钟周期里,每Y个时钟周期会有X个数据读出FIFO 
    则,FIFO的最小深度是? 
    首先,这道题不一定有解 
    有解的必要条件是在一定时间内(足够长),写入的数据数量一定要等于读出的数据数量 
    因此有:A/B * w_clk = X/Y * r_clk 
    其次,算出写数据的最大burst_length。考虑最坏情况 
    比如,如果条件给出,每100个写时钟,写入80个数据,那么在背靠背的情况下,burst_length = 2*80=160 
    最后,fifo_depth = burst_length - burst_length * X/Y * r_clk/w_clk 
    BTW:通常,为了安全起见,都会多留一些depth的余度
    个人觉得,公式应该是这样: 
    A/(B * w_clk) = X/(Y * r_clk) 
    fifo_depth = burst_length - burst_length * X/Y * w_clk /r_clk 
    举例说明: 
    如果100个写时钟周期可以写入80个数据,10个读时钟可以读出8个数据 
    其中w_ck=5ns,r_ck=10ns 
    如果按照之前的公式,得出的深度为:fifo_depth = burst_length - burst_length * X/Y * r_ck/w_clk=160-160*8/10*2=-94,显然是不对的 
    实际上,考虑背靠背(20个clk不发数据+80clk发数据+80clk发数据+20个clk不发数据的200个clk) 
    这样在中间160个写时钟周期连续写的情况下,只能读出160*5/(10*10)*8=64个数据,所以FIFO的深度应该为160-64=96 
    也就是fifo_depth = burst_length - burst_length * X/Y * w_clk /r_clk=160-160*8/10*5/10=96

    9.同步异步电路分析

     在同步电路设计中一般采用D触发器,异步电路设计中一般采用Latch。两者的最大的区别就在于,同步电路有统一的时钟,但是异步电路没有统一的时钟,

     异步复位信号同步释放:其中的异步复位是指复位信号是异步有效的,即复位的发生与clk无关。后半句“同步释放”是指复位信号的撤除也与clk无关,但是复位信号是在下一个clk来到后起的作用(释放)。

    10.各类存储器之间的区别(详见之前写的一篇博客的内容总结部分)。

    11.对竞争冒险的理解,以及如何消除?

         在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。如果布尔式中有相反的信号则可能产生竞争和冒险现象。解决方法:一是添加布尔式的消去项,二是在芯片外部加电容。

    12分频器的设计(任意分频通用设计)

    module square_generator#(parameter FREQ_WORD = 32'd85899)
    (LedCtlWordLocal,clk,rst_n,clk_outI,clk_outQ);
        input LedCtlWordLocal;
        input clk; //50MHz 
        input rst_n;//clock reset 
        output reg clk_outI,clk_outQ;
    //-------------------------------------- 
    reg [31:0] count='b1;
    always@(posedge clk)
    begin
        count <= count + FREQ_WORD;
    end
    //-------------------------------------- 
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            clk_outI <= 'b1;
        else
        begin
            if(count < 32'h7FFF_FFFF)
                clk_outI <= 'b1;
            else
                clk_outI <= LedCtlWordLocal;
            if((count>32'h3FFFFFFF)&&(count < 32'hbFFFFFFF))
                clk_outQ <= 1'b1;
            else
                clk_outQ <= LedCtlWordLocal;
        end
    end
    endmodule 
  • 相关阅读:
    Python 一条语句如何在多行显示的问题
    代理模式
    MySQL workbench中的PK,NN,UQ,BIN,UN,ZF,AI说明
    异步加载 Echarts图的数据
    Web页面中两个listbox的option的转移
    半透明效果
    在地图上使图片透明
    加载图片方式
    获取鼠标坐标
    画笔与画刷
  • 原文地址:https://www.cnblogs.com/Dinging006/p/9280029.html
Copyright © 2011-2022 走看看