+ Post New Thread
Page 1 of 2 1 2 LastLast
Results 1 to 20 of 27
  1. #1
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Cordic Algorithm Question

    Hi,

    I am implementing CORDIC algorithm.

    The source code could be found at https://www.edaplayground.com/x/3tHk or below:

    I have some problem with the look up table 'arctan' in the code. My fraction representation could be incorrect for the calculation of z[i+1].

    Could anyone help ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    module cordic(z0, xn, yn);
      
      input [6:0] z0;
      output [6:0] xn, yn;
     
      parameter N= 40; // number of iterations
      
      reg [(N-1):0] d;
      reg [(N-1):0] x, y, z, arctan [(N-1):0];
     
      initial begin
          arctan[0] = 1;
     
          for(integer j=0; j<(N-1); j=j+1)
          begin
              arctan[j+1] = arctan[j] >> (j+1);
          end
      end
     
      always @(*)
      begin
          for(integer i=0; i<N; i=i+1)
          begin
            d[i] = (z[i]<0) ? -1 : 1;
     
            x[i+1] = x[i] - y[i]*d[i] >> i;
            y[i+1] = y[i] + x[i]*d[i] >> i;
            z[i+1] = z[i] - d[i]*arctan[i];
          end
      end
     
      assign x[0] = 0.6073;
      assign y[0] = 0;
      assign z[0] = z0;
     
      assign xn = x[N-1]; // xn = cos(z0)
      assign yn = y[N-1]; // yn = sin(z0)
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    `timescale 1ns/100ps
     
    module cordic_tb;
     
      reg [6:0] z0, xn, yn;
     
      cordic C1
      (
          .z0(z0), .xn(xn), .yn(yn)
      );
     
      initial begin
          $dumpfile("cordic.vcd");
          $dumpvars(0, cordic_tb);
     
          z0 = 30; 
     
          #20 $finish;
      end
     
    endmodule

    •   Alt13th May 2017, 07:45

      advertising

        
       

  2. #2
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    I have modified the code accordingly after cross-checking with the octave code. However, why y[2] == 0 ?

    i= 0, x[i]=10011011011101001, y[i]=00000000000000000, z[i]=0000000000000000011110, d[i]= 0, arctan[i]=0000000000000000101101
    i= 1, x[i]=10011011011101001, y[i]=10011011011101001, z[i]=1111111111111111110001, d[i]= 1, arctan[i]=0000000000000000011011
    i= 2, x[i]=00011011011101001, y[i]=00000000000000000, z[i]=0000000000000000001100, d[i]= 0, arctan[i]=0000000000000000001110
    i= 3, x[i]=00000110110111010, y[i]=00000110110111010, z[i]=1111111111111111111110, d[i]= 1, arctan[i]=0000000000000000000111
    i= 4, x[i]=00000001101101110, y[i]=00000000000000000, z[i]=0000000000000000000101, d[i]= 0, arctan[i]=0000000000000000000100
    i= 5, x[i]=00000000000110110, y[i]=00000000000110110, z[i]=0000000000000000000001, d[i]= 0, arctan[i]=0000000000000000000010
    i= 6, x[i]=00000000000000000, y[i]=00000000000000011, z[i]=1111111111111111111111, d[i]= 1, arctan[i]=0000000000000000000001
    i= 7, x[i]=00000000000000000, y[i]=00000000000000000, z[i]=0000000000000000000000, d[i]= 0, arctan[i]=0000000000000000000000
    i= 8, x[i]=00000000000000000, y[i]=00000000000000000, z[i]=0000000000000000000000, d[i]= 0, arctan[i]=0000000000000000000000
    i= 9, x[i]=00000000000000000, y[i]=00000000000000000, z[i]=0000000000000000000000, d[i]= 0, arctan[i]=0000000000000000000000
    Done
    Code:
    function [ Co,Si] = Cordic( De0 )
    De0=input('De0=')
    Co0=0.60725;
    Si0=0;
    Cos_ar=[];
    Sin_ar=[];
    De_ar=[];
    Cos_ar(1)=Co0;
    Sin_ar(1)=Si0;
    De_ar(1)=De0;
    i=1;
    while(1)
    tj=2.^-(i-1);
    phi=atand(tj);
    if(De_ar(i)>=0)
        D=1;
    else
        D=-1;
    end
        De_ar(i+1)=De_ar(i)-D*phi;
        Cos_ar(i+1)=Cos_ar(i)-D*tj.*Sin_ar(i);
        Sin_ar(i+1)=Sin_ar(i)+D*tj.*Cos_ar(i);
        Co=Cos_ar(i);
        Si=Sin_ar(i);
        A=cosd(De0);
        B=sind(De0);
        if(abs(B-Si)<0.0001 && abs(A-Co)<0.0001)
            break
        end
        i=i+1;
    end
    
    Cosde=cosd(De0)
    Sinde=sind(De0)
    Co
    Si
    i
    end
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    
    module cordic(z0, xn, yn);
      
      input [21:0] z0;
      output [16:0] xn, yn;
     
      parameter N= 10; // number of iterations
      
      reg [(N-1):0] d;
      reg [16:0] x [(N-1):0];
      reg [16:0] y [(N-1):0];
      reg [21:0] z [(N-1):0];
      reg [21:0] arctan [(N-1):0];
     
      initial begin 
        
        x[0] = 'b10011011011101001;  // 0.60725 in binary
        y[0] = 0;
     
        arctan[0] = 45.0;
        arctan[1] = 26.6;
        arctan[2] = 14.0;
        arctan[3] =  7.1;
        arctan[4] =  3.6;
        arctan[5] =  1.8;
        arctan[6] =  0.9;
        arctan[7] =  0.4;
        arctan[8] =  0.2;
        arctan[9] =  0.1;
      end
     
      integer i;
     
      always @(*)
        begin       z[0] = z0;
          for(i=0; i<N; i=i+1)
          begin
            d[i] = (z[i][16] == 0) ? 0 : 1;
     
            if(d[i] == 0) begin
              x[i+1] = x[i] - y[i] >> i;
              y[i+1] = y[i] + x[i] >> i;
              z[i+1] = z[i] - arctan[i];
            end
            
            else begin
              x[i+1] = x[i] + y[i] >> i;
              y[i+1] = y[i] - x[i] >> i;
              z[i+1] = z[i] + arctan[i];
            end
            
            $display("i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b", i,x[i],y[i],z[i],d[i],arctan[i]);
          end
      end
     
      assign xn = x[N-1]; // xn = cos(z0)
      assign yn = y[N-1]; // yn = sin(z0)
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    `timescale 1ns/100ps
     
    module cordic_tb;
     
      reg[21:0] z0;
      wire[16:0] xn, yn;
     
    cordic C1
    (
        .z0(z0), .xn(xn), .yn(yn)
    );
     
    initial begin
        $dumpfile("cordic.vcd");
        $dumpvars(0, cordic_tb);
     
        #10 z0 = 30; 
    end
     
    endmodule



  3. #3
    Super Moderator
    Points: 236,483, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    40,894
    Helped
    12497 / 12497
    Points
    236,483
    Level
    100

    Re: Cordic Algorithm Question

    You apparently realized that
    Code:
    assign x[0] = 0.6073;
    makes no sense.

    But you are still assigning real values to unsigned arctan[] array, keeping only the integer part, as the variable dump shows. Need to think about a suitable fractional number representation.



  4. #4
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    Thanks FvM.

    However, my focus now is not on fractional representation of that arctan array since they are being approximated by simulator. I will however take extra care of the arctan array when I am done with the logic flow of the algorithm.

    By the way, do you have any idea why y[2] == 0 ?



  5. #5
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    I have solved the bugs. Lines 40, 41, 46 and 47 have to be written in the following manner:

    x[i+1] = x[i] - (y[i] >>> i);

    Now, when I move on to pipelined version of the same logic, I face problem with d and z. https://www.edaplayground.com/x/4ymA

    I have a feeling that the pipeline structure that I am using is not right. Could anyone advise ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    
    module cordic_pipelined(clk, z0, xn, yn);
      
      input clk;
      input [21:0] z0;
      output [16:0] xn, yn;
     
      parameter N= 10; // number of iterations
      
      reg d;
      reg [16:0] x, x_next;
      reg [16:0] y, y_next;
      reg [21:0] z, z_next;
      reg [21:0] arctan [(N-1):0];
     
      integer i, i_next;
      
      initial begin 
        
        x = 'b10011011011101001;  // 0.60725 in binary
        y = 0;
        
        i = 0;
        i_next = 0;
        
        arctan[0] = 45.0;
        arctan[1] = 26.6;
        arctan[2] = 14.0;
        arctan[3] =  7.1;
        arctan[4] =  3.6;
        arctan[5] =  1.8;
        arctan[6] =  0.9;
        arctan[7] =  0.4;
        arctan[8] =  0.2;
        arctan[9] =  0.1;
      end
     
      always @ (posedge clk)
        begin
          x <= x_next;
          y <= y_next;
          z <= z_next;
      
          i <= i_next;
        end
     
      always @(*)
        begin    z = z0;
     
            d = (z[21] == 0) ? 0 : 1;
     
            if(d == 0) begin
              x_next = x - (y >>> i);
              y_next = y + (x >>> i);
              z_next = z - arctan[i];
            end
            
            else begin
              x_next = x + (y >>> i);
              y_next = y - (x >>> i);
              z_next = z + arctan[i];
            end
            
          if (i<(N-1))
            i_next = i + 1;
          
          $display("i=%2d, x=%b, y=%b, z=%b, z_next=%b, d=%2d, arctan[i]=%b", i,x,y,z,z_next,d,arctan[i]);
     
      end
     
      assign xn = x; // xn = cos(z0)
      assign yn = y; // yn = sin(z0)
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    `timescale 1ns/100ps
     
    module cordic_pipelined_tb;
     
      reg clk;
      reg[21:0] z0;
      wire[16:0] xn, yn;
     
      cordic_pipelined C1
      (
        .clk(clk), .z0(z0), .xn(xn), .yn(yn)
      );
     
      initial begin
        $dumpfile("cordic_pipelined.vcd");
        $dumpvars(0, cordic_pipelined_tb);
        
        clk = 0;
         z0 = 45; 
        #120 $finish;
      end
      
      always #5 clk = !clk;
     
    endmodule



  6. #6
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    You can't put real numbers into a reg:
    Code:
        x = 'b10011011011101001;  // 0.60725 in binary
        y = 0;
        
        i = 0;
        i_next = 0;
        
        arctan[0] = 45.0;
        arctan[1] = 26.6;
        arctan[2] = 14.0;
        arctan[3] =  7.1;
        arctan[4] =  3.6;
        arctan[5] =  1.8;
        arctan[6] =  0.9;
        arctan[7] =  0.4;
        arctan[8] =  0.2;
        arctan[9] =  0.1;
    this will result in the following arctan[0] thru arctan[9] values:
    Code:
        arctan[0] = 22'd45;
        arctan[1] = 22'd26;
        arctan[2] = 22'd14;
        arctan[3] =  22'd7;
        arctan[4] =  22'd3;
        arctan[5] =  22'd1;
        arctan[6] =  22'd0;
        arctan[7] =  22'd0;
        arctan[8] =  22'd0;
        arctan[9] =  22'd0;
    x is 17 bits and the arctan values should be 17-bit fractional values if you want your decimal points to like up so, arctan should have values like so:
    Code:
    arctan[4] = 22'h073333;
    ...
    arctan[8] = 22'h006666;
    arctan[9] = 22'h003333;
    and currently your edaplayground code shows:
    Code:
        arctan[0] = 'b101101_0000; // 45.0;
        arctan[1] = 'b011010_1001; // 26.6;
        arctan[2] = 'b001110_0000; // 14.0;
        arctan[3] = 'b000111_0001; // 7.1;
        arctan[4] = 'b000011_1001; // 3.6;
        arctan[5] = 'b000001_1100; // 1.8;
        arctan[6] = 'b000000_1110; // 0.9;
        arctan[7] = 'b000000_0110; // 0.4;
        arctan[8] = 'b000000_0011; // 0.2;
        arctan[9] = 'b000000_0001; // 0.1;
    which is wrong, .1 cannot be represented in binary as 'b00000_0001



  7. #7
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    ads-ee,

    Why 0.1 cannot be represented in binary as 'b00000_0001 ?

    I have updated the pure combinatorial circuit code version at https://www.edaplayground.com/x/449A or below:

    Although it works for me, I suspect there are still some bugs around z0, z and arctan. Could you advise ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    
    module cordic(z0, xn, yn);
      
      input  [10:0] z0;
      output  [16:0] xn, yn;
     
      parameter N= 10; // number of iterations
      
      reg [(N-1):0] d;
      reg  [16:0] x [(N-1):0];
      reg  [16:0] y [(N-1):0];
      reg  [10:0] z [(N-1):0];
      reg  [10:0] arctan [(N-1):0];
     
      initial begin
        
        x[0] = 'b010011011011101001;  // 0.60725 in binary
        y[0] = 0;
     
        arctan[0] = 'b010_1101_0000; // 45.0;
        arctan[1] = 'b001_1010_1001; // 26.6;
        arctan[2] = 'b000_1110_0000; // 14.0;
        arctan[3] = 'b000_0111_0001; // 7.1;
        arctan[4] = 'b000_0011_1001; // 3.6;
        arctan[5] = 'b000_0001_1100; // 1.8;
        arctan[6] = 'b000_0000_1110; // 0.9;
        arctan[7] = 'b000_0000_0110; // 0.4;
        arctan[8] = 'b000_0000_0011; // 0.2;
        arctan[9] = 'b000_0000_0001; // 0.1;
      end
     
      integer i;
     
      always @(*)
        begin       z[0] = z0;
          for(i=0; i<N; i=i+1)
          begin
            d[i] = (z[i][10] == 0) ? 0 : 1;
     
            if(d[i] == 0) begin
              x[i+1] = x[i] - ((y[i]) >> i);
              y[i+1] = y[i] + ((x[i]) >> i);
              z[i+1] = z[i] - arctan[i];
            end
            
            else begin
              x[i+1] = x[i] + ((y[i]) >> i);
              y[i+1] = y[i] - ((x[i]) >> i);
              z[i+1] = z[i] + arctan[i];
            end
            
            $display("i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b", i,x[i],y[i],z[i],d[i],arctan[i]);
          end
      end
     
      assign xn = x[N-1]; // xn = cos(z0)
      assign yn = y[N-1]; // yn = sin(z0)
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    `timescale 1ns/100ps
     
    module cordic_tb;
     
      reg  [10:0] z0;
      wire  [16:0] xn, yn;
     
    cordic C1
    (
        .z0(z0), .xn(xn), .yn(yn)
    );
     
    initial begin
        $dumpfile("cordic.vcd");
        $dumpvars(0, cordic_tb);
     
        #10 z0 = 10'b010_1101_0000; 
    end
     
    endmodule



  8. #8
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    Quote Originally Posted by promach View Post
    ads-ee,

    Why 0.1 cannot be represented in binary as 'b00000_0001 ?
    If you think that can be done then why do you have x = 'b10011011011101001; // 0.60725 in binary

    There isn't any consistency between the two representations.

    Maybe you should learn how fractions are represented in binary, or do you plan on making your own math library for your special numeric representation. You'll have to have all the functions +, -, x, /, etc all as instantiated components to do such a thing as the synthesis tools use the representation I gave for binary fractions.



  9. #9
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    ads-ee:

    Thanks. I understand how fraction is represented now.

    I have implemented three versions of the cordic algorithm:

    Combinatorial: https://www.edaplayground.com/x/449A
    Clocked: https://www.edaplayground.com/x/4MQN
    Pipelined: https://www.edaplayground.com/x/4ymA

    I am trying to fix some unknown states (z[i]=xxxxxxxxxxx) on three code versions before synthesis. Once successful synthesis and hardware testing, I will upload directly source code of all three versions in this thread.

    Why would RHS of https://www.diffchecker.com/9YTcSxXK generate unknown state (z[i]=xxxxxxxxxxx) while LHS would not ?

    Click image for larger version. 

Name:	Screenshot from 2017-05-17 00-33-24.png 
Views:	2 
Size:	157.3 KB 
ID:	138795



  10. #10
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    Because the right side code will only perform the z[0]=z0 once initially and your testbench only sets z0 at #10 so it's always X prior to that. Besides that since the assignment is inside the initial block z[0] isn't even logically connected to the z0 input. The left sets z[0] on every rising edge of the clock, so it eventually gets set to the constant at #10 in the testbench. If you want z[0] to be CONNECTED to z0 then you can use assign z[0] = z0; or do the assignment inside a always @* block to keep z[0] as a reg type.

    Using initial blocks to set constants (and assigning inputs to internal logic) in Verilog is wrong. You should make all the constants parameter or localparm and get rid of the initial block. IMO initial blocks do not belong in synthesizable code and if you have them you can't port the code to an ASIC and expect it to work as ASIC tools ignore synthesis of initial blocks.

    I don't think you really understand Verilog very well. You should read the LRM or a Verilog book not an online tutorial. Nearly all the online tutorials are terrible or inaccurate.



    •   Alt16th May 2017, 18:55

      advertising

        
       

  11. #11
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    Thanks. I am reading on parameter now since I have the following problem.

    https://www.edaplayground.com/x/449A

    I have "error: syntax error in parameter list." for the following line #15:

    parameter [10:0] arctan [9:0] =
    {
    11'b000_0000_0001, 11'b000_0000_0011, 11'b000_0000_0110, 11'b000_0000_1110, 11'b000_0001_1100,
    11'b000_0011_1001, 11'b000_0111_0001, 11'b000_1110_0000, 11'b001_1010_1001, 11'b010_1101_0000
    };

    vcs does not detect such syntax error, but iverilog does ? Why ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    
    `timescale 1ns/100ps
     
    module cordic(z0, xn, yn);
      
      input [10:0] z0;
      output [16:0] xn, yn;
     
      parameter N= 10; // number of iterations
      
      reg [(N-1):0] d;
      reg [16:0] x [N:0];
      reg [16:0] y [N:0];
      reg [10:0] z [N:0];
     
      parameter [10:0] arctan [9:0] =
      {
        11'b000_0000_0001, 11'b000_0000_0011, 11'b000_0000_0110, 11'b000_0000_1110, 11'b000_0001_1100,
        11'b000_0011_1001, 11'b000_0111_0001, 11'b000_1110_0000, 11'b001_1010_1001, 11'b010_1101_0000
      };  
        
        /*
        arctan[0] = 'b010_1101_0000; // 45.0;
        arctan[1] = 'b001_1010_1001; // 26.6;
        arctan[2] = 'b000_1110_0000; // 14.0;
        arctan[3] = 'b000_0111_0001; // 7.1;
        arctan[4] = 'b000_0011_1001; // 3.6;
        arctan[5] = 'b000_0001_1100; // 1.8;
        arctan[6] = 'b000_0000_1110; // 0.9;
        arctan[7] = 'b000_0000_0110; // 0.4;
        arctan[8] = 'b000_0000_0011; // 0.2;
        arctan[9] = 'b000_0000_0001; // 0.1;
        */
     
      assign x[0] = 'b0_10011_0110_1110_1001;  // 0.60725 in binary
      assign y[0] = 0;
      assign z[0] = z0;
      
      integer i;
     
      always @(*)
        begin       
          
          for(i=0; i<N; i=i+1)
          begin
            d[i] = (z[i][10] == 0) ? 0 : 1;
     
            if(d[i] == 0) begin
              x[i+1] = x[i] - (y[i] >> i);
              y[i+1] = y[i] + (x[i] >> i);
              z[i+1] = z[i] - arctan[i];
            end
            
            else begin
              x[i+1] = x[i] + (y[i] >> i);
              y[i+1] = y[i] - (x[i] >> i);
              z[i+1] = z[i] + arctan[i];
            end
            
            $display("i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b", i,x[i],y[i],z[i],d[i],arctan[i]);
          end
      end
     
      assign xn = x[N]; // xn = cos(z0)
      assign yn = y[N]; // yn = sin(z0)
     
    endmodule



  12. #12
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    I have solved the above problem.

    It was found that pure verilog does not allow parameter array, while systemverilog allows.

    I am planning to design the cordic algorithm in multi-cycle implementation.

    Is it possible ?
    If yes, how many states would it have ?



  13. #13
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    ads-ee:

    Could I consider the following as multi-cycle design ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    
    module cordic_clocked(clk, rst, z0, xn, yn);
      
      input clk, rst;
      input [10:0] z0;
      output [16:0] xn, yn;
     
      parameter N= 10; // number of iterations
      
      reg [(N-1):0] d;
      reg [16:0] x [N:0];
      reg [16:0] y [N:0];
      reg [10:0] z [N:0];
      wire [10:0] arctan [(N-1):0]; 
        
      assign arctan[0] = 'b010_1101_0000; // 45.0;
      assign arctan[1] = 'b001_1010_1001; // 26.6;
      assign arctan[2] = 'b000_1110_0000; // 14.0;
      assign arctan[3] = 'b000_0111_0001; // 7.1;
      assign arctan[4] = 'b000_0011_1001; // 3.6;
      assign arctan[5] = 'b000_0001_1100; // 1.8;
      assign arctan[6] = 'b000_0000_1110; // 0.9;
      assign arctan[7] = 'b000_0000_0110; // 0.4;
      assign arctan[8] = 'b000_0000_0011; // 0.2;
      assign arctan[9] = 'b000_0000_0001; // 0.1;
     
      reg [3:0] i;
     
      always @(posedge clk)
        begin       
          if(rst) begin
            x[0] <= 'b0_10011_0110_1110_1001;  // 0.60725 in binary
            y[0] <= 0;
            z[0] <= z0;
            i <= 0;
          end
          
          else begin
            d[i] = (z[i][10] == 0) ? 0 : 1;
     
            if(d[i] == 0) begin
              x[i+1] <= x[i] - (y[i] >> i);
              y[i+1] <= y[i] + (x[i] >> i);
              z[i+1] <= z[i] - arctan[i];
            end
            
            else begin
              x[i+1] <= x[i] + (y[i] >> i);
              y[i+1] <= y[i] - (x[i] >> i);
              z[i+1] <= z[i] + arctan[i];
            end
            
            i <= i + 1;
          end  
          
          $display("rst=%1b, i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b",rst, i,x[i],y[i],z[i],d[i],arctan[i]);
     
      end
     
      assign xn = x[N]; // xn = cos(z0)
      assign yn = y[N]; // yn = sin(z0)
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    `timescale 1ns/100ps
     
    module cordic_clocked_tb;
     
      reg clk, rst;
      reg [10:0] z0;
      wire [16:0] xn, yn;
     
      cordic_clocked C1
      (
        .clk(clk), .rst(rst), .z0(z0), .xn(xn), .yn(yn)
      );
     
      initial begin
        $dumpfile("cordic_clocked.vcd");
        $dumpvars(0, cordic_clocked_tb);
        
        rst = 1;
        clk = 0;
        z0 = 11'b010_1101_0000; 
     
        #10 rst = 0;
        #100 $finish;
      end
     
      always #5 clk = !clk;
      
    endmodule



  14. #14
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    I'm not sure you understand that a multicycle design isn't just a design that is pipelined. It is a design that allows multiple clock cycles before an operation completes. The outputs of the first set or registers holds unchanged over two or more clocks cycles and the next register caputures the result at the end of those clock cycles. This is usually done by including an enable in the design.



  15. #15
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    ads-ee: Regarding the multi-cycle design, let me do it again.

    I have two long questions which I will split into two posts.

    A) https://www.edaplayground.com/x/449A

    I am trying to capture xn=x[i] into a text file named "cos_out.txt". Same applies to yn and zn.

    There should be 10 entries in the text file.
    However, I am only getting only a single xn in the text file, which is the value of x[9] in the last iteration.

    Any advice ?

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    
    `timescale 1ns/100ps
     
    module cordic(z0, xn, yn, zn);
      
      input [10:0] z0;
      output reg [16:0] xn, yn;
      output reg [10:0] zn;
     
      parameter N= 10; // number of iterations
      
      reg [(N-1):0] d;
      reg [16:0] x [(N-1):0];
      reg [16:0] y [(N-1):0];
      reg [10:0] z [(N-1):0];
     
      wire [10:0] arctan [(N-1):0];
        
        
      assign arctan[0] = 'b010_1101_0000; // 45.0;
      assign arctan[1] = 'b001_1010_1001; // 26.6;
      assign arctan[2] = 'b000_1110_0000; // 14.0;
      assign arctan[3] = 'b000_0111_0001; // 7.1;
      assign arctan[4] = 'b000_0011_1001; // 3.6;
      assign arctan[5] = 'b000_0001_1100; // 1.8;
      assign arctan[6] = 'b000_0000_1110; // 0.9;
      assign arctan[7] = 'b000_0000_0110; // 0.4;
      assign arctan[8] = 'b000_0000_0011; // 0.2;
      assign arctan[9] = 'b000_0000_0001; // 0.1;
      
      integer i;
     
      always @(*)
        begin       
          x[0] = 'b0_10011_0110_1110_1001;  // 0.60725 in binary
          y[0] = 0;
          z[0] = z0;
          
          for(i=0; i<N; i=i+1)
          begin
            d[i] = (z[i][10] == 0) ? 0 : 1;
     
            if(d[i] == 0) begin
              x[i+1] = x[i] - (y[i] >> i);
              y[i+1] = y[i] + (x[i] >> i);
              z[i+1] = z[i] - arctan[i];
            end
            
            else begin
              x[i+1] = x[i] + (y[i] >> i);
              y[i+1] = y[i] - (x[i] >> i);
              z[i+1] = z[i] + arctan[i];
            end
     
            xn = x[i]; // xn = cos(z0)
            yn = y[i]; // yn = sin(z0)
            zn = z[i];
            
            $display("i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b", i,x[i],y[i],z[i],d[i],arctan[i]);
          end
      end
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    `timescale 1ns/100ps
     
    module cordic_tb;
     
      parameter N= 10; // number of iterations
      
      reg [10:0] z0;
      wire [16:0] xn, yn;
      wire [10:0] zn;
     
      // file operators
      integer I_out, Q_out, Z_out;
      
      cordic C1
      (
        .z0(z0), .xn(xn), .yn(yn), .zn(zn)
      );
     
      initial begin
        $dumpfile("cordic.vcd");
        $dumpvars(0, cordic_tb);
     
        I_out = $fopen("cos_out.txt", "w");     // Output file for debugging
        Q_out = $fopen("sin_out.txt", "w");     // Output file for debugging
        Z_out = $fopen("angle_out.txt", "w"); // Output file for debugging
        
        z0 = 11'b010_1101_0000; // 45 degrees
        #100
        $fclose(I_out);
        $fclose(Q_out);
        $fclose(Z_out);
        
        #10 $finish;
      end
      
      always @(xn, yn, zn)
        begin
          $fwrite(I_out, "%d\n", xn);
          $fwrite(Q_out, "%d\n", yn);
          $fwrite(Z_out, "%d\n", zn);
        end
      
    endmodule

    - - - Updated - - -

    B) https://www.edaplayground.com/x/4ymA

    I have some problem debugging unknown states (xxxxxxxxx) in between pipeline stages.

    I understand it takes time to fill in the pipeline slots for x_o, y_o and z_o, but it should only be one clock cycle, right ? The verbose simulation output does not align with the observation of continuous xxxxxxxx states across stages. Any help ?

    [2017-05-18 03:06:02 EDT] iverilog '-Wall' 'cordic_stage.v' design.sv testbench.sv && unbuffer vvp a.out
    VCD info: dumpfile cordic_pipelined.vcd opened for output.
    i= 0, x_i=10011011011101001, y_i=00000000000000000, z_i=01011010000, x_next=10011011011101001, y_next=10011011011101001, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=01011010000
    i= 1, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00110101001
    i= 2, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00011100000
    i= 3, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00001110001
    i= 4, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000111001
    i= 5, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000011100
    i= 6, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000001110
    i= 7, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000110
    i= 8, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000011
    i= 9, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000001
    i= 0, x_i=10011011011101001, y_i=00000000000000000, z_i=01011010000, x_next=10011011011101001, y_next=10011011011101001, z_next=00000000000, x_o=10011011011101001, y_o=10011011011101001, z_o=00000000000, d= 0, arctan[i]=01011010000
    i= 1, x_i=10011011011101001, y_i=10011011011101001, z_i=00000000000, x_next=01001101101110101, y_next=11101001001011101, z_next=11001010111, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=00110101001
    i= 1, x_i=10011011011101001, y_i=10011011011101001, z_i=00000000000, x_next=01001101101110101, y_next=11101001001011101, z_next=11001010111, x_o=01001101101110101, y_o=11101001001011101, z_o=11001010111, d= 0, arctan[i]=00110101001
    i= 2, x_i=01001101101110101, y_i=11101001001011101, z_i=11001010111, x_next=10001000000001100, y_next=11010101110000000, z_next=11100110111, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00011100000
    i= 2, x_i=01001101101110101, y_i=11101001001011101, z_i=11001010111, x_next=10001000000001100, y_next=11010101110000000, z_next=11100110111, x_o=10001000000001100, y_o=11010101110000000, z_o=11100110111, d= 1, arctan[i]=00011100000
    i= 3, x_i=10001000000001100, y_i=11010101110000000, z_i=11100110111, x_next=10100010101111100, y_next=11000100101111111, z_next=11110101000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00001110001
    i= 3, x_i=10001000000001100, y_i=11010101110000000, z_i=11100110111, x_next=10100010101111100, y_next=11000100101111111, z_next=11110101000, x_o=10100010101111100, y_o=11000100101111111, z_o=11110101000, d= 1, arctan[i]=00001110001
    i= 4, x_i=10100010101111100, y_i=11000100101111111, z_i=11110101000, x_next=10101111000010011, y_next=10111010100101000, z_next=11111100001, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00000111001
    i= 4, x_i=10100010101111100, y_i=11000100101111111, z_i=11110101000, x_next=10101111000010011, y_next=10111010100101000, z_next=11111100001, x_o=10101111000010011, y_o=10111010100101000, z_o=11111100001, d= 1, arctan[i]=00000111001
    i= 5, x_i=10101111000010011, y_i=10111010100101000, z_i=11111100001, x_next=10110100110111100, y_next=10110101000111000, z_next=11111111101, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00000011100
    i= 5, x_i=10101111000010011, y_i=10111010100101000, z_i=11111100001, x_next=10110100110111100, y_next=10110101000111000, z_next=11111111101, x_o=10110100110111100, y_o=10110101000111000, z_o=11111111101, d= 1, arctan[i]=00000011100
    i= 6, x_i=10110100110111100, y_i=10110101000111000, z_i=11111111101, x_next=10110111101100100, y_next=10110010010010010, z_next=00000001011, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00000001110
    i= 6, x_i=10110100110111100, y_i=10110101000111000, z_i=11111111101, x_next=10110111101100100, y_next=10110010010010010, z_next=00000001011, x_o=10110111101100100, y_o=10110010010010010, z_o=00000001011, d= 1, arctan[i]=00000001110
    i= 7, x_i=10110111101100100, y_i=10110010010010010, z_i=00000001011, x_next=10110110010011011, y_next=10110011101110000, z_next=00000000101, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=00000000110
    i= 7, x_i=10110111101100100, y_i=10110010010010010, z_i=00000001011, x_next=10110110010011011, y_next=10110011101110000, z_next=00000000101, x_o=10110110010011011, y_o=10110011101110000, z_o=00000000101, d= 0, arctan[i]=00000000110
    i= 8, x_i=10110110010011011, y_i=10110011101110000, z_i=00000000101, x_next=10110101100110100, y_next=10110100011011100, z_next=00000000010, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=00000000011
    i= 8, x_i=10110110010011011, y_i=10110011101110000, z_i=00000000101, x_next=10110101100110100, y_next=10110100011011100, z_next=00000000010, x_o=10110101100110100, y_o=10110100011011100, z_o=00000000010, d= 0, arctan[i]=00000000011
    i= 9, x_i=10110101100110100, y_i=10110100011011100, z_i=00000000010, x_next=10110101010000000, y_next=10110100110010001, z_next=00000000001, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=00000000001
    i= 9, x_i=10110101100110100, y_i=10110100011011100, z_i=00000000010, x_next=10110101010000000, y_next=10110100110010001, z_next=00000000001, x_o=10110101010000000, y_o=10110100110010001, z_o=00000000001, d= 0, arctan[i]=00000000001
    Finding VCD file...
    ./cordic_pipelined.vcd
    [2017-05-18 03:06:03 EDT] Opening EPWave...
    Done
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    `timescale 1ns/100ps
     
    module cordic_pipelined(clk, z0, xn, yn);
      
      input clk;
      input [10:0] z0;
      output [16:0] xn, yn;
     
      parameter N = 10; // number of iterations
      
      reg [(N-1):0] d;
      wire [16:0] x [N:0];
      wire [16:0] y [N:0];
      wire [10:0] z [N:0];
     
      assign x[0] = 'b0_10011_0110_1110_1001;  // 0.60725 in binary
      assign y[0] = 0;
      assign z[0] = z0;
      
      wire [10:0] arctan [(N-1):0];
        
      assign arctan[0] = 'b010_1101_0000; // 45.0;
      assign arctan[1] = 'b001_1010_1001; // 26.6;
      assign arctan[2] = 'b000_1110_0000; // 14.0;
      assign arctan[3] = 'b000_0111_0001; // 7.1;
      assign arctan[4] = 'b000_0011_1001; // 3.6;
      assign arctan[5] = 'b000_0001_1100; // 1.8;
      assign arctan[6] = 'b000_0000_1110; // 0.9;
      assign arctan[7] = 'b000_0000_0110; // 0.4;
      assign arctan[8] = 'b000_0000_0011; // 0.2;
      assign arctan[9] = 'b000_0000_0001; // 0.1;
     
      genvar i;
      generate
        for(i=0; i<N; i=i+1)
          begin
            cordic_stage #(.i(i)) stage_i
            (
              .clk(clk), 
              .x_i(x[i]), .x_o(x[i+1]), 
              .y_i(y[i]), .y_o(y[i+1]), 
              .z_i(z[i]), .z_o(z[i+1]),
              .arctan(arctan[i])
            );
          end
      endgenerate
     
      assign xn = x[N]; // xn = cos(z0)
      assign yn = y[N]; // yn = sin(z0)
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    `timescale 1ns/100ps
     
    module cordic_stage(clk, x_i, y_i, z_i, x_o, y_o, z_o, arctan);
      
      input [10:0] arctan;
      parameter i=0;
      
      input clk;
      input [16:0] x_i, y_i;
      input [10:0] z_i;
      output [16:0] x_o, y_o;
      output [10:0] z_o;
      
      reg d;
      reg [16:0] x_o, x_next;
      reg [16:0] y_o, y_next;
      reg [10:0] z_o, z_next;
      
      always @ (posedge clk)
        begin
          x_o <= x_next;
          y_o <= y_next;
          z_o <= z_next; 
        end
     
      always @(*)
        begin    
     
          d = (z_i[10] == 0) ? 0 : 1;
     
          if(d == 0) begin
            x_next = x_i - (y_i >> i);
            y_next = y_i + (x_i >> i);
            z_next = z_i - arctan;
          end
     
          else begin
            x_next = x_i + (y_i >> i);
            y_next = y_i - (x_i >> i);
            z_next = z_i + arctan;
          end
          
          $display("i=%2d, x_i=%b, y_i=%b, z_i=%b, x_next=%b, y_next=%b, z_next=%b, x_o=%b, y_o=%b, z_o=%b, d=%2d, arctan[i]=%b", i,x_i,y_i,z_i,x_next,y_next,z_next,x_o,y_o,z_o,d,arctan);
     
      end
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    `timescale 1ns/100ps
     
    module cordic_pipelined_tb;
     
      reg clk;
      reg [10:0] z0;
      wire [16:0] xn, yn;
     
      cordic_pipelined C1
      (
        .clk(clk), .z0(z0), .xn(xn), .yn(yn)
      );
     
      initial begin
        $dumpfile("cordic_pipelined.vcd");
        $dumpvars(0, cordic_pipelined_tb);
        
        clk = 0;
        z0 = 11'b010_1101_0000; 
        
        #120 $finish;
      end
      
      always #5 clk = !clk;
     
    endmodule



  16. #16
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    A) because for loops are not used for writing sequential operations, which is what you are trying to use if for. Every time a read signal changes in the always @(*) block the for loop iterates over all 0-9 i values instantly in 0 time. What you've described is a large deep combinational "blob" of logic. So yeah, all you will get is the last [9] iteration output.

    The other for loop in the generate replicates 10 copies of your cordic_stage logic.

    B) I also don't get why there is an issue with the x's you have 10 stages of cordic_statge logic each one has a register in it that is initially X, so you get a display of a bunch of signals with X 10 times, one for each of the cordic_stage instances (as they all have a display task in them). I kind of suspect you don't know what your code translates to in hardware. Personally I would have made the display task in the testbench and accessed all the nodes in the design using the '.' hierarchy, that would have avoided the confusing mess of the output. I'd also change to use hex output to make the output shorter and easier to read.

    If the values were correctly done as binary fixed point then you could have used %.8f (e.g. 8-bit fractional) to output fixed point decimal values, but as you've got some non-standard custom method of representing fractional data you can't do this, too bad for you.



    •   Alt18th May 2017, 19:51

      advertising

        
       

  17. #17
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    ads-ee:

    A) If I wish to capture all 10 entries into the text file instead of the last [9] iteration output, could you advise how to do it since the for loop iterates in zero time ?

    B) Thanks for the "." hierarchy advice, however it does not work in accessing generated instances of cordic_stage.
    Do you have any idea how to implement the .start() as shown in http://stackoverflow.com/a/7341055/6422632

    Besides, what do you mean by "If the values were correctly done as binary fixed point then you could have used %.8f (e.g. 8-bit fractional) to output fixed point decimal values," ?

    Click image for larger version. 

Name:	Screenshot from 2017-05-19 17-16-36.png 
Views:	2 
Size:	67.3 KB 
ID:	138850



  18. #18
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    Quote Originally Posted by promach View Post
    ads-ee:

    A) If I wish to capture all 10 entries into the text file instead of the last [9] iteration output, could you advise how to do it since the for loop iterates in zero time ?
    Code:
    $display (....., C1.x[0], C1.x[1], ...etc);
    Though you'll need to name the begin-end block (i.e. begin : name_of_block) of the for loop so you can add that name into the . hierachy, which answers your B problem below.
    B) Thanks for the "." hierarchy advice, however it does not work in accessing generated instances of cordic_stage.
    Do you have any idea how to implement the .start() as shown in http://stackoverflow.com/a/7341055/6422632
    Not sure what their problem was, but here is a post about accessing signals in a generate block module instantiation, I use this all the time in my code. http://www.edaboard.com/showthread.p...=1#post1065894

    Besides, what do you mean by "If the values were correctly done as binary fixed point then you could have used %.8f (e.g. 8-bit fractional) to output fixed point decimal values," ?
    Try this in a simulator:
    A 2's complement 12-bit with 12-bit fractional (Q11.12 or fx12.24).
    Code Verilog - [expand]
    1
    2
    3
    4
    
    reg [23:0] fixed_point_binary = 24'h015_001; // 21.000244140625 exactly
      initial begin
        $display ("%.12f", fixed_point_binary/4096.0);
      end

    - - - Updated - - -

    My apologies, I see now that you were using values rounded to 1 decimal place:
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    module display_test;
     
      reg [23:0] fixed_point_binary = 24'h015_001;
     
      initial begin
        $display ("%.12f", fixed_point_binary/4096.0);
      end
     
      integer i;
      // requires compiling with -sv option enabled
      reg [9:0] arctan [0:9] = '{10'h2d_0, 10'h1a_9, 10'h0e_0, 10'h07_1, 10'h03_9,
                                 10'h01_c, 10'h00_e, 10'h00_6, 10'h00_3, 10'h00_1};
     
      initial begin
        $display ("Acutal fractional values");
        for (i=0;i<10;i=i+1) begin
          $display ("%.4f", arctan[i]/16.0);
        end
     
        $display ("Rounded to 1 decimal place");
        for (i=0;i<10;i=i+1) begin
          $display ("%.1f", arctan[i]/16.0);
        end
      end
     
    endmodule
    Code:
    # 21.000244140625
    # Actual fractional values
    # 45.0000
    # 26.5625
    # 14.0000
    # 7.0625
    # 3.5625
    # 1.7500
    # 0.8750
    # 0.3750
    # 0.1875
    # 0.0625
    # Rounded to 1 decimal place
    # 45.0
    # 26.6
    # 14.0
    # 7.1
    # 3.6
    # 1.8
    # 0.9
    # 0.4
    # 0.2
    # 0.1
    Didn't realize this because there is nothing in your comments that indicate the values as being rounded and the code included a comment that had the exact precision value for: 'b0_10011_0110_1110_1001; // 0.60725 in binary. You should avoid doing such rounding (for a comment) or at leas specify that the values are rounded to one decimal place.

    So sorry about continually harping about your lack of using standard binary fractional representation.



  19. #19
    Full Member level 3
    Points: 936, Level: 6

    Join Date
    Feb 2016
    Posts
    152
    Helped
    0 / 0
    Points
    936
    Level
    6

    Re: Cordic Algorithm Question

    ads-ee:

    I have modified using your method accordingly as follows, but it gives me unpredicted verbose output especially i ?

    https://www.edaplayground.com/x/4ymA

    Code:
    [2017-05-21 21:06:34 EDT] iverilog '-Wall' 'cordic_stage.v' design.sv testbench.sv  && unbuffer vvp a.out  
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    design.sv:54: warning: @* is sensitive to all 11 words in array 'x'.
    design.sv:55: warning: @* is sensitive to all 11 words in array 'y'.
    VCD info: dumpfile cordic_pipelined.vcd opened for output.
    i= 0, x_i=10011011011101001, y_i=00000000000000000, z_i=01011010000, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=xxxxxxxxxxx, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=01011010000
    i= 1, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00110101001
    i= 2, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00011100000
    i= 3, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00001110001
    i= 4, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000111001
    i= 5, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000011100
    i= 6, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000001110
    i= 7, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000110
    i= 8, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000011
    i= 9, x_i=xxxxxxxxxxxxxxxxx, y_i=xxxxxxxxxxxxxxxxx, z_i=xxxxxxxxxxx, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000001
    i= 0, x_i=10011011011101001, y_i=00000000000000000, z_i=01011010000, x_next=10011011011101001, y_next=10011011011101001, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=01011010000
    i= 1, x_i=10011011011101001, y_i=10011011011101001, z_i=00000000000, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00110101001
    i= 0, x_i=10011011011101001, y_i=00000000000000000, z_i=01011010000, x_next=10011011011101001, y_next=10011011011101001, z_next=00000000000, x_o=10011011011101001, y_o=10011011011101001, z_o=00000000000, d= 0, arctan[i]=01011010000
    i= 1, x_i=10011011011101001, y_i=10011011011101001, z_i=00000000000, x_next=01001101101110101, y_next=11101001001011101, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=00110101001
    i= 2, x_i=01001101101110101, y_i=11101001001011101, z_i=11001010111, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00011100000
    i= 1, x_i=10011011011101001, y_i=10011011011101001, z_i=00000000000, x_next=01001101101110101, y_next=11101001001011101, z_next=00000000000, x_o=01001101101110101, y_o=11101001001011101, z_o=11001010111, d= 0, arctan[i]=00110101001
    i= 2, x_i=01001101101110101, y_i=11101001001011101, z_i=11001010111, x_next=10001000000001100, y_next=11010101110000000, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00011100000
    i= 3, x_i=10001000000001100, y_i=11010101110000000, z_i=11100110111, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00001110001
    i= 2, x_i=01001101101110101, y_i=11101001001011101, z_i=11001010111, x_next=10001000000001100, y_next=11010101110000000, z_next=00000000000, x_o=10001000000001100, y_o=11010101110000000, z_o=11100110111, d= 1, arctan[i]=00011100000
    i= 3, x_i=10001000000001100, y_i=11010101110000000, z_i=11100110111, x_next=10100010101111100, y_next=11000100101111111, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00001110001
    i= 4, x_i=10100010101111100, y_i=11000100101111111, z_i=11110101000, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000111001
    i= 3, x_i=10001000000001100, y_i=11010101110000000, z_i=11100110111, x_next=10100010101111100, y_next=11000100101111111, z_next=00000000000, x_o=10100010101111100, y_o=11000100101111111, z_o=11110101000, d= 1, arctan[i]=00001110001
    i= 4, x_i=10100010101111100, y_i=11000100101111111, z_i=11110101000, x_next=10101111000010011, y_next=10111010100101000, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00000111001
    i= 5, x_i=10101111000010011, y_i=10111010100101000, z_i=11111100001, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000011100
    i= 4, x_i=10100010101111100, y_i=11000100101111111, z_i=11110101000, x_next=10101111000010011, y_next=10111010100101000, z_next=00000000000, x_o=10101111000010011, y_o=10111010100101000, z_o=11111100001, d= 1, arctan[i]=00000111001
    i= 5, x_i=10101111000010011, y_i=10111010100101000, z_i=11111100001, x_next=10110100110111100, y_next=10110101000111000, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00000011100
    i= 6, x_i=10110100110111100, y_i=10110101000111000, z_i=11111111101, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000001110
    i= 5, x_i=10101111000010011, y_i=10111010100101000, z_i=11111100001, x_next=10110100110111100, y_next=10110101000111000, z_next=00000000000, x_o=10110100110111100, y_o=10110101000111000, z_o=11111111101, d= 1, arctan[i]=00000011100
    i= 6, x_i=10110100110111100, y_i=10110101000111000, z_i=11111111101, x_next=10110111101100100, y_next=10110010010010010, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 1, arctan[i]=00000001110
    i= 7, x_i=10110111101100100, y_i=10110010010010010, z_i=00000001011, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000110
    i= 6, x_i=10110100110111100, y_i=10110101000111000, z_i=11111111101, x_next=10110111101100100, y_next=10110010010010010, z_next=00000000000, x_o=10110111101100100, y_o=10110010010010010, z_o=00000001011, d= 1, arctan[i]=00000001110
    i= 7, x_i=10110111101100100, y_i=10110010010010010, z_i=00000001011, x_next=10110110010011011, y_next=10110011101110000, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= 0, arctan[i]=00000000110
    i= 8, x_i=10110110010011011, y_i=10110011101110000, z_i=00000000101, x_next=xxxxxxxxxxxxxxxxx, y_next=xxxxxxxxxxxxxxxxx, z_next=00000000000, x_o=xxxxxxxxxxxxxxxxx, y_o=xxxxxxxxxxxxxxxxx, z_o=xxxxxxxxxxx, d= x, arctan[i]=00000000011
    i= 7, x_i=10110111101100100, y_i=10110010010010010, z_i=00000001011, x_next=10110110010011011, y_next=10110011101110000, z_next=000000Finding VCD file...
    ./cordic_pipelined.vcd
    [2017-05-21 21:06:35 EDT] Opening EPWave...
    Done
    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
    `timescale 1ns/100ps
     
    module cordic_pipelined_tb;
     
      reg clk;
      reg [10:0] z0;
      wire [16:0] xn, yn;
     
      cordic_pipelined C1
      (
        .clk(clk), .z0(z0), .xn(xn), .yn(yn)
      );
     
      initial begin
        $dumpfile("cordic_pipelined.vcd");
        $dumpvars(0, cordic_pipelined_tb);
        
        clk = 0;
        z0 = 11'b010_1101_0000; 
        
        #120 $finish;
      end
      
      always #5 clk = !clk;
      
      genvar j;
      generate
        for(j=0; j<C1.N; j=j+1)
          begin
            always @(*)
              begin
                $display("i=%2d, x_i=%b, y_i=%b, z_i=%b, x_next=%b, y_next=%b, z_next=%b, x_o=%b, y_o=%b, z_o=%b, d=%2d, arctan[i]=%b", C1.stage_generate[j].i, C1.stage_generate[j].stage_i.x_i, C1.stage_generate[j].stage_i.y_i, C1.stage_generate[j].stage_i.z_i, C1.stage_generate[j].stage_i.x_next, C1.stage_generate[j].stage_i.y_next, C1.stage_generate[0].stage_i.z_next, C1.stage_generate[j].stage_i.x_o, C1.stage_generate[j].stage_i.y_o, C1.stage_generate[j].stage_i.z_o, C1.stage_generate[j].stage_i.d, C1.stage_generate[j].stage_i.arctan);
     
              end
          end
      endgenerate
     
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    `timescale 1ns/100ps
     
    module cordic_pipelined(clk, z0, xn, yn);
      
      input clk;
      input [10:0] z0;
      output reg [16:0] xn, yn;
     
      parameter N = 10; // number of iterations
      
      reg [(N-1):0] d;
      wire [16:0] x [N:0];
      wire [16:0] y [N:0];
      wire [10:0] z [N:0];
     
      assign x[0] = 'b0_10011_0110_1110_1001;  // 0.60725 in binary
      assign y[0] = 0;
      assign z[0] = z0;
      
      wire [10:0] arctan [(N-1):0];
        
      assign arctan[0] = 'b010_1101_0000; // 45.0;
      assign arctan[1] = 'b001_1010_1001; // 26.6;
      assign arctan[2] = 'b000_1110_0000; // 14.0;
      assign arctan[3] = 'b000_0111_0001; // 7.1;
      assign arctan[4] = 'b000_0011_1001; // 3.6;
      assign arctan[5] = 'b000_0001_1100; // 1.8;
      assign arctan[6] = 'b000_0000_1110; // 0.9;
      assign arctan[7] = 'b000_0000_0110; // 0.4;
      assign arctan[8] = 'b000_0000_0011; // 0.2;
      assign arctan[9] = 'b000_0000_0001; // 0.1;
     
      genvar i;
      generate
        for(i=0; i<N; i=i+1)
          begin: stage_generate
            cordic_stage #(.i(i)) stage_i
            (
              .clk(clk), 
              .x_i(x[i]), .x_o(x[i+1]), 
              .y_i(y[i]), .y_o(y[i+1]), 
              .z_i(z[i]), .z_o(z[i+1]),
              .arctan(arctan[i])
            );
          end
      endgenerate
     
      genvar j;
      generate
        for(j=0; j<N; j=j+1)
          begin
            always @(*)
              begin
                xn = x[stage_generate[j].i]; // xn = cos(z0)
                yn = y[stage_generate[j].i]; // yn = sin(z0)
              end
          end
      endgenerate
      
    endmodule

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    
    `timescale 1ns/100ps
     
    module cordic_stage(clk, x_i, y_i, z_i, x_o, y_o, z_o, arctan);
      
      input [10:0] arctan;
      parameter i=0;
      
      input clk;
      input [16:0] x_i, y_i;
      input [10:0] z_i;
      output [16:0] x_o, y_o;
      output [10:0] z_o;
      
      reg d;
      reg [16:0] x_o, x_next;
      reg [16:0] y_o, y_next;
      reg [10:0] z_o, z_next;
      
      always @ (posedge clk)
        begin
          x_o <= x_next;
          y_o <= y_next;
          z_o <= z_next; 
        end
     
      always @(*)
        begin    
     
          d = (z_i[10] == 0) ? 0 : 1;
     
          if(d == 0) begin
            x_next = x_i - (y_i >> i);
            y_next = y_i + (x_i >> i);
            z_next = z_i - arctan;
          end
     
          else begin
            x_next = x_i + (y_i >> i);
            y_next = y_i - (x_i >> i);
            z_next = z_i + arctan;
          end
          
      end
     
    endmodule



  20. #20
    Super Moderator
    Points: 27,697, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,323
    Helped
    1535 / 1535
    Points
    27,697
    Level
    40

    Re: Cordic Algorithm Question

    As you didnt post the design.sv file cant say why you are getting the problem with the always. You probably have an array name missing indicies in the always.

    If your problem is with the display of the output it is because you don't seem to understand how the for loop works. You are getting all 10 iteration of the display output anytime the inputs change. That is probably not what you intended. Personally I would put the display for loop inside a clocked always probably on the negedge.

    It might also be beneficial to add a display like a line of '-' or '=' before entering the for loop so you can tell where the separate times where it entered the for loop occur. You might also consider adding %t and $time to tell when in the simulation it entered the for loop.



--[[ ]]--