001-CORDIC实现除法
Posted mia1004
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了001-CORDIC实现除法相关的知识,希望对你有一定的参考价值。
2019年10月6日10:07:26
CORDIC除法原理不再赘述:
MATLAB(适用条件:除数不能超过被除数的2倍):
function div_res = cordic_div(frac_up, frac_down, loops) % INTIAL div_res = 0; value = 1; % CORDIC for i = 0:loops - 1 if((frac_down * frac_up) < 0) x_new = frac_down; y_new = (frac_up + frac_down) * 2; frac_down = x_new; frac_up = y_new; div_res = div_res - value * 2 ^-i; else x_new = frac_down; y_new = (frac_up - frac_down) * 2; frac_down = x_new; frac_up = y_new; div_res = div_res + value * 2 ^-i; end end end
对应FPGA实现思路:
1)初始化对应RST复位实现;
2)(frac_down * frac_up) < 0 用异或实现;
3)迭代利用generate + 寄存器组实现,每一个迭代单元单独例化一个子程序;
4)2^-i,以及 * 2 ,利用移位实现;
对应时序:
对应FPGA代码:
tb
`timescale 1ns / 1ps module tb; /************* PARAMETER ******************/ parameter LOOPS = 15; parameter DATWIDTH = 16; parameter RESWIDTH = 12; /**************** INPUT OUTOUT ************/ logic signed [DATWIDTH - 1:0] fracDown; logic signed [DATWIDTH - 1:0] fracUp; logic signed [RESWIDTH - 1:0] divRes; /**************** INITIAL *****************/ logic clk; logic rst; initial begin clk = 0; rst = 1‘b1; fracDown = 0; fracUp = 0; #20 rst = 1‘b0; #200 fracDown = 16‘d200; fracUp = -16‘d40; #1000 $stop; end always #2 clk = !clk; /**************** CORDIV ******************/ cordic_div #( .LOOPS(LOOPS), .DATWIDTH(DATWIDTH), .RESWIDTH(RESWIDTH) ) Ucordic_div( .clk(clk), .rst(rst), .fracDown(fracDown), .fracUp(fracUp), .divRes(divRes) ); glbl glbl(); endmodule
cordic_div
module cordic_div(clk, rst, fracDown, fracUp, divRes); /********** PARAMETER **************/ parameter LOOPS = 15; parameter DATWIDTH = 16; parameter RESWIDTH = 12; /********** INPUT OUTPUT ***********/ input clk; input rst; input signed [DATWIDTH - 1:0] fracDown; input signed [DATWIDTH - 1:0] fracUp; output wire signed [RESWIDTH - 1:0] divRes; /********** CORDIC *****************/ // PIPE LINE wire signed [LOOPS:0][DATWIDTH - 1:0] fracDown1; wire signed [LOOPS:0][DATWIDTH - 1:0] fracUp1; wire signed [LOOPS:0][RESWIDTH - 1:0] divRes1; // INITIAL assign fracDown1[0] = fracDown; assign fracUp1[0] = fracUp; assign divRes1[0] = RESWIDTH1‘b0; genvar ii; generate for (ii = 0; ii < LOOPS; ii = ii + 1) begin: cordic_ii cordiv_unit #( .DATWIDTH(DATWIDTH), .RESWIDTH(RESWIDTH), .STAGE(ii) ) Ucordiv_unit( .clk(clk), .rst(rst), .xin(fracDown1[ii]), .yin(fracUp1[ii]), .zin(divRes1[ii]), .xout(fracDown1[ii + 1]), .yout(fracUp1[ii + 1]), .zout(divRes1[ii + 1]) ); end endgenerate assign divRes = divRes1[LOOPS]; endmodule
cordiv_unit
module cordiv_unit(clk, rst, xin, yin, zin, xout, yout, zout); /*************** PARAMETER ********************/ parameter DATWIDTH = 16; parameter RESWIDTH = 12; parameter STAGE = 0; parameter VALUE = 12‘h400; /************** INPUT OUTPUT ******************/ input clk; input rst; input signed [DATWIDTH - 1:0] xin; input signed [DATWIDTH - 1:0] yin; input signed [RESWIDTH - 1:0] zin; output reg signed [DATWIDTH - 1:0] xout; output wire signed [DATWIDTH - 1:0] yout; output reg signed [RESWIDTH - 1:0] zout; /************** CORDIC UINIT *******************/ reg [DATWIDTH - 1:0] yout1; always @(posedge clk) begin if(rst) begin xout <= DATWIDTH1‘b0; yout1 <= DATWIDTH1‘b0; zout <= RESWIDTH1‘b0; end else begin xout <= xin; if(xin[DATWIDTH - 1]^yin[DATWIDTH - 1]) begin yout1 <= yin + xin; zout <= zin - (VALUE >> STAGE); end else begin yout1 <= yin - xin; zout <= zin + (VALUE >> STAGE); end end end assign yout = yout1[DATWIDTH - 1], yout1[DATWIDTH - 3:0], 1‘b0; endmodule
仿真结果:
即-40/200 = 0.2 ,仿真结果为:-205/1024(2^10) = -0.2002,仿真正确。
module delay:LOOPS = 15 clk.
以上是关于001-CORDIC实现除法的主要内容,如果未能解决你的问题,请参考以下文章