---------------------------------------------------------------------------------- --EE 552 -- porta_amp.vhd --Project : Porta-AMP --Author : Kevin Mlazgar -- --Created on : Dec 6, 1999 -- -- Program Functional Description: -- -- This module integrates the Parallel Port interface, -- MP3 Streaming Interface, and DRAM Memory Management -- Interface. -- -- --Max Speed : 29.67 MHz -- -- --Chip/ Input Output Bidir Memory Memory LCs --POF Device Pins Pins Pins Bits % Utilized LCs % Utilized -- --porta_amp -- EPF10K20RC240-4 15 32 16 0 0 % 534 46 % -- -- -- -- -- -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.seg_decode_pkg.all; use work.mem_mgmt_cont_pkg.all; use work.ppi_pkg.all; use work.mp3_decode_pkg.all; entity porta_amp is port ( clock : in std_logic; reset : in std_logic; -- 7 segment display display1 : out std_logic_vector(6 downto 0); -- PPI external lines -- ppi_ready_int : buffer std_logic; -- testing purposes -- external device ports -- ppi_data_in : in std_logic_vector(7 downto 0); ppi_davailn : out std_logic; -- S3 - mode neg. only ppi_xflag : buffer std_logic; -- S4 - mode neg. only ppi_ackdreq : out std_logic; -- S5 - mode neg. only ppi_intr : out std_logic; -- S6 - mode neg. only ppi_waitn : out std_logic; -- /S7 - EPP handshaking ppi_writen : in std_logic; -- /C0 - EPP handshaking ppi_dstroben : in std_logic; -- /C1 - EPP handshaking ppi_astroben : in std_logic; -- /C3 - EPP handshaking ppi_ninit : in std_logic; -- C2 - ppi reset -- DRAM external lines -- -- RAS lines to DRAM -- acts as bank select rasn : out std_logic_vector(3 downto 0); -- CASN line to common CASN line on DRAM DIMM casn : out std_logic; -- write enable line to DRAM -- '1' indicates a READ from DRAM -- '0' indicates a WRITE to DRAM wen : out std_logic; -- data path to DRAM dram_datapath : inout std_logic_vector(15 downto 0); -- address path to DRAM (time multiplexed address lines) dram_addresspath : out std_logic_vector(9 downto 0); -- MP3 external signals -- mp3_demand : in std_logic; mp3_chipclk : out std_logic; mp3_chipresetn : out std_logic; mp3_dataout: out std_logic ); end entity porta_amp; architecture mixed of porta_amp is type state_type is (ppi_check, ppi_getting_data, write_check, write_wait1, write_wait2, end_write, read_check, read_wait_for_valid_data1, read_wait_for_valid_data2, mp3_check, send_mp3_data ); signal state : state_type; signal display_data1 : std_logic_vector(3 downto 0); signal mc_ram_ready_int : std_logic; signal mc_ram_enable_int : std_logic; signal mc_ram_read_write_int : std_logic; signal mc_ram_no_data_int : std_logic; signal mc_cmd_ack_int : std_logic; signal count, count_end : std_logic_vector(21 downto 0); signal delay_done : std_logic; -- PPI signals signal ppi_data_out_int : std_logic_vector(15 downto 0); signal ppi_download_int : std_logic; -- in from Master Control -- signal ppi_ready_int : std_logic; -- out to Master Control signal ppi_dldone_int : std_logic; -- out to Master Control signal ppi_timeout_int : std_logic; -- out to Master Control signal mp3_enable_int, mp3_ready_int, mp3_reset_int : std_logic; signal mp3_datain_int : std_logic_vector(15 downto 0); begin -- have ppi download all the time ppi_download_int <= '1'; epp : ppi port map( -- external device ports -- ppi_data_in => ppi_data_in, ppi_davailn => ppi_davailn, -- S3 - mode neg. only ppi_xflag => ppi_xflag, -- S4 - mode neg. only ppi_ackdreq => ppi_ackdreq, -- S5 - mode neg. only ppi_intr => ppi_intr, -- S6 - mode neg. only ppi_waitn => ppi_waitn, -- /S7 - EPP handshaking ppi_writen => ppi_writen, -- /C0 - EPP handshaking ppi_dstroben => ppi_dstroben, -- /C1 - EPP handshaking ppi_astroben => ppi_astroben, -- /C3 - EPP handshaking ppi_ninit => ppi_ninit, -- C2 - ppi reset -- internal device ports -- ppi_clock => clock, -- global clock ppi_reset => reset, -- global reset ppi_download => ppi_download_int, -- in from Master Control ppi_ready => ppi_ready_int, -- out to Master Control ppi_dldone => ppi_dldone_int, -- out to Master Control ppi_timeout => ppi_timeout_int, -- out to Master Control ppi_data_out => ppi_data_out_int ); dram_cont : mem_mgmt_cont port map ( -- clock mem_mgmt_clk => clock, -- reset mem_mgmt_reset => reset, -- **************************** -- ** DRAM Interface Signals ** -- RAS lines to DRAM -- acts as bank select rasn => rasn, -- CASN line to common CASN line on DRAM DIMM casn => casn, -- write enable line to DRAM -- '1' indicates a READ to DRAM -- '0' indicates a WRITE from DRAM wen => wen, -- data path to DRAM dram_datapath => dram_datapath, -- address path to DRAM (time multiplexed address lines) dram_addresspath => dram_addresspath, -- ****************************** -- ** Porta-AMP Direct Signals ** -- signal to the master indicating that the interface is ready for -- a command. -- The master should NEVER address the sdram interface if this -- signal is low. -- If a read or write had been issued or a refresh is in progress this -- signal will go low during the access. When it goes high again there -- is valid data available on the mc_datapath_out for a read, -- or the write is done. mc_ram_ready => mc_ram_ready_int, -- client active-high Chip Select signal is asserted when cpu is addressing -- the memory management controller. -- The data will be loaded into the write_data register of -- the primary data path if a write is also being issued... mc_ram_enable => mc_ram_enable_int, -- client read/writen line -- '1' indicates a READ -- '0' indicates a WRITE -- A 1 clock period latency is required to switch between these. -- i.e. wait a period before asserting mc_ram_enable! -- While doing a read or a write hold this signal at its value and -- assert mc_ram_enable to do another read or write. Once this signal -- is changed a further read or write will occur at the start of memory. mc_ram_read_write => mc_ram_read_write_int, -- signal indicating that there is no valid song data in sdram or -- that have reached end of present song... mc_ram_no_data => mc_ram_no_data_int, -- data path to Porta_AMP master mc_datapath_in => ppi_data_out_int, mc_datapath_out => mp3_datain_int ); mp3_decoder : mp3 generic map ( datawidth => 16, clock_divider =>5 ) port map ( mp3_clock => clock, mp3_reset => mp3_reset_int, mp3_enable => mp3_enable_int, mp3_ready => mp3_ready_int, mp3_datain => mp3_datain_int, -- external connections mp3_demand => mp3_demand, mp3_chipclk => mp3_chipclk, mp3_chipresetn => mp3_chipresetn, mp3_dataout => mp3_dataout ); with state select display_data1 <= "0001" when ppi_check, "0010" when ppi_getting_data, "0011" when write_check, "0100" when write_wait1, "0101" when write_wait2, "0110" when end_write, "0111" when read_check, "1000" when read_wait_for_valid_data1, "1001" when read_wait_for_valid_data2, "1010" when mp3_check, "1011" when send_mp3_data, "1100" when others; seg7_dec1 : seg_decode port map ( value => display_data1, decode => display1 ); with state select mc_ram_enable_int <= '1' when write_check, '1' when read_check, '0' when others; with state select mc_ram_read_write_int <= '0' when ppi_check, '0' when ppi_getting_data, '0' when write_check, '0' when write_wait1, '0' when write_wait2, '1' when end_write, '1' when others; with state select mp3_reset_int <= '1' when end_write, '0' when others; with state select mp3_enable_int <= '1' when send_mp3_data, '0' when others; StateLogic : process (reset, clock) begin if reset = '0' then state <= ppi_check; elsif rising_edge(clock) then case state is when ppi_check => if ppi_dldone_int = '1' then -- will assume got data state <= end_write; elsif ppi_ready_int = '0' then state <= ppi_getting_data; else state <= ppi_check; end if; when ppi_getting_data => if ppi_dldone_int = '1' then -- will assume got data state <= end_write; elsif ppi_ready_int = '1' then -- got data, so save it state <= write_check; else state <= ppi_getting_data; end if; -- check if dram is ready -- assert mc_ram_enable high and mc_ram_read_write low when write_check => if mc_ram_ready_int = '1' then state <= write_wait1; else state <= write_check; end if; when write_wait1 => if mc_ram_ready_int = '0' then state <= write_wait2; else state <= write_wait1; -- should NEVER occur end if; when write_wait2 => if mc_ram_ready_int = '1' then state <= ppi_check; else state <= write_wait2; end if; -- indicate to DRAM that the write is over -- by deasserting the mc_ram_read_write to high when end_write => state <= read_check; -- check if dram is ready -- assert mc_ram_enable high and mc_ram_read_write high -- to start a read as soon as is ready... when read_check => if mc_ram_ready_int = '1' and mc_ram_no_data_int = '0' then state <= read_wait_for_valid_data1; else state <= read_check; end if; -- verify request being serviced when read_wait_for_valid_data1 => if mc_ram_ready_int = '0' then state <= read_wait_for_valid_data2; else state <= read_wait_for_valid_data1; end if; -- data out should be valid after here when read_wait_for_valid_data2 => if mc_ram_ready_int = '1' then state <= mp3_check; else state <= read_wait_for_valid_data2; end if; -- we have valid data here so check if mp3 streamer -- wants it... when mp3_check => if mp3_ready_int = '1' then -- mp3 ready for data state <= send_mp3_data; else state <= mp3_check; end if; -- put mp3_enable high to send data when send_mp3_data => if mp3_ready_int = '0' then -- mp3 has gotten data state <= read_check; else state <= send_mp3_data; end if; end case; end if; end process StateLogic; end mixed;