------------------------------------------------------------------------------- -- th9958_arbiter.vhd -- VRAM access arbitration block for TH9958 -- -- Copyright (C) 2008 Takayuki Hara -- All rights reserved. ------------------------------------------------------------------------------- -- -- Redistribution and use of this software or any derivative works, -- are permitted provided that the following conditions are met: -- -- 1. Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- 2. Redistributions in binary form must reproduce the above -- copyright notice, this list of conditions and the following -- disclaimer in the documentation and/or other materials -- provided with the distribution. -- 3. Redistributions may not be sold, nor may they be used in a -- commercial product or activity without specific prior written -- permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- ------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY TH9958_ARBITER IS PORT( CLK : IN STD_LOGIC; RESET_N : IN STD_LOGIC; ENABLE : IN STD_LOGIC; DRAM_PRE : IN STD_LOGIC; GRP_REQ : IN STD_LOGIC; SPR_REQ : IN STD_LOGIC; CPU_REQ : IN STD_LOGIC; CMD_REQ : IN STD_LOGIC; CPU_WR : IN STD_LOGIC; CMD_WR : IN STD_LOGIC; CPU_D : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ); CMD_D : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ); GRP_ADR : IN STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SPR_ADR : IN STD_LOGIC_VECTOR( 16 DOWNTO 0 ); CPU_ADR : IN STD_LOGIC_VECTOR( 16 DOWNTO 0 ); CMD_ADR : IN STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SPR_ACK : OUT STD_LOGIC; CPU_ACK : OUT STD_LOGIC; CMD_ACK : OUT STD_LOGIC; SPR_LATCH : OUT STD_LOGIC; CPU_LATCH : OUT STD_LOGIC; CMD_LATCH : OUT STD_LOGIC; IL_MODE : IN STD_LOGIC; -- DRAM INTERFACE DRAM_ADR : OUT STD_LOGIC_VECTOR( 16 DOWNTO 0 ); DRAM_OZ : OUT STD_LOGIC; DRAM_WZ : OUT STD_LOGIC; DRAM_D : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 ) ); END TH9958_ARBITER; ARCHITECTURE RTL OF TH9958_ARBITER IS SIGNAL W_SPR_REQ : STD_LOGIC; SIGNAL W_CPU_REQ : STD_LOGIC; SIGNAL W_CMD_REQ : STD_LOGIC; SIGNAL W_ALL_REQ : STD_LOGIC; SIGNAL W_PRE_WR_REQ : STD_LOGIC; SIGNAL W_RD_REQ : STD_LOGIC; SIGNAL W_WR_REQ : STD_LOGIC; SIGNAL W_REQ01 : STD_LOGIC; SIGNAL W_REQ02 : STD_LOGIC; SIGNAL W_GRP_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_SPR_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_CPU_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_CMD_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PRE_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL FF_SPR_REQ0 : STD_LOGIC; SIGNAL FF_CPU_REQ0 : STD_LOGIC; SIGNAL FF_CMD_REQ0 : STD_LOGIC; SIGNAL FF_SPR_REQ1 : STD_LOGIC; SIGNAL FF_CPU_REQ1 : STD_LOGIC; SIGNAL FF_CMD_REQ1 : STD_LOGIC; SIGNAL FF_SPR_REQ2 : STD_LOGIC; SIGNAL FF_CPU_REQ2 : STD_LOGIC; SIGNAL FF_CMD_REQ2 : STD_LOGIC; SIGNAL FF_DRAM_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL FF_DRAM_OZ : STD_LOGIC; SIGNAL FF_DRAM_WZ : STD_LOGIC; SIGNAL FF_DRAM_D : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); BEGIN SPR_ACK <= FF_SPR_REQ0; CPU_ACK <= FF_CPU_REQ0; CMD_ACK <= FF_CMD_REQ0; SPR_LATCH <= FF_SPR_REQ2; CPU_LATCH <= FF_CPU_REQ2; CMD_LATCH <= FF_CMD_REQ2; DRAM_ADR <= FF_DRAM_ADR; DRAM_OZ <= FF_DRAM_OZ; DRAM_WZ <= FF_DRAM_WZ; DRAM_D <= FF_DRAM_D; --------------------------------------------------------------------------- -- REQUEST SIGNAL --------------------------------------------------------------------------- W_REQ01 <= GRP_REQ OR SPR_REQ; W_REQ02 <= W_REQ01 OR CPU_REQ; W_ALL_REQ <= W_REQ02 OR CMD_REQ; W_SPR_REQ <= (NOT GRP_REQ) AND SPR_REQ; W_CPU_REQ <= (NOT W_REQ01) AND CPU_REQ; W_CMD_REQ <= (NOT W_REQ02) AND CMD_REQ; W_PRE_WR_REQ<= ((NOT W_REQ01) AND CPU_WR) OR ((NOT W_REQ02) AND CMD_WR); W_RD_REQ <= DRAM_PRE AND (NOT W_PRE_WR_REQ) AND W_ALL_REQ; W_WR_REQ <= DRAM_PRE AND W_PRE_WR_REQ; --------------------------------------------------------------------------- -- ACK/LATCH --------------------------------------------------------------------------- PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_SPR_REQ0 <= '0'; FF_CPU_REQ0 <= '0'; FF_CMD_REQ0 <= '0'; FF_SPR_REQ1 <= '0'; FF_CPU_REQ1 <= '0'; FF_CMD_REQ1 <= '0'; FF_SPR_REQ2 <= '0'; FF_CPU_REQ2 <= '0'; FF_CMD_REQ2 <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN FF_SPR_REQ0 <= W_SPR_REQ AND DRAM_PRE; FF_CPU_REQ0 <= W_CPU_REQ AND DRAM_PRE; FF_CMD_REQ0 <= W_CMD_REQ AND DRAM_PRE; FF_SPR_REQ1 <= FF_SPR_REQ0; FF_CPU_REQ1 <= FF_CPU_REQ0; FF_CMD_REQ1 <= FF_CMD_REQ0; FF_SPR_REQ2 <= FF_SPR_REQ1; FF_CPU_REQ2 <= FF_CPU_REQ1; FF_CMD_REQ2 <= FF_CMD_REQ1; END IF; END IF; END PROCESS; --------------------------------------------------------------------------- -- REQUEST --------------------------------------------------------------------------- PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_DRAM_OZ <= '1'; FF_DRAM_WZ <= '1'; ELSIF( CLK'EVENT AND CLK = '1' )THEN FF_DRAM_OZ <= NOT (ENABLE AND DRAM_PRE AND W_RD_REQ); FF_DRAM_WZ <= NOT (ENABLE AND DRAM_PRE AND W_WR_REQ); END IF; END PROCESS; --------------------------------------------------------------------------- -- ADDRESS --------------------------------------------------------------------------- W_GRP_ADR <= GRP_ADR WHEN( GRP_REQ = '1' )ELSE (OTHERS => '0'); W_SPR_ADR <= SPR_ADR WHEN( W_SPR_REQ = '1' )ELSE (OTHERS => '0'); W_CPU_ADR <= CPU_ADR WHEN( W_CPU_REQ = '1' )ELSE (OTHERS => '0'); W_CMD_ADR <= CMD_ADR WHEN( W_CMD_REQ = '1' )ELSE (OTHERS => '0'); W_PRE_ADR <= W_GRP_ADR OR W_SPR_ADR OR W_CPU_ADR OR W_CMD_ADR; W_ADR <= W_PRE_ADR(0) & W_PRE_ADR( 16 DOWNTO 1 ) WHEN( IL_MODE = '1' )ELSE -- INTERLEAVE W_PRE_ADR; -- NORMAL PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_DRAM_ADR <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN FF_DRAM_ADR <= W_ADR; END IF; END IF; END PROCESS; --------------------------------------------------------------------------- -- DATA --------------------------------------------------------------------------- PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_DRAM_D <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( W_CPU_REQ = '1' )THEN FF_DRAM_D <= CPU_D; ELSE FF_DRAM_D <= CMD_D; END IF; END IF; END IF; END PROCESS; END RTL;