------------------------------------------------------------------------------- -- -- memmgr.vhd: three-logical-port memory manager -- Dan R. K. Ports -- 6.111 final project, 2003/12/06 -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; entity memmgr is port ( aaddr, baddr, caddr : in std_logic_vector(14-1 downto 0); adata, bdata, cdata : in std_logic_vector(8-1 downto 0) := (others => 'Z'); aq, bq, cq : out std_logic_vector(8-1 downto 0) := (others => 'Z'); awr, bwr, cwr : in std_logic; clk, reset : in std_logic; areq, breq, creq : in std_logic; adone, bdone, cdone : out std_logic; ramaddr : out std_logic_vector(14-1 downto 0); ramdata : inout std_logic_vector(8-1 downto 0) := (others => 'Z'); -- ramdatain : in std_logic_vector(7 downto 0); -- ramdataout : out std_logic_vector(7 downto 0); curportout : out std_logic_vector(1 downto 0); ramwe : out std_logic); end memmgr; architecture behavioral of memmgr is signal priport : std_logic_vector(1 downto 0) := "01"; signal curport : std_logic_vector(1 downto 0) := "00"; signal aserv, bserv, cserv : std_logic := '0'; signal writing : std_logic := '0'; begin -- behavioral curportout <= curport; -- purpose: select current port to service -- type : combinational -- inputs : clk -- outputs: curport portselect: process (clk, reset) begin -- process portselect if reset = '1' then priport <= "01"; curport <= "00"; elsif rising_edge(clk) then case priport is when "01" => priport <= "10"; if areq = '1' and aserv = '0' then curport <= "01"; elsif breq = '1' and bserv = '0' then curport <= "10"; elsif creq = '1' and cserv = '0' then curport <= "11"; else curport <= "00"; end if; when "10" => priport <= "11"; if breq = '1' and bserv = '0' then curport <= "10"; elsif creq = '1' and cserv = '0' then curport <= "11"; elsif areq = '1' and aserv = '0' then curport <= "01"; else curport <= "00"; end if; when "11" => priport <= "01"; if creq = '1' and cserv = '0' then curport <= "11"; elsif areq = '1' and aserv = '0' then curport <= "01"; elsif breq = '1' and bserv = '0' then curport <= "10"; else curport <= "00"; end if; when others => priport <= "10"; if areq = '1' and aserv = '0' then curport <= "01"; elsif breq = '1' and bserv = '0' then curport <= "10"; elsif creq = '1' and cserv = '0' then curport <= "11"; else curport <= "00"; end if; end case; end if; end process portselect; aserv <= '1' when curport = "01" else '0'; bserv <= '1' when curport = "10" else '0'; cserv <= '1' when curport = "11" else '0'; adone <= aserv; bdone <= bserv; cdone <= cserv; with curport select ramaddr <= aaddr when "01", baddr when "10", caddr when "11", (others => '0') when others; writing <= '1' when (curport = "01" and awr = '1') or (curport = "10" and bwr = '1') or (curport = "11" and cwr = '1') else '0'; ramwe <= writing and not clk; -- purpose: read inputs from ram on falling edge of clock -- type : combinational -- inputs : clk, ramdata, curport -- outputs: adata/bdata/cdata rdmux: process (clk, writing, reset) begin -- process rdmux if falling_edge(clk) then if writing = '0' and reset = '0' then case curport is when "01" => aq <= ramdata; --* when "10" => bq <= ramdata; when "11" => cq <= ramdata; when others => null; end case; end if; end if; end process rdmux; -- purpose: output data for writing -- type : combinational -- inputs : writing, adata, bdata, cdata -- outputs: ramdata wrmux: process (writing, adata, bdata, cdata) begin -- process wrmux if writing = '1' then case curport is when "01" => ramdata <= adata; --* when "10" => ramdata <= bdata; when "11" => ramdata <= cdata; when others => null; end case; else ramdata <= (others => 'Z'); --* -- FIXME for unsim end if; end process wrmux; -- -- purpose: mux data bus appropriately -- -- type : combinational -- -- inputs : curport, adata, bdata, cdata, ramdata, awr, bwr, cwr -- -- outputs: adata, bdata, cdata, ramdata, ramwe -- memmux: process (curport, adata, bdata, cdata, ramdata, awr, bwr, cwr, reset) -- begin -- process memmux -- if reset = '1' then -- adata <= (others => 'Z'); -- bdata <= (others => 'Z'); -- cdata <= (others => 'Z'); -- ramdata <= (others => 'Z'); -- ramwe <= '0'; -- else -- case curport is -- when "01" => -- if awr = '1' then -- ramdata <= adata; -- adata <= (others => 'Z'); -- ramwe <= '1'; -- else -- adata <= ramdata; -- ramdata <= (others => 'Z'); -- ramwe <= '0'; -- end if; -- bdata <= bdata; -- cdata <= cdata; -- -- when "10" => -- if bwr = '1' then -- ramdata <= bdata; -- bdata <= (others => 'Z'); -- ramwe <= '1'; -- else -- bdata <= ramdata; -- ramdata <= (others => 'Z'); -- ramwe <= '0'; -- end if; -- adata <= adata; -- cdata <= cdata; -- -- when "11" => -- if cwr = '1' then -- ramdata <= cdata; -- cdata <= (others => 'Z'); -- ramwe <= '1'; -- else -- cdata <= ramdata; -- ramdata <= (others => 'Z'); -- ramwe <= '0'; -- end if; -- adata <= adata; -- bdata <= bdata; -- -- when others => -- ramwe <= '0'; -- ramdata <= (others => 'Z'); -- end case; -- end if; -- end process memmux; end behavioral;