Forum Discussion

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

quartus error

Hello.

I am trying to compile some VHDL code (deserializer) in Quartus II and the compiler returns me a bunch of errors:

Error (10818): Can't infer register for "qs[0]" at deserializer.vhd(101) because it does not hold its value outside the clock edge

for all the qs[ ]

I tryed to compile the same source in modelsim and it worked fine. Althought i can make a schematic file or write it in AHDL and it will work as VHDL code. So i cannot understand why the VHDL file is not syntesizable. Maybe someone can help me with it.

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.numeric_std.all;

entity deserializer is

--- {{{ interface signals declaration

port(

--- {{{ system clock

sclk : in std_logic; -- 270 Mhz deserializer clock. Deserializes data into 2-bit words.

pclk : in std_logic; -- 27 Mhz word rate clock.

reset : in std_logic; -- Async active high reset

--- }}}

--- {{{ interface 1

data_in : in std_logic; -- 10-bit parallel unscrambled data in

--- }}}

--- {{{ interface 2

q : out std_logic_vector(9 downto 0) -- 1-bit deserialized data output.

--data_10b_out : out std_logic_vector(9 downto 0); -- 10-bit parallel unscrambled data in

--- }}}

);

end deserializer;

--- }}}

--- {{{ RTL Architecture Declaration

architecture STRUCTURE of deserializer is

--- {{{ internal signals declaration

signal inc : std_logic_vector (3 downto 0):="0000";

signal qs : std_logic_vector(9 downto 0) :="0000000000" ;

--- }}}

begin -- rtl

--- {{{ sequential process

-- purpose: sequential process

-- type : sequential

-- inputs : sclk, rst

-- outputs: q

sync_count : process(sclk,pclk, reset)

--variable inc : std_logic_vector (3 downto 0);

begin

if (reset = '1') then

qs <= "0000000000";

elsif rising_edge(pclk) then

q<=qs ;

-- pour pouvoir synthètiser le bloc avec quartus

end if;

if (rising_edge(sclk)) then

inc <= inc+1;

if (inc = "1001") then -- return to '0' when inc achieve '9'

inc <= "0000";

end if;

case inc is -- i is the counter in 0 to 9

when "0000" => qs(9) <= data_in;

when "0001" => qs(8) <= data_in;

when "0010" => qs(7) <= data_in;

when "0011" => qs(6) <= data_in;

when "0100" => qs(5) <= data_in;

when "0101" => qs(4) <= data_in;

when "0110" => qs(3) <= data_in;

when "0111" => qs(2) <= data_in;

when "1000" => qs(1) <= data_in;

when "1001" => qs(0) <= data_in;

when others => qs <= "0000000000";

end case;

end if;

end process sync_count;

--- }}}

end STRUCTURE;

thank you for your help

10 Replies

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

    You are not supposed to use two clk edges per process, only one per process.

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

    i'm used to use two clk in the same process and it works...i can show you the example of the serializer which i coded in vhdl using two clk in the same process:

    library ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_unsigned.all;

    use ieee.numeric_std.all;

    entity serializer is

    --- {{{ interface signals declaration

    port(

    --- {{{ system clock

    sclk : in std_logic; -- 270 Mhz deserializer clock. Deserializes data into 2-bit words.

    pclk : in std_logic; -- 27 Mhz word rate clock.

    reset : in std_logic; -- Async active high reset

    --- }}}

    --- {{{ interface 1

    data10b : in std_logic_vector(9 downto 0); -- 10-bit parallel unscrambled data in

    --- }}}

    --- {{{ interface 2

    data_out1 : out std_logic

    -- 1-bit deserialized data output.

    --data_10b_out : out std_logic_vector(9 downto 0); -- 10-bit parallel unscrambled data in

    --- }}}

    );

    end serializer;

    --- }}}

    --- {{{ RTL Architecture Declaration

    architecture STRUCTURE of serializer is

    --- {{{ internal signals declaration

    --signal en : std_logic;

    signal data10s : std_logic_vector(9 downto 0); -- 10-bit parallel unscrambled data in

    --- }}}

    SIGNAL index : integer := 9;

    begin -- rtl

    --- {{{ sequential process

    -- purpose: sequential process

    -- type : sequential

    -- inputs : sclk, rst

    -- outputs: q

    sync_count : process(sclk,pclk, reset)

    BEGIN

    if (reset = '1') then data10s <= "0000000000";

    elsif rising_edge(pclk) then

    data10s <= data10b;

    -- inc:="0000";-- pour pouvoir synthètiser le bloc avec quartus

    end if;

    if (rising_edge(sclk)) then

    data_out1 <= data10s(index);

    index <= index - 1;

    if index = 0 then

    index <= 9;

    end if;

    end if;

    end process sync_count;

    --- }}}

    end STRUCTURE;

    so i don't think it doesn't work because of the two clk in the same process..

    what do you think?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    You are not supposed to use two clk edges per process

    --- Quote End ---

    It's something similar. Exactly, the problem is, that qs <= "0000000000"; must be mutual exclusive to the other qs[] assignments. The code should look like this:

    --- Quote Start ---

    if (reset = '1') then

    qs <= "0000000000";

    elsif (rising_edge(sclk)) then

    end if;

    --- Quote End ---

    It is basically allowed, to have multiple clock sensitive blocks in a process, but it doesn't make sense. The code is much clearer with only one clock sensitive condition in a process.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You may have escaped once but not anymore.

    I hav never heard of two edge process in synthesis VHDL.

    It is al too easy to break it up.

    additionally, you can use constrained integer counter then just say:

    qs(count) <= data_in; -- no need for case
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Also consider this:

    you can use the fast clk only 270MHz and then say:

    q(count) <= data_in; -- no need for double register

    your module can just read input on the counter i.e. in place of the parallel clk 27MHz - assuming it is synchronised to 270

    what is left is care with word boundaries
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    sorry but i still have a little problem;

    my new code is:

    ibrary ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_unsigned.all;

    use ieee.numeric_std.all;

    entity deserializer is

    --- {{{ interface signals declaration

    port(

    --- {{{ system clock

    sclk : in std_logic; -- 270 Mhz deserializer clock. Deserializes data into 2-bit words.

    pclk : in std_logic; -- 27 Mhz word rate clock.

    reset : in std_logic; -- Async active high reset

    --- }}}

    --- {{{ interface 1

    data_in : in std_logic; -- 10-bit parallel unscrambled data in

    --- }}}

    --- {{{ interface 2

    q : out std_logic_vector(9 downto 0) -- 1-bit deserialized data output.

    --data_10b_out : out std_logic_vector(9 downto 0); -- 10-bit parallel unscrambled data in

    --- }}}

    );

    end deserializer;

    --- }}}

    --- {{{ RTL Architecture Declaration

    architecture STRUCTURE of deserializer is

    --- {{{ internal signals declaration

    signal inc : std_logic_vector (3 downto 0):="0000";

    signal qs : std_logic_vector(9 downto 0) :="0000000000" ;

    --- }}}

    begin -- rtl

    --- {{{ sequential process

    -- purpose: sequential process

    -- type : sequential

    -- inputs : sclk, rst

    -- outputs: q

    sync_count : process(sclk,pclk, reset)

    --variable inc : std_logic_vector (3 downto 0);

    begin

    if rising_edge(pclk) then

    q<=qs ;

    inc<="0000"; -- <--this coz me a problem in compilation (depends on differents clock edge)..where should i write it?

    end if;

    -- pour pouvoir synthètiser le bloc avec quartus

    if (reset = '1') then

    qs <= "0000000000";

    elsif (rising_edge(sclk)) then

    inc <= inc+1;

    if (inc = "1001") then -- return to '0' when inc achieve '9'

    inc <= "0000";

    end if;

    case inc is -- i is the counter in 0 to 9

    when "0000" => qs(9) <= data_in;

    when "0001" => qs(8) <= data_in;

    when "0010" => qs(7) <= data_in;

    when "0011" => qs(6) <= data_in;

    when "0100" => qs(5) <= data_in;

    when "0101" => qs(4) <= data_in;

    when "0110" => qs(3) <= data_in;

    when "0111" => qs(2) <= data_in;

    when "1000" => qs(1) <= data_in;

    when "1001" => qs(0) <= data_in;

    when others => qs <= "0000000000";

    end case;

    end if;

    end process sync_count;

    --- }}}

    end STRUCTURE;

    how can i get inc="0000" at every rising edge of the pclk, because i would beginig counting at this rising of pclk clock?

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

    i forget to mention that without the red line the code works but don't do the real function

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

    Hi,

    try something like this code:

    serializer

    
    signal clk27_d : std_logic;
    signal count : integer range 0 to 9;
     
    process(reset,clk270)
    begin
    if reset = '1' then
       q <=  '0';
       clk27_d <= '0';
       count <= 0;
    elsif rising_edge(clk270) then
     
       clk27_d <= clk_27; -- for word boundary detection
     
       if clk27 = '1' and clk27_d = '0' then
          count <= 1;
       elsif count = 9 then
          count <= 0;
       else
          count <= count + 1;
       end if;
     
       q <= data_in(count);
     
    end if;
    end process;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Note above code is a serilizer. You can do a desrializer on same basis.

    I possibly got mixed up with serializer/deserilizer

    important note:

    Your desrialiser will not work since there is no indication of word beginning. You must send a signal from serialiser to indicate that, send it with the first bit. or use clk27 edge if properly aligned with data transition.

    desrialiser

    
    signal clk27_d : std_logic;
    signal count : integer range 0 to 9;
     
    process(reset,clk270)
    begin
    if reset = '1' then
       q <=  (others => '0');
       clk27_d <= '0';
       count <= 0;
    elsif rising_edge(clk270) then
     
       clk27_d <= clk_27; -- for word boundary detection
     
       if clk27 = '1' and clk27_d = '0' then
          count <= 1;
       elsif count = 9 then
          count <= 0;
       else
          count <= count + 1;
       end if;
     
       q(count) <= data_in;
     
    end if;
    end process;