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

Subversion Repositories single_port

[/] [single_port/] [trunk/] [VHDL/] [linked_list_mem_pkg.vhd] - Rev 15

Compare with Previous | Blame | View Log

----------------------------------------------------------------------
----                                                              ----
---- Single port asynchronous RAM simulation model                ----
----                                                              ----
---- This file is part of the single_port project                 ----
----                                                              ----
---- Description                                                  ----
---- This package implements functions to allocate, write, read   ----
---- and deallocate a linked list based memory.                   ----
----                                                              ----
---- Authors:                                                     ----
---- - Robert Paley, rpaley_yid@yahoo.com                         ----
---- - Michael Geng, vhdl@MichaelGeng.de                          ----
----                                                              ----
---- References:                                                  ----
----   1. The Designer's Guide to VHDL by Peter Ashenden          ----
----      ISBN: 1-55860-270-4 (pbk.)                              ----
----   2. Writing Testbenches - Functional Verification of HDL    ----
----      models by Janick Bergeron | ISBN: 0-7923-7766-4         ----
----                                                              ----
----------------------------------------------------------------------
----                                                              ----
---- Copyright (C) 2005 Authors and OPENCORES.ORG                 ----
----                                                              ----
---- This source file may be used and distributed without         ----
---- restriction provided that this copyright statement is not    ----
---- removed from the file and that any derivative work contains  ----
---- the original copyright notice and the associated disclaimer. ----
----                                                              ----
---- This source file is free software; you can redistribute it   ----
---- and/or modify it under the terms of the GNU Lesser General   ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any   ----
---- later version.                                               ----
----                                                              ----
---- This source is distributed in the hope that it will be       ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied   ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ----
---- PURPOSE. See the GNU Lesser General Public License for more  ----
---- details.                                                     ----
----                                                              ----
---- You should have received a copy of the GNU Lesser General    ----
---- Public License along with this source; if not, download it   ----
---- from http://www.opencores.org/lgpl.shtml                     ----
----                                                              ----
----------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2  2005/10/12 19:39:27  mgeng
-- Buses unconstrained, LGPL header added
--
-- Revision 1.1.1.1  2003/01/14 21:48:10  rpaley_yid
-- initial checkin 
--
-- Revision 1.1  2003/01/14 17:47:32  Default
-- Initial revision
--
-- Revision 1.1  2002/12/24 18:03:50  Default
-- Initial revision
--
LIBRARY IEEE;
LIBRARY WORK;
USE IEEE.STD_LOGIC_1164.ALL;
USE WORK.single_port_pkg.all;
 
PACKAGE linked_list_mem_pkg IS
  CONSTANT PAGEDEPTH : INTEGER := 256; -- memory page depth
  -- pointer to one data word in the memory
  -- The reason for using a pointer here is that it seems to be the only way to keep the model
  -- independent of the data width
  TYPE data_ptr IS ACCESS BIT_VECTOR;
  -- data memory array type definition
  TYPE mem_array_typ IS ARRAY (0 TO PAGEDEPTH-1) OF data_ptr;
  -- Define memory page linked list cell. This cell contains
  -- the mem_array, starting page address, valid data array and 
  -- the pointer to the next element in the linked list.
  TYPE mem_page_typ;
  -- pointer to next item in the linked list.
  TYPE mem_page_ptr IS ACCESS mem_page_typ;
  TYPE mem_page_typ IS RECORD
    mem_array    : mem_array_typ; -- data memory
    page_address : addr_typ;
    next_cell    : mem_page_ptr;
  END RECORD mem_page_typ;
  PROCEDURE rw_mem (
    VARIABLE data       : INOUT STD_LOGIC_VECTOR;
    VARIABLE addr       : IN    addr_typ;
    VARIABLE next_cell  : INOUT mem_page_ptr;
    CONSTANT write_flag : IN    BOOLEAN);
  PROCEDURE deallocate_mem (
    VARIABLE next_cell : INOUT mem_page_ptr);
 
END PACKAGE linked_list_mem_pkg;
 
PACKAGE BODY linked_list_mem_pkg IS
  -- --------------------------------------------------
  -- The purpose of this procedure is to write a memory location from 
  -- the linked list, if the particular page does not exist, create it.
  -- --------------------------------------------------  
  PROCEDURE rw_mem (
    VARIABLE data       : INOUT STD_LOGIC_VECTOR;
    VARIABLE addr       : IN    addr_typ;
    VARIABLE next_cell  : INOUT mem_page_ptr;
    CONSTANT write_flag : IN    BOOLEAN) IS
    VARIABLE current_cell_v : mem_page_ptr; -- current page pointer
    VARIABLE page_address_v : addr_typ;     -- calculated page address
    VARIABLE index_v        : INTEGER;      -- address within the memory page
    VARIABLE mem_array_v    : mem_array_typ;
  BEGIN
    -- Copy the top of the linked list pointer to a working pointer
    current_cell_v := next_cell; 
    -- Calculate the index within the page from the given address
    index_v := addr MOD PAGEDEPTH; 
    -- Calculate the page address from the given address
    page_address_v := addr - index_v; 
    -- Search through the memory to determine if the calculated
    -- memory page exists. Stop searching when reach the end of
    -- the linked list.
    WHILE ( current_cell_v /= NULL AND 
            current_cell_v.page_address /= page_address_v) LOOP
      current_cell_v := current_cell_v.next_cell;
    END LOOP; 
 
    IF write_flag THEN 
      IF ( current_cell_v /= NULL AND -- Check if address exists in memory.
           current_cell_v.page_address = page_address_v ) THEN
        -- Found the memory page the particular address belongs to
        IF ( current_cell_v.mem_array(index_v) /= NULL ) THEN
          current_cell_v.mem_array(index_v).ALL := TO_BITVECTOR(data);
        ELSE
          current_cell_v.mem_array(index_v) := NEW BIT_VECTOR'(TO_BITVECTOR(data));
        END IF;
      ELSE 
        -- The memory page the address belongs to was not allocated in memory.
        -- Allocate page here and assign data.
        mem_array_v(index_v) := NEW BIT_VECTOR'(TO_BITVECTOR(data));
        next_cell := NEW mem_page_typ'( mem_array => mem_array_v,
                                  page_address => page_address_v,
                                  next_cell => next_cell); 
      END IF;
    ELSE -- Read memory
      IF ( current_cell_v /= NULL AND -- Check if address exists in memory.
           current_cell_v.page_address = page_address_v AND 
           current_cell_v.mem_array(index_v) /= NULL ) THEN
        -- Found the memory page the particular address belongs to,
        -- and the memory location has valid data.
        data := TO_STDLOGICVECTOR(current_cell_v.mem_array(index_v).ALL);
      ELSE 
        -- Trying to read from unwritten or unallocated 
        -- memory location, return 'U';
        data := (data'RANGE => 'U');
      END IF;
    END IF;  
  END PROCEDURE rw_mem; 
 
  PROCEDURE deallocate_mem (
    VARIABLE next_cell : INOUT mem_page_ptr) IS
    VARIABLE delete_cell_v : mem_page_ptr;
  BEGIN 
    -- Deallocate the linked link memory from work station memory.
    WHILE next_cell /= NULL LOOP -- while not reached the end of the LL
      delete_cell_v := next_cell; -- Copy pointer to record for deleting
      FOR i IN 0 TO PAGEDEPTH-1 LOOP
        IF delete_cell_v.mem_array(i) /= NULL THEN
          deallocate(delete_cell_v.mem_array(i));
        END IF;
      END LOOP;
      next_cell := next_cell.next_cell; -- set pointer to next cell in LL
      deallocate(delete_cell_v); -- Deallocate current cell from memory.
    END LOOP;
  END PROCEDURE deallocate_mem;
END PACKAGE BODY linked_list_mem_pkg;
 

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.