-- +-----------------------------+
-- | Copyright 1995-1996 DOULOS  |
-- |       Library: memory       |
-- |    designer : Tim Pagden    |
-- |     opened: 26 Nov 1995     |
-- +-----------------------------+

library vfp;
library ieee;

architecture original of sram_core_GENERIC is
  use vfp.host_environment_parameters.all;
  use vfp.standard_types.all;
  use vfp.generic_functions.all;
  use vfp.generic_conversions.all;
  use IEEE.std_logic_1164.all;

  constant memory_depth : integer := 2 ** address_width;
  constant num_bits_in_integer : integer := vfp.host_environment_parameters.num_bits_in_integer;
  
  attribute dnh_file_name : string(1 to 12);
  attribute dnh_file_name of sram_core_GENERIC : entity is architecture_DNH_filename; 

begin

  -- address, 0 to 31
  -- memory_depth, 0 to 7
  -- num_slices_in_integer, 4
  -- WE is inactive after the posedge until the -ve edge
  -- CS and OE are both active high

  -- the disadvantage of modeling with integer memory is that there's
  -- no representation of undefined or unknown in the integer memory
  -- itself. As the default value of integer is 100..000 in 32 bit
  -- parlance, you have to be aware that 000..000 could mean 
  -- uninitialized as well as real all-zero data
  ram_access: process (address, cs, we, oe)
    constant num_slices_in_integer : integer := num_bits_in_integer / data_in'length;
    constant memory_depth : integer := (2**(address'length)) / num_slices_in_integer;
    type integer_memory is array (0 to memory_depth-1) of integer;
    variable memory_array : integer_memory;
    variable memory_index : integer;
    variable memory_data : integer;
    variable memory_word : std_ulogic_vector(num_bits_in_integer-1 downto 0);
    variable intra_memory_index : integer;
    variable upper_bound : integer;
    variable invalid_control_signals : boolean;
    variable address_int : integer;
  begin
    data_out <= (others => 'X'); -- initially set output buffers driving unknowns
    if not (cs = '1' or cs = '0') then
      invalid_control_signals := TRUE;
    elsif not (oe = '1' or oe = '0') then
      invalid_control_signals := TRUE;
    elsif not (we = '1' or we = '0') then
      invalid_control_signals := TRUE;
    else
      invalid_control_signals := FALSE;
      data_out <= (others => 'Z'); 
      -- set output buffers high-impedance if memory control signals are valid levels
    end if;
    if not invalid_control_signals then
      -- cs, oe and we must each be 1 or 0 for this branch to be taken
      address_int := to_integer(address);
      if cs = '1' then -- memory access possible
        if oe = '1' then  -- read or clash possible
          if we = '1' then
            -- read cycle
            memory_index := address_int / num_slices_in_integer; -- 4 := 17/4
            -- converts address into index into memory
            memory_data := memory_array(memory_index);
            -- extracts integer where addressed word is placed
            memory_word := to_std_ulogic_vector (memory_data, num_bits_in_integer);
            -- converts integer to 32-bit vector
            intra_memory_index := address_int mod num_slices_in_integer; -- 1 := 17/4
            -- address now used to get word-index of addressed word in 32-bit vector
            upper_bound := (intra_memory_index + 1) * data_out'length;
            -- defines upper index of addressed word in 32-bit vector
            data_out <= To_StdLogicVector (memory_word(upper_bound-1 downto upper_bound-data_out'length));
            -- To_StdLogicVector is IEEE std_logic_1164, drives data bus with addressed memory word
          elsif we = '0' then
            assert false
              report "oe and we are both active." 
              severity warning;
          end if;
        elsif oe = '0' then -- oe is inactive, only write possible
          if (we = '1') and we'event then
            -- write cycle
            memory_index := address_int / num_slices_in_integer; 
            -- converts address into index into memory
            memory_data := memory_array(memory_index);
            -- extracts integer where addressed word is placed
            memory_word := to_std_ulogic_vector (memory_data, num_bits_in_integer);
            -- converts integer to 32-bit vector
            intra_memory_index := address_int mod num_slices_in_integer;
            -- address now used to get word-index of addressed word in 32-bit vector
            upper_bound := (intra_memory_index + 1) * data_in'length;
            -- defines upper index of addressed word in 32-bit vector
            memory_word(upper_bound-1 downto upper_bound-data_in'length) := to_StdULogicVector (data_in);
            -- inserts data into extracted memory word
            -- ... now convert whole word to integer & place back in integer array
            memory_array(memory_index) := to_integer(to_twos_complement(memory_word));
          elsif we = '1' then
            -- both we and oe not active, nowt happens
          elsif we = '0' then
            -- we active, nowt happens until posedge of WE
          end if;
        end if;
      else
        -- memory not selected
      end if;
    else
      assert false
        report "Control signals are not active, memory is not selected."
        severity note;
    end if;
  end process;
  
end original;

<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>