Problem in designing NCO using cordic algorithm

Status
Not open for further replies.

jubin007

Newbie level 4
Joined
Mar 10, 2015
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
60
I am pursuing M.Tech in VLSI design and have designed a pipelined Cordic based NCO but i am having glitches in my output. This is a part of my m.tech thesis and i will have to complete very soon.
It will be of great help if someone kindly helps me sort out my problem. i have attached the program and simulation result. in the wave, you will see that there is a repetitive glitch coming from my program. If you help me sort it out, it will be really helpful.
 

Attachments

  • needurgenthelpindesignofcordicbasednco.zip
    30.7 KB · Views: 112


It appears you misunderstand how a Verilog for loop works...for loops are unrolled at compile time to generate multiple indexed copies of hardware.

You have written a combination of a software style for loop (as in a temporal loop) and a hardware for loop (spatial replication of the X, Y, and Z registers). This coding style doesn't work as the for loop will be unrolled and I think the only assigns that exists when simulation starts are: assign X_shr = X[17]>>>i;, assign Y_shr = Y[17]>>>i;, and assign Z_sign = Z[17][31];.

If you code your X, Y, and Z outputs with the RHS of your assigns the code will synthesize and simulate correctly as it will represent a proper set of pipelined registers.

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
// stage 1 to N-1//
  genvar i;
  generate
    for (i=0; i< 18; i=i+1)
    begin: abc
      wire Z_sign; //sign = di
      wire signed [31:0]X_shr; // shift right X
      wire signed [31:0]Y_shr; // shift right Y
      assign X_shr= X[i]>>>i;
      assign Y_shr= Y[i]>>>i;
      assign Z_sign= Z[i][31];
      always @(posedge clk)
        begin
// must use the [i] versions directly to index the correct Z, Y, and X values
      X[i+1]<= Z[i][31] ? X[i]+ (Y[i]>>>i) : X[i]- (Y[i]>>>i);
      Y[i+1]<= Z[i][31] ? Y[i]- (X[i]>>>i) : Y[i]+ (X[i]>>>i);
      Z[i+1]<= Z[i][31] ? Z[i]+ atan_table[i] : Z[i]- atan_table[i];
// can't use the continuous assign values as they will not reflect the intention
// of using the [i] versions for each of the parallel pieces of logic. I'm not
// entirely sure, which of the Z[i], X[i], and Y[i] was used for the itterations,
// but the assign was causing it to use only one of them instead of the correct
// [i] version.
//      X[i+1]<= Z_sign ? X[i]+ Y_shr : X[i]- Y_shr;
//      Y[i+1]<= Z_sign ? Y[i]- X_shr : Y[i]+ X_shr;
//      Z[i+1]<= Z_sign ? Z[i]+ atan_table[i] : Z[i]- atan_table[i];
    end
  end
  endgenerate


Here is the output with the change:


You can remove all the assigns and the declarations. You also can get rid of the generate-endgenerate if you place the for inside the always block changing the genvar i; to an integer i; declaration. Makes for nice compact clean looking code.
 
Last edited:

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…