- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, but I use 2 clocks with one clock edges. This isn't synthesizable?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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';
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ---
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page