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 ;
|