# Problem in designing NCO using cordic algorithm

Status
Not open for further replies.

#### jubin007

##### Newbie level 4
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: 56

##### Super Moderator
Staff member
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.

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.