FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6343 Discussions

NCO and FIR COmpiler Megafunction performance

Altera_Forum
Honored Contributor II
1,839 Views

For learning purpose,  

 

I just added two NCO O/Ps with 1 MHz and 5 MHz. 

 

NCO1 = 1 MHz 

NCO2 = 5 MHz 

 

and using FIR Compiler unit ( with Fc = 1.25 MHz), I filtered the mixture of these two sine waves. 

The filtered O/P is a sine wave, but not near 1 MHz, its around 500 KHz. 

pls see the image attached. 

 

Any suggestions for improvement. 

thanks
0 Kudos
19 Replies
Altera_Forum
Honored Contributor II
543 Views

Are you sure about your figures? NCO1 is meant to be 1MHz yet you have several cycles over 1000ns interval as per your diagram(you should have one cycle running for 1000ns period). it is probably 10MHz.

0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Thanks Kaz. 

 

It is not 1000 ns, it is 10000 ns, and it covers 10 cycles. 

so 1 cycle = 1000 ns = 1 MHz.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

My eyesight is gone?? 

 

OK in that case if you save your NCO1,NCO2, adder, filtered output to work space as array and attach it to your post then I might get better eyesight
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Sure, 

I am attaching .VWF as well as .VCD file. 

Also, if you want to see the project , I can upload it.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

I don't have your tools exactly. I only wanted mat files (or txt files) for the outputs of NCO1,NCO2,adder,filter. just 1000 samples per each will do

0 Kudos
Altera_Forum
Honored Contributor II
543 Views

I don't understand your way of operating the filter flow control signals. You're picking a few samples of the input data instead of reading it continuously.

0 Kudos
Altera_Forum
Honored Contributor II
543 Views

This is the top level code : 

The mixing of two signals is being performed here in the top level. 

 

module ncofilter(phi_inc_i, 

phi_inc_i_2 , 

clk,  

reset_n, 

clken,  

fsin_o,  

fcos_o,  

fsin_o_2,  

out_valid, 

out_valid_2,  

connect_o,  

ast_sink_valid, 

ast_source_ready, 

ast_sink_error, 

ast_sink_ready, 

ast_source_valid, 

ast_source_error, 

ast_source_data); 

 

input [31:0] phi_inc_i; 

input [31:0] phi_inc_i_2; 

input clk; 

input reset_n; 

input clken; 

 

output [17:0] fsin_o; 

output [17:0] fcos_o; 

output [17:0] fsin_o_2; 

output out_valid; 

output out_valid_2; 

output [18:0] connect_o; 

 

//reg [18:0] connect; 

reg [18:0] connect_o; 

 

input ast_sink_valid; 

input ast_source_ready; 

input [1:0] ast_sink_error; 

output [31:0] ast_source_data; 

output ast_sink_ready; 

output ast_source_valid; 

output [1:0] ast_source_error; 

 

reg [18:0] mix; 

 

 

//assign connect_o = mix; 

 

my_nco_4 nco_3( 

.phi_inc_i(phi_inc_i), 

.clk(clk), 

.reset_n(reset_n), 

.clken(clken), 

.fsin_o(fsin_o), 

.fcos_o(fcos_o), 

.out_valid(out_valid)); 

 

new_nco nco_4( 

.phi_inc_i(phi_inc_i_2), 

.clk(clk), 

.reset_n(reset_n), 

.clken(clken), 

.fsin_o(fsin_o_2), 

.out_valid(out_valid_2)); 

 

my_filter filter_1( 

.clk(clk), 

.reset_n(reset_n), 

.ast_sink_data(mix), 

.ast_sink_valid(ast_sink_valid), 

.ast_source_ready(ast_source_ready), 

.ast_sink_error(ast_sink_error), 

.ast_source_data(ast_source_data), 

.ast_sink_ready(ast_sink_ready), 

.ast_source_valid(ast_source_valid), 

.ast_source_error(ast_source_error)); 

 

 

 

always @(posedge clk) 

begin 

mix <= fsin_o +fsin_o_2; 

end 

 

always @(posedge clk) 

begin 

connect_o <= mix; 

end 

 

endmodule  

 

 

 

Hope it helps.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

@ kaz 

 

in that case, you can use gtkwave+ (open source) to view vcd file. 

i dont know how to convert the file format into txt etc.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Another problem: 

mix <= fsin_o +fsin_o_2; 

Is summing both 18 bit signals to 18 bit (causing overflow) and than assigning the result to a 19 bit variable.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

I reviewed the vfw waveform and think to understand the filter problem. It's operating at 5 MHz sampling rate only, although ast_sink_valid is pemanently enabled with 100 MHz input clock. It's the filter design.

0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Thanks FvM 

 

u were rite, problem was with sampling rate, which by mistake was set to 1.0E7 

after setting it to 1E8,  

the O/P is good, though not smooth, but frequency wise its good. 

thanks 

see attachement.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

 

--- Quote Start ---  

the O/P is good, though not smooth, but frequency wise its good. 

--- Quote End ---  

 

Yes the overflow problem mentioned in my previous post isn't yet solved.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

 

--- Quote Start ---  

Yes the overflow problem mentioned in my previous post isn't yet solved. 

--- Quote End ---  

 

 

I don't see overflow problem since it is 18 bits + 18bits => 19 bits
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

 

--- Quote Start ---  

I don't see overflow problem since it is 18 bits + 18bits => 19 bits 

--- Quote End ---  

 

I know that this is a popular misunderstanding of Verilog (and VHDL too) expression length evaluation. 

 

First point, even without understanding the overflow cause in Verilog terms, the waveforms don't allow any doubt about it.  

 

In the below assignment, both input variables are 18 bit and the variable receiving the sum is 19 bit. 

mix <= fsin_o +fsin_o_2; 

 

The mistake is in assuming that the assignment LHS would determine the expression length, but it doesn't. It's the maximum bit length of involved input terms, 18 bit in this case. Please refer to the detailed and instructive chapter 5.4 expression bit lengths in IEEE Std 1364.  

 

To avoid overflows, you have to extend one of both input terms before the add operation to 19 bit (with sign extension). Or use the simple trick suggested in the Verilog specification, add an integer 0 which extends the intermediate result to 32 bit. 

 

mix <= fsin_o +fsin_o_2 + 0;
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Thanks FvM for the note. However in that case it is not really misunderstanding of verilog(or vhdl) by the designer but rather misunderstanding of designer by verilog or vhdl. 

 

common sense tells me that if result is 19 bits and operands are 18 bits then why on earth would the result depend on input width and not output width. 

 

Normally in vhdl adder inference - a far as I remember - it does not let input width be less than output forcing in effect avoidance of this scenario, 

 

So in short, it is a ludicrous mistake in the standards to be that misleading.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

In VHDL, the result length of an add operation is just the same, the length of the largest summand. There's however an important difference that helps you to avoid the observed overflow problem, VHDL doesn't allow to assign the 18 bit sum to a 19 bit variable:  

Error (10344): VHDL expression error at unsigned_adder.vhd(27): expression has 18 elements, but must have 19 elements 

 

In VHDL, an automatic length extension of add result would be unwanted, because an overflow within the same result width is often required, e.g. for counters. 

 

In less strictly typed Verilog, an automatic extension would be an option, but obviously the language designers decided differently.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

For understanding the effect of no. of bits of output, i wrote a simple code : 

 

module testing (in1, in2, out,out1, out2); input in1; input in2; output out; output out1; output out2; assign out = in1 + in2; assign out1 = in1 + in2; assign out2 = in1 + in2; endmodule  

 

this design i simulated with unsigned decimals. in1 and in2 = 1 to 36; 

the various outputs are as shown in attachment. 

 

http://www.alteraforum.com/forum/attachment.php?attachmentid=6206&stc=1&d=1345964169  

 

The same design i simulated for signed decimal input. and result is : 

 

http://www.alteraforum.com/forum/attachment.php?attachmentid=6207&stc=1&d=1345964401  

 

CLEARLY : 

 

I believe, in verilog, if we assign a higher no. of bits to output, the result doesnt vary or affected by the nature of input viz. signed/unsigned etc. 

 

what do u think ??
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Thanks for example, I have to correct my previous statement. In the discussed assignment, the expression bit length is context determined. So kaz was right about correct evaluation to 19 bit. 

mix <= fsin_o +fsin_o_2 + 0; 

 

The waveforms seems to indicate an overflow, but it's actually the result of a wrong number display format, signed instead of unsigned. The same thing happens in your example. 

 

You have to care however, that NCO output and FIR filter are using the same number representation. If they are different, the filter will get a distorted input signal. I guess this happens in your test. You can change from unsigned (offset binary) to signed representation by inverting the MSB. 

 

I apologize for causing confusion.
0 Kudos
Altera_Forum
Honored Contributor II
543 Views

Thank FvM. 

So I believe even though the binary arithmetic performed may be right, but its not fully correct till its correct interpretation, and thats what the key feature of implementing signal processing on FPGAs : representation !! 

 

:)
0 Kudos
Reply