-------------------------------------------------------------------- -- ELETTRONICA dei SISTEMI DIGITALI -- -- Parallela.vhd -------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity parallela is port( clk,reset : in std_logic; addr_bus : in std_logic_vector(0 to 7); data_bus : in std_logic_vector(0 to 7); busy,tr_error : out std_logic; pp_handshake_out: out std_logic; pp_handshake_in : in std_logic; pp_data : out std_logic_vector(0 to 7) ); end parallela; architecture parallela_P of parallela is type stato is (start,richiesta,trasmissione,chiusura); signal cs,ns : stato; signal count,ncount : unsigned(0 to 5); signal time_over,start_transmission : std_logic; signal outgoing_data : std_logic_vector(0 to 7); begin -- Registro a 8 bit contenente il dato da trasmettere. -- Dotato di reset asincrono ed enable (start_transmission) process(clk,reset) begin if reset='1' then outgoing_data <= (others=>'0'); elsif clk'event and clk='1' then if start_transmission='1' then outgoing_data <= data_bus; end if; end if; end process; -- Parte sequenziale della FSM: memorizzazione lo stato della FSM -- Nota: a seconda della presenza o meno di reset nella sensitivity -- list del processo si ha un reset sincrono o asincrono process(clk) begin if reset = '1' or time_over='1' then cs <= start; elsif clk'event and clk='1' then cs <= ns; end if; end process; ---------------- Parte Combinatoria --------------------------------------- -- Address Decoding: Riconosce scritture sulla interfaccia -- dando il via alla trasmissione (combinatorio) process(addr_bus) begin if conv_integer(addr_bus)=16#40# then start_transmission <= '1'; else start_transmission <= '0'; end if; end process; -- Parte combinatoria: determina lo stato futuro !!! process(cs,outgoing_data,start_transmission,pp_handshake_in,time_over) begin case(cs) is when start => -- Determinazione delle uscite: solo tr_Error e' realizzata -- con una descrizione di Mealy .. BUSY <= '0'; PP_DATA <= (others => 'Z'); pp_handshake_out <= '1'; if pp_handshake_in='0' then tr_error <= '1'; else tr_error <= '0'; end if; -- Calcolo dello stato futuro -- Nota: poiche' questo mux e' basato sullo stesso selettore -- del precedente, si sarebbero ottenute prestazioni superiori -- innestando entrambe le scelte nello stesso costrutto if. -- In questo modo si e' voluto preservare la distinzione formale -- tra calcolo dello stato e dell'uscita. -- Lo stato seguente mostra un esempio della scelta opposta! if start_transmission='1' and pp_handshake_in='1' then ns <= richiesta; else ns <= start; end if; when richiesta => -- Determinazione delle uscite BUSY <= '1'; PP_DATA <= (others => 'Z'); pp_handshake_out <= '0'; -- Calcolo dello stato futuro -- (e della uscita tr_error descritta in stile Mealy) if pp_handshake_in='0' then ns <= trasmissione; tr_error <= '0'; elsif time_over='1' then ns <= start; tr_error <= '1'; else ns <= richiesta; tr_error <= '0'; end if; when trasmissione => -- Determinazione delle uscite (descrizione di Moore) BUSY <= '1'; PP_DATA <= outgoing_data; pp_handshake_out <= '0'; tr_error <= '0'; -- Calcolo dello stato futuro if pp_handshake_in='1' then ns <= chiusura; else ns <= trasmissione; end if; when chiusura => -- Determinazione delle uscite (descrizione di Moore) BUSY <= '1'; PP_DATA <= (others => 'Z'); pp_handshake_out <= '1'; tr_error <= '0'; -- Calcolo dello stato futuro ns <= start; when others => BUSY <= '1'; PP_DATA <= (others => 'Z'); pp_handshake_out <= '1'; tr_error <= '0'; -- Calcolo dello stato futuro ns <= start; end case; end process; --- CONTATORE DI TIME OUT ---------------------------------------------------- -- Parte combinatoria: -- Azzeramento contatempo (conto solo se la FSM e'in attesa di risposta dal PC) process(cs,count) begin if (cs=richiesta) then ncount<=count+conv_unsigned(1,6); else ncount<=conv_unsigned(0,6); end if; end process; -- Segnalazione di time over dopo 0.5 microsecondi (a 40 MHZ=> 20 intervalli di Clk) -- Nota: si poteva "Collassare" il processo in quello precedente ma il fatto di -- assegnare elaborazioni indipendenti a processi diversi facilita una maggiore -- efficenza nel processo di sintesi logica. process(ncount) begin if ncount=conv_unsigned(19,6) then time_over<='1'; else time_over<='0'; end if; end process; -- Parte sequenziale process(clk) begin if reset = '1' or time_over='1' then count <= conv_unsigned(0,6); elsif clk'event and clk='1' then count <= ncount; end if; end process; end parallela_p;