VHDL codes for the phase accumulator and the LUT required in NCO

Status
Not open for further replies.

anand37

Newbie level 4
Joined
Jan 22, 2008
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,329
please can any one give me the vhdl codes for the phase accumulator and the LUT(look up table) required in a numerically controlled oscillator.
 

vhdl code for dds

Hello,

here are a few snippets, that show how a sine table can be generated from HDL.

Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.math_real.all;

GENERIC
(
NNCO : INTEGER := 10; -- output amplitude resolution
NAKKUI : INTEGER := 10; -- akku integer bits = phase resolution
);
--
--
ARCHITECTURE rtl OF nco IS

CONSTANT ROMSIZE : INTEGER := 2**(NAKKUI-1);
CONSTANT ROMMAX : INTEGER := 2**(NNCO-1)-1;
TYPE SINTAB IS ARRAY(0 TO ROMSIZE-1) OF STD_LOGIC_VECTOR (NNCO-2 DOWNTO 0);
SIGNAL SINROM: SINTAB;

BEGIN

-- For FPGA devices, this construct infers ROM sine table,
-- for RAMless devices (MAX II) an LE based table instead
-- only the 0..pi positive half is represented

GENROM:
FOR idx in 0 TO ROMSIZE-1 GENERATE
CONSTANT x: REAL := SIN(real(idx)*MATH_PI/real(ROMSIZE));
CONSTANT xn: UNSIGNED (NNCO-2 DOWNTO 0) := CONV_UNSIGNED(INTEGER(x*real(ROMMAX)),NNCO-1);
BEGIN
SINROM(idx) <= STD_LOGIC_VECTOR(xn); 
END GENERATE; 

--
--
END;

Regards,
Frank
 
nco code

Is this synthesizble code.byee

Added after 6 minutes:

hi this is the code for NCO/DDS


LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE IEEE.numeric_std.ALL;



ENTITY nco IS
-- Declarations
port ( clk : in std_logic;
reset : in std_logic;
din : in signed(11 downto 0);
dout : out signed(7 downto 0)
);
END nco ;

-- hds interface_end
ARCHITECTURE behavior OF nco IS
type vectype is array (0 to 256) of signed(7 downto 0);
-- ROM cosrom
constant cosrom : vectype := (
0 => "01111111",
1 => "01111111",
2 => "01111111",
3 => "01111111",
4 => "01111111",
5 => "01111111",
6 => "01111111",
7 => "01111111",
8 => "01111111",
9 => "01111111",
10 => "01111111",
11 => "01111111",
12 => "01111111",
13 => "01111111",
14 => "01111111",
15 => "01111111",
16 => "01111111",
17 => "01111111",
18 => "01111111",
19 => "01111111",
20 => "01111111",
21 => "01111111",
22 => "01111111",
23 => "01111111",
24 => "01111111",
25 => "01111110",
26 => "01111110",
27 => "01111110",
28 => "01111110",
29 => "01111110",
30 => "01111110",
31 => "01111110",
32 => "01111110",
33 => "01111101",
34 => "01111101",
35 => "01111101",
36 => "01111101",
37 => "01111101",
38 => "01111101",
39 => "01111100",
40 => "01111100",
41 => "01111100",
42 => "01111100",
43 => "01111100",
44 => "01111011",
45 => "01111011",
46 => "01111011",
47 => "01111011",
48 => "01111010",
49 => "01111010",
50 => "01111010",
51 => "01111010",
52 => "01111010",
53 => "01111001",
54 => "01111001",
55 => "01111001",
56 => "01111001",
57 => "01111000",
58 => "01111000",
59 => "01111000",
60 => "01110111",
61 => "01110111",
62 => "01110111",
63 => "01110111",
64 => "01110110",
65 => "01110110",
66 => "01110110",
67 => "01110101",
68 => "01110101",
69 => "01110101",
70 => "01110100",
71 => "01110100",
72 => "01110100",
73 => "01110011",
74 => "01110011",
75 => "01110011",
76 => "01110010",
77 => "01110010",
78 => "01110010",
79 => "01110001",
80 => "01110001",
81 => "01110001",
82 => "01110000",
83 => "01110000",
84 => "01101111",
85 => "01101111",
86 => "01101111",
87 => "01101110",
88 => "01101110",
89 => "01101101",
90 => "01101101",
91 => "01101101",
92 => "01101100",
93 => "01101100",
94 => "01101011",
95 => "01101011",
96 => "01101010",
97 => "01101010",
98 => "01101010",
99 => "01101001",
100 => "01101001",
101 => "01101000",
102 => "01101000",
103 => "01100111",
104 => "01100111",
105 => "01100110",
106 => "01100110",
107 => "01100101",
108 => "01100101",
109 => "01100100",
110 => "01100100",
111 => "01100011",
112 => "01100011",
113 => "01100010",
114 => "01100010",
115 => "01100001",
116 => "01100001",
117 => "01100000",
118 => "01100000",
119 => "01011111",
120 => "01011111",
121 => "01011110",
122 => "01011110",
123 => "01011101",
124 => "01011101",
125 => "01011100",
126 => "01011100",
127 => "01011011",
128 => "01011011",
129 => "01011010",
130 => "01011001",
131 => "01011001",
132 => "01011000",
133 => "01011000",
134 => "01010111",
135 => "01010111",
136 => "01010110",
137 => "01010101",
138 => "01010101",
139 => "01010100",
140 => "01010100",
141 => "01010011",
142 => "01010010",
143 => "01010010",
144 => "01010001",
145 => "01010001",
146 => "01010000",
147 => "01001111",
148 => "01001111",
149 => "01001110",
150 => "01001110",
151 => "01001101",
152 => "01001100",
153 => "01001100",
154 => "01001011",
155 => "01001010",
156 => "01001010",
157 => "01001001",
158 => "01001000",
159 => "01001000",
160 => "01000111",
161 => "01000111",
162 => "01000110",
163 => "01000101",
164 => "01000101",
165 => "01000100",
166 => "01000011",
167 => "01000011",
168 => "01000010",
169 => "01000001",
170 => "01000001",
171 => "01000000",
172 => "00111111",
173 => "00111110",
174 => "00111110",
175 => "00111101",
176 => "00111100",
177 => "00111100",
178 => "00111011",
179 => "00111010",
180 => "00111010",
181 => "00111001",
182 => "00111000",
183 => "00111000",
184 => "00110111",
185 => "00110110",
186 => "00110101",
187 => "00110101",
188 => "00110100",
189 => "00110011",
190 => "00110011",
191 => "00110010",
192 => "00110001",
193 => "00110000",
194 => "00110000",
195 => "00101111",
196 => "00101110",
197 => "00101101",
198 => "00101101",
199 => "00101100",
200 => "00101011",
201 => "00101010",
202 => "00101010",
203 => "00101001",
204 => "00101000",
205 => "00100111",
206 => "00100111",
207 => "00100110",
208 => "00100101",
209 => "00100100",
210 => "00100100",
211 => "00100011",
212 => "00100010",
213 => "00100001",
214 => "00100001",
215 => "00100000",
216 => "00011111",
217 => "00011110",
218 => "00011110",
219 => "00011101",
220 => "00011100",
221 => "00011011",
222 => "00011011",
223 => "00011010",
224 => "00011001",
225 => "00011000",
226 => "00011000",
227 => "00010111",
228 => "00010110",
229 => "00010101",
230 => "00010100",
231 => "00010100",
232 => "00010011",
233 => "00010010",
234 => "00010001",
235 => "00010001",
236 => "00010000",
237 => "00001111",
238 => "00001110",
239 => "00001101",
240 => "00001101",
241 => "00001100",
242 => "00001011",
243 => "00001010",
244 => "00001010",
245 => "00001001",
246 => "00001000",
247 => "00000111",
248 => "00000110",
249 => "00000110",
250 => "00000101",
251 => "00000100",
252 => "00000011",
253 => "00000010",
254 => "00000010",
255 => "00000001",
256 => "00000000");

signal dtemp : unsigned(17 downto 0);
signal din_buf : signed(17 downto 0);
signal dtemp1 : integer;
constant offset : unsigned(17 downto 0) := "000100000000000000";

begin

process(CLK, RESET)
begin
if (RESET='1') then
dout <= (others => '0');
din_buf <= (others => '0');
dtemp <= (others => '0');
dtemp1 <= 0;
elsif rising_edge(CLK) then
din_buf <= din(11)&din(11)&din(11)&din(11)&din(11)&din(11)&din;
dtemp <= dtemp + unsigned(din_buf) + offset;
dtemp1 <= to_integer(dtemp(17 downto 8));
if (dtemp1 >= 0) and (dtemp1 < 257) then
dout <= cosrom(dtemp1);
elsif (dtemp1 >= 257) and (dtemp1 < 513) then
dout <= -cosrom(512-dtemp1);
elsif (dtemp1 >= 513) and (dtemp1 < 769) then
dout <= -cosrom(dtemp1-512);
else
dout <= cosrom(1024-dtemp1);
end if;
end if;
end process;
END behavior;

Added after 1 minutes:

i hope this helped uif so press help button.
 

vhdl nco

Hello,

did you notice, that the table generation code from my example is also synthezisable code? For an 8-Bit address ROM, definition line-by-line seems suitable, for a >10-Bit-adress, it seems somewhat annoying, but of course better understandable.

Regards,
Frank
 

vhdl code for nco

hey frank i understood your logic but i will be very thankful if u can elaborate or give a detailed program........
 

nco verilog

Hi FvM, I'm curious, which synthesis tools support SIN()? I would certainly like to use floating-point math functions in my Verilog `initial section to initialize coefficient ROMs.

I realize that it's difficult to synthesize actual floating point hardware, but it seems straightforward to support floating point during initialization of register arrays and constants.
 

nco, vhdl

Hello,

I don't know of a synthesis tool that doesn't support ieee math_real package for compile time calculations, but could be. Altera does certainly, I would be very surprized if Xilinx can't.

I should mention, that this kind of calculations isn't limited to simple calculations as filling a table. You can perform also perform complex matrix operations. I have a design, where the bit reduction for a CIC flter (pruning) is calculated in VHDL, with the compile time calculations taking more than half of total text.

Regards,
Frank
 

dds vhdl code

Do you have a simple compilable VHDL example that I can try in the Xilinx tools? I'm weak in VHDL, and can't determine if your above example is complete or not. Both XST and ModelSim choke on the "GENERIC" in line 6.

The Xilinx ISE docs say the following, so maybe XST does support VHDL math functions at compile time: "Functions and procedures in the math_real packages, as well as the real type, are for calculations only. They are not supported for synthesis in XST."

XST definitely doesn't support Verilog's math functions or real type.
 

numerically controlled oscillator vhdl

Hello,

Both XST and ModelSim choke on the "GENERIC" in line 6
That must be due to a syntax error, strange general settings, or such. GENERIC should be supported by any VHDL tool. Similar code has been used with ModelSim since years. I give you a complete component definition as reference, unsupported "as is", just saying that it worked in Quartus and ModelSim.

Regards,
Frank

P.S.: I forgot the code
 

numerical controlled oscillator vhdl

can any one send me details of NOC
 

nco vhdl code

Thanks Frank, it works in Xilinx XST. I never realized that XST supported VHDL's 'real' type and math functions during initialization and constants. I'll try encouraging Xilinx to support them in Verilog too.
 
vhdl codes for nco

I have VHDL as my HDL "native language", using Verilog only on customers demand or when editing components. Thus I never considered, if similar tools may exist in Verilog. I'm rather sure, that real arithmetics must exist for Verilog simulation, otherwise the language would be worthless in this field, but I don't know regarding synthesis support.

You should consider the possibility, that a HDL compiler could support some options demanded by the language standard, although they are never mentioned in a manual. This is the case to my knowledge with optional BEGIN statement in the FOR GENERATE loop in my code. Didn't yet find a reference in a VHDL compiler manual, but it's defined in IEEE 1076.
 
sin table vhdl

I only use Verilog. VHDL raises my blood pressure too rapidly.

ModelSim supports Verilog's 'real' type, math functions, and file I/O functions. Very handy in test benches.

IEEE 1364 is my favorite Verilog reference. Much better than any Verilog book or manual I've seen.
 

dds vhdl code fpga

I realize that it's difficult to synthesize actual floating point hardware, but it seems straightforward to support floating point during initialization of register arrays and constants.
 

dds hdl

hi guys im new to vhdl and trying to build a direct digital synthesizer..would be a great help if someone could send me complete vhdl code..
regards
 

nco code list

Hey everyone, well I have a little problem related to the same topic, the nco,



I have the VHDL code for all the components, but I don't know how to make the main code, relating all this components, can anyone help me, please?

adder

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;



entity additionneur is
port(accum,offset,Q:in std_logic_vector (17 downto 0);
C0,S ut std_logic_vector (17 downto 0)
);
end additionneur;

architecture Behavioral of additionneur is
component demi_additionneur
port(accum,offset:in std_logic_vector (17 downto 0);
R,Sut std_logic_vector (17 downto 0)
);
end component;
signal S1,S2,S3:std_logic_vector(17 downto 0);
Begin
instance1:demi_additionneur port map(accum,offset,S1,S2);
instance2:demi_additionneur port map(S2,Q,S3,S);

C0<= S1 or S3;

end Behavioral;

half-adder

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity demi_additionneur is
port(accum,offset:in std_logic_vector (17 downto 0);
R,Sut std_logic_vector (17 downto 0)
);
end demi_additionneur;
architecture Behavioral of demi_additionneur is
begin
S<=accum xor offset;
R<=accum and offset;
end Behavioral;

latch

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity bascule is
port( D:in std_logic_vector (17 downto 0);
clk:in std_logic;
reset: in std_logic;
Qut std_logic_vector (17 downto 0)

);
end bascule;

architecture Behavioral of bascule is

begin
process (clk,reset)

begin
if (reset='1') then Q<="000000000000000000";
elsif (clk'event and clk='1') then Q<=D ;
end if;

end process;
end Behavioral;

cosineROM
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity cosrom is
port (

Entree: in std_logic_vector(17 downto 0);
output: out std_logic_vector(7 downto 0)
);
end cosrom;

architecture Behavioral of cosrom is
type cosROM_Array is array (0 to 256) of std_logic_vector(6 downto 0);
constant Table : cosROM_Array := ( 0 => "1000011",
1 => "1111111",
2 => "1111001",
3 => "1111111",
4 => "1111100",
5 => "1111111",
6 => "1111111",
7 => "1111111",
8 => "1111111",
9 => "1111111",
10 => "1111111",
11 => "1111111",
12 => "1111111",
13 => "1111111",
14 => "1111111",
15 => "1111111",
16 => "1111111",
17 => "1111111",
18 => "1111111",
19 => "1111111",
20 => "1111111",
21 => "1111111",
22 => "1111111",
23 => "1111111",
24 => "1111111",
25 => "1111111",
26 => "1111110",
27 => "1111110",
28 => "1111110",
29 => "1111110",
30 => "1111110",
31 => "1111110",
32 => "1111110",
33 => "1111110",
34 => "1111101",
35 => "1111101",
36 => "1111101",
37 => "1111101",
38 => "1111101",
39 => "1111100",
40 => "1111100",
41 => "1111100",
42 => "1111100",
43 => "1111100",
44 => "1111011",
45 => "1111011",
46 => "1111011",
47 => "1111011",
48 => "1111010",
49 => "1111010",
50 => "1111010",
51 => "1111010",
52 => "1111010",
53 => "1111010",
54 => "1111001",
55 => "1111001",
56 => "1111001",
57 => "1111001",
58 => "1111001",
59 => "1111000",
60 => "1111000",
61 => "1111000",
62 => "1110111",
63 => "1110111",
64 => "1110111",
65 => "1110111",
66 => "1110110",
67 => "1110110",
68 => "1110110",
69 => "1110101",
70 => "1110101",
71 => "1110101",
72 => "1110100",
73 => "1110100",
74 => "1110100",
75 => "1110010",
76 => "1110010",
77 => "1110010",
78 => "1110001",
79 => "1110001",
80 => "1110001",
81 => "1110000",
82 => "1110000",
83 => "1101110",
84 => "1101110",
85 => "1101101",
86 => "1101101",
87 => "1101101",
88 => "1101100",
89 => "1101100",
90 => "1101011",
91 => "1101011",
92 => "1101010",
93 => "1101010",
94 => "1101010",
95 => "1101001",
96 => "1101001",
97 => "1101000",
98 => "1101000",
99 => "1100111",
100 => "1100111",
101 => "1100110",
102 => "1100110",
103 => "1100110",
104 => "1100101",
105 => "1100101",
106 => "1100100",
107 => "1100100",
108 => "1100011",
109 => "1100011",
110 => "1100010",
111 => "1100010",
112 => "1100001",
113 => "1100001",
114 => "1100000",
115 => "1100000",
116 => "1011111",
117 => "1011111",
118 => "1011110",
119 => "1011110",
120 => "1011101",
121 => "1011101",
122 => "1011100",
123 => "1011100",
124 => "1011011",
125 => "1011011",
126 => "1011010",
127 => "1011001",
128 => "1011000",
129 => "1011000",
130 => "1010111",
131 => "1010111",
132 => "1010100",
133 => "1010100",
134 => "1010011",
135 => "1010010",
136 => "1010010",
137 => "1010001",
138 => "1010001",
139 => "1010000",
140 => "1001111",
141 => "1001111",
142 => "1001110",
143 => "1001110",
144 => "1001101",
145 => "1001100",
146 => "1001100",
147 => "1001011",
148 => "1001010",
149 => "1001010",
150 => "1001001",
151 => "1001000",
152 => "1001000",
153 => "1000111",
154 => "1000111",
155 => "1111111",
156 => "1000110",
157 => "1000101",
158 => "1000101",
159 => "1000100",
160 => "1000011",
161 => "1000011",
162 => "1000010",
163 => "1111101",
164 => "1000001",
165 => "1000001",
166 => "1000000",
167 => "0111111",
168 => "0111110",
169 => "0111110",
170 => "0111101",
171 => "0111100",
172 => "0111100",
173 => "0111011",
174 => "0111010",
175 => "0111010",
176 => "0111001",
177 => "0111000",
178 => "0110111",
179 => "0110110",
180 => "0110101",
181 => "0110101",
182 => "0110100",
183 => "0110011",
184 => "0110011",
185 => "0110010",
186 => "0110001",
187 => "0110000",
188 => "0110000",
189 => "0101111",
190 => "0101110",
191 => "0101101",
192 => "0101101",
193 => "0101100",
194 => "0101011",
195 => "0101010",
196 => "0101010",
197 => "0101001",
198 => "0101000",
199 => "0100111",
200 => "0100111",
201 => "0100110",
202 => "0100111",
203 => "0100111",
204 => "0100110",
205 => "0100101",
206 => "0100100",
207 => "0100100",
208 => "0100011",
209 => "0100010",
210 => "0100001",
211 => "0100001",
212 => "0100000",
213 => "0100001",
214 => "0100001",
215 => "0100000",
216 => "0011111",
217 => "0011110",
218 => "0011110",
219 => "0011101",
220 => "0011100",
221 => "0011011",
222 => "0011011",
223 => "0011010",
224 => "0011001",
225 => "0011000",
226 => "0011000",
227 => "0010111",
228 => "0010110",
229 => "0010101",
230 => "0010100",
231 => "0010100",
232 => "0010011",
233 => "0010010",
234 => "0010001",
235 => "0010001",
236 => "0010000",
237 => "0001111",
238 => "0001110",
239 => "0001101",
240 => "0001101",
241 => "0001100",
242 => "0001011",
243 => "0001010",
244 => "0001010",
245 => "0001001",
246 => "0001000",
247 => "0000111",
248 => "0000110",
249 => "0000110",
250 => "0000101",
251 => "0000100",
252 => "0000011",
253 => "0000010",
254 => "0000010",
255 => "0000001",
256 => "1111111"
);
begin
process(Entree)
begin
if (Entree >= "000000000" and Entree <= "100000000") then
output <= '0' & Table (conv_integer(Entree));
elsif (Entree > "100000000" and Entree <= "1000000000") then
output <= '1' & Table (512- conv_integer(Entree));
elsif (Entree > "1000000000" and Entree <= "1100000000") then
output <= '1' & Table ( conv_integer(Entree)- 512);
elsif (Entree > "11000000000" and Entree <= "10000000000") then
output <= '0' & Table ( 1024 - conv_integer(Entree));
end if;
end process;

end Behavioral;
 

nco ieee

hi i got through the codes in the second code given by anand i had a doubt about the simulation it gets stuck during simulation at line 296 where init says error .should the phase be changed evry clock period i mean din
 

vhdl code for NCO

hi Frank,
I am new in Vhdl language and using Altera cyclone III device. I need a code of sin generation table. But when i compile your code, it highlights math_real package. How can i compile your code? How can i check the contents of sin table? I am badly in need of this solution?

Thanks
Nusrat
 

Re: nco code




hello sir.
this code looks quite good for NCO. it is synthesizable too. But i have a problem regarding the understanding of output frequency of nco??
when 8 bit data from LUT is passed through ADC, we get analog value . my point is how do we get the cosine wave? how is output frequency controlled by input data?
 
vhdl code for NCO

from above example:
1024<->2*pi
fo = fclk * din/1024
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…