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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [System09_Trenz_TE0141/] [secd_ram_controller.vhd] - Rev 134

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,	read32_low_deselect,
                      write32_high, write32_high_deselect, write32_low, write32_low_deselect,
							 read8_ram, write8_ram, read8_cf, write8_cf );
 
  signal state, next_state : state_type;
 
  signal read32_buff : std_logic_vector(31 downto 0);
  signal read32_hen, read32_len : std_logic;
 
begin
 
 
secd_ram_process : process( state, 
                            read32_enable, write32_enable, addr32, din32, 
                            cs8_ram, rw8, addr8, din8 )
begin
    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');
		 read32_hen <= '0';
		 read32_len <= '0';
		 dout8      <= (others => '0');
       if read32_enable = '1' then
           hold8  <= '0';
		     busy32 <= '1';
		     next_state <= read32_high;
       elsif write32_enable = '1' then
           hold8  <= '0';
		     busy32 <= '1';
		     next_state <= write32_high;
       elsif (cs8_ram = '1') and (rw8 = '1') then
           hold8  <= '1';
		     busy32 <= '1';
		     next_state <= read8_ram;
       elsif (cs8_ram = '1') and (rw8 = '0') then
           hold8  <= '1';
		     busy32 <= '1';
		     next_state <= write8_ram;
       elsif (cs8_cf = '1') and (rw8 = '1') then
           hold8  <= '1';
		     busy32 <= '1';
		     next_state <= read8_cf;
       elsif (cs8_cf = '1') and (rw8 = '0') then
           hold8  <= '1';
		     busy32 <= '1';
		     next_state <= write8_cf;
       else
           hold8  <= '0';
		     busy32 <= '0';
		     next_state <= idle;
       end if;
 
    when read32_high =>
	    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'; 
		 ram_io <= (others => 'Z');
		 read32_hen <= '1';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= read32_high_deselect;
 
    when read32_high_deselect =>
	    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');
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= read32_low;
 
    when read32_low =>
	    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');
		 read32_hen <= '0';
		 read32_len <= '1';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= read32_low_deselect;
 
    when read32_low_deselect =>
	    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');
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '0';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= idle;
 
    when write32_high =>
	    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);
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= write32_high_deselect;
 
    when write32_high_deselect =>
	    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');
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= write32_low;
 
    when write32_low =>
	    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 <= din32(15 downto 0);
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '0';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= write32_low_deselect;
 
    when write32_low_deselect =>
	    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');
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '0';
		 dout8  <= (others => '0');
		 hold8  <= cs8_ram;
		 next_state <= idle;
 
    when read8_ram =>
		 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); 
		 ram_io <= (others => 'Z');
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 if addr8(0) = '0' then
	       dout8 <= ram_io(15 downto 8);
       else
		    dout8 <= ram_io(7 downto 0);
       end if;
		 hold8 <= '0';
		 -- Synchronize on the CPU clock
		 if clk8 = '1' then
		     next_state <= idle;
       else
		     next_state <= read8_ram;
       end if;
 
    when write8_ram =>
	    ram_a(1) <= '1';
		 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); 
		 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;
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 hold8  <= '0';
		 -- Synchronize on the CPU clock
		 if clk8 = '1' then 
		     next_state <= idle;
       else
		     next_state <= write8_ram;
       end if;
 
 
    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');
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8 <= ram_io(7 downto 0);
		 if cf_release = '1' then
           hold8 <= '0';
		     next_state <= idle;
       else
           hold8 <= '1';
		     next_state <= read8_cf;
       end if;
 
    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'; 
	    ram_io(15 downto 8) <= (others => '0');
		 ram_io( 7 downto 0) <= din8;
		 read32_hen <= '0';
		 read32_len <= '0';
		 busy32 <= '1';
		 dout8  <= (others => '0');
		 if cf_release = '1' then
           hold8 <= '0';
		     next_state <= idle;
       else
           hold8 <= '1';
		     next_state <= write8_cf;
       end if;
 
   when others =>
	    null;
 
	end case;
end process;
 
  --
  -- RAM state machine
  -- clock state transitions
  -- and register 32 bit reads.
  --
  -- Try experimenting with the clock edge
  -- The Clock edge should be the same
  -- as the transition edge of the
  -- 12.5 MHz 6809 clock.
  -- 
  ram_state_machine : process( clk, reset, read32_buff )
  begin
     if reset = '1' then
	      state <= idle;
		   read32_buff <= (others => '0');
     elsif falling_edge( clk ) then
	      state <= next_state;
		   if read32_hen = '1' then
		       read32_buff(31 downto 16) <= ram_io;
         end if;
		   if read32_len = '1' then
		       read32_buff(15 downto 0) <= ram_io;
         end if;
	  end if;
	  dout32 <= read32_buff; 
  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.