Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16623 Discussions

Quartus VHDL compiler returns error 10818

Altera_Forum
Honored Contributor II
2,578 Views

Hello. 

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

Warning (10631): VHDL Process Statement warning at AddrDecoder.vhd(20): inferring latch(es) for signal or variable "dataout_s", which holds its previous value in one or more paths through the process 

Error (10818): Can't infer register for "dataout[0]" at AddrDecoder.vhd(61) becuse it does not hold its value outside the clock edge 

 

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. 

 

The code is:  

library IEEE; 

use IEEE.std_logic_1164.all; 

 

entity addrdecoder is 

port( 

    inbit : in std_logic; 

    clk : in std_logic; 

    sel : in std_logic; 

    dataout : out std_logic_vector(7 downto 0); 

    complete : out std_logic; 

    flat: in std_logic_vector(2 downto 0)); 

end addrdecoder; 

 

architecture arc_addrdecoder of addrdecoder is 

signal dataout_s : std_logic_vector(7 downto 0); 

signal done: std_logic; 

signal currbit : std_logic_vector(2 downto 0); 

begin 

process(sel,clk,done) 

begin 

    if(sel='1') then 

        dataout<=x"0f"; 

        dataout_s<=x"0f"; 

        done<='0'; 

        currbit<="000"; 

else 

        if(clk'event and clk='1' and done='0') then 

            case currbit is 

                when "000" =>  

                    dataout_s(7)<=inbit; 

                    currbit<="001"; when "001" =>  

                    dataout_s(6)<=inbit; 

                    currbit<="010"; when "010" =>  

                    dataout_s(5)<=inbit; 

                    currbit<="011"; when "011" =>  

                    dataout_s(4)<=inbit; 

                    currbit<="100"; when "100" =>  

                    dataout_s(3)<=inbit; 

                    currbit<="101"; when "101" =>  

                    dataout_s(2)<=inbit; 

                    currbit<="110"; when "110" =>  

                    dataout_s(1)<=inbit; 

                    currbit<="111"; when "111" =>  

                    currbit<="111"; 

                    done<='1'; when others => 

                     dataout_s<=x"FF"; 

            done<='0'; 

             currbit<="000"; [/INDENT] end case;[/INDENT] 

end if;[/INDENT] 

end if; 

if(done'event and done='1') then 

     if(flat=dataout_s(6 downto 4)) then 

     dataout<=dataout_s; 

            dataout(0)<=inbit; 

end if;[/INDENT] 

end if; 

end process;  

complete<=done; [/INDENT]end arc_addrdecoder;  

 

configuration cfg_addrdecoder of addrdecoder is 

for arc_addrdecoder 

end for; 

end cfg_addrdecoder; 

 

The code should do the following:  

1) the sel pin is reset pin. when it is high the output is x"0f" 

2) when the sel is going low the chip will get 8 pulses of the clock pushing "inbit" from MSB to LSB into the register "dataout_s" 

3) after 8 clk pulses the code will compare the pushed data, bits 4 to 6 ,to an external address "flat" and if it is equal then the pushed data will be transfered to the dataout pins and complete signal will become high. 

 

Thanks all.
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
1,162 Views

You have two problems in your code. 

 

First, your reset is asynchronous, but it deviates from the standard idiom for registers with asynchronous resets. Many synthesis tools require that certain hardware constructs be described with very specific idiomatic code, because they aren't intelligent enough to infer the right thing in every situation. Registers with asynchronous resets are one of those constructs. I think you may find that you have to replace your "else if(clk'event ... ) then ... end if; end if;" with "elsif (clk'event ... ) then ... end if;" to make Quartus happy. You may also have to move the "and done = '0'" into a nested if statement of its own. I'm not sure how much of that will be necessary though; Quartus may be one of the more flexible tools in this regard. 

 

Secondly, your "if(done'event and done='1') then" code is well and truly unsynthesizable. You've written it to say that the comparison should be done _immediately_ once done is loaded with '1' (i.e., without waiting for the next clock edge) and that the results should be loaded asynchronously. That's just not doable in hardware. You need to move it into your clocked code above and remove the done'event part.
0 Kudos
Altera_Forum
Honored Contributor II
1,162 Views

Oh, now that I actually look at what your circuit is meant to do, I should also mention that there's a more efficient way to do it. Look up "shift registers" on the web if you're interested.

0 Kudos
Altera_Forum
Honored Contributor II
1,162 Views

One last thing; you'll need to rework the cycle timing if you intended to load 8 inbits in a row. Otherwise changing the final code from asynchronous to synchronous will make you load the last "inbit" value one cycle late. To fix, you could move the final code into the 'when "111"' clause itself. But I'd recommend that you look up shift registers instead and rewrite your code.

0 Kudos
Altera_Forum
Honored Contributor II
1,162 Views

Here is the VHDL code,i have make it OK! 

It works! 

 

library IEEE; 

use IEEE.std_logic_1164.all; 

 

entity addrdecoder is 

port( 

inbit : in std_logic; 

clk : in std_logic; 

sel : in std_logic; 

dataout : out std_logic_vector(7 downto 0); 

complete : out std_logic; 

flat: in std_logic_vector(2 downto 0) 

); 

end addrdecoder; 

 

architecture arc_addrdecoder of addrdecoder is 

signal dataout_s : std_logic_vector(7 downto 0); 

signal done: std_logic; 

signal currbit : std_logic_vector(2 downto 0); 

begin 

process(sel,clk,done) 

begin 

if(sel='1') then 

dataout<=x"0f"; 

dataout_s<=x"0f"; 

done<='0'; 

currbit<="000"; 

elsif(clk'event and clk='1' ) then 

if done='0' then 

case currbit is 

when "000" =>  

dataout_s(7)<=inbit; 

currbit<="001"; 

when "001" =>  

dataout_s(6)<=inbit; 

currbit<="010"; 

when "010" =>  

dataout_s(5)<=inbit; 

currbit<="011"; 

when "011" =>  

dataout_s(4)<=inbit; 

currbit<="100"; 

when "100" =>  

dataout_s(3)<=inbit; 

currbit<="101"; 

when "101" =>  

dataout_s(2)<=inbit; 

currbit<="110"; 

when "110" =>  

dataout_s(1)<=inbit; 

currbit<="111"; 

when "111" =>  

currbit<="111"; 

done<='1'; 

when others => 

dataout_s<=x"FF"; 

done<='0'; 

currbit<="000"; 

end case; 

if(done'event and done='1') then 

if(flat=dataout_s(6 downto 4)) then 

dataout<=dataout_s; 

dataout(0)<=inbit; 

end if; 

end if; 

end if; 

end if; 

end process;  

complete<=done;  

end arc_addrdecoder;  

 

configuration cfg_addrdecoder of addrdecoder is 

for arc_addrdecoder 

end for; 

end cfg_addrdecoder;
0 Kudos
Reply