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

Subversion Repositories plasma_fpu

[/] [plasma_fpu/] [trunk/] [test/] [vhdl/] [plasma_memory.vhd] - Rev 2

Compare with Previous | Blame | View Log

-- --------------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<
-- --------------------------------------------------------------------------
-- TITLE:       Plasma MEMORY MODEL
-- AUTHOR:      Alex Schoenberger (Alex.Schoenberger@ies.tu-darmstadt.de)
-- COMMENT:     This project is based on Plasma CPU core by Steve Rhoads
 
-- www.ies.tu-darmstadt.de
-- TU Darmstadt
-- Institute for Integrated Systems
-- Merckstr. 25
 
-- 64283 Darmstadt - GERMANY
-- --------------------------------------------------------------------------
-- PROJECT:       Plasma CPU core with FPU
-- FILENAME:      plasma_memory.vhd
-- --------------------------------------------------------------------------
-- COPYRIGHT: 
--  This project is distributed by GPLv2.0
--  Software placed into the public domain by the author.
--  Software 'as is' without warranty.  Author liable for nothing.
-- --------------------------------------------------------------------------
-- DESCRIPTION:
--    memory interface
 
--    NOT SYNTHESIZABLE
 
-- --------------------------------------------------------------------------
-- Revision History
-- --------------------------------------------------------------------------
-- Revision   Date    Author     CHANGES
-- 1.0      4/2014    AS         initial
-- --------------------------------------------------------------------------
library IEEE;
   use IEEE.std_logic_1164.ALL;
   use IEEE.numeric_std.ALL;
 
library STD;
  use STD.textio.ALL;
 
library PLASMA;
   use PLASMA.plasma_pack.ALL;
 
package plasma_memory_pack is
 
  constant PLASMA_MEM_RANGE           : natural         := 25;
  constant PLASMA_MEM_SIZE            : std_logic_vector(PLASMA_MEM_RANGE     - 1 downto 0) := '1' & x"a2_0014";
  constant PLASMA_MEM_SIZE_RANGE      : natural         := to_integer(unsigned(PLASMA_MEM_SIZE));
 
  type t_plasma_memory                is array(PLASMA_MEM_SIZE_RANGE          - 1 downto 0)   of  t_plasma_mem_word;
 
  subtype t_prog_addr                 is std_logic_vector(PLASMA_MEM_RANGE    - 1 downto 0);
  subtype t_data_addr                 is std_logic_vector(PLASMA_MEM_RANGE    - 1 downto 0);
 
  component plasma_memory is
  port(
    clk               : in  std_logic;
    reset             : in  std_logic;
    wr_mask           : in  t_plasma_mask;
    rd_mask           : in  t_plasma_mask;
    prog_addr         : in  t_plasma_word;
    data_addr         : in  t_plasma_word;
    prog_out          : out t_plasma_word;
    data_in           : in  t_plasma_word;
    data_out          : out t_plasma_word
  );
  end component plasma_memory;
 
  procedure read_instr( signal  instr   : out t_plasma_word;
                                addr    : in  t_prog_addr;
                                memory  :     t_plasma_memory );
 
 
  procedure read_heap( signal   data    : out t_plasma_word;
                       signal   data_in : in  t_plasma_word;
                                addr    : in  t_data_addr;
                                mask    : in  t_plasma_mask;
                                memory  :     t_plasma_memory );
 
  procedure write_heap(signal   data    : in  t_plasma_word;
                                addr    : in  t_data_addr;
                                mask    : in  t_plasma_mask;
                       variable memory  : out t_plasma_memory );
 
  procedure printf(             memory  : t_plasma_memory );
 
  function ascii(int: integer) return character;
 
end package plasma_memory_pack;
 
 
package body plasma_memory_pack is
 
  procedure read_instr( signal instr  : out t_plasma_word;
                               addr   : in  t_prog_addr;
                               memory :     t_plasma_memory ) is
    variable i_addr   : natural := 0;
  begin
    i_addr := to_integer(unsigned(addr));
 
    instr(31 downto 24)  <= memory(i_addr    );
    instr(23 downto 16)  <= memory(i_addr + 1);
    instr(15 downto  8)  <= memory(i_addr + 2);
    instr( 7 downto  0)  <= memory(i_addr + 3);
  end procedure read_instr;
 
  procedure read_heap( signal data    : out t_plasma_word;
                       signal data_in : in  t_plasma_word;
                              addr    : in  t_data_addr;
                              mask    : in  t_plasma_mask;
                              memory  :     t_plasma_memory ) is
    variable i_addr    : natural := 0;
  begin
    i_addr := to_integer(unsigned(addr));
 
    case mask is
      when PLASMA_MASK_READ8   =>
        data(31 downto 24)  <= memory(i_addr  );
        data(23 downto 16)  <= memory(i_addr  );
        data(15 downto  8)  <= memory(i_addr  );
        data( 7 downto  0)  <= memory(i_addr  );
 
      when PLASMA_MASK_READ16  =>  
        data(31 downto 24)  <= memory(i_addr  );
        data(23 downto 16)  <= memory(i_addr + 1);
        data(15 downto  8)  <= memory(i_addr  );
        data( 7 downto  0)  <= memory(i_addr + 1);
 
      when PLASMA_MASK_READ32L =>
        data(31 downto 24)  <= memory(i_addr  );
        data(23 downto 16)  <= memory(i_addr + 1);
        data(15 downto  0)  <= data_in(15 downto 0);
 
      when PLASMA_MASK_READ32R  =>
        data(31 downto 16)  <= data_in(31 downto 16);
        data(15 downto  8)  <= memory(i_addr + 2);
        data( 7 downto  0)  <= memory(i_addr + 3);
 
      when PLASMA_MASK_READ32  =>  
        data(31 downto 24)  <= memory(i_addr  );
        data(23 downto 16)  <= memory(i_addr + 1);
        data(15 downto  8)  <= memory(i_addr + 2);
        data( 7 downto  0)  <= memory(i_addr + 3);
 
      when others     => 
        data                <= (others => '0');
    end case;
  end procedure read_heap;
 
  procedure write_heap(signal   data    : in  t_plasma_word;
                                addr    : in  t_data_addr;
                                mask    : in  t_plasma_mask;
                       variable memory  : out t_plasma_memory ) is
    variable i_addr     : natural := 0;
  begin
    i_addr := to_integer(unsigned(addr));
 
    case mask is
      when PLASMA_MASK_WRITE8   =>  
        memory(i_addr    ) := data( 7 downto  0);
 
      when PLASMA_MASK_WRITE16  =>  
        memory(i_addr + 1) := data( 7 downto  0);
        memory(i_addr    ) := data(15 downto  8);
 
      when PLASMA_MASK_WRITE32L =>
        memory(i_addr + 1) := data(23 downto 16);
        memory(i_addr    ) := data(31 downto 24);
 
      when PLASMA_MASK_WRITE32R =>  
        memory(i_addr + 3) := data( 7 downto  0);
        memory(i_addr + 2) := data(15 downto  8);
 
      when PLASMA_MASK_WRITE32  =>  
        memory(i_addr + 3) := data( 7 downto  0);
        memory(i_addr + 2) := data(15 downto  8);
        memory(i_addr + 1) := data(23 downto 16);
        memory(i_addr    ) := data(31 downto 24);
 
      when others               => 
    end case;
 
  end procedure write_heap;
 
  procedure printf( memory : t_plasma_memory ) is
 
    constant ADDR                 : integer := 27394060;
 
    variable message_addr         : t_plasma_word;
    variable message_length       : t_plasma_word;
 
    variable i_addr               : integer;
    variable i_length             : integer;
 
    variable message              : line;
 
  begin
 
    -- get message address and length of the message
    message_addr    := memory(ADDR    ) & memory(ADDR + 1) & memory(ADDR + 2) & memory(ADDR + 3);
    message_length  := memory(ADDR + 4) & memory(ADDR + 5) & memory(ADDR + 6) & memory(ADDR + 7);
 
    -- and convert the values to integer
    i_addr          := to_integer(unsigned(message_addr));
    i_length        := to_integer(unsigned(message_length));
 
    -- initialise the message string
    message         := new string(1 to i_length);
 
    -- read ascii characters, last character is 0
    for i in 0 to i_length - 1 loop
      message(i + 1) := ascii( to_integer(unsigned(memory(i_addr + i))));
    end loop;
 
    -- print message text
    report message.ALL;
 
  end procedure printf;
 
 
  function ascii(int: integer) return character is
      variable c: character;
    begin
      case int is
        when  10 => c := ' ';
        when  32 => c := ' ';
        when  33 => c := '!';
        when  34 => c := '"';
        when  35 => c := '#';
        when  36 => c := '$';
        when  37 => c := '%';
        when  38 => c := '&';
        when  39 => c := ''';
        when  40 => c := '(';
        when  41 => c := ')';
        when  42 => c := '*';
        when  43 => c := '+';
        when  44 => c := ',';
        when  45 => c := '-';
        when  46 => c := '.';
        when  47 => c := '/';
        when  48 => c := '0';
        when  49 => c := '1';
        when  50 => c := '2';
        when  51 => c := '3';
        when  52 => c := '4';
        when  53 => c := '5';
        when  54 => c := '6';
        when  55 => c := '7';
        when  56 => c := '8';
        when  57 => c := '9';
        when  58 => c := ':';
        when  59 => c := ';';
        when  60 => c := '<';
        when  61 => c := '=';
        when  62 => c := '>';
        when  63 => c := '?';
        when  64 => c := '@';
        when  65 => c := 'A';
        when  66 => c := 'B';
        when  67 => c := 'C';
        when  68 => c := 'D';
        when  69 => c := 'E';
        when  70 => c := 'F';
        when  71 => c := 'G';
        when  72 => c := 'H';
        when  73 => c := 'I';
        when  74 => c := 'J';
        when  75 => c := 'K';
        when  76 => c := 'L';
        when  77 => c := 'M';
        when  78 => c := 'N';
        when  79 => c := 'O';
        when  80 => c := 'P';
        when  81 => c := 'Q';
        when  82 => c := 'R';
        when  83 => c := 'S';
        when  84 => c := 'T';
        when  85 => c := 'U';
        when  86 => c := 'V';
        when  87 => c := 'W';
        when  88 => c := 'X';
        when  89 => c := 'Y';
        when  90 => c := 'Z';
        when  91 => c := '[';
        when  92 => c := '\';
        when  93 => c := ']';
        when  94 => c := '^';
        when  95 => c := '_';
        when  96 => c := '`';
        when  97 => c := 'a';
        when  98 => c := 'b';
        when  99 => c := 'c';
        when 100 => c := 'd';
        when 101 => c := 'e';
        when 102 => c := 'f';
        when 103 => c := 'g';
        when 104 => c := 'h';
        when 105 => c := 'i';
        when 106 => c := 'j';
        when 107 => c := 'k';
        when 108 => c := 'l';
        when 109 => c := 'm';
        when 110 => c := 'n';
        when 111 => c := 'o';
        when 112 => c := 'p';
        when 113 => c := 'q';
        when 114 => c := 'r';
        when 115 => c := 's';
        when 116 => c := 't';
        when 117 => c := 'u';
        when 118 => c := 'v';
        when 119 => c := 'w';
        when 120 => c := 'x';
        when 121 => c := 'y';
        when 122 => c := 'z';
        when 123 => c := '{';
        when 124 => c := '|';
        when 125 => c := '}';        
        when 126 => c := '~';
        when others => c := '?'; report "Could not decode this ASCII integer value " & integer'image(int);
      end case;
    return c;
  end ascii;
 
end package body plasma_memory_pack;
 
 
--  _____  _                _____ __  __            __  __ ______ __  __  ____  _______     __
-- |  __ \| |        /\    / ____|  \/  |   /\     |  \/  |  ____|  \/  |/ __ \|  __ \ \   / /
-- | |__) | |       /  \  | (___ | \  / |  /  \    | \  / | |__  | \  / | |  | | |__) \ \_/ / 
-- |  ___/| |      / /\ \  \___ \| |\/| | / /\ \   | |\/| |  __| | |\/| | |  | |  _  / \   /  
-- | |    | |____ / ____ \ ____) | |  | |/ ____ \  | |  | | |____| |  | | |__| | | \ \  | |   
-- |_|    |______/_/    \_\_____/|_|  |_/_/    \_\ |_|  |_|______|_|  |_|\____/|_|  \_\ |_| 
library IEEE;
   use IEEE.std_logic_1164.ALL;
   use IEEE.numeric_std.ALL;
 
library PLASMA;
   use PLASMA.plasma_pack.ALL;
 
library MEMORY;
  use MEMORY.plasma_memory_pack.ALL;
 
entity plasma_memory is
  port(
    clk               : in  std_logic;
    reset             : in  std_logic;
    wr_mask           : in  t_plasma_mask;
    rd_mask           : in  t_plasma_mask;
    prog_addr         : in  t_plasma_word;
    data_addr         : in  t_plasma_word;
    prog_out          : out t_plasma_word;
    data_in           : in  t_plasma_word;
    data_out          : out t_plasma_word
  );
end entity plasma_memory;
 
 
architecture behav_plasma_memory of plasma_memory is
 
  shared variable ram             : t_plasma_memory;
 
  alias inst_addr                 : t_prog_addr is prog_addr(PLASMA_MEM_RANGE - 1 downto 0);
  alias heap_addr                 : t_data_addr is data_addr(PLASMA_MEM_RANGE - 1 downto 0);
 
begin
 
memory_access:
  process( clk )
  begin
    if falling_edge( clk ) then
 
      -- ########### READ INSTRUCTION ###################
      read_instr( prog_out,         inst_addr,          ram );
 
      -- ########### READ HEAP ##########################
      read_heap( data_out, data_in, heap_addr, rd_mask, ram );
 
      -- ########### WRITE HEAP #########################
      write_heap( data_in,          heap_addr, wr_mask, ram );
 
      -- ########### PRINTF FUNCTION ####################
      if i_sim_control.print_message = '1' then
        printf( ram );
      end if;
 
    end if;
  end process;
 
end behav_plasma_memory;

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.