Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Urgent Help Needed in VHDL

i have got a code from some forum regarding NCO(NUMERICALLY CONTROLLED OSCILLATOR).

but when i compile the code in MODELSIM,it gives just 1 ERROR:

** Error: E:/project/nco1.vhd(67): near "constant": expecting: END

** Error: E:/project/nco1.vhd(68): near "constant": expecting: END

HERE IS THE CODE FOR NCO:

--------------------------------------------------------------------------

-- --

-- Numeric Oscillator --

-- with quadrature output and pipeline --

-- Not usable at full clock frequency (clk_en always '1') !! --

-- --

-- --

--------------------------------------------------------------------------

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

USE ieee.math_real.all;

ENTITY nco IS

GENERIC

(

NNCO : INTEGER := 10; -- output resolution

NAKKUI : INTEGER := 10; -- akku integer bits

NAKKUF : INTEGER := 6; -- akku fractional bits

FC : REAL := 0.01; -- center frequency / fclk resp. fclk_en

NFRQ : INTEGER := 11 -- frequeny input resolution

);

PORT

(

CLK : IN STD_LOGIC;

RESET : IN STD_LOGIC := '0';

CLK_EN : IN STD_LOGIC; -- clock qualifier

FRQ : IN SIGNED(NFRQ-1 downto 0) := (others => '0'); -- optional frequency modulation/tuning input

DPHI : IN SIGNED(7 downto 0) := (others => '0'); -- optional q output phaseshift

I : OUT SIGNED(NNCO-1 downto 0);

Q : OUT SIGNED(NNCO-1 downto 0);

UPDATE : OUT STD_LOGIC; -- new output data available

SYNC : OUT STD_LOGIC -- I output crosses phase zero

);

END nco;

ARCHITECTURE rtl OF nco IS

CONSTANT FCI : INTEGER := INTEGER(REAL(2**(NAKKUI+NAKKUF))*FC);

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;

SIGNAL romaddress : STD_LOGIC_VECTOR (NAKKUI-2 DOWNTO 0);

SIGNAL romdata : STD_LOGIC_VECTOR (NNCO-2 DOWNTO 0);

SIGNAL romaddress2 : STD_LOGIC_VECTOR (NAKKUI-2 DOWNTO 0);

SIGNAL akku : UNSIGNED (NAKKUI+NAKKUF-1 downto 0);

SIGNAL akku2 : UNSIGNED (1 downto 0); -- Q quadrant info

SIGNAL sgn1 : STD_LOGIC;

SIGNAL sgn2 : STD_LOGIC;

SIGNAL clk_en_v : STD_LOGIC;

SIGNAL clk_en_v2 : STD_LOGIC;

SIGNAL clk_en_v3 : STD_LOGIC;

BEGIN

-- For FPGA devices, this construct infers ROM sine table,

-- RAMless devices (MAX II) must use 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 GENROM;

PROCESS (clk, reset)

VARIABLE n_akku : SIGNED (NAKKUI+NAKKUF-1 downto 0);

VARIABLE ra_s : SIGNED (NAKKUI-2 DOWNTO 0);

BEGIN

if reset = '1'then

akku <= (others => '0');

i <= (others => '0');

q <= (others => '0');

clk_en_v <= '0';

clk_en_v2 <= '0';

clk_en_v3 <= '0';

UPDATE <= '0';

SYNC <= '0';

romaddress <= (others => '0');

romaddress2 <= (others => '0');

elsif rising_edge(clk) THEN

clk_en_v <= CLK_EN;

clk_en_v2 <= clk_en_v;

clk_en_v3 <= clk_en_v2;

UPDATE <= clk_en_v3;

IF CLK_EN = '1' then

n_akku := signed(akku) + fci + frq;

romaddress <= STD_LOGIC_VECTOR(n_akku(akku'left-1 downto NAKKUF));

romaddress2(romaddress2'left-1 downto 0) <= STD_LOGIC_VECTOR(n_akku(akku'left-2 downto NAKKUF));

romaddress2(romaddress2'left) <= NOT n_akku(akku'left-1);

akku <= unsigned(n_akku(akku'left downto 0));

if akku(akku'left)='1' and n_akku(akku'left)='0' then

sync <= '1';

else

sync <= '0';

end if;

akku2 <= unsigned(n_akku(akku'left downto akku'left-1)) + 1;

ELSIF clk_en_v = '1' THEN

sgn1 <= akku(akku'left);

sgn2 <= akku2(1);

ra_s := SIGNED(romaddress2)+dphi;

romaddress <= STD_LOGIC_VECTOR(ra_s);

END IF;

IF clk_en_v2 = '1' THEN

if sgn1 = '0' then

i <= SIGNED('0'& romdata);

else

i <= -SIGNED('0'& romdata);

end if;

ELSIF clk_en_v3 = '1' THEN

if sgn2 = '0' then

q <= SIGNED('0'& romdata);

else

q <= -SIGNED('0'& romdata);

end if;

END IF;

romdata <= SINROM(CONV_INTEGER(UNSIGNED(romaddress)));

end if;

END PROCESS;

END rtl;

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Looks like ModelSim doesn't support a block declarative part in a generate statement. Apparently, I never checked. You have to use a different method for sine table generation, e.g. an initializing function.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This code compiles for me in modelsim 6.4a fine.

    Is there any reason why you have SINROM as a signal an not a constant? you could use a function to generate the rom instead of a generate statement.