library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; -- Family MAX7000 -- LC 39 -- FlipFlops 36 -- Proposed Freq. 50MHZ (Period 20 ns) -- (Wait states: 0,1,2,3) entity microbus is port ( clk,reset : in std_logic; -- Porte verso il microprocessore Micro_mr : in std_logic; Micro_addr : in std_logic_vector(15 downto 0); Micro_data : out std_logic_vector(15 downto 0); Ready : out std_logic; -- Porte verso le memorie esterne Mem_mr : out std_logic; Mem_addr : out std_logic_vector(15 downto 0); Mem_data : in std_logic_vector(15 downto 0) ); end microbus; architecture b of microbus is type stato is (idle,waitstate,read); signal cs,ns : stato; signal ws,nws : unsigned(1 downto 0); signal ck_addr: std_logic_vector(15 downto 0); begin -- Processo sequenziale process(clk,reset) begin if reset='1' then cs <= idle; ws <= conv_unsigned(0,2); elsif clk'event and clk='1' then cs <= ns; ws <= nws; end if; end process; -- Campionamento dell'indirizzo valido dal microprocessore (processo sequenziale) -- Viene utilizzato per tenere costante l'indirizzo durante tutti i wait states -- (registro senza reset ma con enable) process(clk) begin if clk'event and clk='1' then if cs=idle and Micro_mr='1' then ck_addr <= Micro_Addr; end if; end if; end process; -- Campionamento del Dato valido dalla memoria (processo sequenziale) -- Viene utilizzato per immagazzinare il dato letto dopo i wait states -- fino alla prossima operazione di lettura -- (registro senza reset ma con enable) process(clk) begin if clk'event and clk='1' then if cs=read then Micro_data <= Mem_data; end if; end if; end process; process(cs,ws,Micro_mr,Micro_addr,ck_addr) begin case cs is when idle=> Mem_addr <= (others=>'Z'); Ready <= '1'; Mem_mr <= '0'; if Micro_mr='0' then ns <= idle; nws <= Conv_unsigned(0,2); else if Micro_addr(7 downto 6)="00" then ns <= read; nws <= Conv_unsigned(0,2); elsif Micro_addr(7 downto 6)="01" then ns <= waitstate; nws <= Conv_unsigned(1,2); elsif Micro_addr(7 downto 6)="10" then ns <= waitstate; nws <= Conv_unsigned(0,2); elsif Micro_addr(7 downto 6)="11" then ns <= waitstate; nws <= Conv_unsigned(2,2); else ns <= idle; nws <= Conv_unsigned(0,2); end if; end if; when waitstate => Mem_addr <= ck_addr; Ready <= '0'; Mem_mr <= '1'; if ws>Conv_unsigned(0,2) then ns <= waitstate; nws <= ws-Conv_unsigned(1,2); else ns <= read; nws <= Conv_unsigned(0,2); end if; when read => Mem_addr <= ck_addr; Mem_mr <= '1'; Ready <= '0'; ns <= idle; nws <= Conv_unsigned(0,2); end case; end process; end b;