aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/issue2166/tb5.vhdl
blob: 38bb5920dcad0f203ce5a1f4ea4461ab15541fb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std.textio.all ;
library IEEE ;
  use IEEE.std_logic_1164.all ;
  use IEEE.numeric_std.all ;
  use IEEE.numeric_std_unsigned.all ;

package MemoryPkg is
  type MemoryPType is protected
    procedure MemInit (ID : integer ;  AddrWidth, DataWidth  : integer);

    procedure MemWrite (
      ID    : integer ;
      Addr  : std_logic_vector ;
      Data  : std_logic_vector
    ) ;
  end protected MemoryPType ;
end;

package body MemoryPkg is
  constant BLOCK_WIDTH : integer := 10 ;

  function InitMemoryBaseType(Size : integer) return integer_vector is
  begin
    return (Size / 32 downto 1 => 0);
  end;

  type MemoryPType is protected body

    subtype MemoryBaseType is integer_vector ;
    type MemBlockType      is array (integer range <>) of MemoryBaseType ;
    type MemBlockPtrType   is access MemBlockType ;
    type MemArrayType      is array (integer range <>) of MemBlockPtrType ;
    type MemArrayPtrType   is access MemArrayType ;

    type MemStructType is record
      MemArrayPtr         : MemArrayPtrType ;
      AddrWidth           : integer ;
      DataWidth           : natural ;
      BlockWidth          : natural ;
      MemoryBaseTypeWidth : natural ;
    end record MemStructType ;

    -- New Structure
    type     ItemArrayType    is array (integer range <>) of MemStructType ;
    type     ItemArrayPtrType is access ItemArrayType ;

    variable Template         : ItemArrayType(1 to 1) := (1 => (NULL, -1, 1, 0, 0)) ;  -- Work around for QS 2020.04 and 2021.02
    variable MemStructPtr     : ItemArrayPtrType := new ItemArrayType'(Template) ;
    variable NumItems         : integer := 0 ;
    constant MIN_NUM_ITEMS    : integer := 32 ; -- Min amount to resize array

   ------------------------------------------------------------
    -- PT Local
    procedure MemInit (ID : integer ;  AddrWidth, DataWidth  : integer ) is
    ------------------------------------------------------------
      constant ADJ_BLOCK_WIDTH : integer := minimum(BLOCK_WIDTH, AddrWidth) ;
    begin
      if AddrWidth <= 0 then
        return ;
      end if ;
      if DataWidth <= 0 then
        return ;
      end if ;

      MemStructPtr(ID).AddrWidth           := AddrWidth ;
      MemStructPtr(ID).DataWidth           := DataWidth ;
      MemStructPtr(ID).MemoryBaseTypeWidth := (DataWidth + 31) / 32;
      MemStructPtr(ID).BlockWidth          := ADJ_BLOCK_WIDTH ;
      MemStructPtr(ID).MemArrayPtr         := new MemArrayType(0 to 2**(AddrWidth-ADJ_BLOCK_WIDTH)-1) ;
    end procedure MemInit ;

    ------------------------------------------------------------
    procedure MemWrite (
    ------------------------------------------------------------
      ID    : integer ;
      Addr  : std_logic_vector ;
      Data  : std_logic_vector
    ) is
      variable BlockWidth : integer ;
      variable MemoryBaseTypeWidth : integer ;
      variable BlockAddr, WordAddr  : integer ;
    begin
      BlockWidth := MemStructPtr(ID).BlockWidth ;
      MemoryBaseTypeWidth := MemStructPtr(ID).MemoryBaseTypeWidth ;
      BlockAddr  := 0 ;

      -- If empty, allocate a memory block
      if MemStructPtr(ID).MemArrayPtr(BlockAddr) = NULL then
        MemStructPtr(ID).MemArrayPtr(BlockAddr) := new MemBlockType(0 to 2**BlockWidth-1)(MemoryBaseTypeWidth downto 1) ; -- => InitMemoryBaseType(Data'length)) ;
        MemStructPtr(ID).MemArrayPtr(BlockAddr)(0 to 2**BlockWidth-1) := (0 to 2**BlockWidth-1 => InitMemoryBaseType(Data'length)) ;
      end if ;
    end procedure MemWrite ;
  end protected body MemoryPType ;
end;

library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
use work.MemoryPkg.all;

entity tb3 is
end;

architecture behav of tb3 is
  shared variable MemoryStore : MemoryPType ;
begin
  process
  begin
    MemoryStore.MemInit(1, AddrWidth => 20, DataWidth => 16);

    MemoryStore.MemWrite(1, x"00000", x"0000");
    wait;
  end process;
end ;