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

Qurtus vs Modelsim

Altera_Forum
Honored Contributor II
3,400 Views

I wrote code in ModelSim and this code generate wave, who I expected, but Quartus genrate error 

 

Error (10822): HDL error at klaw.vhd(110): couldn't implement registers for assignments on this clock edge 

 

What should I think about this?
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
1,347 Views

 

--- Quote Start ---  

What should I think about this? 

--- Quote End ---  

 

VHDL code isn't always synthesizable. If you try e.g. to assign a signal on both clock edges, it doesn't work in FPGA hardware. Rember that HDL means hardware description language. If no suitable hardware exist for your code, it can't be synthesized.
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

Ok, but I use 2 clocks with one clock edges. This isn't synthesizable?

0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

 

--- Quote Start ---  

Ok, but I use 2 clocks with one clock edges. This isn't synthesizable? 

--- Quote End ---  

 

Do you mean, one signal is assigned depending on two different clock edges? Most likely not synthesizable. You should show a HDL code example for clarification.
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

Quartus throw error in done_ps2'event and done_ps2 = '1'. 

 

process(clk, rst) begin if( rst = '0') then Present_State <= Read_but; elsif( rising_edge(clk) ) then Present_State <= Next_State; end if; end process; process(Present_State, key1, key2, key3, done_ps2) begin case Present_State is when Read_but => code_choice <= "01"; if(key1 = '1') then code_temp <= PushF5; Next_State <= Push; elsif(key2 = '1') then code_temp <= PushLeft; Next_State <= Push; elsif(key3 = '1') then code_temp <= PushRight; Next_State <= Push; else Next_State <= Read_but; end if; when Push => start_ps2 <= '1'; if (done_ps2'event and done_ps2 = '1') then start_ps2 <= '0'; Next_State <= Break; code_choice <= "10"; end if; when Break => start_ps2 <= '1'; if (done_ps2'event and done_ps2 = '1') then start_ps2 <= '0'; Next_State <= Release; code_choice <= "01"; end if; when Release => start_ps2 <= '1'; if (done_ps2'event and done_ps2 = '1') then start_ps2 <= '0'; Next_State <= Read_but; end if; end case; end process;
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

Hi, 

 

Your second process is meant to be combinatorial and should not contain the done_ps2 edge(which is in wrong place anyway). 

 

done_ps2 is not a clock I assume. If you want to use clock edge it must be at beginning of process like your first process. rules of clock edge coding are strict for synthesis. 

 

If you want done_pse ris detection then you can do that by other ways.
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

OK, THX, Now I use process to detect edge in signal done_ps2 and Quartus accepted this structure, but in other file i detect 2 edge in one clock. How else solve this probelm? 

 

--registers process (clk20khz, rst) begin if rst = '0' then Present_State <= ST_idle; c_reg <= (others => '0'); b_reg <= (others => '0'); n_reg <= (others => '0'); elsif (clk20khz'event and clk20khz ='1') then Present_State <= Next_State; c_reg <= c_next; b_reg <= b_next; n_reg <= n_next; end if; end process; --odd parity bit par <= not (dane_we(7) xor dane_we(6) xor dane_we(5) xor dane_we(4) xor dane_we(3) xor dane_we(2) xor dane_we(1) xor dane_we(0)); ----------------------------------------------------------------------------- process(Present_State, n_reg, b_reg, c_reg, dane_we, par, fall_edge, start, clk20khz) begin ---Next_State <= Present_State; c_next <= c_reg; n_next <= n_reg; b_next <= b_reg; ps2c_out <= '1'; ps2d_out <= '1'; tri_c <= '0'; tri_d <= '0'; case Present_State is when ST_idle => done <= '0'; if start = '1' then b_next <= par & dane_we; c_next <= "0000010"; -- wait 100 us Next_State <= ST_rts; else Next_State <= ST_idle; end if; when ST_rts => -- request to send ps2c_out <= '0'; tri_c <= '1'; c_next <= c_reg - 1; if(c_reg = 0) then Next_State <= ST_start; end if; when ST_start => -- assert start bit ps2d_out <= '0'; tri_d <= '1'; ps2c_out <= clk20khz; tri_c <= '1'; if (falling_edge(clk20khz)) then n_next <= "1000"; Next_State <= ST_data; end if; when ST_data => -- 8 data + 1 parity ps2d_out <= b_reg(0); tri_d <= '1'; ps2c_out <= clk20khz; tri_c <= '1'; if (falling_edge(clk20khz)) then b_next <= '0' & b_reg(8 downto 1); if n_reg = 0 then Next_State <= ST_stop; else n_next <= n_reg - 1; Next_State <= ST_data; end if; end if; when ST_stop => -- assume floating high for ps2d if (falling_edge(clk20khz)) then Next_State <= ST_idle; done <= '1'; end if; end case; end process; -- tri_state buffers CLOCK_PS_OUT <= ps2c_out when tri_c = '1' else 'Z'; DATA_PS_OUT <= ps2d_out when tri_d = '1' else 'Z';
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

I am afraid you messed it up now. 

 

Your first code was better relatively. You are repeating the same mistake. 

falling_edge, rising_edge are equivalent to if clk'event ...etc 

 

I reconfirm: 

1) You should use edge triggering at start of your chosen synch process.  

2)If your other process is meant to be combinatorial then don't use edge triggering at all. 

 

To detect rise or fall of any signal level then use your clk as follows: 

 

-- in a clked process 

ps2_1d <= ps2; 

ps2_2d <= ps2_1d; 

 

and outside clked process: 

ps2_rise = ps2_1d and not ps2_2d; 

this will detect rise of ps2 level on your clk(not actual rising edge itself)
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

To be synthesizable, sequential processes must follow the basic scheme shown in the Quartus VHDL templates 

process(reset, clk) is -- Declaration(s) begin if(reset = '1') then -- Asynchronous Sequential Statement(s) elsif(rising_edge(clk)) then -- Synchronous Sequential Statement(s) end if; end process;  

Edge sensitive expressions inside of a combinational process can't be represented in hardware. If you need e.g. to start a timer from the combinational process, place it in an individual process and make it act on the state variables.
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

Yes, you're right. I must remember that is it HDL not language programming. 

 

Now so fall edge I detect in this way ... 

 

process(clk20khz, rst) begin if rst = '0' then clk_r <= '0'; elsif (rising_edge(clk20khz)) then clk_r <= '1'; clk_r <= not clk_r; end if; end process; fall_edge <= clk_r and (not clk20khz); I get warning that  

"code_choice" "code_temp" "Next_State" "start_ps2" "done", which holds its previous value in one or more paths through the process. 

 

How do I remove this warnings? 

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_signed.all; entity klaw is port( but1, but2, but3 : in std_logic; clk, rst : in std_logic; DATA_PS_OUT, CLOCK_PS_OUT : inout std_logic ); end klaw; architecture klaw_arch of klaw is component ps2 port( rst, clk20khz : in std_logic; start : in std_logic; done : out std_logic; DATA_PS_OUT, CLOCK_PS_OUT : inout std_logic; dane_we : in std_logic_vector(7 downto 0) ); end component; component dzielnik_f generic( NBit : integer := 19; --4 --19 - 10Hz Div : integer := 250000 --2 --250000 - 10Hz ); port( clk, rst : in std_logic; --50MHz clk_out : out std_logic --1MHz ); end component; component debounce port( clk_in : in std_logic; D_in : in std_logic; Q_out : buffer std_logic := '0' ); end component; type State is (Read_but, Push, Break, Release); signal Present_State, Next_State : State; signal clk10Hz, clk20khz: std_logic; signal key1, key2, key3 : std_logic; signal code : std_logic_vector(7 downto 0); constant PushF5 : std_logic_vector(7 downto 0) := "00111111"; constant PushESC : std_logic_vector(7 downto 0) := "00000001"; constant PushRight : std_logic_vector(7 downto 0) := "01001101"; constant PushLeft : std_logic_vector(7 downto 0) := "01001011"; constant ReleaseKey : std_logic_vector(7 downto 0) := "11110000"; signal start_ps2, done_ps2, done : std_logic; signal code_temp : std_logic_vector(7 downto 0); signal code_choice : std_logic_vector(1 downto 0); begin deb_clk: dzielnik_f generic map(NBit => 8, div => 16) port map(clk => clk, rst => rst, clk_out => clk10Hz); key_1: debounce port map(clk_in => clk10Hz, D_in => but1, Q_out => key1); key_2: debounce port map(clk_in => clk10Hz, D_in => but2, Q_out => key2); key_3: debounce port map(clk_in => clk10Hz, D_in => but3, Q_out => key3); ps2_clk: dzielnik_f generic map(NBit => 9, div => 125) port map(clk => clk, rst => rst, clk_out => clk20kHz); ps2_port: ps2 port map(rst => rst, clk20khz => clk20khz, start => start_ps2, done => done_ps2, DATA_PS_OUT => DATA_PS_OUT, CLOCK_PS_OUT => CLOCK_PS_OUT, dane_we => code); process(done_ps2, rst) begin if( rst = '0') then done <= '0'; elsif( rising_edge(done_ps2) ) then done <= '1'; end if; end process; process(clk, rst) begin if( rst = '0') then Present_State <= Read_but; elsif( rising_edge(clk) ) then Present_State <= Next_State; end if; end process; process(Present_State, key1, key2, key3, done) begin -- start_ps2 <= '0'; -- code_temp <= (others => '0'); -- code_choice <= "00"; -- Next_State <= Read_but; case Present_State is when Read_but => code_choice <= "01"; if(key1 = '1') then code_temp <= PushF5; Next_State <= Push; elsif(key2 = '1') then code_temp <= PushLeft; Next_State <= Push; elsif(key3 = '1') then code_temp <= PushRight; Next_State <= Push; else Next_State <= Read_but; end if; when Push => start_ps2 <= '1'; if (done = '1') then start_ps2 <= '0'; Next_State <= Break; code_choice <= "10"; end if; when Break => start_ps2 <= '1'; if (done = '1') then start_ps2 <= '0'; Next_State <= Release; code_choice <= "01"; end if; when Release => start_ps2 <= '1'; if (done = '1') then start_ps2 <= '0'; Next_State <= Read_but; end if; end case; end process; code <= code_temp when code_choice = "01" else ReleaseKey when code_choice = "10" else (others => 'Z'); end klaw_arch; Quartus throows warning in line 92 and 96.
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

The "inferring latch(es)" warning is given, because for some cases/input conditions no value is assigned to the signals. The compiler  

adds a logic loop to hold the previous state in this cases. You should consider, what's the actual intended logic behaviour. Adding  

Next_State <= Present_State; in front of the case construct is one way to cancel the logic loop, a complete decoding for Next_State another. 

 

I don't see, why a warning is given for signal "done", although I wonder, if the "onw-way" assignment is achieving the intended purpose.  

 

Generally, feeding done to the state machine without synchronzing it to clk before can cause timing violations and unexpected behaviour.  

 

Finally in the below code, clk_r <= '1' is simply ignored: 

elsif (rising_edge(clk20khz)) then clk_r <= '1'; clk_r <= not clk_r; end if;
0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

I have problem. In wector file I have node Next_State, but in report whis value don't appear. 

Compiler shown such a this mesagge 

 

 

--- Quote Start ---  

 

Warning: Compiler packed, optimized or synthesized away node "Next_State". Ignored vector source file node. 

 

--- Quote End ---  

What this mean? 

 

process(clk, rst) begin if( rst = '0') then Present_State <= Read_but; elsif( rising_edge(clk) ) then Present_State <= Next_State; end if; end process; process(Present_State, key1, key2, key3, done) begin case Present_State is when Read_but => start_ps2 <= '0'; if(key1 = '1') then -- code_temp <= PushF5; code_choice <= "00"; Next_State <= Push; elsif(key2 = '1') then -- code_temp <= PushLeft; code_choice <= "01"; Next_State <= Push; elsif(key3 = '1') then -- code_temp <= PushRight; code_choice <= "11"; Next_State <= Push; else -- code_temp <= (others => '0'); code_choice <= "ZZ"; Next_State <= Read_but; end if; when Push => start_ps2 <= '1'; if (done = '1') then start_ps2 <= '0'; Next_State <= Break; code_choice <= "10"; else -- code_temp <= (others => '0'); code_choice <= "ZZ"; Next_State <= Push; end if; when Break => start_ps2 <= '1'; if (done = '1') then start_ps2 <= '0'; Next_State <= Release; code_choice <= "00"; else -- code_temp <= (others => '0'); code_choice <= "ZZ"; Next_State <= Break; end if; when Release => start_ps2 <= '1'; code_choice <= "ZZ"; -- code_temp <= (others => '0'); if (done = '1') then start_ps2 <= '0'; Next_State <= Read_but; else Next_State <= Release; end if; end case; end process; code <= PushF5 when code_choice = "00" else PushLeft when code_choice = "01" else PushRight when code_choice = "11" else ReleaseKey when code_choice = "10" else (others => 'Z');  

 

And what mean this message? 

 

--- Quote Start ---  

 

Warning: Converted tri-state buffer "code[0]" feeding internal logic into a wire 

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
1,347 Views

Next_State isn't a real signal in your design. It doesn't represent an FPGA resource. Present_State is the only real FSM signal, represented by a number of registers. They are loaded with a the new state vector on every clock edge depending on actual state and input conditions. Ony real signals can be shown in Quartus simulation are accessed by SignalTap II.  

 

Also internal tri-state signals don't really exist in an FPGA. They can be used to describe internal connections, but are converted by the design compiler to multiplexers and other logic elements. The warning informs you about this fact.
0 Kudos
Reply