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

.mif file generation of perticular freuency

Altera_Forum
Honored Contributor II
4,135 Views

hi, 

i am facing a problem to generate a .mif file of perticular frecuency for initializing the ROM in my tone generation project...can anybody help me regarding this...
0 Kudos
26 Replies
Altera_Forum
Honored Contributor II
1,193 Views

Hi, 

 

The frequency depends on your Fs i.e. f = Fs/Number of points per cycle. 

 

To generate one sinusoid cycle of n points in Matlab and quantising onto 16 bits signed: 

data = sin(2*pi*[0:n-1]/n); 

data = round(data* (2^15-1)/max(data)); 

 

you can then display data as a column, copy and paste to a mif file(This is quicker than writing mif text) 

 

Kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

hi..thanks Kaz...but actually i have to implement the .mif for perticular frequency like 480 Hz in verilog itself...for that i have to generate a tone by storing this .mif file into Rom. 

actually i don't know about Matlab...so
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

Hi, 

 

If your problem is DSP-builder tool related then I hope somebody else may help. 

However, if you want to generate 480Hz by hand then if your effective clock frequency for the module is say 0.48MHz then you need to generate mif file for rom having 1000 points. This mif file will be good for verilog or vhdl module. Thus to avoid large rom use a low frequency clock. 

 

If you enter Matlab as n= 1000 with my previous statements then you get the data ready. All you have to do is copy and paste to new mif in Qartus(file-> new-> oters ->mif), you will get spread-sheet style of mif. Then set data to 2's complement and paste. 

 

Kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

In this post 

 

http://www.alteraforum.com/forum/showthread.php?t=3448 

 

There is a matlab function that can help you to generate the .mif file.
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

This is where VHDL is significantly more flexible than Verilog. Since VHDL supports all the floating point operations naturally and doesn't complain when a "real" type is being manipulated during synthesis, you can actually code this up extremely generically. 

 

library ieee ; use ieee.std_logic_1164.all ; use ieee.numeric_std.all ; use ieee.math_real.all ; entity complex_tone_ram is generic ( FREQ_SAMPLE : real := 50.0e6 ; FREQ_TONE : real := 4.096e6 ; Q : positive := 12 ; WIDTH : positive := 15 ) ; port ( clock : in std_logic ; sreset : in std_logic ; enable : in std_logic ; i_out : out signed(WIDTH-1 downto 0) ; q_out : out signed(WIDTH-1 downto 0) ) ; end entity ; -- complex_tone_ram architecture arch of complex_tone_ram is -- Naive search for LCM between sample rate and tone to be generated function calculate_num_points( sample_rate, tone : real ) return integer is variable retval : integer ; begin retval := 1 ; while( (tone*real(retval)/sample_rate) mod 1.0 /= 0.0 ) loop retval := retval + 1 ; end loop ; return retval ; end function ; -- A constant to hold the number of points constant NUM_POINTS : integer := calculate_num_points( FREQ_SAMPLE, FREQ_TONE ) ; -- The RAM type that will be inferred type ram_t is array(NUM_POINTS-1 downto 0) of signed(WIDTH-1 downto 0) ; -- A function to populate the RAM function populate_ram( phase_increment, scale : real ) return ram_t is variable retval : ram_t := (others =>(others =>'0')) ; begin for i in retval'range loop retval(i) := to_signed(integer(round(scale*cos(phase_increment*real(i)))), retval(i)'length) ; end loop ; return retval ; end function ; -- The RAM signal itself signal ram : ram_t := populate_ram( FREQ_TONE/FREQ_SAMPLE * MATH_2_PI, real(2**Q) ) ; -- Find the location which is 90 degrees out of phase with 1.0 function find_q_start_address( ram : ram_t ) return integer is variable retval : integer ; begin retval := 0 ; for i in ram'range loop if( ram(i) = 0 and ram(i+1) > 0 ) then retval := i ; end if ; end loop ; return retval ; end function ; constant I_START_ADDRESS : integer := 0 ; constant Q_START_ADDRESS : integer := find_q_start_address( populate_ram( FREQ_TONE/FREQ_SAMPLE * MATH_2_PI, real(2**Q) ) ) ; -- I and Q address signals signal i_address : integer range ram_t'range := I_START_ADDRESS ; signal q_address : integer range ram_t'range := Q_START_ADDRESS ; begin generate_addresses : process( clock ) begin if( rising_edge( clock ) ) then if( sreset = '1' ) then i_address <= I_START_ADDRESS ; q_address <= Q_START_ADDRESS ; else if( enable = '1' ) then if( i_address = ram'high ) then i_address <= 0 ; else i_address <= i_address + 1 ; end if ; if( q_address = ram'high ) then q_address <= 0 ; else q_address <= q_address + 1 ; end if ; end if ; end if ; end if ; end process ; create_tone_output : process( clock ) begin if( rising_edge( clock ) ) then i_out <= ram(i_address) ; q_out <= ram(q_address) ; end if ; end process ; end architecture ; -- arch  

 

All will be done at compile time for any particular complex frequency. Obviously this can be adapted to be a real-only tone generator as well. 

 

NOTE: Quartus II has an issue with performing a loop more than 10,000 times, but I believe that check can be disabled if you require. 

 

EDIT: Also note the Q starting address with be in-phase with the I starting address if the number of sample points is not divisible by 4.
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

hi , 

thanx for this vhdl code.. 

can u tell me how much frequency of signal it will generate..... 

actually i have to generate a frequency of 425Hz ...so for that what changes i have to make in this code.....
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

No. 

 

The code is well written and easy enough to simulate. 

 

If you honestly don't know where to make the changes, I suggest you pick up a good VHDL book and start reading. 

 

Good luck!
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

hi . i made the the changes : 

FREQ_TONE : real := 425e0 ; 

 

but after that when i compiled it gives an error.. 

can u help me regarding this
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

you also need to enter the freq_sample as your clock's actual frequency. 

 

However although this code is well written it fails at some values... 

Moreover I am not sure if it gives phase continuity correctly. It is also rigid and may be good for one particular frequency but could result in very large memory especially for small values of tone relative to clock. 

 

You better use Altera NCO compiler. This is more versatile and can generate any frequency less than clk/2 including very very fine steps by simply changing the tuning word value. 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

hi Kaz.. 

thanx ..but can u tell me the settings i have to do in NCO compiler for generating a frequency of 425 Hz... 

it will generate the mif file of that frequency or anything else?? 

plz tell me soon
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

Hi, 

 

an NCO generates any frequency below clk/2 on the fly by changing the tuning word value. 

 

The tuning word value depends on your clock frequency and tone as well as the width of tuning word and there is a formula for that.  

 

The easiest way is this: 

When you enter your NCO settings you will find entry for sampling frequency(your effective clock) and a given tone in Hz ...etc then the GUI will get you the tuning word value. 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

Real numbers require a decimal point, so 425e0 is not a valid real number, but 425.0 will work. 

 

It is true that if you have a system clock of 50MHz and wish to produce a tone of 425Hz, the MIF can get large. On the other hand, you can throttle the generation of the tone using the enable strobe to manage the size of the ROM generated. The sample frequency then becomes the rate at which the enable line is strobed while the tone value stays the same. 

 

While the original question was to be able to generate a single tone, it is true the Altera NCO can produce a variety of tones based on the tuning word. If tuning is something that is required, I'd recommend reading up on cordics (http://en.wikipedia.org/wiki/cordic).
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

Hi, 

 

I don't see tuning as an issue for our friend Kapilvar. But as a ready-made design I suggested that. 

 

If it was me, I will generate my own mif using ant tool and simply read out in firmware - a very basic module. 

 

At work, we generate carriers just from few data points, no need for memory even. You may even just as well use two values if you accept harmonics. 

 

so just use a clock twice your tone and output the two values. 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

 

--- Quote Start ---  

If it was me, I will generate my own mif using ant tool and simply read out in firmware - a very basic module. 

--- Quote End ---  

 

 

Why use a different tool when VHDL can do this for you? I suppose if you are using NIOS II this makes sense, but without it I don't quite follow how you would read it out? 

 

It is true that you may only require a few points to generate a tone depending on the quality of the tone that is needed.
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

Hi, 

 

I mean read out in firmware i.e. a normal HDL model with memory initiailsed by mif... 

 

You are quite right that if you can use vhdl itself as your computation tool besides its use as the normal firmware design that is impressive indeed as in your program. 

 

In fact I have never used it as such but I need to try it... the problem is at the end of the day a more powerful tool like Matlab will be eventually needed and mess-up the experience... 

 

Kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

 

--- Quote Start ---  

... the problem is at the end of the day a more powerful tool like Matlab will be eventually needed and mess-up the experience... 

--- Quote End ---  

 

 

I actually try to avoid using MATLAB for anything other than analysis. I've successfully written RRC and Gaussian filter fixed-point coefficient functions for inclusion into hand-written FIR filters for digital downconversion in software defined radios. 

 

Fundamentally, I agree that, for rapid prototyping, using the Megafunctions is probably the easiest route, but for the sake of learning how to implement something efficiently and be somewhat architecture agnostic (as well as not relying on third-party tools) - nothing beats hand writing it and taking the time to fully understand the design. 

 

I am a firm believer in the fact that the power of VHDL allows one to be third party tool independent.
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

Hi, 

 

I agree that handcrafting is essential for understanding and then I will use whatever is faster. 

 

By the way you can modify your previous code to be more efficient by using the idea of DDS(or NCO) i.e. generate just one suitable LUT then a use modulo adder to address the table by jumping according to a tuning word value. If you don't want any tuning then just use a fixed word. 

 

This is explained fully in DDS tutorial from AnalogDevices. 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

hi kaz,, 

in NCO i did like that..it generate some file of .v and .mif for sine and cos 

but in that mif file not any data is their,.....can u plz tell me where is the problem
0 Kudos
Altera_Forum
Honored Contributor II
1,193 Views

hi bpadalino.. 

i tried with tone frequency : 44.0e1 but it still giving an error 

Error (10536): VHDL Loop Statement error at complex_tone_ram.vhdl(29): loop must terminate within 10,000 iterations 

 

can u plz modify ur code for that perticular frequency...
0 Kudos
Altera_Forum
Honored Contributor II
1,154 Views

 

--- Quote Start ---  

hi kaz,, 

in NCO i did like that..it generate some file of .v and .mif for sine and cos 

but in that mif file not any data is their,.....can u plz tell me where is the problem 

--- Quote End ---  

 

 

Hi, 

 

You better try the module first, it will work... 

 

you probably have chosen a setting that does not need memory. 

 

I remember there is setting for "Large memory", "small memory" , "cordic" ...etc. 

 

If you choose small memory it uses multipliers, if you choose large memory it 

does not use multiplier but mem could be very large... You can see the resource usage in the GUI. 

 

The cordic uses logic only instead of multipliers and (I believe) it doesn't use memory so no mif data needed. 

 

Kaz
0 Kudos
Reply