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

Subversion Repositories astron_ram

[/] [astron_ram/] [trunk/] [common_ram_pkg.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2009
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22
LIBRARY IEEE, common_pkg_lib;
23
USE IEEE.STD_LOGIC_1164.ALL;
24
USE IEEE.NUMERIC_STD.ALL;
25
USE common_pkg_lib.common_pkg.ALL;
26
 
27
PACKAGE common_ram_pkg IS
28
 
29
  ------------------------------------------------------------------------------
30
  -- Simple memory access (for MM control interface)
31
  ------------------------------------------------------------------------------
32
 
33
  -- Assume the MM bus is for a 32 bit processor, therefore on the processor
34
  -- side of a memory peripheral typcially use c_word_w = 32 for the address
35
  -- and data fields in the MM bus records. However the MM bus can also be used
36
  -- on the user side of a memory peripheral and there the data width should
37
  -- not be limited by the processor type but rather by the maximum user data
38
  -- width on the streaming interface.
39
  --
40
  -- The std_logic_vector widths in the record need to be defined, because in
41
  -- a record they can not be unconstrained. A signal that needs less address
42
  -- or data width simply leaves the unused MSbits at 'X'. The actually used
43
  -- width of a memory gets set via a generic record type t_c_mem.
44
  --
45
  -- The alternative is to not put the std_logic_vector elements in the record,
46
  -- and declare them seperately, however then the compact representation that
47
  -- records provide gets lost, because the record then only contains wr_en and
48
  -- rd_en. Another alternative is to define the address as a integer and the
49
  -- data as an integer. However this limits their range to 32 bit numbers,
50
  -- which can be too few for data.
51
 
52
  -- Do not change these widths, because c_word_w just fits in a VHDL INTEGER
53
  -- Should wider address range or data width be needed, then define a new
54
  -- record type eg. t_mem_ctlr or t_mem_bus for that with
55
  -- sufficient widths.
56
 
57
  -- Choose smallest maximum slv lengths that fit all use cases, because unconstrained record fields slv is not allowed
58
  CONSTANT c_mem_address_w  : NATURAL := 32;   -- address range (suits 32-bit processor)
59
  CONSTANT c_mem_data_w     : NATURAL := 72;   -- data width (suit up to 8 bytes, that can also be 9 bit bytes)
60
  CONSTANT c_mem_address_sz : NATURAL := c_mem_address_w/c_byte_w;
61
  CONSTANT c_mem_data_sz    : NATURAL := c_mem_data_w/c_byte_w;
62
 
63
  TYPE t_mem_miso IS RECORD  -- Master In Slave Out
64
    rddata      : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);  -- data width (suits 1, 2 or 4 bytes)
65
    rdval       : STD_LOGIC;
66
    waitrequest : STD_LOGIC;
67
  END RECORD;
68
 
69
  TYPE t_mem_mosi IS RECORD  -- Master Out Slave In
70
    address     : STD_LOGIC_VECTOR(c_mem_address_w-1 DOWNTO 0);  -- address range (suits 32-bit processor)
71
    wrdata      : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);     -- data width (suits 1, 2 or 4 bytes)
72
    wr          : STD_LOGIC;
73
    rd          : STD_LOGIC;
74
  END RECORD;
75
 
76
  CONSTANT c_mem_miso_rst : t_mem_miso := ((OTHERS=>'0'), '0', '0');
77
  CONSTANT c_mem_mosi_rst : t_mem_mosi := ((OTHERS=>'0'), (OTHERS=>'0'), '0', '0');
78
 
79
  -- Multi port array for MM records
80
  TYPE t_mem_miso_arr IS ARRAY (INTEGER RANGE <>) OF t_mem_miso;
81
  TYPE t_mem_mosi_arr IS ARRAY (INTEGER RANGE <>) OF t_mem_mosi;
82
 
83
  -- Resize functions to fit an integer or an SLV in the corresponding t_mem_miso or t_mem_mosi field width
84
  FUNCTION TO_MEM_ADDRESS(n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- unsigned, use integer to support 32 bit range
85
  FUNCTION TO_MEM_DATA(   n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- unsigned, alias of TO_MEM_DATA()
86
  FUNCTION TO_MEM_UDATA(  n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- unsigned, use integer to support 32 bit range
87
  FUNCTION TO_MEM_SDATA(  n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- sign extended
88
  FUNCTION RESIZE_MEM_ADDRESS(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- unsigned
89
  FUNCTION RESIZE_MEM_DATA(   vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- unsigned, alias of RESIZE_MEM_UDATA
90
  FUNCTION RESIZE_MEM_UDATA(  vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- unsigned
91
  FUNCTION RESIZE_MEM_SDATA(  vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- sign extended
92
  FUNCTION RESIZE_MEM_XDATA(  vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- set unused MSBits to 'X'
93
 
94
 
95
  ------------------------------------------------------------------------------
96
  -- Burst memory access (for DDR access interface)
97
  ------------------------------------------------------------------------------
98
 
99
  -- Choose smallest maximum slv lengths that fit all use cases, because unconstrained record fields slv is not allowed
100
  CONSTANT c_mem_ctlr_address_w    : NATURAL := 32;
101
  CONSTANT c_mem_ctlr_data_w       : NATURAL := 576;
102
  CONSTANT c_mem_ctlr_burstsize_w  : NATURAL := c_mem_ctlr_address_w;
103
 
104
  TYPE t_mem_ctlr_miso IS RECORD
105
    rddata        : STD_LOGIC_VECTOR(c_mem_ctlr_data_w-1 DOWNTO 0);
106
    rdval         : STD_LOGIC;
107
    waitrequest_n : STD_LOGIC;  -- comparable to DP siso.ready
108
    done          : STD_LOGIC;  -- comparable to DP siso.xon, not part of Avalon bus, can eg. act as init done or init ok or ready for next block, useful for DDR controller
109
    cal_ok        : STD_LOGIC;
110
    cal_fail      : STD_LOGIC;
111
  END RECORD;
112
 
113
  TYPE t_mem_ctlr_mosi IS RECORD
114
    address       : STD_LOGIC_VECTOR(c_mem_ctlr_address_w-1 DOWNTO 0);
115
    wrdata        : STD_LOGIC_VECTOR(c_mem_ctlr_data_w-1 DOWNTO 0);
116
    wr            : STD_LOGIC;
117
    rd            : STD_LOGIC;
118
    burstbegin    : STD_LOGIC;
119
    burstsize     : STD_LOGIC_VECTOR(c_mem_ctlr_burstsize_w-1 DOWNTO 0);
120
    flush         : STD_LOGIC;  -- not part of Avalon bus, but useful for DDR driver
121
  END RECORD;
122
 
123
  CONSTANT c_mem_ctlr_miso_rst : t_mem_ctlr_miso := ((OTHERS=>'0'), '0', '0', '0', '0', '0');
124
  CONSTANT c_mem_ctlr_mosi_rst : t_mem_ctlr_mosi := ((OTHERS=>'0'), (OTHERS=>'0'), '0', '0', '0', (OTHERS=>'0'), '0');
125
 
126
  -- Multi port array for mem_ctlr records
127
  TYPE t_mem_ctlr_miso_arr IS ARRAY (INTEGER RANGE <>) OF t_mem_ctlr_miso;
128
  TYPE t_mem_ctlr_mosi_arr IS ARRAY (INTEGER RANGE <>) OF t_mem_ctlr_mosi;
129
 
130
 
131
  -- Resize functions to fit an integer or an SLV in the corresponding t_mem_ctlr_miso or t_mem_ctlr_mosi field width
132
  FUNCTION TO_MEM_CTLR_ADDRESS(  n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- unsigned, use integer to support 32 bit range
133
  FUNCTION TO_MEM_CTLR_DATA(     n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- unsigned
134
  FUNCTION TO_MEM_CTLR_BURSTSIZE(n : INTEGER) RETURN STD_LOGIC_VECTOR;  -- unsigned
135
 
136
  FUNCTION RESIZE_MEM_CTLR_ADDRESS(  vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- unsigned
137
  FUNCTION RESIZE_MEM_CTLR_DATA(     vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- unsigned
138
  FUNCTION RESIZE_MEM_CTLR_BURSTSIZE(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- unsigned
139
 
140
 
141
  ------------------------------------------------------------------------------
142
  -- RAM block memory and MM register defintions
143
  ------------------------------------------------------------------------------
144
  TYPE t_c_mem IS RECORD
145
    latency   : NATURAL;    -- read latency
146
    adr_w     : NATURAL;
147
    dat_w     : NATURAL;
148
    nof_dat   : NATURAL;    -- optional, nof dat words <= 2**adr_w
149
    init_sl   : STD_LOGIC;  -- optional, init all dat words to std_logic '0', '1' or 'X'
150
    --init_file : STRING;     -- "UNUSED", unconstrained length can not be in record 
151
  END RECORD;
152
 
153
  CONSTANT c_mem_ram_rd_latency : NATURAL := 2;  -- note common_ram_crw_crw(stratix4) now also supports read latency 1
154
  CONSTANT c_mem_ram            : t_c_mem := (c_mem_ram_rd_latency, 10,  9, 2**10, 'X');  -- 1 M9K
155
 
156
  CONSTANT c_mem_reg_rd_latency : NATURAL := 1;
157
  CONSTANT c_mem_reg            : t_c_mem := (c_mem_reg_rd_latency,  1, 32,     1, 'X');
158
 
159
  CONSTANT c_mem_reg_init_w     : NATURAL := 1*256*32;  -- >= largest expected value of dat_w*nof_dat (256 * 32 bit = 1k byte)
160
 
161
 
162
  ------------------------------------------------------------------------------
163
  -- Functions to swap endianess
164
  ------------------------------------------------------------------------------
165
  FUNCTION func_mem_swap_endianess(mm : t_mem_miso; sz : NATURAL) RETURN t_mem_miso;
166
  FUNCTION func_mem_swap_endianess(mm : t_mem_mosi; sz : NATURAL) RETURN t_mem_mosi;
167
 
168
END common_ram_pkg;
169
 
170
PACKAGE BODY common_ram_pkg IS
171
 
172
  -- Resize functions to fit an integer or an SLV in the corresponding t_mem_miso or t_mem_mosi field width
173
  FUNCTION TO_MEM_ADDRESS(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
174
  BEGIN
175
    RETURN RESIZE_UVEC(TO_SVEC(n, 32), c_mem_address_w);
176
  END TO_MEM_ADDRESS;
177
 
178
  FUNCTION TO_MEM_DATA(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
179
  BEGIN
180
    RETURN TO_MEM_UDATA(n);
181
  END TO_MEM_DATA;
182
 
183
  FUNCTION TO_MEM_UDATA(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
184
  BEGIN
185
    RETURN RESIZE_UVEC(TO_SVEC(n, 32), c_mem_data_w);
186
  END TO_MEM_UDATA;
187
 
188
  FUNCTION TO_MEM_SDATA(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
189
  BEGIN
190
    RETURN RESIZE_SVEC(TO_SVEC(n, 32), c_mem_data_w);
191
  END TO_MEM_SDATA;
192
 
193
  FUNCTION RESIZE_MEM_ADDRESS(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
194
  BEGIN
195
    RETURN RESIZE_UVEC(vec, c_mem_address_w);
196
  END RESIZE_MEM_ADDRESS;
197
 
198
  FUNCTION RESIZE_MEM_DATA(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
199
  BEGIN
200
    RETURN RESIZE_MEM_UDATA(vec);
201
  END RESIZE_MEM_DATA;
202
 
203
  FUNCTION RESIZE_MEM_UDATA(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
204
  BEGIN
205
    RETURN RESIZE_UVEC(vec, c_mem_data_w);
206
  END RESIZE_MEM_UDATA;
207
 
208
  FUNCTION RESIZE_MEM_SDATA(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
209
  BEGIN
210
    RETURN RESIZE_SVEC(vec, c_mem_data_w);
211
  END RESIZE_MEM_SDATA;
212
 
213
  FUNCTION RESIZE_MEM_XDATA(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
214
    VARIABLE v_vec : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0) := (OTHERS=>'X');
215
  BEGIN
216
    v_vec(vec'LENGTH-1 DOWNTO 0) := vec;
217
    RETURN v_vec;
218
  END RESIZE_MEM_XDATA;
219
 
220
 
221
  -- Resize functions to fit an integer or an SLV in the corresponding t_mem_miso or t_mem_mosi field width
222
  FUNCTION TO_MEM_CTLR_ADDRESS(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
223
  BEGIN
224
    RETURN RESIZE_UVEC(TO_SVEC(n, 32), c_mem_ctlr_address_w);
225
  END TO_MEM_CTLR_ADDRESS;
226
 
227
  FUNCTION TO_MEM_CTLR_DATA(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
228
  BEGIN
229
    RETURN RESIZE_UVEC(TO_SVEC(n, 32), c_mem_ctlr_data_w);
230
  END TO_MEM_CTLR_DATA;
231
 
232
  FUNCTION TO_MEM_CTLR_BURSTSIZE(n : INTEGER) RETURN STD_LOGIC_VECTOR IS
233
  BEGIN
234
    RETURN RESIZE_UVEC(TO_SVEC(n, 32), c_mem_ctlr_burstsize_w);
235
  END TO_MEM_CTLR_BURSTSIZE;
236
 
237
  FUNCTION RESIZE_MEM_CTLR_ADDRESS(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
238
  BEGIN
239
    RETURN RESIZE_UVEC(vec, c_mem_ctlr_address_w);
240
  END RESIZE_MEM_CTLR_ADDRESS;
241
 
242
  FUNCTION RESIZE_MEM_CTLR_DATA(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
243
  BEGIN
244
    RETURN RESIZE_UVEC(vec, c_mem_ctlr_data_w);
245
  END RESIZE_MEM_CTLR_DATA;
246
 
247
  FUNCTION RESIZE_MEM_CTLR_BURSTSIZE(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
248
  BEGIN
249
    RETURN RESIZE_UVEC(vec, c_mem_ctlr_burstsize_w);
250
  END RESIZE_MEM_CTLR_BURSTSIZE;
251
 
252
 
253
  -- Functions to swap endianess
254
  FUNCTION func_mem_swap_endianess(mm : t_mem_miso; sz : NATURAL) RETURN t_mem_miso IS
255
    VARIABLE v_mm : t_mem_miso;
256
  BEGIN
257
    -- Master In Slave Out
258
    v_mm.rddata  := hton(mm.rddata, sz);
259
    RETURN v_mm;
260
  END func_mem_swap_endianess;
261
 
262
  FUNCTION func_mem_swap_endianess(mm : t_mem_mosi; sz : NATURAL) RETURN t_mem_mosi IS
263
    VARIABLE v_mm : t_mem_mosi;
264
  BEGIN
265
    -- Master Out Slave In
266
    v_mm.address := mm.address;
267
    v_mm.wrdata  := hton(mm.wrdata, sz);
268
    v_mm.wr      := mm.wr;
269
    v_mm.rd      := mm.rd;
270
    RETURN v_mm;
271
  END func_mem_swap_endianess;
272
 
273
END common_ram_pkg;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.