无符号连续运算除法器
作者:互联网
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 endmoduleView 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 endmoduleView Code
4.modelsim仿真结果
标签:除法器,wire,运算,符号,numer,clken,WIDTHN,input,reg 来源: https://www.cnblogs.com/xingjian92/p/14994055.html