- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi,
i've implemented a nco megafunction with a 64 bit phase accumulator in order to obtain very high precision output frequencies. Now to be able to program externally (by microcontroller for example) the phase increment value and also to make my nco fully programmable, i need to write vhdl code for this function: Phase_Inc = Fout*2^N/F_clk. The parameters for the fuction should be Fout, F_clk and N (number of bits). The output should be a std_logic_vector(63 downto 0) in my case. Could you help me? ThanksLink Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- hi, i've implemented a nco megafunction with a 64 bit phase accumulator in order to obtain very high precision output frequencies. Now to be able to program externally (by microcontroller for example) the phase increment value and also to make my nco fully programmable, i need to write vhdl code for this function: Phase_Inc = Fout*2^N/F_clk. The parameters for the fuction should be Fout, F_clk and N (number of bits). The output should be a std_logic_vector(63 downto 0) in my case. Could you help me? Thanks --- Quote End --- try this. you need numeric_std library
function get_phase_inc(Fout,clk,N : natural) return std_logic_vector is
variable phase : integer;
begin
phase := Fout*2**N/clk;
return std_logic_vector(to_unsigned(phase,N));
end function;
signal test : std_logic_vector(7 downto 0);
...
test <= get_phase_inc(10,100,8);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the problem arises when N is 64 as a integer is not enough to represent it.
How could i resolve?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- the problem arises when N is 64 as a integer is not enough to represent it. How could i resolve? --- Quote End --- Indeed.. try this since Fo*2^64/clk = Fo*2^32/clk * 2*32/clk.
function phase_inc(Fout,clk, N : natural) return std_logic_vector is
variable phase : integer;
variable temp1,temp2:unsigned(N/2-1 downto 0);
begin
phase := Fout*(2**N/2)/clk;
temp1 := to_unsigned(phase,32);
phase := (2**N/2)/clk;
temp2 := to_unsigned(phase,32);
return std_logic_vector(temp1*temp2);
end function;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
actually you need to go lower than 2^32 as temp1,temp2 exceed 2^32, try 2^16
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I finally see no way to get value without losing resolution as there is no support for 64 bits range
anyway 64 bits phase accum is too drastic, 24 bits is ok generally- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
looks like this will work (not a function)
constant fo:unsigned(31 downto 0) := x"11110000";
constant fclk : unsigned(31 downto 0) := x"ffff0000";
constant temp: unsigned(95 downto 0) := fo & x"0000000000000000";
constant phase : unsigned(95 downto 0) := temp/fclk;
then choose 64 bits of phase
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ok I'll try this way then I'll let you know...
i don't understand the constant temp.... So if my numbers is: Fo=4050Hz Fclk=250Khz N=64 how could i put them in your code? Thanks- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- ok I'll try this way then I'll let you know... i don't understand the constant temp.... So if my numbers is: Fo=4050Hz Fclk=250Khz N=64 how could i put them in your code? Thanks --- Quote End --- just insert the binary value(in hex) of 4050 for Fo and 250000 for Fclk. Keep everything else same (2**64 is implied by the zeros on temp)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It works thanks
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