- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
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