OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [System09_Trenz_TE0141/] [secd_ram_controller_hans.vhd] - Rev 108

Go to most recent revision | Compare with Previous | Blame | View Log

-- secd_ram_controller.vhd
--
-- Multiplex the external 16 bit SRAM to the 32 bit interface required
-- by the CPU and provide for an 8 bit backside port for the 6809 to
-- read and write SECD memory
 
library ieee;
 
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
entity secd_ram_controller is
  port(
    clk              : in std_logic;
    reset            : in std_logic;
 
    secd_stopped     : in std_logic;
 
                                        -- Internal interface to SECD (16k x 32)
    din32            : in std_logic_vector(31 downto 0);
    dout32           : out std_logic_vector(31 downto 0);
    addr32           : in std_logic_vector(13 downto 0);
    read32_enable    : in std_logic;
    write32_enable   : in std_logic;
    busy32           : out std_logic;
 
                                        -- Internal interface to 6809 (64k x 8)
    clk8             : in std_logic;
    din8             : in std_logic_vector(7 downto 0);
    dout8            : out std_logic_vector(7 downto 0);
    addr8            : in std_logic_vector(15 downto 0);
    rw8              : in std_logic;
    cs8_ram          : in std_logic;
    hold8            : out std_logic;
    cs8_cf           : in std_logic;
 
                                        -- External interface
    ram_oen          : out std_logic;
    ram_cen          : out std_logic;
    ram_wen          : out std_logic;
    ram_io           : inout std_logic_vector(15 downto 0);
    ram_a            : out std_logic_vector(20 downto 1);
    ram_bhen         : out std_logic;
    ram_blen         : out std_logic
    );
end;
 
architecture external_ram of secd_ram_controller is
 
  type hold_state_type is ( hold_release_state, hold_request_state );
 
  signal cf_hold_state : hold_state_type;
 
  signal cf_release  : std_logic;
  signal cf_count    : std_logic_vector(3 downto 0);
 
  type state_type is (idle, 
                      read32_high, read32_high_deselect, read32_low,
                      write32_high, write32_high_deselect, write32_low,
                      read8_ram, write8_ram, read8_cf, write8_cf );
 
  signal state : state_type;
  signal dout8_en : std_logic;
 
begin
 
 
  secd_ram_process : process( clk, state, reset,
                              read32_enable, write32_enable, addr32, din32, 
                              cs8_ram, rw8, addr8, din8 )
  begin
    if reset = '1' then
        ram_a(20 downto 1) <= (others => '0');
        ram_cen  <= '1';
        ram_oen  <= '1';
        ram_wen  <= '1';
        ram_bhen <= '1';
        ram_blen <= '1'; 
        ram_io   <= (others => 'Z');
		  dout8_en <= '0';
        hold8    <= '0';
        busy32   <= '0';
        state    <= idle;
    elsif rising_edge(clk) then
      case state is
        when idle =>
          ram_a(20 downto 1) <= (others => '0');
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          ram_io   <= (others => 'Z');
          dout8_en <= '0';
          if read32_enable = '1' then
            ram_a(1) <= '0';
            ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
            ram_cen  <= '0';
            ram_oen  <= '0';
            ram_wen  <= '1';
            ram_bhen <= '0';
            ram_blen <= '0'; 
            hold8    <= cs8_ram or cs8_cf;
            busy32   <= '1';
            state    <= read32_high;
          elsif write32_enable = '1' then
            ram_a(1) <= '0';
            ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
            ram_cen  <= '0';
            ram_oen  <= '1';
            ram_wen  <= '0';
            ram_bhen <= '0';
            ram_blen <= '0'; 
            ram_io   <= din32(31 downto 16);
            hold8    <= cs8_ram or cs8_cf;
            busy32   <= '1';
            state <= write32_high;
          elsif (cs8_ram = '1') and (rw8 = '1') then
            ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
            ram_cen  <= '0';
            ram_oen  <= '0';
            ram_wen  <= '1';
            ram_bhen <= addr8(0);
            ram_blen <= not addr8(0); 
            dout8_en <= '1';
            hold8    <= '0';
            busy32   <= '1';
            state    <= read8_ram;
          elsif (cs8_ram = '1') and (rw8 = '0') then
            ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
            ram_cen  <= '0';
            ram_oen  <= '1';
            ram_wen  <= '0';
            ram_bhen <= addr8(0);
            ram_blen <= not addr8(0); 
            if addr8(0) = '0' then
              ram_io(15 downto 8) <= din8;
              ram_io( 7 downto 0) <= (others => 'Z');
            else
              ram_io(15 downto 8) <= (others => 'Z');
              ram_io( 7 downto 0) <= din8;
            end if;
            hold8    <= '0';
            busy32   <= '1';
            state    <= write8_ram;
          elsif (cs8_cf = '1') and (rw8 = '1') then
            ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
            dout8_en <= '1';
            busy32   <= '1';
            if cf_release = '1' then
              hold8  <= '0';
              state  <= read8_cf;
            else
              hold8  <= '1';
              state  <= idle;
            end if;
          elsif (cs8_cf = '1') and (rw8 = '0') then
            ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
            busy32   <= '1';
            if addr8(0) = '0' then
              ram_io(15 downto 8) <= din8;
              ram_io( 7 downto 0) <= (others => 'Z');
            else
              ram_io(15 downto 8) <= (others => 'Z');
              ram_io( 7 downto 0) <= din8;
            end if;
            if cf_release = '1' then
              hold8  <= '0';
              state  <= write8_cf;
            else
              hold8  <= '1';
              state  <= idle;
            end if;
          else
            hold8    <= '0';
            busy32   <= '0';
            state    <= idle;
          end if;
 
        when read32_high =>
          ram_a(1) <= '1';
          ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          ram_io   <= (others => 'Z');
			 dout32(31 downto 16) <= ram_io;
          busy32   <= '1';
          dout8_en <= '0';
          hold8    <= cs8_ram or cs8_cf;
          state    <= read32_high_deselect;
 
        when read32_high_deselect =>
          ram_a(1) <= '1';
          ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
          ram_cen  <= '0';
          ram_oen  <= '0';
          ram_wen  <= '1';
          ram_bhen <= '0';
          ram_blen <= '0'; 
          ram_io   <= (others => 'Z');
          busy32   <= '1';
          dout8_en <= '0';
          hold8    <= cs8_ram or cs8_cf;
          state    <= read32_low;
 
        when read32_low =>
          ram_a(1) <= '0';
          ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          ram_io   <= (others => 'Z');
			 dout32(15 downto 0) <= ram_io;
          busy32   <= '0';
          dout8_en <= '0';
          hold8    <= cs8_ram or cs8_cf;
          state    <= idle;
 
        when write32_high =>
          ram_a(1) <= '1';
          ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          ram_io   <= (others => 'Z');
          busy32   <= '1';
          dout8_en <= '0';
          hold8    <= cs8_ram or cs8_cf;
          state    <= write32_high_deselect;
 
        when write32_high_deselect =>
          ram_a(1) <= '1';
          ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
          ram_cen  <= '0';
          ram_oen  <= '1';
          ram_wen  <= '0';
          ram_bhen <= '0';
          ram_blen <= '0'; 
          ram_io   <= din32(15 downto 0);
          busy32   <= '1';
          dout8_en <= '0';
          hold8    <= cs8_ram or cs8_cf;
          state    <= write32_low;
 
        when write32_low =>
          ram_a(1) <= '0';
          ram_a(20 downto 2) <= "00000" & addr32(13 downto 0);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          ram_io   <= (others => 'Z');
          busy32   <= '0';
          dout8_en <= '0';
          hold8    <= cs8_ram or cs8_cf;
          state    <= idle;
 
        when read8_ram =>
          ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_io   <= (others => 'Z');
          busy32   <= '0';
          dout8_en <= '0';
          hold8    <= '0';
          state    <= idle;
 
        when write8_ram =>
          ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_io(15 downto 0) <= (others => 'Z');
          busy32   <= '0';
          dout8_en <= '0';
          hold8    <= '0';
          state    <= idle;
 
        when read8_cf =>
          ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          ram_io   <= (others => 'Z');
          busy32   <= '0';
          dout8_en <= '0';
          hold8    <= '0';
          state    <= idle;
 
        when write8_cf =>
          ram_a(1) <= '1';
          ram_a(20 downto 1) <= "00000" & addr8(15 downto 1);
          ram_cen  <= '1';
          ram_oen  <= '1';
          ram_wen  <= '1';
          ram_bhen <= '1';
          ram_blen <= '1'; 
          busy32   <= '1';
          dout8_en <= '0';
          hold8    <= '0';
          state    <= idle;
 
        when others =>
          null;
 
      end case;
    end if;
  end process;
 
--
-- 8 Bit data bus output enable process
--
-- The point of this process is that data must be
-- passed through from the ram input,
-- and not clocked, so it is ready for the CPU
-- on the trailing clock edge
--  
dout8_selector : process( dout8_en, addr8, ram_io )
begin
    if dout8_en = '0' then
	     dout8 <= ( others => '0' );
    else
        if addr8(0) = '0' then
            dout8 <= ram_io(15 downto 8);
        else
            dout8 <= ram_io(7 downto 0);
        end if;
    end if;
end process;
 
--
-- Hold CF access	for a few cycles
-- synchronize with the CPU clock
-- hold release is set on the rising edge
-- of the CPU clock so that you have one
-- VGA clock cycle to return to the idle state
-- of the secd_ram_process state machine.
--
  cf_hold_proc: process( clk8, reset )
  begin
    if reset = '1' then
      cf_release    <= '0';
      cf_count      <= "0000";
      cf_hold_state <= hold_release_state;
    elsif rising_edge( clk8 ) then
      case cf_hold_state is
        when hold_release_state =>
          cf_release <= '0';
          if cs8_cf = '1' then
            cf_count      <= "0011";
            cf_hold_state <= hold_request_state;
          end if;
 
        when hold_request_state =>
          cf_count <= cf_count - "0001";
          if cf_count = "0000" then
            cf_release    <= '1';
            cf_hold_state <= hold_release_state;
          end if;
        when others =>
          null;
      end case;
    end if;
 
  end process;
 
end;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.