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 
  • 相关阅读:
    LeetCode 81 Search in Rotated Sorted Array II(循环有序数组中的查找问题)
    LeetCode 80 Remove Duplicates from Sorted Array II(移除数组中出现两次以上的元素)
    LeetCode 79 Word Search(单词查找)
    LeetCode 78 Subsets (所有子集)
    LeetCode 77 Combinations(排列组合)
    LeetCode 50 Pow(x, n) (实现幂运算)
    LeetCode 49 Group Anagrams(字符串分组)
    LeetCode 48 Rotate Image(2D图像旋转问题)
    LeetCode 47 Permutations II(全排列)
    LeetCode 46 Permutations(全排列问题)
  • 原文地址:https://www.cnblogs.com/Dinging006/p/9280029.html
Copyright © 2011-2022 走看看