• 无符号连续运算除法器


    1.起因:

           最近移植工程的时候要用到除法器,但是某国产FPGA的除法器IP核只支持单个数的除法,要等到这个除法运算结束后才能开始下一个数的除法运算,没办法做连续的除法运算。网上能找到的除法运算也是只支持单个数的除法运算,索性自己写一个

    2.除法器原理

           见下面连接,写的比较详细清楚

           https://www.cnblogs.com/Dinging006/p/9382657.html.

    3.FPGA代码

      1 module divider
      2 #(
      3   parameter  WIDTHN = 26,
      4              WIDTHD = 15
      5 )
      6 (
      7   numer,
      8   denom,
      9   clken,
     10   clk,
     11   reset,
     12   quotient,
     13   rfd
     14 );
     15 
     16   input wire[WIDTHN-1:0]  numer;
     17   input wire[WIDTHD-1:0]  denom;
     18   input wire              clken;
     19   input wire              clk;
     20   input wire              reset;
     21 
     22   output wire[WIDTHN-1:0]  quotient;
     23   output wire              rfd; 
     24 
     25 divider_b3c8e366d43b4ebbb7424ac7d85e03b7 
     26 #(
     27   .WIDTHN   ( WIDTHN ),
     28   .WIDTHD   ( WIDTHD )
     29 ) 
     30 divider_u (
     31   .numer    ( numer    ),
     32   .denom    ( denom    ),
     33   .clken    ( clken    ),
     34   .clk      ( clk      ),
     35   .reset    ( reset    ),
     36   .quotient ( quotient ),
     37   .rfd      ( rfd      )
     38 );
     39   
     40 endmodule
     41 
     42 
     43 
     44 // *******************************
     45 `resetall
     46 `timescale 1ns / 1ps
     47 
     48 
     49 module divider_b3c8e366d43b4ebbb7424ac7d85e03b7
     50 #(
     51   parameter  WIDTHN = 26,
     52              WIDTHD = 15
     53 )
     54 (
     55   clk,
     56   reset,
     57   clken,
     58   numer,  
     59   denom,
     60   quotient, 
     61   rfd    
     62 );
     63   
     64   input wire                clk;
     65   input wire                reset;
     66   //input start,
     67   input wire                clken;
     68   input wire[(WIDTHN-1):0]  numer;
     69   input wire[(WIDTHD-1):0]  denom;
     70   //output
     71   output reg[(WIDTHN-1):0]  quotient;
     72   output reg                rfd;
     73   
     74   reg [WIDTHN-1  :0]        clken_dly;
     75   reg [2*WIDTHN-1:0]        numer_tmp[WIDTHN:0];
     76   reg [2*WIDTHN-1:0]        denom_tmp[WIDTHN-1:0];
     77   
     78   wire[2*WIDTHN-1:0]        shift_numer[WIDTHN:1];
     79   reg [4:0]                 i;
     80   reg [4:0]                 j;
     81 
     82 always@(posedge clk or posedge reset) 
     83   if(reset==1'd1) 
     84     clken_dly <= {WIDTHN{1'b0}};
     85   else 
     86     clken_dly <= {clken_dly[WIDTHN-2:0],clken};
     87         
     88 always@(posedge clk or posedge reset) 
     89   if(reset==1'd1) 
     90   begin
     91     numer_tmp[0] <= {2*WIDTHN{1'b0}};
     92     denom_tmp[0] <= {2*WIDTHN{1'b0}};     
     93   end
     94   else if(clken==1'd1)
     95   begin
     96     numer_tmp[0] <= {{(WIDTHN-1){1'd0}},numer,1'b0};
     97     denom_tmp[0] <= {denom,{WIDTHN{1'd0}}};
     98   end
     99 
    100 always@(posedge clk or posedge reset) 
    101   if(reset==1'd1) 
    102   begin
    103     for(j=1;j<WIDTHN;j=j+1)
    104     begin
    105       // numer_tmp[j] <= {2*WIDTHN{1'b0}};
    106       denom_tmp[j] <= {2*WIDTHN{1'b0}};   
    107     end
    108   end
    109   else 
    110   begin
    111     for(i=1;i<WIDTHN;i=i+1)
    112     begin
    113       denom_tmp[i] <= denom_tmp[i-1];
    114     end
    115   end
    116 
    117 genvar k;
    118 generate
    119     for(k=1;k<=WIDTHN;k=k+1)
    120     begin:loops
    121       assign shift_numer[k] = (numer_tmp[k-1]>denom_tmp[k-1])?(numer_tmp[k-1]-denom_tmp[k-1]+1'd1):numer_tmp[k-1];
    122       always@(posedge clk) 
    123         begin
    124           numer_tmp[k] <= {shift_numer[k][2*WIDTHN-2:0],1'b0};
    125         end       
    126     end
    127 endgenerate
    128 
    129 always@(posedge clk or posedge reset) 
    130   if(reset==1'd1) 
    131   begin
    132     rfd <= 1'd0;
    133     quotient <= {WIDTHN{1'b0}};
    134   end
    135   else 
    136   begin
    137     rfd <= clken_dly[WIDTHN-1];
    138     quotient <= shift_numer[WIDTHN][WIDTHN-1:0];
    139   end
    140 
    141     
    142 endmodule
    View Code
     1 `timescale 1ns/1ns
     2 module testbench();
     3      reg            sclk;
     4      reg            rst_n;
     5      reg            clken;
     6      
     7      initial
     8      begin
     9           sclk = 0;
    10           rst_n <= 0;
    11           #1010
    12           rst_n <= 1;
    13      end
    14      
    15      always#10 sclk = ~sclk;
    16      
    17     reg [25:0]      numer;
    18     reg [14:0]      denom;
    19     always@(posedge sclk or negedge rst_n) 
    20         if(rst_n==1'd0) 
    21         begin
    22           numer <= 26'd0;
    23           denom <= 15'd0;
    24           clken <= 1'd0;    
    25         end
    26         else
    27         begin
    28           numer <= {$random}%2048;
    29           denom <= {$random}%25;    
    30           clken <= {$random}%2;
    31         end
    32 
    33 
    34 divider 
    35 #(
    36   .WIDTHN   ( 26 ),
    37   .WIDTHD   ( 15 )
    38 )
    39 divider_init(
    40   .numer    (numer),
    41   .denom    (denom),
    42   .clken    (clken),
    43   .clk      (sclk),
    44   .reset    (~rst_n),
    45   .quotient (),
    46   .rfd      ()
    47 );
    48 
    49 endmodule
    View Code

    4.modelsim仿真结果

  • 相关阅读:
    OpenGL的几何变换2之内观察立方体
    OpenGL的几何变换[转]
    OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数详解
    OpenGL的glScalef缩放变换函数详解
    [centos][ntp][administrator] chrony ntp
    [dpdk][kni] dpdk kernel network interface
    [administrator][netctl] 给未插线未UP端口设置IP
    [administrator] rpmbuild
    OWA (Office Web Access)
    [network] netfilter
  • 原文地址:https://www.cnblogs.com/xingjian92/p/14994055.html
Copyright © 2020-2023  润新知