Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Cordic Algorithm Question

Status
Not open for further replies.

promach

Advanced Member level 4
Joined
Feb 22, 2016
Messages
1,199
Helped
2
Reputation
4
Reaction score
5
Trophy points
1,318
Activity points
11,636
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

 

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

i= 0, x=10011011011101001, y=00000000000000000, z=0000000000000000011110, d= 0, arctan=0000000000000000101101
i= 1, x=10011011011101001, y=10011011011101001, z=1111111111111111110001, d= 1, arctan=0000000000000000011011
i= 2, x=00011011011101001, y=00000000000000000, z=0000000000000000001100, d= 0, arctan=0000000000000000001110
i= 3, x=00000110110111010, y=00000110110111010, z=1111111111111111111110, d= 1, arctan=0000000000000000000111
i= 4, x=00000001101101110, y=00000000000000000, z=0000000000000000000101, d= 0, arctan=0000000000000000000100
i= 5, x=00000000000110110, y=00000000000110110, z=0000000000000000000001, d= 0, arctan=0000000000000000000010
i= 6, x=00000000000000000, y=00000000000000011, z=1111111111111111111111, d= 1, arctan=0000000000000000000001
i= 7, x=00000000000000000, y=00000000000000000, z=0000000000000000000000, d= 0, arctan=0000000000000000000000
i= 8, x=00000000000000000, y=00000000000000000, z=0000000000000000000000, d= 0, arctan=0000000000000000000000
i= 9, x=00000000000000000, y=00000000000000000, z=0000000000000000000000, d= 0, arctan=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

 

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.
 

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 ?
 

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

x[i+1] = x - (y >>> 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

 

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
 

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

 

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.
 

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=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=xxxxxxxxxxx) while LHS would not ?

Screenshot from 2017-05-17 00-33-24.png
 

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.
 

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

 

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 ?
 

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

 

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.
 

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 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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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=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

 

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.
 

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 https://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," ?

Screenshot from 2017-05-19 17-16-36.png
 

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 https://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. https://www.edaboard.com/showthread.php?t=248697&p=1065894&viewfull=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.
 

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

 

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.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top