mboost-dp1
VHDL - Hvad er en latch??
- Forside
- ⟨
- Forum
- ⟨
- Programmering
Hey gutter, er der en den forklare hvad der menes med en latch??
jeg får denne warning:
jeg får denne warning:
WARNING:Xst:737 - Found 32-bit latch for signal <q>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
#3:
Jo, det er det.
Advarslen betyder at synthesizeren må indsætte nogle latches (hukommelsesenheder) for q nogle steder hvor du ikke selv har bedt om det.
Det skyldes som regel at du ikke har lavet et ordentligt flip-flop register til q, eller at du bruger et signal som om det var en variabel i et programmeringssporg.
Du kan evt. poste din kode, så kan det være jeg kan se hvad der er galt.
Jo, det er det.
Advarslen betyder at synthesizeren må indsætte nogle latches (hukommelsesenheder) for q nogle steder hvor du ikke selv har bedt om det.
Det skyldes som regel at du ikke har lavet et ordentligt flip-flop register til q, eller at du bruger et signal som om det var en variabel i et programmeringssporg.
Du kan evt. poste din kode, så kan det være jeg kan se hvad der er galt.
Emil Melgaard (4) skrev:Det skyldes som regel at du ikke har lavet et ordentligt flip-flop register til q, eller at du bruger et signal som om det var en variabel i et programmeringssporg.
Det er rigtigt at jeg har oprettet q som en variabel i et almindeligt programmeringssprog, ved ikke hvordan man skal sætte sådan en flipflop op...
Kode:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY PS_2_to_lcd IS
PORT ( clk, reset: IN STD_LOGIC;
Ok : IN STD_LOGIC;
Data : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
Start : OUT STD_LOGIC;
RS : OUT STD_LOGIC;
ps2d, ps2c: in std_logic;
rx_en: in std_logic
);
END PS_2_to_lcd;
ARCHITECTURE Behavioral OF PS_2_to_lcd IS
-- Values of every state for initializing the display listed in an array.
TYPE init_values IS ARRAY(0 TO 18) OF STD_LOGIC_VECTOR (7 DOWNTO 0);
CONSTANT Initialize: init_values :=
("00000000",
"00111100",
"00000001",
"10010111",
"00000010",
"00010100",
"00000011",
"10100000",
"00000100",
"00000000",
"00001000",
"00000000",
"00001001",
"00000000",
"00001010",
"00000000",
"00001011",
"00000000",
"00001100");
--Valures of RS for initializing the display listed in an array.
TYPE read_states IS ARRAY(0 TO 18) OF STD_LOGIC;
CONSTANT Read_State: read_states :=
('1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1');
-- Signals for the initialize statemachine
TYPE state_type IS (ini_collect, ini_send, key_collect, key_send);
SHARED VARIABLE q: INTEGER := 0;
SIGNAL state_reg, state_next: state_type;
SIGNAL Key: STD_LOGIC_VECTOR(7 DOWNTO 0);
-- Signals for the PS/2 reader statemachine
type rx_statetype is (idle, dps, load);
signal rx_state_reg, rx_state_next: rx_statetype;
signal filter_reg, filter_next: std_logic_vector(7 downto 0);
signal f_ps2c_reg,f_ps2c_next: std_logic;
signal b_reg, b_next: std_logic_vector(10 downto 0);
signal n_reg,n_next: unsigned(3 downto 0);
signal fall_edge: std_logic;
SIGNAL rx_done_tick: std_logic;
SIGNAL dout: std_logic_vector(7 downto 0);
BEGIN
-- FSM state register
PROCESS(clk, reset)
BEGIN
IF reset='1' THEN
state_reg <= ini_collect;
-- q := "0";
ELSIF (clk'event AND clk = '1') THEN
state_reg <= state_next;
END IF;
END PROCESS;
-- FSM control path next-state logic.
PROCESS(state_reg, Ok, Key, rx_done_tick)
BEGIN
Start <= '0';
state_next <= state_reg;
CASE state_reg IS
WHEN ini_collect =>
Data <= Initialize(q);
RS <= Read_State(q);
state_next <= ini_send;
WHEN ini_send =>
Data <= Initialize(q);
RS <= Read_State(q);
Start <= '1';
IF (Ok = '1') THEN
IF (q <= 17) THEN
q :=q+1;
state_next <= ini_collect;
ELSIF (q = 18) THEN
q := 18;
state_next <= key_collect;
ELSE q := 18;
END IF;
END IF;
WHEN key_collect =>
IF (rx_done_tick = '1') THEN
Data <= Key;
RS <= '0';
state_next <= key_send;
END IF;
WHEN key_send =>
Data <= Key;
RS <='0';
Start <= '1';
IF (Ok = '1') THEN
state_next <= ini_collect;
END IF;
END CASE;
END PROCESS;
Som det ses bruger jeg 'q' til at tælle pladsen i mine arrays op med en.
Nogen forslag til hvordan jeg "flipflopper" q? :)
Problemet er denne her linje:
q :=q+1;
I VHDL sker tingene ikke kun én gang, så med ovenstående linje vil du tælle q op så hurtigt den kan få signalet igennem ALU'en så længe den er i state ini_send.
For at gøre q til en flip-flop (register), kan du kan gøre det samme som du gør med state. Dvs. du laver "q_reg" og "q_next" i stedet for "q".
I din state register process tilføjer du linjen "q_reg := q_next;" der hvor du også har "state_reg <= state_next;", og så sørger du for at alle de steder du læser q bruger du q_reg, og alle de steder hvor du sætter q bruger du q_next.
Linjen fra før kommer så til at blive:
q_next := q_reg;
Så bliver q kun talt op når den clock'er.
q :=q+1;
I VHDL sker tingene ikke kun én gang, så med ovenstående linje vil du tælle q op så hurtigt den kan få signalet igennem ALU'en så længe den er i state ini_send.
For at gøre q til en flip-flop (register), kan du kan gøre det samme som du gør med state. Dvs. du laver "q_reg" og "q_next" i stedet for "q".
I din state register process tilføjer du linjen "q_reg := q_next;" der hvor du også har "state_reg <= state_next;", og så sørger du for at alle de steder du læser q bruger du q_reg, og alle de steder hvor du sætter q bruger du q_next.
Linjen fra før kommer så til at blive:
q_next := q_reg;
Så bliver q kun talt op når den clock'er.
jeg får den samme varning om:
Key:
Data
Rs
Kan du se hvad der gør at de kommer?
q kan jeg godt se, men ikke de tre andre...
Key:
WARNING:Xst:737 - Found 8-bit latch for signal <Key>. Latches may be generated from incomplete case or if statements.
Data
WARNING:Xst:737 - Found 8-bit latch for signal <Data>. Latches may be generated from incomplete case or if statements.
Rs
WARNING:Xst:737 - Found 1-bit latch for signal <RS>. Latches may be generated from incomplete case or if statements.
Kan du se hvad der gør at de kommer?
q kan jeg godt se, men ikke de tre andre...
Key: Så vidt jeg kan se, giver du aldrig key en værdi. Mangler der noget kode?
Data og Rs:
Når den er i tilstand key_collect er det ikke altid Data og Rs får en værdi. Det skal du sørge for at de altid får.
Muligvis bør du også lave en "when others" til din case hvor du giver dem en værdi, men det er jeg ikke helt sikker på om er nødvendigt.
Alternativt kan du give dem en default værdi i starten af process'en, som du gør med "Start".
Data og Rs:
Når den er i tilstand key_collect er det ikke altid Data og Rs får en værdi. Det skal du sørge for at de altid får.
Muligvis bør du også lave en "when others" til din case hvor du giver dem en værdi, men det er jeg ikke helt sikker på om er nødvendigt.
Alternativt kan du give dem en default værdi i starten af process'en, som du gør med "Start".
Nyt problem... hvad Sker der lige for det, denne error poppede op lige pludslig mens jeg rettede det med q tællen. hvad er der galt?
Hele koden:
ERROR:Xst:800 - "C:/Users/steven/Desktop/ASC1/VHDL/LCD_Driver/Init.vhd" line 266: Multi-source on Integers in Concurrent Assignment.
Hele koden:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
ENTITY PS_2_to_lcd IS
PORT ( clk, reset: IN STD_LOGIC;
Ok : INOUT STD_LOGIC;
Data : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
Start : OUT STD_LOGIC;
RS : OUT STD_LOGIC;
ps2d, ps2c: in std_logic; -- key data, key clock
rx_en: in std_logic
);
END PS_2_to_lcd;
ARCHITECTURE Behavioral OF PS_2_to_lcd IS
--=======================================================================
-- Values of every state for initializing the display listed in an array.
--=======================================================================
TYPE init_values IS ARRAY(0 TO 18) OF STD_LOGIC_VECTOR (7 DOWNTO 0);
CONSTANT Initialize: init_values :=
("10000000",
"00111100",
"00000001",
"10010111",
"00000010",
"00010100",
"00000011",
"10100000",
"00000100",
"00000000",
"00001000",
"00000000",
"00001001",
"00000000",
"00001010",
"00000000",
"00001011",
"00000000",
"00001100");
--=======================================================================
--Valures of RS for initializing the display listed in an array.
--=======================================================================
TYPE read_states IS ARRAY(0 TO 18) OF STD_LOGIC;
CONSTANT Read_State: read_states :=
('1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1',
'0',
'1');
--=======================================================================
-- Signals for the initialize statemachine
--=======================================================================
TYPE state_type IS (ini_collect, ini_send, key_collect, key_send);
SHARED VARIABLE q_reg, q_next: INTEGER RANGE 0 to 18 := 0;
SIGNAL state_reg, state_next: state_type;
SIGNAL Key: STD_LOGIC_VECTOR(7 DOWNTO 0);
--=======================================================================
-- Signals for the PS/2 reader statemachine
--=======================================================================
type rx_statetype is (idle, dps, load);
signal rx_state_reg, rx_state_next: rx_statetype;
signal filter_reg, filter_next: std_logic_vector(7 downto 0);
signal f_ps2c_reg,f_ps2c_next: std_logic;
signal b_reg, b_next: std_logic_vector(10 downto 0);
signal n_reg,n_next: unsigned(3 downto 0);
signal fall_edge: std_logic;
SIGNAL rx_done_tick: std_logic;
SIGNAL dout: std_logic_vector(7 downto 0);
--=======================================================================
-- Signal for the Counter to OK
--=======================================================================
SIGNAL count_next, count_reg: std_logic_vector(25 downto 0);
BEGIN
--=======================================================================
-- FSM state register
--=======================================================================
PROCESS(clk, reset)
BEGIN
IF reset='1' THEN
state_reg <= ini_collect;
q_reg := 0;
ELSIF (clk'event AND clk = '1') THEN
state_reg <= state_next;
q_reg := q_next;
END IF;
END PROCESS;
--=======================================================================
-- FSM control path next-state logic.
--=======================================================================
PROCESS(state_reg, Ok, Key, rx_done_tick)
BEGIN
Start <= '0';
state_next <= state_reg;
CASE state_reg IS
WHEN ini_collect =>
Data <= Initialize(q_reg);
RS <= Read_State(q_reg);
state_next <= ini_send;
WHEN ini_send =>
Data <= Initialize(q_reg);
RS <= Read_State(q_reg);
Start <= '1';
IF (Ok = '1') THEN
IF (q_reg <= 17) THEN
q_next:= q_reg+1;
state_next <= ini_collect;
ELSIF (q_reg = 18) THEN
q_reg := 18;
state_next <= key_collect;
ELSE q_reg := 18;
END IF;
END IF;
WHEN key_collect =>
Data <= Initialize(q_reg);
RS <= Read_State(q_reg);
IF (rx_done_tick = '1') THEN
Data <= Key;
RS <= '0';
state_next <= key_send;
END IF;
WHEN key_send =>
Data <= Key;
RS <='0';
Start <= '1';
IF (Ok = '1') THEN
state_next <= ini_collect;
END IF;
END CASE;
END PROCESS;
--=======================================================================
-- PS/2 Keyboard reading part.
--=======================================================================
PROCESS (clk, reset)
begin
if reset='1' then
filter_reg <= (others=>'0');
f_ps2c_reg <= '0';
elsif (clk'event and clk='1') then
filter_reg <= filter_next;
f_ps2c_reg <= f_ps2c_next;
end if;
end process;
filter_next <= ps2c & filter_reg(7 downto 1);
f_ps2c_next <= '1' when filter_reg="11111111" else
'0' when filter_reg="00000000" else
f_ps2c_reg;
fall_edge <= f_ps2c_reg and (not f_ps2c_next);
--=======================================================================
-- fsmd to extract the 8-bit data registers
--=======================================================================
process (clk, reset)
begin
if reset='1' then
rx_state_reg <= idle;
n_reg <= (others=>'0');
b_reg <= (others=>'0');
count_reg <= (others => '0');
elsif (clk'event and clk='1') then
rx_state_reg <= rx_state_next;
n_reg <= n_next;
b_reg <= b_next;
if (Ok = '1') then
count_reg <= (others => '0');
else count_reg <= count_next;
end if;
end if;
end process;
--=======================================================================
-- next-state logic
--=======================================================================
process(rx_state_reg,n_r eg,b_reg,fall_edge,rx_en,ps2d)
begin
rx_done_tick <='0';
rx_state_next <= rx_state_reg;
n_next <= n_reg;
b_next <= b_reg;
case rx_state_reg is
when idle =>
if fall_edge='1' and rx_en='1' then
-- shift in start bit
b_next <= ps2d & b_reg(10 downto 1);
n_next <= "1001";
rx_state_next <= dps;
end if;
when dps => -- 8 danmnmnmnmnnmnta + 1 pairty + 1 stop
if fall_edge='1' then
b_next <= ps2d & b_reg(10 downto 1);
if n_reg = 0 then
rx_state_next <=load;
else
n_next <= n_reg - 1;
end if;
end if;
when load =>
-- 1 extra clock to complete the last shift
rx_state_next <= idle;
rx_done_tick <='1';
end case;
end process;
count_next <= count_reg + 1;
-- Ok <= '1' WHEN count_reg="10111110101111000010000000" ELSE '0';
Ok <= '1' WHEN count_reg="00000000000000000000000011" ELSE '0';
--=======================================================================
-- output
--=======================================================================
dout <= b_reg(8 downto 1); -- data bits
Key <= dout;
END Behavioral;
ELSIF (q_reg = 18) THEN
q_reg := 18;
state_next <= key_collect;
ELSE q_reg := 18;
Du må ikke sætte q_reg direkte til en værdi. Du skal bruge q_next.
Gå til top
Opret dig som bruger i dag
Det er gratis, og du binder dig ikke til noget.
Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.