OpenCores
URL https://opencores.org/ocsvn/verilog_cordic_core/verilog_cordic_core/trunk

Subversion Repositories verilog_cordic_core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/tags/rel_1/cordic.v File deleted
/tags/rel_1/manual.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/rel_1/manual.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/tb_cordic.v =================================================================== --- trunk/tb_cordic.v (revision 3) +++ trunk/tb_cordic.v (nonexistent) @@ -1,254 +0,0 @@ -`timescale 1ns/1ns -/* - CORDIC testbench - - This testbench assumes the default settings for `defines - in the cordic.v file. If you change any of the defaults - you may have to make modifications to this file as well. - - This testbench uses `defines from the cordic.v file - make sure you have the `include path set correctly for your - environment. -*/ -`include "cordic.v" -module tb (); - - wire [`XY_BITS:0] x_o,y_o; - wire [`THETA_BITS:0] theta_o; - reg [`XY_BITS:0] x_i,y_i; - reg [`THETA_BITS:0] theta_i; // angle in radians - reg clock,reset; - reg init; - -cordic UUT (.clk(clock),.rst(reset), -`ifdef ITERATE - .init(init), -`endif - .x_i(x_i),.y_i(y_i),.theta_i(theta_i), - .x_o(x_o),.y_o(y_o),.theta_o(theta_o)); - - integer i,j,k; - real a_i,a_o,a_e; - real rx,ry,rex,rey; - - reg signed [`XY_BITS:0] ex,ey; - - reg signed [16:0] x [90:0]; - reg signed [16:0] y [90:0]; - reg signed [16:0] z [90:0]; - - task show_vector_results; - input integer j; - input [`THETA_BITS:0] theta; - begin - a_i = (j * 3.14) / 180; - a_o = theta; - a_o = a_o / 32768; - if (a_o > a_i) a_e = a_o - a_i; else a_e = a_i - a_o; - if (a_e > 0.001) - $display("angle %f computed %f error %f",a_i,a_o,a_o - a_i); - else - $display("angle %f computed %f",a_i,a_o); - end - endtask - - task show_rotate_results; - input integer j; - input [`XY_BITS:0] lx; - input [`XY_BITS:0] ly; - begin - rx = lx;// / 65535; - ry = ly;// / 65535; - rx = rx / 32768; //65535; - ry = ry / 32768; //65535; - if (lx > x[j]) ex = lx - x[j]; else ex = x[j] - lx; - if (ly > y[j]) ey = ly - y[j]; else ey = y[j] - ly; - if (ex > 10 || ey > 10) - $display("Angle: %d sin = %f cos = %f errors %d %d",j,ry,rx,ey,ex); - else - $display("Angle: %d sin = %f cos = %f",j,ry,rx); - end - endtask - - task show_results; - input integer j; - input [`XY_BITS:0] lx; - input [`XY_BITS:0] ly; - input [`THETA_BITS:0] ltheta; - begin -`ifdef VECTOR - show_vector_results(j,ltheta); -`endif -`ifdef ROTATE - show_rotate_results(j,lx,ly); -`endif - end - endtask - initial begin - $display("starting simulation"); -`ifdef PIPELINE - $display("PIPELINE configuration"); -`endif -`ifdef ITERATE - $display("ITERATE configuration"); -`endif -`ifdef COMBINATORIAL - $display("COMBINATORIAL configuration"); -`endif - - // The following table is computed for U(1,15) format numbers - // The angle data z[] is in radians - x[0] <= 17'd32768; y[0] <= 17'd0; z[0] <= 17'd0; - x[1] <= 17'd32763; y[1] <= 17'd571; z[1] <= 17'd571; - x[2] <= 17'd32748; y[2] <= 17'd1143; z[2] <= 17'd1143; - x[3] <= 17'd32723; y[3] <= 17'd1714; z[3] <= 17'd1715; - x[4] <= 17'd32688; y[4] <= 17'd2285; z[4] <= 17'd2287; - x[5] <= 17'd32643; y[5] <= 17'd2855; z[5] <= 17'd2859; - x[6] <= 17'd32588; y[6] <= 17'd3425; z[6] <= 17'd3431; - x[7] <= 17'd32523; y[7] <= 17'd3993; z[7] <= 17'd4003; - x[8] <= 17'd32449; y[8] <= 17'd4560; z[8] <= 17'd4575; - x[9] <= 17'd32364; y[9] <= 17'd5126; z[9] <= 17'd5147; - x[10] <= 17'd32270; y[10] <= 17'd5690; z[10] <= 17'd5719; - x[11] <= 17'd32165; y[11] <= 17'd6252; z[11] <= 17'd6291; - x[12] <= 17'd32051; y[12] <= 17'd6812; z[12] <= 17'd6862; - x[13] <= 17'd31928; y[13] <= 17'd7371; z[13] <= 17'd7434; - x[14] <= 17'd31794; y[14] <= 17'd7927; z[14] <= 17'd8006; - x[15] <= 17'd31651; y[15] <= 17'd8480; z[15] <= 17'd8578; - x[16] <= 17'd31498; y[16] <= 17'd9032; z[16] <= 17'd9150; - x[17] <= 17'd31336; y[17] <= 17'd9580; z[17] <= 17'd9722; - x[18] <= 17'd31164; y[18] <= 17'd10125; z[18] <= 17'd10294; - x[19] <= 17'd30982; y[19] <= 17'd10668; z[19] <= 17'd10866; - x[20] <= 17'd30791; y[20] <= 17'd11207; z[20] <= 17'd11438; - x[21] <= 17'd30591; y[21] <= 17'd11743; z[21] <= 17'd12010; - x[22] <= 17'd30381; y[22] <= 17'd12275; z[22] <= 17'd12582; - x[23] <= 17'd30163; y[23] <= 17'd12803; z[23] <= 17'd13153; - x[24] <= 17'd29935; y[24] <= 17'd13327; z[24] <= 17'd13725; - x[25] <= 17'd29697; y[25] <= 17'd13848; z[25] <= 17'd14297; - x[26] <= 17'd29451; y[26] <= 17'd14364; z[26] <= 17'd14869; - x[27] <= 17'd29196; y[27] <= 17'd14876; z[27] <= 17'd15441; - x[28] <= 17'd28932; y[28] <= 17'd15383; z[28] <= 17'd16013; - x[29] <= 17'd28659; y[29] <= 17'd15886; z[29] <= 17'd16585; - x[30] <= 17'd28377; y[30] <= 17'd16383; z[30] <= 17'd17157; - x[31] <= 17'd28087; y[31] <= 17'd16876; z[31] <= 17'd17729; - x[32] <= 17'd27788; y[32] <= 17'd17364; z[32] <= 17'd18301; - x[33] <= 17'd27481; y[33] <= 17'd17846; z[33] <= 17'd18873; - x[34] <= 17'd27165; y[34] <= 17'd18323; z[34] <= 17'd19444; - x[35] <= 17'd26841; y[35] <= 17'd18794; z[35] <= 17'd20016; - x[36] <= 17'd26509; y[36] <= 17'd19260; z[36] <= 17'd20588; - x[37] <= 17'd26169; y[37] <= 17'd19720; z[37] <= 17'd21160; - x[38] <= 17'd25821; y[38] <= 17'd20173; z[38] <= 17'd21732; - x[39] <= 17'd25465; y[39] <= 17'd20621; z[39] <= 17'd22304; - x[40] <= 17'd25101; y[40] <= 17'd21062; z[40] <= 17'd22876; - x[41] <= 17'd24730; y[41] <= 17'd21497; z[41] <= 17'd23448; - x[42] <= 17'd24351; y[42] <= 17'd21926; z[42] <= 17'd24020; - x[43] <= 17'd23964; y[43] <= 17'd22347; z[43] <= 17'd24592; - x[44] <= 17'd23571; y[44] <= 17'd22762; z[44] <= 17'd25164; - x[45] <= 17'd23170; y[45] <= 17'd23170; z[45] <= 17'd25735; - x[46] <= 17'd22762; y[46] <= 17'd23571; z[46] <= 17'd26307; - x[47] <= 17'd22347; y[47] <= 17'd23964; z[47] <= 17'd26879; - x[48] <= 17'd21926; y[48] <= 17'd24351; z[48] <= 17'd27451; - x[49] <= 17'd21497; y[49] <= 17'd24730; z[49] <= 17'd28023; - x[50] <= 17'd21062; y[50] <= 17'd25101; z[50] <= 17'd28595; - x[51] <= 17'd20621; y[51] <= 17'd25465; z[51] <= 17'd29167; - x[52] <= 17'd20173; y[52] <= 17'd25821; z[52] <= 17'd29739; - x[53] <= 17'd19720; y[53] <= 17'd26169; z[53] <= 17'd30311; - x[54] <= 17'd19260; y[54] <= 17'd26509; z[54] <= 17'd30883; - x[55] <= 17'd18794; y[55] <= 17'd26841; z[55] <= 17'd31455; - x[56] <= 17'd18323; y[56] <= 17'd27165; z[56] <= 17'd32026; - x[57] <= 17'd17846; y[57] <= 17'd27481; z[57] <= 17'd32598; - x[58] <= 17'd17364; y[58] <= 17'd27788; z[58] <= 17'd33170; - x[59] <= 17'd16876; y[59] <= 17'd28087; z[59] <= 17'd33742; - x[60] <= 17'd16384; y[60] <= 17'd28377; z[60] <= 17'd34314; - x[61] <= 17'd15886; y[61] <= 17'd28659; z[61] <= 17'd34886; - x[62] <= 17'd15383; y[62] <= 17'd28932; z[62] <= 17'd35458; - x[63] <= 17'd14876; y[63] <= 17'd29196; z[63] <= 17'd36030; - x[64] <= 17'd14364; y[64] <= 17'd29451; z[64] <= 17'd36602; - x[65] <= 17'd13848; y[65] <= 17'd29697; z[65] <= 17'd37174; - x[66] <= 17'd13327; y[66] <= 17'd29935; z[66] <= 17'd37746; - x[67] <= 17'd12803; y[67] <= 17'd30163; z[67] <= 17'd38317; - x[68] <= 17'd12275; y[68] <= 17'd30381; z[68] <= 17'd38889; - x[69] <= 17'd11743; y[69] <= 17'd30591; z[69] <= 17'd39461; - x[70] <= 17'd11207; y[70] <= 17'd30791; z[70] <= 17'd40033; - x[71] <= 17'd10668; y[71] <= 17'd30982; z[71] <= 17'd40605; - x[72] <= 17'd10125; y[72] <= 17'd31164; z[72] <= 17'd41177; - x[73] <= 17'd9580; y[73] <= 17'd31336; z[73] <= 17'd41749; - x[74] <= 17'd9032; y[74] <= 17'd31498; z[74] <= 17'd42321; - x[75] <= 17'd8480; y[75] <= 17'd31651; z[75] <= 17'd42893; - x[76] <= 17'd7927; y[76] <= 17'd31794; z[76] <= 17'd43465; - x[77] <= 17'd7371; y[77] <= 17'd31928; z[77] <= 17'd44037; - x[78] <= 17'd6812; y[78] <= 17'd32051; z[78] <= 17'd44608; - x[79] <= 17'd6252; y[79] <= 17'd32165; z[79] <= 17'd45180; - x[80] <= 17'd5690; y[80] <= 17'd32270; z[80] <= 17'd45752; - x[81] <= 17'd5126; y[81] <= 17'd32364; z[81] <= 17'd46324; - x[82] <= 17'd4560; y[82] <= 17'd32449; z[82] <= 17'd46896; - x[83] <= 17'd3993; y[83] <= 17'd32523; z[83] <= 17'd47468; - x[84] <= 17'd3425; y[84] <= 17'd32588; z[84] <= 17'd48040; - x[85] <= 17'd2855; y[85] <= 17'd32643; z[85] <= 17'd48612; - x[86] <= 17'd2285; y[86] <= 17'd32688; z[86] <= 17'd49184; - x[87] <= 17'd1714; y[87] <= 17'd32723; z[87] <= 17'd49756; - x[88] <= 17'd1143; y[88] <= 17'd32748; z[88] <= 17'd50328; - x[89] <= 17'd571; y[89] <= 17'd32763; z[89] <= 17'd50899; - x[90] <= 17'd0; y[90] <= 17'd32768; z[90] <= 17'd51471; - - clock <= 0; - init <= 0; - reset <= 1; - x_i <= 0; - y_i <= 0; - theta_i <= 0; - #1 clock <= 1; - #1 clock <= 0; - reset <= 0; - - for (j=0;j<=90;j = j+1) begin // test 91 different angles, 0 to 90 degrees -`ifdef ROTATE // compute sin and cos - x_i <= `CORDIC_1; - y_i <= 0; - theta_i <= z[j]; -`endif -`ifdef VECTOR // compute the arctan - x_i <= x[j]; - y_i <= y[j]; - theta_i <= 0; -`endif - - -`ifdef ITERATE - init <= 1; // load the value into the rotator - #1 clock <= 1; - #1 clock <= 0; - init <= 0; - for(i=0;i<`ITERATIONS;i = i+1) begin // iterate on the value - #1 clock <= 1; - #1 clock <= 0; - end - show_results(j,x_o,y_o,theta_o); -`endif - - -`ifdef COMBINATORIAL - #1; // give a little time to view the waveform... - show_results(j,x_o,y_o,theta_o); -`endif - -`ifdef PIPELINE - #1 clock <= 1; - #1 clock <= 0; - if (j >= (`ITERATIONS-2)) begin // wait until the results start popping out - show_results((j-(`ITERATIONS-2)),x_o,y_o,theta_o); - end - if (j == 90) // now flush the pipe - for(i=0;i<(`ITERATIONS-2);i = i+1) begin - #1 clock <= 1; - #1 clock <= 0; - show_results((90-`ITERATIONS+3+i),x_o,y_o,theta_o); - end -`endif - - - end - for(i=0;i<16;i=i+1) // dump a few extra clock just for grins - #1 clock <= ~clock; -end - -endmodule Index: trunk/manual.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/manual.pdf =================================================================== --- trunk/manual.pdf (revision 3) +++ trunk/manual.pdf (nonexistent)
trunk/manual.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/cordic.v =================================================================== --- trunk/cordic.v (revision 3) +++ trunk/cordic.v (nonexistent) @@ -1,379 +0,0 @@ -/* file: cordic.v - author: Dale Drinkard - release: 08/06/2008 - - brief: - - First Quadrant CORDIC - - This is a self contained, configurable CORDIC generator - The user can modify the `defines below to customize the code generation. - This code is for the first quadrant, but is easily extended to the full - circle by first doing a coarse rotation. For example, to compute the - arctan of -y/x, in the second quadrant, feed the cordic function y/x and - then add 90 degrees (or pi/2 if using radian mode) to the result. When - computing sin and cos of an angle, coarse rotate the angle into the first quadrant - by subtracting the appropriate number of 90 (or pi/2) increments to get the angle in - the first quadrant, keep track of this value, feed the cordic the angle. Then - simply change the sign of the results based on this stored number. - - To use the core comment/uncomment the `defines below. The user can change the number - of bits that represent the x,y, and theta values. The core can operate in either radian - or degree mode. - **NOTE** Even though there are allowances for changeing many parameters of the code, it is - strongly advised that the user understand the CORDIC algorythm before monkeying with these - settings. By default, the core uses 16+sign (17 bit) numbers for x,y, and theta, and iterates 16 - times in the algorythm. There are two arctan function tables,one for radian and one for degree - mode. If more iterations or higher precision calculations are desired then a new arctan table will - need to be computed. - - - The core will operate in one - of two modes: - - - ROTATE: In this mode the user supplies a X and Y cartesian vector and an angle. The - CORDIC rotator seeks to reduce the angle to zero by rotating the vector. - - To compute the cos and sin of the angle, set the inputs as follows: - - y_in = 0; - x_in = `CORDIC_1 - theta_in = the input angle - - on completion: - - y_out = sin - x_out = cos - - The `CORDIC_1 above is the inverse of the cordic gain... or ~0.603 - The input angle depends on whether you build in radian or degree mode - see the description of the `defines below. - - - VECTOR: In this mode the user supplies the tangent value in x and y and the rotator - seeks to minimize the y value, thus computing the angle. - - To compute the arctan set the inputs as follows - - y_in and x_in such that y/x = the tangent value for which you wish to find the angle - theta_in = 0; - - on completion - - theta_out = the angle - - - -*/ - -/* data valid flag - - The iterative CORDIC implementations take a predetermined number of clock cycles to complete - If the VALID_FLAG is defined the core instantiates a dvalid_in and dvalid_out signal. This - signal makes no sense in the COMBINATORIAL mode. -*/ -// `define VALID_FLAG - -/* Angle mode - - The CORDIC can work with the angle expressed in radians or degrees - Uncomment the appropriate `define below. - RADIAN_16 uses 16 bit values (+ sign bit for 17 bit accuracy). angle information - is in the format U(1,15) where bit 16 is the sign bit, bit 15 is the whole number part - and bits [14:0] are the fractional parts. - DEGREE_8_8 uses U(8,8) + a sign bit where bit 16 = the sign bit, [15:8] = the whole number part - and [7:0] = the fractional. - - The user can define other formats by creating a new tanangle function -*/ -// `define DEGREE_8_8 -`define RADIAN_16 - -/* Bit accuracy for sin and cos - - The X and Y values are computed using a `XY_BITS + sign bit accuracy. The format is assumed to be U(1,15) + sign bit - However, the CORDIC algorythm really doesn't care. -*/ -`define XY_BITS 16 - -/* Bit accuracy for theta - - The angle can be represented in either degree or radians. This define determines the number of bits used to represent the - angle. Going to a higher number of bits would allow more iterations thus improving accuracy. 16 bits is enough for - most applications. -*/ -`define THETA_BITS 16 - -/* Iteration accuracy - - This is the number of times the algorithm will iterate. For pipelined options, this is the number of stages. - This number is <= the number of bits used in the angles - -*/ -`define ITERATIONS 16 -`define ITERATION_BITS 4 // 2^ITERATION_BITS = ITERATIONS - -/* Implementation options - - The CORDIC core can be realized in one of three methods: - ITERATE: This option builds a single ROTATOR. The user provides the arguments and gives the core ITERATIONS - clock cycles to get the result. A signal named init is instantiated to load the input values. It uses the - least amount of LUTs - PIPELINE: This option can take a new input on every clock and gives results ITERATIONS clock cycles later. It uses the - most amount of LUTS. - COMBINATORIAL: This option gives a result in a single clock cycle at the expense of very deep logic levels. The - combinatorial implementation runs at about 10 mhz while the iterative ones run at about 125 in a - Lattice ECP2 device. -*/ -//`define ITERATE -`define PIPELINE -//`define COMBINATORIAL - -/* CORDIC function - The CORDIC core works in one of two methods: VECTOR and ROTATE. - VECTOR: This mode seeks to reduce the Y values and is used to compute an angle given a point. - Enter the sin and cos of the desired angle and the core calculates the angle. This - mode computes ARCTAN. - ROTATE: This mode seeks to reduce the angle. It can be used to compute the sin and cos of a given angle -*/ -//`define VECTOR // computes the arctan and square root - `define ROTATE // computes sin cos - - -/* CORDIC GAIN - The CORDIC algorithm has an associated gain that is: - - CORDIC_gain = for (i=0;i> 1) | (D[`XY_BITS] << `XY_BITS); - end -endmodule -/* Rotator - This module is the heart of the CORDIC computer and implements the CORDIC algorithm. - Input values x_i, y_i, and z_i are micro computed based on the iteration step - and the arctan of that step. See the description of the CORDIC algorithm for details. - -*/ -module rotator ( - input wire clk, - input wire rst, -`ifdef ITERATE - input wire init, - input wire [`ITERATION_BITS:0] iteration, - input wire signed [`THETA_BITS:0] tangle, -`endif - input wire signed [`XY_BITS:0] x_i, - input wire signed [`XY_BITS:0] y_i, - input wire signed [`THETA_BITS:0] z_i, - output wire signed [`XY_BITS:0] x_o, - output wire signed [`XY_BITS:0] y_o, - output wire signed [`THETA_BITS:0] z_o - ); - -`ifdef GENERATE_LOOP - parameter integer iteration = 0; - parameter signed [`THETA_BITS:0] tangle = 0; -`endif - reg signed [`XY_BITS:0] x_1; - reg signed [`XY_BITS:0] y_1; - reg signed [`THETA_BITS:0] z_1; - wire signed [`XY_BITS:0] x_i_shifted; - wire signed [`XY_BITS:0] y_i_shifted; - signed_shifter x_shifter(iteration,x_i,x_i_shifted); - signed_shifter y_shifter(iteration,y_i,y_i_shifted); -`ifdef COMBINATORIAL - always @ * -`endif -`ifdef ITERATE - always @ (posedge clk) -`endif -`ifdef PIPELINE - always @ (posedge clk) -`endif - if (rst) begin - x_1 <= 0; - y_1 <= 0; - z_1 <= 0; - end else begin -`ifdef ITERATE - if (init) begin - x_1 <= x_i; - y_1 <= y_i; - z_1 <= z_i; - end else -`endif -`ifdef ROTATE - if (z_i < 0) begin -`endif -`ifdef VECTOR - if (y_i > 0) begin -`endif - x_1 <= x_i + y_i_shifted; //shifter(y_1,i); //(y_1 >> i); - y_1 <= y_i - x_i_shifted; //shifter(x_1,i); //(x_1 >> i); - z_1 <= z_i + tangle; - end else begin - x_1 <= x_i - y_i_shifted; //shifter(y_1,i); //(y_1 >> i); - y_1 <= y_i + x_i_shifted; //shifter(x_1,i); //(x_1 >> i); - z_1 <= z_i - tangle; - end - end - assign x_o = x_1; - assign y_o = y_1; - assign z_o = z_1; -endmodule -/* - CORDIC - -*/ -module cordic ( - input wire clk, - input wire rst, -`ifdef ITERATE - input wire init, -`endif - input wire signed [`XY_BITS:0] x_i, - input wire signed [`XY_BITS:0] y_i, - input wire signed [`THETA_BITS:0] theta_i, - - output wire signed [`XY_BITS:0] x_o, - output wire signed [`XY_BITS:0] y_o, - output wire signed [`THETA_BITS:0] theta_o -`ifdef VALID_FLAG - ,input wire valid_in, output wire valid_out -`endif -); - -`ifdef RADIAN_16 -/* - arctan table in radian format 16 bit + sign bit. -*/ -function [`THETA_BITS:0] tanangle; - input [3:0] i; - begin - case (i) - 4'b0000: tanangle = 17'd25735 ; // 1/1 - 4'b0001: tanangle = 17'd15192; // 1/2 - 4'b0010: tanangle = 17'd8027; // 1/4 - 4'b0011: tanangle = 17'd4075; // 1/8 - 4'b0100: tanangle = 17'd2045; // 1/16 - 4'b0101: tanangle = 17'd1024; // 1/32 - 4'b0110: tanangle = 17'd512; // 1/64 - 4'b0111: tanangle = 17'd256; // 1/128 - 4'b1000: tanangle = 17'd128; // 1/256 - 4'b1001: tanangle = 17'd64; // 1/512 - 4'b1010: tanangle = 17'd32; // 1/1024 - 4'b1011: tanangle = 17'd16; // 1/2048 - 4'b1100: tanangle = 17'd8; // 1/4096 - 4'b1101: tanangle = 17'd4; // 1/8192 - 4'b1110: tanangle = 17'd2; // 1/16k - 4'b1111: tanangle = 17'd1; // 1/32k - endcase - end -endfunction -`endif -`ifdef DEGREE_8_8 -/* - arctan table in degree U(8,8) format 16 bits + sign bit -*/ -function [`THETA_BITS:0] tanangle; - input [3:0] i; - begin - case (i) - 0: tanangle = 17'd11520; // theta = 45.000000 - 1: tanangle = 17'd6800; // theta = 22.500000 - 2: tanangle = 17'd3593; // theta = 11.250000 - 3: tanangle = 17'd1824; // theta = 5.625000 - 4: tanangle = 17'd915; // theta = 2.812500 - 5: tanangle = 17'd458; // theta = 1.406250 - 6: tanangle = 17'd229; // theta = 0.703125 - 7: tanangle = 17'd114; // theta = 0.351562 - 8: tanangle = 17'd57; // theta = 0.175781 - 9: tanangle = 17'd28; // theta = 0.087891 - 10: tanangle = 17'd14; // theta = 0.043945 - 11: tanangle = 17'd7; // theta = 0.021973 - 12: tanangle = 17'd3; // theta = 0.010986 - 13: tanangle = 17'd1; // theta = 0.005493 - 14: tanangle = 17'd0; // theta = 0.002747 - 15: tanangle = 17'd0; // theta = 0.001373 - endcase - end -endfunction -`endif - -`ifdef GENERATE_LOOP - wire signed [`XY_BITS:0] x [`ITERATIONS-1:0]; - wire signed [`XY_BITS:0] y [`ITERATIONS-1:0]; - wire signed [`THETA_BITS:0] z [`ITERATIONS-1:0]; - assign x[0] = x_i; - assign y[0] = y_i; - assign z[0] = theta_i; - assign x_o = x[`ITERATIONS-1]; - assign y_o = y[`ITERATIONS-1]; - assign theta_o = z[`ITERATIONS-1]; -`endif // GENERATE_LOOP - -`ifdef VALID_FLAG - wire [`ITERATIONS-1:0] v; - assign valid_out v[`ITERATIONS-1]; -always @ (posedge clk or posedge rst) - if (rst) v <= 0; - else begin - v <= v << 1; - v[0] <= valid_in; - end -`endif - -`ifdef GENERATE_LOOP -genvar i; -generate for(i=0;i<`ITERATIONS-1;i=i+1) begin - rotator U (clk,rst,x[i],y[i],z[i],x[i+1],y[i+1],z[i+1]); - defparam U.iteration = i; - defparam U.tangle = tanangle(i); -end -endgenerate -`endif - -`ifdef ITERATE - reg [`ITERATION_BITS:0] iteration; - wire signed [`XY_BITS:0] x,y,z; - assign x = init ? x_i : x_o; - assign y = init ? y_i : y_o; - assign z = init ? theta_i : theta_o; - always @ (posedge clk or posedge init) - if (init) iteration <= 0; - else iteration <= iteration + 1; - rotator U (clk,rst,init,iteration,tanangle(iteration),x,y,z,x_o,y_o,theta_o); -`endif -endmodule - - Index: verilog_cordic_core/trunk/manual.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: verilog_cordic_core/trunk/manual.pdf =================================================================== --- verilog_cordic_core/trunk/manual.pdf (nonexistent) +++ verilog_cordic_core/trunk/manual.pdf (revision 4)
verilog_cordic_core/trunk/manual.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: verilog_cordic_core/trunk/cordic.v =================================================================== --- verilog_cordic_core/trunk/cordic.v (nonexistent) +++ verilog_cordic_core/trunk/cordic.v (revision 4) @@ -0,0 +1,379 @@ +/* file: cordic.v + author: Dale Drinkard + release: 08/06/2008 + + brief: + + First Quadrant CORDIC + + This is a self contained, configurable CORDIC generator + The user can modify the `defines below to customize the code generation. + This code is for the first quadrant, but is easily extended to the full + circle by first doing a coarse rotation. For example, to compute the + arctan of -y/x, in the second quadrant, feed the cordic function y/x and + then add 90 degrees (or pi/2 if using radian mode) to the result. When + computing sin and cos of an angle, coarse rotate the angle into the first quadrant + by subtracting the appropriate number of 90 (or pi/2) increments to get the angle in + the first quadrant, keep track of this value, feed the cordic the angle. Then + simply change the sign of the results based on this stored number. + + To use the core comment/uncomment the `defines below. The user can change the number + of bits that represent the x,y, and theta values. The core can operate in either radian + or degree mode. + **NOTE** Even though there are allowances for changeing many parameters of the code, it is + strongly advised that the user understand the CORDIC algorythm before monkeying with these + settings. By default, the core uses 16+sign (17 bit) numbers for x,y, and theta, and iterates 16 + times in the algorythm. There are two arctan function tables,one for radian and one for degree + mode. If more iterations or higher precision calculations are desired then a new arctan table will + need to be computed. + + + The core will operate in one + of two modes: + + + ROTATE: In this mode the user supplies a X and Y cartesian vector and an angle. The + CORDIC rotator seeks to reduce the angle to zero by rotating the vector. + + To compute the cos and sin of the angle, set the inputs as follows: + + y_in = 0; + x_in = `CORDIC_1 + theta_in = the input angle + + on completion: + + y_out = sin + x_out = cos + + The `CORDIC_1 above is the inverse of the cordic gain... or ~0.603 + The input angle depends on whether you build in radian or degree mode + see the description of the `defines below. + + + VECTOR: In this mode the user supplies the tangent value in x and y and the rotator + seeks to minimize the y value, thus computing the angle. + + To compute the arctan set the inputs as follows + + y_in and x_in such that y/x = the tangent value for which you wish to find the angle + theta_in = 0; + + on completion + + theta_out = the angle + + + +*/ + +/* data valid flag + + The iterative CORDIC implementations take a predetermined number of clock cycles to complete + If the VALID_FLAG is defined the core instantiates a dvalid_in and dvalid_out signal. This + signal makes no sense in the COMBINATORIAL mode. +*/ +// `define VALID_FLAG + +/* Angle mode + + The CORDIC can work with the angle expressed in radians or degrees + Uncomment the appropriate `define below. + RADIAN_16 uses 16 bit values (+ sign bit for 17 bit accuracy). angle information + is in the format U(1,15) where bit 16 is the sign bit, bit 15 is the whole number part + and bits [14:0] are the fractional parts. + DEGREE_8_8 uses U(8,8) + a sign bit where bit 16 = the sign bit, [15:8] = the whole number part + and [7:0] = the fractional. + + The user can define other formats by creating a new tanangle function +*/ +// `define DEGREE_8_8 +`define RADIAN_16 + +/* Bit accuracy for sin and cos + + The X and Y values are computed using a `XY_BITS + sign bit accuracy. The format is assumed to be U(1,15) + sign bit + However, the CORDIC algorythm really doesn't care. +*/ +`define XY_BITS 16 + +/* Bit accuracy for theta + + The angle can be represented in either degree or radians. This define determines the number of bits used to represent the + angle. Going to a higher number of bits would allow more iterations thus improving accuracy. 16 bits is enough for + most applications. +*/ +`define THETA_BITS 16 + +/* Iteration accuracy + + This is the number of times the algorithm will iterate. For pipelined options, this is the number of stages. + This number is <= the number of bits used in the angles + +*/ +`define ITERATIONS 16 +`define ITERATION_BITS 4 // 2^ITERATION_BITS = ITERATIONS + +/* Implementation options + + The CORDIC core can be realized in one of three methods: + ITERATE: This option builds a single ROTATOR. The user provides the arguments and gives the core ITERATIONS + clock cycles to get the result. A signal named init is instantiated to load the input values. It uses the + least amount of LUTs + PIPELINE: This option can take a new input on every clock and gives results ITERATIONS clock cycles later. It uses the + most amount of LUTS. + COMBINATORIAL: This option gives a result in a single clock cycle at the expense of very deep logic levels. The + combinatorial implementation runs at about 10 mhz while the iterative ones run at about 125 in a + Lattice ECP2 device. +*/ +//`define ITERATE +`define PIPELINE +//`define COMBINATORIAL + +/* CORDIC function + The CORDIC core works in one of two methods: VECTOR and ROTATE. + VECTOR: This mode seeks to reduce the Y values and is used to compute an angle given a point. + Enter the sin and cos of the desired angle and the core calculates the angle. This + mode computes ARCTAN. + ROTATE: This mode seeks to reduce the angle. It can be used to compute the sin and cos of a given angle +*/ +//`define VECTOR // computes the arctan and square root + `define ROTATE // computes sin cos + + +/* CORDIC GAIN + The CORDIC algorithm has an associated gain that is: + + CORDIC_gain = for (i=0;i> 1) | (D[`XY_BITS] << `XY_BITS); + end +endmodule +/* Rotator + This module is the heart of the CORDIC computer and implements the CORDIC algorithm. + Input values x_i, y_i, and z_i are micro computed based on the iteration step + and the arctan of that step. See the description of the CORDIC algorithm for details. + +*/ +module rotator ( + input wire clk, + input wire rst, +`ifdef ITERATE + input wire init, + input wire [`ITERATION_BITS:0] iteration, + input wire signed [`THETA_BITS:0] tangle, +`endif + input wire signed [`XY_BITS:0] x_i, + input wire signed [`XY_BITS:0] y_i, + input wire signed [`THETA_BITS:0] z_i, + output wire signed [`XY_BITS:0] x_o, + output wire signed [`XY_BITS:0] y_o, + output wire signed [`THETA_BITS:0] z_o + ); + +`ifdef GENERATE_LOOP + parameter integer iteration = 0; + parameter signed [`THETA_BITS:0] tangle = 0; +`endif + reg signed [`XY_BITS:0] x_1; + reg signed [`XY_BITS:0] y_1; + reg signed [`THETA_BITS:0] z_1; + wire signed [`XY_BITS:0] x_i_shifted; + wire signed [`XY_BITS:0] y_i_shifted; + signed_shifter x_shifter(iteration,x_i,x_i_shifted); + signed_shifter y_shifter(iteration,y_i,y_i_shifted); +`ifdef COMBINATORIAL + always @ * +`endif +`ifdef ITERATE + always @ (posedge clk) +`endif +`ifdef PIPELINE + always @ (posedge clk) +`endif + if (rst) begin + x_1 <= 0; + y_1 <= 0; + z_1 <= 0; + end else begin +`ifdef ITERATE + if (init) begin + x_1 <= x_i; + y_1 <= y_i; + z_1 <= z_i; + end else +`endif +`ifdef ROTATE + if (z_i < 0) begin +`endif +`ifdef VECTOR + if (y_i > 0) begin +`endif + x_1 <= x_i + y_i_shifted; //shifter(y_1,i); //(y_1 >> i); + y_1 <= y_i - x_i_shifted; //shifter(x_1,i); //(x_1 >> i); + z_1 <= z_i + tangle; + end else begin + x_1 <= x_i - y_i_shifted; //shifter(y_1,i); //(y_1 >> i); + y_1 <= y_i + x_i_shifted; //shifter(x_1,i); //(x_1 >> i); + z_1 <= z_i - tangle; + end + end + assign x_o = x_1; + assign y_o = y_1; + assign z_o = z_1; +endmodule +/* + CORDIC + +*/ +module cordic ( + input wire clk, + input wire rst, +`ifdef ITERATE + input wire init, +`endif + input wire signed [`XY_BITS:0] x_i, + input wire signed [`XY_BITS:0] y_i, + input wire signed [`THETA_BITS:0] theta_i, + + output wire signed [`XY_BITS:0] x_o, + output wire signed [`XY_BITS:0] y_o, + output wire signed [`THETA_BITS:0] theta_o +`ifdef VALID_FLAG + ,input wire valid_in, output wire valid_out +`endif +); + +`ifdef RADIAN_16 +/* + arctan table in radian format 16 bit + sign bit. +*/ +function [`THETA_BITS:0] tanangle; + input [3:0] i; + begin + case (i) + 4'b0000: tanangle = 17'd25735 ; // 1/1 + 4'b0001: tanangle = 17'd15192; // 1/2 + 4'b0010: tanangle = 17'd8027; // 1/4 + 4'b0011: tanangle = 17'd4075; // 1/8 + 4'b0100: tanangle = 17'd2045; // 1/16 + 4'b0101: tanangle = 17'd1024; // 1/32 + 4'b0110: tanangle = 17'd512; // 1/64 + 4'b0111: tanangle = 17'd256; // 1/128 + 4'b1000: tanangle = 17'd128; // 1/256 + 4'b1001: tanangle = 17'd64; // 1/512 + 4'b1010: tanangle = 17'd32; // 1/1024 + 4'b1011: tanangle = 17'd16; // 1/2048 + 4'b1100: tanangle = 17'd8; // 1/4096 + 4'b1101: tanangle = 17'd4; // 1/8192 + 4'b1110: tanangle = 17'd2; // 1/16k + 4'b1111: tanangle = 17'd1; // 1/32k + endcase + end +endfunction +`endif +`ifdef DEGREE_8_8 +/* + arctan table in degree U(8,8) format 16 bits + sign bit +*/ +function [`THETA_BITS:0] tanangle; + input [3:0] i; + begin + case (i) + 0: tanangle = 17'd11520; // theta = 45.000000 + 1: tanangle = 17'd6800; // theta = 22.500000 + 2: tanangle = 17'd3593; // theta = 11.250000 + 3: tanangle = 17'd1824; // theta = 5.625000 + 4: tanangle = 17'd915; // theta = 2.812500 + 5: tanangle = 17'd458; // theta = 1.406250 + 6: tanangle = 17'd229; // theta = 0.703125 + 7: tanangle = 17'd114; // theta = 0.351562 + 8: tanangle = 17'd57; // theta = 0.175781 + 9: tanangle = 17'd28; // theta = 0.087891 + 10: tanangle = 17'd14; // theta = 0.043945 + 11: tanangle = 17'd7; // theta = 0.021973 + 12: tanangle = 17'd3; // theta = 0.010986 + 13: tanangle = 17'd1; // theta = 0.005493 + 14: tanangle = 17'd0; // theta = 0.002747 + 15: tanangle = 17'd0; // theta = 0.001373 + endcase + end +endfunction +`endif + +`ifdef GENERATE_LOOP + wire signed [`XY_BITS:0] x [`ITERATIONS-1:0]; + wire signed [`XY_BITS:0] y [`ITERATIONS-1:0]; + wire signed [`THETA_BITS:0] z [`ITERATIONS-1:0]; + assign x[0] = x_i; + assign y[0] = y_i; + assign z[0] = theta_i; + assign x_o = x[`ITERATIONS-1]; + assign y_o = y[`ITERATIONS-1]; + assign theta_o = z[`ITERATIONS-1]; +`endif // GENERATE_LOOP + +`ifdef VALID_FLAG + wire [`ITERATIONS-1:0] v; + assign valid_out v[`ITERATIONS-1]; +always @ (posedge clk or posedge rst) + if (rst) v <= 0; + else begin + v <= v << 1; + v[0] <= valid_in; + end +`endif + +`ifdef GENERATE_LOOP +genvar i; +generate for(i=0;i<`ITERATIONS-1;i=i+1) begin + rotator U (clk,rst,x[i],y[i],z[i],x[i+1],y[i+1],z[i+1]); + defparam U.iteration = i; + defparam U.tangle = tanangle(i); +end +endgenerate +`endif + +`ifdef ITERATE + reg [`ITERATION_BITS:0] iteration; + wire signed [`XY_BITS:0] x,y,z; + assign x = init ? x_i : x_o; + assign y = init ? y_i : y_o; + assign z = init ? theta_i : theta_o; + always @ (posedge clk or posedge init) + if (init) iteration <= 0; + else iteration <= iteration + 1; + rotator U (clk,rst,init,iteration,tanangle(iteration),x,y,z,x_o,y_o,theta_o); +`endif +endmodule + + Index: verilog_cordic_core/trunk/tb_cordic.v =================================================================== --- verilog_cordic_core/trunk/tb_cordic.v (nonexistent) +++ verilog_cordic_core/trunk/tb_cordic.v (revision 4) @@ -0,0 +1,254 @@ +`timescale 1ns/1ns +/* + CORDIC testbench + + This testbench assumes the default settings for `defines + in the cordic.v file. If you change any of the defaults + you may have to make modifications to this file as well. + + This testbench uses `defines from the cordic.v file + make sure you have the `include path set correctly for your + environment. +*/ +`include "cordic.v" +module tb (); + + wire [`XY_BITS:0] x_o,y_o; + wire [`THETA_BITS:0] theta_o; + reg [`XY_BITS:0] x_i,y_i; + reg [`THETA_BITS:0] theta_i; // angle in radians + reg clock,reset; + reg init; + +cordic UUT (.clk(clock),.rst(reset), +`ifdef ITERATE + .init(init), +`endif + .x_i(x_i),.y_i(y_i),.theta_i(theta_i), + .x_o(x_o),.y_o(y_o),.theta_o(theta_o)); + + integer i,j,k; + real a_i,a_o,a_e; + real rx,ry,rex,rey; + + reg signed [`XY_BITS:0] ex,ey; + + reg signed [16:0] x [90:0]; + reg signed [16:0] y [90:0]; + reg signed [16:0] z [90:0]; + + task show_vector_results; + input integer j; + input [`THETA_BITS:0] theta; + begin + a_i = (j * 3.14) / 180; + a_o = theta; + a_o = a_o / 32768; + if (a_o > a_i) a_e = a_o - a_i; else a_e = a_i - a_o; + if (a_e > 0.001) + $display("angle %f computed %f error %f",a_i,a_o,a_o - a_i); + else + $display("angle %f computed %f",a_i,a_o); + end + endtask + + task show_rotate_results; + input integer j; + input [`XY_BITS:0] lx; + input [`XY_BITS:0] ly; + begin + rx = lx;// / 65535; + ry = ly;// / 65535; + rx = rx / 32768; //65535; + ry = ry / 32768; //65535; + if (lx > x[j]) ex = lx - x[j]; else ex = x[j] - lx; + if (ly > y[j]) ey = ly - y[j]; else ey = y[j] - ly; + if (ex > 10 || ey > 10) + $display("Angle: %d sin = %f cos = %f errors %d %d",j,ry,rx,ey,ex); + else + $display("Angle: %d sin = %f cos = %f",j,ry,rx); + end + endtask + + task show_results; + input integer j; + input [`XY_BITS:0] lx; + input [`XY_BITS:0] ly; + input [`THETA_BITS:0] ltheta; + begin +`ifdef VECTOR + show_vector_results(j,ltheta); +`endif +`ifdef ROTATE + show_rotate_results(j,lx,ly); +`endif + end + endtask + initial begin + $display("starting simulation"); +`ifdef PIPELINE + $display("PIPELINE configuration"); +`endif +`ifdef ITERATE + $display("ITERATE configuration"); +`endif +`ifdef COMBINATORIAL + $display("COMBINATORIAL configuration"); +`endif + + // The following table is computed for U(1,15) format numbers + // The angle data z[] is in radians + x[0] <= 17'd32768; y[0] <= 17'd0; z[0] <= 17'd0; + x[1] <= 17'd32763; y[1] <= 17'd571; z[1] <= 17'd571; + x[2] <= 17'd32748; y[2] <= 17'd1143; z[2] <= 17'd1143; + x[3] <= 17'd32723; y[3] <= 17'd1714; z[3] <= 17'd1715; + x[4] <= 17'd32688; y[4] <= 17'd2285; z[4] <= 17'd2287; + x[5] <= 17'd32643; y[5] <= 17'd2855; z[5] <= 17'd2859; + x[6] <= 17'd32588; y[6] <= 17'd3425; z[6] <= 17'd3431; + x[7] <= 17'd32523; y[7] <= 17'd3993; z[7] <= 17'd4003; + x[8] <= 17'd32449; y[8] <= 17'd4560; z[8] <= 17'd4575; + x[9] <= 17'd32364; y[9] <= 17'd5126; z[9] <= 17'd5147; + x[10] <= 17'd32270; y[10] <= 17'd5690; z[10] <= 17'd5719; + x[11] <= 17'd32165; y[11] <= 17'd6252; z[11] <= 17'd6291; + x[12] <= 17'd32051; y[12] <= 17'd6812; z[12] <= 17'd6862; + x[13] <= 17'd31928; y[13] <= 17'd7371; z[13] <= 17'd7434; + x[14] <= 17'd31794; y[14] <= 17'd7927; z[14] <= 17'd8006; + x[15] <= 17'd31651; y[15] <= 17'd8480; z[15] <= 17'd8578; + x[16] <= 17'd31498; y[16] <= 17'd9032; z[16] <= 17'd9150; + x[17] <= 17'd31336; y[17] <= 17'd9580; z[17] <= 17'd9722; + x[18] <= 17'd31164; y[18] <= 17'd10125; z[18] <= 17'd10294; + x[19] <= 17'd30982; y[19] <= 17'd10668; z[19] <= 17'd10866; + x[20] <= 17'd30791; y[20] <= 17'd11207; z[20] <= 17'd11438; + x[21] <= 17'd30591; y[21] <= 17'd11743; z[21] <= 17'd12010; + x[22] <= 17'd30381; y[22] <= 17'd12275; z[22] <= 17'd12582; + x[23] <= 17'd30163; y[23] <= 17'd12803; z[23] <= 17'd13153; + x[24] <= 17'd29935; y[24] <= 17'd13327; z[24] <= 17'd13725; + x[25] <= 17'd29697; y[25] <= 17'd13848; z[25] <= 17'd14297; + x[26] <= 17'd29451; y[26] <= 17'd14364; z[26] <= 17'd14869; + x[27] <= 17'd29196; y[27] <= 17'd14876; z[27] <= 17'd15441; + x[28] <= 17'd28932; y[28] <= 17'd15383; z[28] <= 17'd16013; + x[29] <= 17'd28659; y[29] <= 17'd15886; z[29] <= 17'd16585; + x[30] <= 17'd28377; y[30] <= 17'd16383; z[30] <= 17'd17157; + x[31] <= 17'd28087; y[31] <= 17'd16876; z[31] <= 17'd17729; + x[32] <= 17'd27788; y[32] <= 17'd17364; z[32] <= 17'd18301; + x[33] <= 17'd27481; y[33] <= 17'd17846; z[33] <= 17'd18873; + x[34] <= 17'd27165; y[34] <= 17'd18323; z[34] <= 17'd19444; + x[35] <= 17'd26841; y[35] <= 17'd18794; z[35] <= 17'd20016; + x[36] <= 17'd26509; y[36] <= 17'd19260; z[36] <= 17'd20588; + x[37] <= 17'd26169; y[37] <= 17'd19720; z[37] <= 17'd21160; + x[38] <= 17'd25821; y[38] <= 17'd20173; z[38] <= 17'd21732; + x[39] <= 17'd25465; y[39] <= 17'd20621; z[39] <= 17'd22304; + x[40] <= 17'd25101; y[40] <= 17'd21062; z[40] <= 17'd22876; + x[41] <= 17'd24730; y[41] <= 17'd21497; z[41] <= 17'd23448; + x[42] <= 17'd24351; y[42] <= 17'd21926; z[42] <= 17'd24020; + x[43] <= 17'd23964; y[43] <= 17'd22347; z[43] <= 17'd24592; + x[44] <= 17'd23571; y[44] <= 17'd22762; z[44] <= 17'd25164; + x[45] <= 17'd23170; y[45] <= 17'd23170; z[45] <= 17'd25735; + x[46] <= 17'd22762; y[46] <= 17'd23571; z[46] <= 17'd26307; + x[47] <= 17'd22347; y[47] <= 17'd23964; z[47] <= 17'd26879; + x[48] <= 17'd21926; y[48] <= 17'd24351; z[48] <= 17'd27451; + x[49] <= 17'd21497; y[49] <= 17'd24730; z[49] <= 17'd28023; + x[50] <= 17'd21062; y[50] <= 17'd25101; z[50] <= 17'd28595; + x[51] <= 17'd20621; y[51] <= 17'd25465; z[51] <= 17'd29167; + x[52] <= 17'd20173; y[52] <= 17'd25821; z[52] <= 17'd29739; + x[53] <= 17'd19720; y[53] <= 17'd26169; z[53] <= 17'd30311; + x[54] <= 17'd19260; y[54] <= 17'd26509; z[54] <= 17'd30883; + x[55] <= 17'd18794; y[55] <= 17'd26841; z[55] <= 17'd31455; + x[56] <= 17'd18323; y[56] <= 17'd27165; z[56] <= 17'd32026; + x[57] <= 17'd17846; y[57] <= 17'd27481; z[57] <= 17'd32598; + x[58] <= 17'd17364; y[58] <= 17'd27788; z[58] <= 17'd33170; + x[59] <= 17'd16876; y[59] <= 17'd28087; z[59] <= 17'd33742; + x[60] <= 17'd16384; y[60] <= 17'd28377; z[60] <= 17'd34314; + x[61] <= 17'd15886; y[61] <= 17'd28659; z[61] <= 17'd34886; + x[62] <= 17'd15383; y[62] <= 17'd28932; z[62] <= 17'd35458; + x[63] <= 17'd14876; y[63] <= 17'd29196; z[63] <= 17'd36030; + x[64] <= 17'd14364; y[64] <= 17'd29451; z[64] <= 17'd36602; + x[65] <= 17'd13848; y[65] <= 17'd29697; z[65] <= 17'd37174; + x[66] <= 17'd13327; y[66] <= 17'd29935; z[66] <= 17'd37746; + x[67] <= 17'd12803; y[67] <= 17'd30163; z[67] <= 17'd38317; + x[68] <= 17'd12275; y[68] <= 17'd30381; z[68] <= 17'd38889; + x[69] <= 17'd11743; y[69] <= 17'd30591; z[69] <= 17'd39461; + x[70] <= 17'd11207; y[70] <= 17'd30791; z[70] <= 17'd40033; + x[71] <= 17'd10668; y[71] <= 17'd30982; z[71] <= 17'd40605; + x[72] <= 17'd10125; y[72] <= 17'd31164; z[72] <= 17'd41177; + x[73] <= 17'd9580; y[73] <= 17'd31336; z[73] <= 17'd41749; + x[74] <= 17'd9032; y[74] <= 17'd31498; z[74] <= 17'd42321; + x[75] <= 17'd8480; y[75] <= 17'd31651; z[75] <= 17'd42893; + x[76] <= 17'd7927; y[76] <= 17'd31794; z[76] <= 17'd43465; + x[77] <= 17'd7371; y[77] <= 17'd31928; z[77] <= 17'd44037; + x[78] <= 17'd6812; y[78] <= 17'd32051; z[78] <= 17'd44608; + x[79] <= 17'd6252; y[79] <= 17'd32165; z[79] <= 17'd45180; + x[80] <= 17'd5690; y[80] <= 17'd32270; z[80] <= 17'd45752; + x[81] <= 17'd5126; y[81] <= 17'd32364; z[81] <= 17'd46324; + x[82] <= 17'd4560; y[82] <= 17'd32449; z[82] <= 17'd46896; + x[83] <= 17'd3993; y[83] <= 17'd32523; z[83] <= 17'd47468; + x[84] <= 17'd3425; y[84] <= 17'd32588; z[84] <= 17'd48040; + x[85] <= 17'd2855; y[85] <= 17'd32643; z[85] <= 17'd48612; + x[86] <= 17'd2285; y[86] <= 17'd32688; z[86] <= 17'd49184; + x[87] <= 17'd1714; y[87] <= 17'd32723; z[87] <= 17'd49756; + x[88] <= 17'd1143; y[88] <= 17'd32748; z[88] <= 17'd50328; + x[89] <= 17'd571; y[89] <= 17'd32763; z[89] <= 17'd50899; + x[90] <= 17'd0; y[90] <= 17'd32768; z[90] <= 17'd51471; + + clock <= 0; + init <= 0; + reset <= 1; + x_i <= 0; + y_i <= 0; + theta_i <= 0; + #1 clock <= 1; + #1 clock <= 0; + reset <= 0; + + for (j=0;j<=90;j = j+1) begin // test 91 different angles, 0 to 90 degrees +`ifdef ROTATE // compute sin and cos + x_i <= `CORDIC_1; + y_i <= 0; + theta_i <= z[j]; +`endif +`ifdef VECTOR // compute the arctan + x_i <= x[j]; + y_i <= y[j]; + theta_i <= 0; +`endif + + +`ifdef ITERATE + init <= 1; // load the value into the rotator + #1 clock <= 1; + #1 clock <= 0; + init <= 0; + for(i=0;i<`ITERATIONS;i = i+1) begin // iterate on the value + #1 clock <= 1; + #1 clock <= 0; + end + show_results(j,x_o,y_o,theta_o); +`endif + + +`ifdef COMBINATORIAL + #1; // give a little time to view the waveform... + show_results(j,x_o,y_o,theta_o); +`endif + +`ifdef PIPELINE + #1 clock <= 1; + #1 clock <= 0; + if (j >= (`ITERATIONS-2)) begin // wait until the results start popping out + show_results((j-(`ITERATIONS-2)),x_o,y_o,theta_o); + end + if (j == 90) // now flush the pipe + for(i=0;i<(`ITERATIONS-2);i = i+1) begin + #1 clock <= 1; + #1 clock <= 0; + show_results((90-`ITERATIONS+3+i),x_o,y_o,theta_o); + end +`endif + + + end + for(i=0;i<16;i=i+1) // dump a few extra clock just for grins + #1 clock <= ~clock; +end + +endmodule Index: verilog_cordic_core/trunk =================================================================== --- verilog_cordic_core/trunk (nonexistent) +++ verilog_cordic_core/trunk (revision 4)
verilog_cordic_core/trunk Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: verilog_cordic_core/web_uploads =================================================================== --- verilog_cordic_core/web_uploads (nonexistent) +++ verilog_cordic_core/web_uploads (revision 4)
verilog_cordic_core/web_uploads Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: verilog_cordic_core/branches =================================================================== --- verilog_cordic_core/branches (nonexistent) +++ verilog_cordic_core/branches (revision 4)
verilog_cordic_core/branches Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: verilog_cordic_core/tags/rel_1/manual.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: verilog_cordic_core/tags/rel_1/manual.pdf =================================================================== --- verilog_cordic_core/tags/rel_1/manual.pdf (nonexistent) +++ verilog_cordic_core/tags/rel_1/manual.pdf (revision 4)
verilog_cordic_core/tags/rel_1/manual.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: verilog_cordic_core/tags/rel_1/cordic.v =================================================================== --- verilog_cordic_core/tags/rel_1/cordic.v (nonexistent) +++ verilog_cordic_core/tags/rel_1/cordic.v (revision 4) @@ -0,0 +1,379 @@ +/* file: cordic.v + author: Dale Drinkard + release: 08/06/2008 + + brief: + + First Quadrant CORDIC + + This is a self contained, configurable CORDIC generator + The user can modify the `defines below to customize the code generation. + This code is for the first quadrant, but is easily extended to the full + circle by first doing a coarse rotation. For example, to compute the + arctan of -y/x, in the second quadrant, feed the cordic function y/x and + then add 90 degrees (or pi/2 if using radian mode) to the result. When + computing sin and cos of an angle, coarse rotate the angle into the first quadrant + by subtracting the appropriate number of 90 (or pi/2) increments to get the angle in + the first quadrant, keep track of this value, feed the cordic the angle. Then + simply change the sign of the results based on this stored number. + + To use the core comment/uncomment the `defines below. The user can change the number + of bits that represent the x,y, and theta values. The core can operate in either radian + or degree mode. + **NOTE** Even though there are allowances for changeing many parameters of the code, it is + strongly advised that the user understand the CORDIC algorythm before monkeying with these + settings. By default, the core uses 16+sign (17 bit) numbers for x,y, and theta, and iterates 16 + times in the algorythm. There are two arctan function tables,one for radian and one for degree + mode. If more iterations or higher precision calculations are desired then a new arctan table will + need to be computed. + + + The core will operate in one + of two modes: + + + ROTATE: In this mode the user supplies a X and Y cartesian vector and an angle. The + CORDIC rotator seeks to reduce the angle to zero by rotating the vector. + + To compute the cos and sin of the angle, set the inputs as follows: + + y_in = 0; + x_in = `CORDIC_1 + theta_in = the input angle + + on completion: + + y_out = sin + x_out = cos + + The `CORDIC_1 above is the inverse of the cordic gain... or ~0.603 + The input angle depends on whether you build in radian or degree mode + see the description of the `defines below. + + + VECTOR: In this mode the user supplies the tangent value in x and y and the rotator + seeks to minimize the y value, thus computing the angle. + + To compute the arctan set the inputs as follows + + y_in and x_in such that y/x = the tangent value for which you wish to find the angle + theta_in = 0; + + on completion + + theta_out = the angle + + + +*/ + +/* data valid flag + + The iterative CORDIC implementations take a predetermined number of clock cycles to complete + If the VALID_FLAG is defined the core instantiates a dvalid_in and dvalid_out signal. This + signal makes no sense in the COMBINATORIAL mode. +*/ +// `define VALID_FLAG + +/* Angle mode + + The CORDIC can work with the angle expressed in radians or degrees + Uncomment the appropriate `define below. + RADIAN_16 uses 16 bit values (+ sign bit for 17 bit accuracy). angle information + is in the format U(1,15) where bit 16 is the sign bit, bit 15 is the whole number part + and bits [14:0] are the fractional parts. + DEGREE_8_8 uses U(8,8) + a sign bit where bit 16 = the sign bit, [15:8] = the whole number part + and [7:0] = the fractional. + + The user can define other formats by creating a new tanangle function +*/ +// `define DEGREE_8_8 +`define RADIAN_16 + +/* Bit accuracy for sin and cos + + The X and Y values are computed using a `XY_BITS + sign bit accuracy. The format is assumed to be U(1,15) + sign bit + However, the CORDIC algorythm really doesn't care. +*/ +`define XY_BITS 16 + +/* Bit accuracy for theta + + The angle can be represented in either degree or radians. This define determines the number of bits used to represent the + angle. Going to a higher number of bits would allow more iterations thus improving accuracy. 16 bits is enough for + most applications. +*/ +`define THETA_BITS 16 + +/* Iteration accuracy + + This is the number of times the algorithm will iterate. For pipelined options, this is the number of stages. + This number is <= the number of bits used in the angles + +*/ +`define ITERATIONS 16 +`define ITERATION_BITS 4 // 2^ITERATION_BITS = ITERATIONS + +/* Implementation options + + The CORDIC core can be realized in one of three methods: + ITERATE: This option builds a single ROTATOR. The user provides the arguments and gives the core ITERATIONS + clock cycles to get the result. A signal named init is instantiated to load the input values. It uses the + least amount of LUTs + PIPELINE: This option can take a new input on every clock and gives results ITERATIONS clock cycles later. It uses the + most amount of LUTS. + COMBINATORIAL: This option gives a result in a single clock cycle at the expense of very deep logic levels. The + combinatorial implementation runs at about 10 mhz while the iterative ones run at about 125 in a + Lattice ECP2 device. +*/ +//`define ITERATE +`define PIPELINE +//`define COMBINATORIAL + +/* CORDIC function + The CORDIC core works in one of two methods: VECTOR and ROTATE. + VECTOR: This mode seeks to reduce the Y values and is used to compute an angle given a point. + Enter the sin and cos of the desired angle and the core calculates the angle. This + mode computes ARCTAN. + ROTATE: This mode seeks to reduce the angle. It can be used to compute the sin and cos of a given angle +*/ +//`define VECTOR // computes the arctan and square root + `define ROTATE // computes sin cos + + +/* CORDIC GAIN + The CORDIC algorithm has an associated gain that is: + + CORDIC_gain = for (i=0;i> 1) | (D[`XY_BITS] << `XY_BITS); + end +endmodule +/* Rotator + This module is the heart of the CORDIC computer and implements the CORDIC algorithm. + Input values x_i, y_i, and z_i are micro computed based on the iteration step + and the arctan of that step. See the description of the CORDIC algorithm for details. + +*/ +module rotator ( + input wire clk, + input wire rst, +`ifdef ITERATE + input wire init, + input wire [`ITERATION_BITS:0] iteration, + input wire signed [`THETA_BITS:0] tangle, +`endif + input wire signed [`XY_BITS:0] x_i, + input wire signed [`XY_BITS:0] y_i, + input wire signed [`THETA_BITS:0] z_i, + output wire signed [`XY_BITS:0] x_o, + output wire signed [`XY_BITS:0] y_o, + output wire signed [`THETA_BITS:0] z_o + ); + +`ifdef GENERATE_LOOP + parameter integer iteration = 0; + parameter signed [`THETA_BITS:0] tangle = 0; +`endif + reg signed [`XY_BITS:0] x_1; + reg signed [`XY_BITS:0] y_1; + reg signed [`THETA_BITS:0] z_1; + wire signed [`XY_BITS:0] x_i_shifted; + wire signed [`XY_BITS:0] y_i_shifted; + signed_shifter x_shifter(iteration,x_i,x_i_shifted); + signed_shifter y_shifter(iteration,y_i,y_i_shifted); +`ifdef COMBINATORIAL + always @ * +`endif +`ifdef ITERATE + always @ (posedge clk) +`endif +`ifdef PIPELINE + always @ (posedge clk) +`endif + if (rst) begin + x_1 <= 0; + y_1 <= 0; + z_1 <= 0; + end else begin +`ifdef ITERATE + if (init) begin + x_1 <= x_i; + y_1 <= y_i; + z_1 <= z_i; + end else +`endif +`ifdef ROTATE + if (z_i < 0) begin +`endif +`ifdef VECTOR + if (y_i > 0) begin +`endif + x_1 <= x_i + y_i_shifted; //shifter(y_1,i); //(y_1 >> i); + y_1 <= y_i - x_i_shifted; //shifter(x_1,i); //(x_1 >> i); + z_1 <= z_i + tangle; + end else begin + x_1 <= x_i - y_i_shifted; //shifter(y_1,i); //(y_1 >> i); + y_1 <= y_i + x_i_shifted; //shifter(x_1,i); //(x_1 >> i); + z_1 <= z_i - tangle; + end + end + assign x_o = x_1; + assign y_o = y_1; + assign z_o = z_1; +endmodule +/* + CORDIC + +*/ +module cordic ( + input wire clk, + input wire rst, +`ifdef ITERATE + input wire init, +`endif + input wire signed [`XY_BITS:0] x_i, + input wire signed [`XY_BITS:0] y_i, + input wire signed [`THETA_BITS:0] theta_i, + + output wire signed [`XY_BITS:0] x_o, + output wire signed [`XY_BITS:0] y_o, + output wire signed [`THETA_BITS:0] theta_o +`ifdef VALID_FLAG + ,input wire valid_in, output wire valid_out +`endif +); + +`ifdef RADIAN_16 +/* + arctan table in radian format 16 bit + sign bit. +*/ +function [`THETA_BITS:0] tanangle; + input [3:0] i; + begin + case (i) + 4'b0000: tanangle = 17'd25735 ; // 1/1 + 4'b0001: tanangle = 17'd15192; // 1/2 + 4'b0010: tanangle = 17'd8027; // 1/4 + 4'b0011: tanangle = 17'd4075; // 1/8 + 4'b0100: tanangle = 17'd2045; // 1/16 + 4'b0101: tanangle = 17'd1024; // 1/32 + 4'b0110: tanangle = 17'd512; // 1/64 + 4'b0111: tanangle = 17'd256; // 1/128 + 4'b1000: tanangle = 17'd128; // 1/256 + 4'b1001: tanangle = 17'd64; // 1/512 + 4'b1010: tanangle = 17'd32; // 1/1024 + 4'b1011: tanangle = 17'd16; // 1/2048 + 4'b1100: tanangle = 17'd8; // 1/4096 + 4'b1101: tanangle = 17'd4; // 1/8192 + 4'b1110: tanangle = 17'd2; // 1/16k + 4'b1111: tanangle = 17'd1; // 1/32k + endcase + end +endfunction +`endif +`ifdef DEGREE_8_8 +/* + arctan table in degree U(8,8) format 16 bits + sign bit +*/ +function [`THETA_BITS:0] tanangle; + input [3:0] i; + begin + case (i) + 0: tanangle = 17'd11520; // theta = 45.000000 + 1: tanangle = 17'd6800; // theta = 22.500000 + 2: tanangle = 17'd3593; // theta = 11.250000 + 3: tanangle = 17'd1824; // theta = 5.625000 + 4: tanangle = 17'd915; // theta = 2.812500 + 5: tanangle = 17'd458; // theta = 1.406250 + 6: tanangle = 17'd229; // theta = 0.703125 + 7: tanangle = 17'd114; // theta = 0.351562 + 8: tanangle = 17'd57; // theta = 0.175781 + 9: tanangle = 17'd28; // theta = 0.087891 + 10: tanangle = 17'd14; // theta = 0.043945 + 11: tanangle = 17'd7; // theta = 0.021973 + 12: tanangle = 17'd3; // theta = 0.010986 + 13: tanangle = 17'd1; // theta = 0.005493 + 14: tanangle = 17'd0; // theta = 0.002747 + 15: tanangle = 17'd0; // theta = 0.001373 + endcase + end +endfunction +`endif + +`ifdef GENERATE_LOOP + wire signed [`XY_BITS:0] x [`ITERATIONS-1:0]; + wire signed [`XY_BITS:0] y [`ITERATIONS-1:0]; + wire signed [`THETA_BITS:0] z [`ITERATIONS-1:0]; + assign x[0] = x_i; + assign y[0] = y_i; + assign z[0] = theta_i; + assign x_o = x[`ITERATIONS-1]; + assign y_o = y[`ITERATIONS-1]; + assign theta_o = z[`ITERATIONS-1]; +`endif // GENERATE_LOOP + +`ifdef VALID_FLAG + wire [`ITERATIONS-1:0] v; + assign valid_out v[`ITERATIONS-1]; +always @ (posedge clk or posedge rst) + if (rst) v <= 0; + else begin + v <= v << 1; + v[0] <= valid_in; + end +`endif + +`ifdef GENERATE_LOOP +genvar i; +generate for(i=0;i<`ITERATIONS-1;i=i+1) begin + rotator U (clk,rst,x[i],y[i],z[i],x[i+1],y[i+1],z[i+1]); + defparam U.iteration = i; + defparam U.tangle = tanangle(i); +end +endgenerate +`endif + +`ifdef ITERATE + reg [`ITERATION_BITS:0] iteration; + wire signed [`XY_BITS:0] x,y,z; + assign x = init ? x_i : x_o; + assign y = init ? y_i : y_o; + assign z = init ? theta_i : theta_o; + always @ (posedge clk or posedge init) + if (init) iteration <= 0; + else iteration <= iteration + 1; + rotator U (clk,rst,init,iteration,tanangle(iteration),x,y,z,x_o,y_o,theta_o); +`endif +endmodule + + Index: verilog_cordic_core/tags/rel_1/tb_cordic.v =================================================================== --- verilog_cordic_core/tags/rel_1/tb_cordic.v (nonexistent) +++ verilog_cordic_core/tags/rel_1/tb_cordic.v (revision 4) @@ -0,0 +1,254 @@ +`timescale 1ns/1ns +/* + CORDIC testbench + + This testbench assumes the default settings for `defines + in the cordic.v file. If you change any of the defaults + you may have to make modifications to this file as well. + + This testbench uses `defines from the cordic.v file + make sure you have the `include path set correctly for your + environment. +*/ +`include "cordic.v" +module tb (); + + wire [`XY_BITS:0] x_o,y_o; + wire [`THETA_BITS:0] theta_o; + reg [`XY_BITS:0] x_i,y_i; + reg [`THETA_BITS:0] theta_i; // angle in radians + reg clock,reset; + reg init; + +cordic UUT (.clk(clock),.rst(reset), +`ifdef ITERATE + .init(init), +`endif + .x_i(x_i),.y_i(y_i),.theta_i(theta_i), + .x_o(x_o),.y_o(y_o),.theta_o(theta_o)); + + integer i,j,k; + real a_i,a_o,a_e; + real rx,ry,rex,rey; + + reg signed [`XY_BITS:0] ex,ey; + + reg signed [16:0] x [90:0]; + reg signed [16:0] y [90:0]; + reg signed [16:0] z [90:0]; + + task show_vector_results; + input integer j; + input [`THETA_BITS:0] theta; + begin + a_i = (j * 3.14) / 180; + a_o = theta; + a_o = a_o / 32768; + if (a_o > a_i) a_e = a_o - a_i; else a_e = a_i - a_o; + if (a_e > 0.001) + $display("angle %f computed %f error %f",a_i,a_o,a_o - a_i); + else + $display("angle %f computed %f",a_i,a_o); + end + endtask + + task show_rotate_results; + input integer j; + input [`XY_BITS:0] lx; + input [`XY_BITS:0] ly; + begin + rx = lx;// / 65535; + ry = ly;// / 65535; + rx = rx / 32768; //65535; + ry = ry / 32768; //65535; + if (lx > x[j]) ex = lx - x[j]; else ex = x[j] - lx; + if (ly > y[j]) ey = ly - y[j]; else ey = y[j] - ly; + if (ex > 10 || ey > 10) + $display("Angle: %d sin = %f cos = %f errors %d %d",j,ry,rx,ey,ex); + else + $display("Angle: %d sin = %f cos = %f",j,ry,rx); + end + endtask + + task show_results; + input integer j; + input [`XY_BITS:0] lx; + input [`XY_BITS:0] ly; + input [`THETA_BITS:0] ltheta; + begin +`ifdef VECTOR + show_vector_results(j,ltheta); +`endif +`ifdef ROTATE + show_rotate_results(j,lx,ly); +`endif + end + endtask + initial begin + $display("starting simulation"); +`ifdef PIPELINE + $display("PIPELINE configuration"); +`endif +`ifdef ITERATE + $display("ITERATE configuration"); +`endif +`ifdef COMBINATORIAL + $display("COMBINATORIAL configuration"); +`endif + + // The following table is computed for U(1,15) format numbers + // The angle data z[] is in radians + x[0] <= 17'd32768; y[0] <= 17'd0; z[0] <= 17'd0; + x[1] <= 17'd32763; y[1] <= 17'd571; z[1] <= 17'd571; + x[2] <= 17'd32748; y[2] <= 17'd1143; z[2] <= 17'd1143; + x[3] <= 17'd32723; y[3] <= 17'd1714; z[3] <= 17'd1715; + x[4] <= 17'd32688; y[4] <= 17'd2285; z[4] <= 17'd2287; + x[5] <= 17'd32643; y[5] <= 17'd2855; z[5] <= 17'd2859; + x[6] <= 17'd32588; y[6] <= 17'd3425; z[6] <= 17'd3431; + x[7] <= 17'd32523; y[7] <= 17'd3993; z[7] <= 17'd4003; + x[8] <= 17'd32449; y[8] <= 17'd4560; z[8] <= 17'd4575; + x[9] <= 17'd32364; y[9] <= 17'd5126; z[9] <= 17'd5147; + x[10] <= 17'd32270; y[10] <= 17'd5690; z[10] <= 17'd5719; + x[11] <= 17'd32165; y[11] <= 17'd6252; z[11] <= 17'd6291; + x[12] <= 17'd32051; y[12] <= 17'd6812; z[12] <= 17'd6862; + x[13] <= 17'd31928; y[13] <= 17'd7371; z[13] <= 17'd7434; + x[14] <= 17'd31794; y[14] <= 17'd7927; z[14] <= 17'd8006; + x[15] <= 17'd31651; y[15] <= 17'd8480; z[15] <= 17'd8578; + x[16] <= 17'd31498; y[16] <= 17'd9032; z[16] <= 17'd9150; + x[17] <= 17'd31336; y[17] <= 17'd9580; z[17] <= 17'd9722; + x[18] <= 17'd31164; y[18] <= 17'd10125; z[18] <= 17'd10294; + x[19] <= 17'd30982; y[19] <= 17'd10668; z[19] <= 17'd10866; + x[20] <= 17'd30791; y[20] <= 17'd11207; z[20] <= 17'd11438; + x[21] <= 17'd30591; y[21] <= 17'd11743; z[21] <= 17'd12010; + x[22] <= 17'd30381; y[22] <= 17'd12275; z[22] <= 17'd12582; + x[23] <= 17'd30163; y[23] <= 17'd12803; z[23] <= 17'd13153; + x[24] <= 17'd29935; y[24] <= 17'd13327; z[24] <= 17'd13725; + x[25] <= 17'd29697; y[25] <= 17'd13848; z[25] <= 17'd14297; + x[26] <= 17'd29451; y[26] <= 17'd14364; z[26] <= 17'd14869; + x[27] <= 17'd29196; y[27] <= 17'd14876; z[27] <= 17'd15441; + x[28] <= 17'd28932; y[28] <= 17'd15383; z[28] <= 17'd16013; + x[29] <= 17'd28659; y[29] <= 17'd15886; z[29] <= 17'd16585; + x[30] <= 17'd28377; y[30] <= 17'd16383; z[30] <= 17'd17157; + x[31] <= 17'd28087; y[31] <= 17'd16876; z[31] <= 17'd17729; + x[32] <= 17'd27788; y[32] <= 17'd17364; z[32] <= 17'd18301; + x[33] <= 17'd27481; y[33] <= 17'd17846; z[33] <= 17'd18873; + x[34] <= 17'd27165; y[34] <= 17'd18323; z[34] <= 17'd19444; + x[35] <= 17'd26841; y[35] <= 17'd18794; z[35] <= 17'd20016; + x[36] <= 17'd26509; y[36] <= 17'd19260; z[36] <= 17'd20588; + x[37] <= 17'd26169; y[37] <= 17'd19720; z[37] <= 17'd21160; + x[38] <= 17'd25821; y[38] <= 17'd20173; z[38] <= 17'd21732; + x[39] <= 17'd25465; y[39] <= 17'd20621; z[39] <= 17'd22304; + x[40] <= 17'd25101; y[40] <= 17'd21062; z[40] <= 17'd22876; + x[41] <= 17'd24730; y[41] <= 17'd21497; z[41] <= 17'd23448; + x[42] <= 17'd24351; y[42] <= 17'd21926; z[42] <= 17'd24020; + x[43] <= 17'd23964; y[43] <= 17'd22347; z[43] <= 17'd24592; + x[44] <= 17'd23571; y[44] <= 17'd22762; z[44] <= 17'd25164; + x[45] <= 17'd23170; y[45] <= 17'd23170; z[45] <= 17'd25735; + x[46] <= 17'd22762; y[46] <= 17'd23571; z[46] <= 17'd26307; + x[47] <= 17'd22347; y[47] <= 17'd23964; z[47] <= 17'd26879; + x[48] <= 17'd21926; y[48] <= 17'd24351; z[48] <= 17'd27451; + x[49] <= 17'd21497; y[49] <= 17'd24730; z[49] <= 17'd28023; + x[50] <= 17'd21062; y[50] <= 17'd25101; z[50] <= 17'd28595; + x[51] <= 17'd20621; y[51] <= 17'd25465; z[51] <= 17'd29167; + x[52] <= 17'd20173; y[52] <= 17'd25821; z[52] <= 17'd29739; + x[53] <= 17'd19720; y[53] <= 17'd26169; z[53] <= 17'd30311; + x[54] <= 17'd19260; y[54] <= 17'd26509; z[54] <= 17'd30883; + x[55] <= 17'd18794; y[55] <= 17'd26841; z[55] <= 17'd31455; + x[56] <= 17'd18323; y[56] <= 17'd27165; z[56] <= 17'd32026; + x[57] <= 17'd17846; y[57] <= 17'd27481; z[57] <= 17'd32598; + x[58] <= 17'd17364; y[58] <= 17'd27788; z[58] <= 17'd33170; + x[59] <= 17'd16876; y[59] <= 17'd28087; z[59] <= 17'd33742; + x[60] <= 17'd16384; y[60] <= 17'd28377; z[60] <= 17'd34314; + x[61] <= 17'd15886; y[61] <= 17'd28659; z[61] <= 17'd34886; + x[62] <= 17'd15383; y[62] <= 17'd28932; z[62] <= 17'd35458; + x[63] <= 17'd14876; y[63] <= 17'd29196; z[63] <= 17'd36030; + x[64] <= 17'd14364; y[64] <= 17'd29451; z[64] <= 17'd36602; + x[65] <= 17'd13848; y[65] <= 17'd29697; z[65] <= 17'd37174; + x[66] <= 17'd13327; y[66] <= 17'd29935; z[66] <= 17'd37746; + x[67] <= 17'd12803; y[67] <= 17'd30163; z[67] <= 17'd38317; + x[68] <= 17'd12275; y[68] <= 17'd30381; z[68] <= 17'd38889; + x[69] <= 17'd11743; y[69] <= 17'd30591; z[69] <= 17'd39461; + x[70] <= 17'd11207; y[70] <= 17'd30791; z[70] <= 17'd40033; + x[71] <= 17'd10668; y[71] <= 17'd30982; z[71] <= 17'd40605; + x[72] <= 17'd10125; y[72] <= 17'd31164; z[72] <= 17'd41177; + x[73] <= 17'd9580; y[73] <= 17'd31336; z[73] <= 17'd41749; + x[74] <= 17'd9032; y[74] <= 17'd31498; z[74] <= 17'd42321; + x[75] <= 17'd8480; y[75] <= 17'd31651; z[75] <= 17'd42893; + x[76] <= 17'd7927; y[76] <= 17'd31794; z[76] <= 17'd43465; + x[77] <= 17'd7371; y[77] <= 17'd31928; z[77] <= 17'd44037; + x[78] <= 17'd6812; y[78] <= 17'd32051; z[78] <= 17'd44608; + x[79] <= 17'd6252; y[79] <= 17'd32165; z[79] <= 17'd45180; + x[80] <= 17'd5690; y[80] <= 17'd32270; z[80] <= 17'd45752; + x[81] <= 17'd5126; y[81] <= 17'd32364; z[81] <= 17'd46324; + x[82] <= 17'd4560; y[82] <= 17'd32449; z[82] <= 17'd46896; + x[83] <= 17'd3993; y[83] <= 17'd32523; z[83] <= 17'd47468; + x[84] <= 17'd3425; y[84] <= 17'd32588; z[84] <= 17'd48040; + x[85] <= 17'd2855; y[85] <= 17'd32643; z[85] <= 17'd48612; + x[86] <= 17'd2285; y[86] <= 17'd32688; z[86] <= 17'd49184; + x[87] <= 17'd1714; y[87] <= 17'd32723; z[87] <= 17'd49756; + x[88] <= 17'd1143; y[88] <= 17'd32748; z[88] <= 17'd50328; + x[89] <= 17'd571; y[89] <= 17'd32763; z[89] <= 17'd50899; + x[90] <= 17'd0; y[90] <= 17'd32768; z[90] <= 17'd51471; + + clock <= 0; + init <= 0; + reset <= 1; + x_i <= 0; + y_i <= 0; + theta_i <= 0; + #1 clock <= 1; + #1 clock <= 0; + reset <= 0; + + for (j=0;j<=90;j = j+1) begin // test 91 different angles, 0 to 90 degrees +`ifdef ROTATE // compute sin and cos + x_i <= `CORDIC_1; + y_i <= 0; + theta_i <= z[j]; +`endif +`ifdef VECTOR // compute the arctan + x_i <= x[j]; + y_i <= y[j]; + theta_i <= 0; +`endif + + +`ifdef ITERATE + init <= 1; // load the value into the rotator + #1 clock <= 1; + #1 clock <= 0; + init <= 0; + for(i=0;i<`ITERATIONS;i = i+1) begin // iterate on the value + #1 clock <= 1; + #1 clock <= 0; + end + show_results(j,x_o,y_o,theta_o); +`endif + + +`ifdef COMBINATORIAL + #1; // give a little time to view the waveform... + show_results(j,x_o,y_o,theta_o); +`endif + +`ifdef PIPELINE + #1 clock <= 1; + #1 clock <= 0; + if (j >= (`ITERATIONS-2)) begin // wait until the results start popping out + show_results((j-(`ITERATIONS-2)),x_o,y_o,theta_o); + end + if (j == 90) // now flush the pipe + for(i=0;i<(`ITERATIONS-2);i = i+1) begin + #1 clock <= 1; + #1 clock <= 0; + show_results((90-`ITERATIONS+3+i),x_o,y_o,theta_o); + end +`endif + + + end + for(i=0;i<16;i=i+1) // dump a few extra clock just for grins + #1 clock <= ~clock; +end + +endmodule Index: verilog_cordic_core/tags =================================================================== --- verilog_cordic_core/tags (nonexistent) +++ verilog_cordic_core/tags (revision 4)
verilog_cordic_core/tags Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ##

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.