• 流水线方式LUT查表法乘法器


      流水线利用非阻塞赋值赋予的是上一时钟周期寄存器的值,来实现对寄存器的依次更新值。如:

    always @ ( posedge CLK )
    begin
    //A[m]表示,一维数组A 中第m 个元素。
    //A[m][n]表示,一维数组A 中第m 个元素,第n 位。
    A[0] <= A_input; // 从外部读取新的A 值
    A[1] <= A[0] | 4'b0001; // 读取A[0]值,并且设置第0 位,然后赋予A[1]
    A[2] <= A[1] | 4'b0010; // 读取A[1]值,并且设置第1 位,然后赋予A[2]
    A[3] <= A[2] | 4'b0100; // 读取A[2]值,并且设置第2 位,然后赋予A[3]
    A[4] <= A[3] | 4'b1000; // 读取A[3]值,并且设置第3 位,然后赋予A[4]
    end

      虽然在一个时钟周期内,但完成A[4]的赋值仍需要5个时钟周期,这正是非阻塞赋值的特性,每次只能更新一次上一个时钟沿寄存器的值。虽然第一次需要5个时钟周期完成,但下一个数据的处理按照时钟的概念,依次进入某一拍子中进行处理,以后的数据处理将不需再等待所谓数据的“潜伏期”。如下图所示:当经过4个潜伏期之后,便会连续的输出结果。

      顶层.v文件,例化方式采用位置例化方法,注意端口次序的先后对应:

      1 module Stream_Line_Lut_Multiplier
      2 (
      3     input CLK,
      4      input RSTn,
      5      
      6      input [7:0]A,
      7      input [7:0]B,
      8      
      9      output [15:0]Product
     10 
     11 );
     12 
     13     /********************/
     14      
     15      wire [8:0]U1_I1_Out;
     16      wire [8:0]U1_I2_Out;
     17      
     18      task1_module U1( CLK, RSTn, A, B, U1_I1_Out, U1_I2_Out );
     19      
     20      wire [7:0]U2_I1_Out;
     21      wire [7:0]U2_I2_Out;
     22      
     23      task2_module U2( CLK, RSTn, U1_I1_Out, U1_I2_Out, U2_I1_Out, U2_I2_Out );
     24      
     25      wire [15:0]Q1_Sig;
     26      wire [15:0]Q2_Sig;
     27      
     28      lut_module U3a( CLK, U2_I1_Out, Q1_Sig );
     29      lut_module U3b( CLK, U2_I2_Out, Q2_Sig );
     30      
     31      /*************************/
     32      
     33      assign Product = Q1_Sig + ( ~Q2_Sig + 1'b1 );
     34      
     35      /*************************/
     36       
     37 endmodule
     38 
     39 module task1_module
     40 (
     41 
     42      input CLK,
     43      input RSTn,
     44      
     45      input [7:0]A,
     46      input [7:0]B,
     47      
     48      output [8:0]I1_Out,
     49      output [8:0]I2_Out
     50      
     51 );
     52     
     53      /***************************/
     54 
     55      reg [8:0]I1;
     56       reg [8:0]I2;
     57       
     58       always @ ( posedge CLK or negedge RSTn )
     59           if( !RSTn )
     60                 begin
     61                   
     62                       I1 <= 9'd0;
     63                         I2 <= 9'd0;
     64                   
     65                  end
     66            else 
     67                 begin
     68                  
     69                      I1 <= { A[7], A } + { B[7], B }; 
     70                       I2 <= { A[7], A } + { ~B[7], ( ~B + 1'b1 ) }; 
     71                  
     72                  end
     73                  
     74     /***************************/
     75      
     76      assign I1_Out = I1;
     77      assign I2_Out = I2;
     78      
     79      /***************************/
     80                  
     81 endmodule
     82 
     83 
     84 
     85 module task2_module
     86 (
     87     input CLK,
     88      input RSTn,
     89      
     90      input [8:0]I1_In,
     91      input [8:0]I2_In,
     92     
     93     output [7:0]I1_Out,
     94      output [7:0]I2_Out 
     95 );
     96 
     97     /************************/
     98      
     99      reg [8:0]I1;
    100      reg [8:0]I2;
    101      
    102      always @ ( posedge CLK or negedge RSTn )
    103          if( !RSTn )
    104               begin
    105                 
    106                     I1 <= 9'd0;
    107                      I2 <= 9'd0;
    108                 
    109                 end
    110           else 
    111               begin
    112                 
    113                     I1 <= I1_In[8] ? ( ~I1_In + 1'b1 ) : I1_In;
    114                      I2 <= I2_In[8] ? ( ~I2_In + 1'b1 ) : I2_In;
    115                 
    116                 end
    117                 
    118     /************************/
    119      
    120      assign I1_Out = I1[7:0];
    121      assign I2_Out = I2[7:0];
    122      
    123      /************************/
    124  
    125 endmodule
    Stream_Line_Lut_Multiplier

      LUT_Rom存放的数据:

     1 0    0    1      2     4        6    9    12    
     2 16    20    25    30    36    42    49    56    
     3 64    72    81    90    100    110    121    132
     4 144    156    169    182    196    210    225    240    
     5 256    272    289    306    324    342    361    380    
     6 400    420    441    462    484    506    529    552    
     7 576    600    625    650    676    702    729    756    
     8 784    812    841    870    900    930    961    992    
     9 1024    1056    1089    1122    1156    1190    1225    1260    1296    1332    1369    1406    1444    1482    1521    1560    1600    1640    1681    1722    1764    1806    1849    1892    1936    1980    2025    2070    2116    2162    2209    2256    2304    2352    2401    2450    2500    2550    2601    2652    2704    2756    2809    2862    2916    2970    3025    3080    3136    3192    3249    3306    3364    3422    3481    3540    3600    3660    3721    3782    3844    3906    3969    4032    4096    4160    4225    4290    4356    4422    4489    4556    4624    4692    4761    4830    4900    4970    5041    5112    5184    5256    5329    5402    5476    5550    5625    5700    5776    5852    5929    6006    6084    6162    6241    6320    6400    6480    6561    6642    6724    6806    6889    6972    7056    7140    7225    7310    7396    7482    7569    7656    7744    7832    7921    8010    8100    8190    8281    8372    8464    8556    8649    8742    8836    8930    9025    9120    9216    9312    9409    9506    9604    9702    9801    9900    10000    10100    10201    10302    10404    10506    10609    10712    10816    10920    11025    11130    11236    11342    11449    11556    11664    11772    11881    11990    12100    12210    12321    12432    12544    12656    12769    12882    12996    13110    13225    13340    13456    13572    13689    13806    13924    14042    14161    14280    14400    14520    14641    14762    14884    15006    15129    15252    15376    15500    15625    15750    15876    16002    16129    16256    
    10                     
    rom

       

      实验过程出现的问题:

      1、前些天刚做过LUT乘法实验,同样查表是用ROM生成的,但这次好几次都是输出全0.

      问题所在:生成ROM的过程中,器件选型要与工程所用器件一直。

      2、使用quartus中TestBench的向导Processing->start->Start TestBench Template Writer时,前提要在设置中设置好仿真工具Modelsim Altera,才能进行模版的生成。

      收获:模版生成貌似挺有用的说,利用模版里边的端口映射模块,可以很简单的用在模块例化的端口映射中,这在端口量很大的工程中很能提高效率。O(∩_∩)O哈哈~

        3、用Modelsim仿真发现,通过调用ROM来实现查表与直接写一个.v的ROM文件相比,前者比后者多了一个潜伏期,这是为何?

      问题所在:在ROM配置的第二页最上边部分,有“What ports should be registered?”选项,意为哪些端口需要被寄存器寄存一拍,输出不要选中。此时,ROM时序示例图如图所示:

    此时潜伏期变成了3个时钟周期,如下图:

      4、更改ROM配置后,出现以下错误:

    address :Input Warning Input port expression (1 bits) is smaller than the input port (8 bits) it drives. Extra input bit(s) "address[7..1]" will be connected to GND.
    clock :Input Warning Input port expression (8 bits) is wider than the input port (1 bits) it drives. The 7 most-significant bit(s) in the expression will be dangling if they have no other fanouts.

      原因:因为采用位置关联法,新配置ROM过后,需要重新调整上述ROM中和clock的顺序。

      5、以下这些错误是绝对可以忽视的。

      6、为什么点了时序仿真输出结果不对?(全零)

      解决:

  • 相关阅读:
    spark简单入门
    vim 树形目录插件NERDTree
    Windows下查看系统端口使用的命令
    网络爬虫爬取动态网页
    Java并查集链表实现
    基于mahout的海量数据关联规则挖掘
    高维特征降维方法-随机映射
    JVM(4)--垃圾回收算法
    Java高并发程序设计(六)--线程池(1)
    Java高并发程序设计(五)--ReentrantLock源码解析
  • 原文地址:https://www.cnblogs.com/fkl523/p/3412767.html
Copyright © 2020-2023  润新知