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
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.
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
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.
This is the top level code :The mixing of two signals is being performed here in the top level. module ncofilter(phi_inc_i,
input [31:0] phi_inc_i;
input [31:0] phi_inc_i_2;
output [17:0] fsin_o;
output [17:0] fcos_o;
output [17:0] fsin_o_2;
output [18:0] connect_o;
//reg [18:0] connect;
reg [18:0] connect_o;
input [1:0] ast_sink_error;
output [31:0] ast_source_data;
output [1:0] ast_source_error;
reg [18:0] mix;
//assign connect_o = mix;
always @(posedge clk)
mix <= fsin_o +fsin_o_2;
always @(posedge clk)
connect_o <= mix;
endmodule Hope it helps.
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.
--- 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.
--- 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
--- 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;
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.
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 elementsIn 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.
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; endmodulethis 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 ??
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.
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 !! :)