其他分享
首页 > 其他分享> > 无符号连续运算除法器

无符号连续运算除法器

作者:互联网

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仿真结果

标签:除法器,wire,运算,符号,numer,clken,WIDTHN,input,reg
来源: https://www.cnblogs.com/xingjian92/p/14994055.html