- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...Link Copied
26 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.....- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page