1 | #ifndef MEMORY_H |
---|
2 | #define MEMORY_H |
---|
3 | |
---|
4 | #include <list> |
---|
5 | #include "systemc.h" |
---|
6 | #include "Common/include/BitManipulation.h" |
---|
7 | #include "Common/include/Debug.h" |
---|
8 | #include "Common/include/Log2.h" |
---|
9 | #include "Common/include/Test.h" |
---|
10 | #include "Behavioural/include/Constants.h" |
---|
11 | #include "Behavioural/include/Types.h" |
---|
12 | |
---|
13 | //================================================================{Memory_t} |
---|
14 | typedef struct |
---|
15 | { |
---|
16 | double _cycle ; |
---|
17 | uint32_t _context ; |
---|
18 | morpheo::behavioural::Tdcache_address_t _address ; |
---|
19 | morpheo::behavioural::Tdcache_type_t _type ; |
---|
20 | morpheo::behavioural::Tdcache_data_t _data_old; |
---|
21 | morpheo::behavioural::Tdcache_data_t _data_new; |
---|
22 | } trace_memory_t; |
---|
23 | |
---|
24 | class Memory_t |
---|
25 | { |
---|
26 | private : const uint32_t _nb_context; |
---|
27 | private : const uint32_t _nb_word ; |
---|
28 | private : const uint32_t _size_word ; |
---|
29 | private : const uint32_t _shift_addr; |
---|
30 | private : const morpheo::behavioural::Tdcache_address_t _mask_addr ; |
---|
31 | private : morpheo::behavioural::Tdcache_data_t ** _data ; |
---|
32 | |
---|
33 | private : std::list<trace_memory_t> _trace_memory; |
---|
34 | |
---|
35 | public : Memory_t (uint32_t nb_context, |
---|
36 | uint32_t nb_word, |
---|
37 | uint32_t size_word): |
---|
38 | _nb_context (nb_context), |
---|
39 | _nb_word (nb_word ), |
---|
40 | _size_word (size_word ), |
---|
41 | _shift_addr (morpheo::log2(size_word/8)), |
---|
42 | _mask_addr (morpheo::gen_mask<morpheo::behavioural::Tdcache_address_t>(_shift_addr)) |
---|
43 | { |
---|
44 | _data = new morpheo::behavioural::Tdcache_data_t * [nb_context]; |
---|
45 | |
---|
46 | for (uint32_t i=0; i<nb_context; i++) |
---|
47 | { |
---|
48 | _data [i] = new morpheo::behavioural::Tdcache_data_t [nb_word]; |
---|
49 | |
---|
50 | // random data |
---|
51 | for (uint32_t j=0; j<nb_word; j++) |
---|
52 | _data [i][j] = static_cast<morpheo::behavioural::Tdcache_data_t>(rand()); |
---|
53 | } |
---|
54 | |
---|
55 | std::cout << "=====[ Memory's information ]" << std::endl |
---|
56 | << " * _nb_context : " << _nb_context << std::endl |
---|
57 | << " * _nb_word : " << _nb_word << std::endl |
---|
58 | << " * _size_word : " << _size_word << std::endl |
---|
59 | << " * _shift_addr : " << _shift_addr << std::endl |
---|
60 | << " * _mask_addr : " << std::hex << _mask_addr << std::dec << std::endl; |
---|
61 | } |
---|
62 | |
---|
63 | public : ~Memory_t (void) |
---|
64 | { |
---|
65 | delete [] _data; |
---|
66 | } |
---|
67 | |
---|
68 | public : morpheo::behavioural::Tdcache_data_t access (uint32_t context, |
---|
69 | morpheo::behavioural::Tdcache_address_t address, |
---|
70 | morpheo::behavioural::Tdcache_type_t type, |
---|
71 | morpheo::behavioural::Tdcache_data_t data) |
---|
72 | { |
---|
73 | std::cout << "<Memory::access>" << std::endl |
---|
74 | << " * context : " << context << std::endl |
---|
75 | << " * address : " << std::hex << address << std::dec << std::endl |
---|
76 | << " * type : " << type << std::endl |
---|
77 | << " * wdata : " << std::hex << data << std::dec << std::endl; |
---|
78 | |
---|
79 | morpheo::behavioural::Tdcache_data_t rdata; |
---|
80 | |
---|
81 | if ((type == DCACHE_TYPE_LOAD_8 ) or |
---|
82 | (type == DCACHE_TYPE_LOAD_16) or |
---|
83 | (type == DCACHE_TYPE_LOAD_32) or |
---|
84 | (type == DCACHE_TYPE_LOAD_64) ) |
---|
85 | rdata = read (context, address, type); |
---|
86 | else |
---|
87 | if ((type == DCACHE_TYPE_STORE_8 ) or |
---|
88 | (type == DCACHE_TYPE_STORE_16) or |
---|
89 | (type == DCACHE_TYPE_STORE_32) or |
---|
90 | (type == DCACHE_TYPE_STORE_64) ) |
---|
91 | rdata = write (context, address, type, data); |
---|
92 | else |
---|
93 | rdata = other (context, address, type); |
---|
94 | |
---|
95 | std::cout << " * rdata : " << std::hex << rdata << std::dec << std::endl; |
---|
96 | |
---|
97 | return rdata; |
---|
98 | } |
---|
99 | |
---|
100 | public : morpheo::behavioural::Tdcache_data_t read_lsq (uint32_t context, |
---|
101 | morpheo::behavioural::Tdcache_address_t address, |
---|
102 | morpheo::behavioural::Tdcache_type_t type) |
---|
103 | { |
---|
104 | if (context>_nb_context) |
---|
105 | TEST_KO("<Memory_t::read> nb context is too high"); |
---|
106 | |
---|
107 | morpheo::behavioural::Tdcache_address_t LSB = address & _mask_addr; |
---|
108 | morpheo::behavioural::Tdcache_address_t MSB = address >> _shift_addr; |
---|
109 | |
---|
110 | if (MSB >_nb_word) |
---|
111 | TEST_KO("<Memory_t::read> address is too high : %8.x", address); |
---|
112 | |
---|
113 | morpheo::behavioural::Tdcache_data_t data = _data [context][MSB] >> (LSB<<3); |
---|
114 | |
---|
115 | switch (type) |
---|
116 | { |
---|
117 | case OPERATION_MEMORY_LOAD_8_Z : |
---|
118 | case OPERATION_MEMORY_LOAD_16_Z : |
---|
119 | case OPERATION_MEMORY_LOAD_32_Z : |
---|
120 | case OPERATION_MEMORY_LOAD_64_Z : |
---|
121 | case OPERATION_MEMORY_LOAD_8_S : |
---|
122 | case OPERATION_MEMORY_LOAD_16_S : |
---|
123 | case OPERATION_MEMORY_LOAD_32_S : |
---|
124 | case OPERATION_MEMORY_LOAD_64_S : return morpheo::extend<morpheo::behavioural::Tdcache_data_t>(_size_word,data, is_operation_memory_load_signed(type),memory_size(type)); |
---|
125 | default : TEST_KO("<Memory_t::read_lsq> invalide type"); return data; |
---|
126 | } |
---|
127 | } |
---|
128 | |
---|
129 | private : morpheo::behavioural::Tdcache_data_t read (uint32_t context, |
---|
130 | morpheo::behavioural::Tdcache_address_t address, |
---|
131 | morpheo::behavioural::Tdcache_type_t type) |
---|
132 | { |
---|
133 | // Address's Read must be aligned |
---|
134 | |
---|
135 | // if ((address & _mask_addr) != 0) |
---|
136 | // TEST_KO("<Memory_t::read> Address is not aligned"); |
---|
137 | |
---|
138 | if (context>_nb_context) |
---|
139 | TEST_KO("<Memory_t::read> nb context is too high"); |
---|
140 | |
---|
141 | morpheo::behavioural::Tdcache_address_t MSB = address >> _shift_addr; |
---|
142 | |
---|
143 | if (MSB >_nb_word) |
---|
144 | TEST_KO("<Memory_t::read> address is too high"); |
---|
145 | |
---|
146 | morpheo::behavioural::Tdcache_data_t rdata = _data [context][MSB]; |
---|
147 | trace_memory_t trace; |
---|
148 | |
---|
149 | trace._cycle = simulation_cycle(); |
---|
150 | trace._context = context; |
---|
151 | trace._address = address; |
---|
152 | trace._type = type; |
---|
153 | trace._data_old = rdata; |
---|
154 | trace._data_new = rdata; |
---|
155 | |
---|
156 | _trace_memory.push_back(trace); |
---|
157 | |
---|
158 | return rdata; |
---|
159 | } |
---|
160 | |
---|
161 | private : morpheo::behavioural::Tdcache_data_t write (uint32_t context, |
---|
162 | morpheo::behavioural::Tdcache_address_t address, |
---|
163 | morpheo::behavioural::Tdcache_type_t type, |
---|
164 | morpheo::behavioural::Tdcache_data_t data) |
---|
165 | { |
---|
166 | std::cout << " * write" << std::endl; |
---|
167 | |
---|
168 | if (context>_nb_context) |
---|
169 | TEST_KO("<Memory_t::read> nb context is too high"); |
---|
170 | |
---|
171 | if (address>_nb_word) |
---|
172 | TEST_KO("<Memory_t::read> address is too high"); |
---|
173 | |
---|
174 | morpheo::behavioural::Tdcache_address_t LSB = address & _mask_addr; |
---|
175 | morpheo::behavioural::Tdcache_address_t MSB = address >> _shift_addr; |
---|
176 | |
---|
177 | std::cout << std::hex |
---|
178 | << " * LSB : " << LSB << std::endl |
---|
179 | << " * MSB : " << MSB << std::endl |
---|
180 | << std::dec; |
---|
181 | |
---|
182 | morpheo::behavioural::Tdcache_data_t data_old = _data [context][MSB]; |
---|
183 | |
---|
184 | // exemple to size_word = 32b |
---|
185 | // LSB index_min |
---|
186 | // 0 0 |
---|
187 | // 1 8 |
---|
188 | // 2 16 |
---|
189 | // 3 24 |
---|
190 | |
---|
191 | uint32_t memory_size = ((type==DCACHE_TYPE_STORE_16)?MEMORY_SIZE_16: |
---|
192 | ((type==DCACHE_TYPE_STORE_32)?MEMORY_SIZE_32: |
---|
193 | ((type==DCACHE_TYPE_STORE_64 )?MEMORY_SIZE_64:MEMORY_SIZE_8))); |
---|
194 | |
---|
195 | uint32_t index_min = LSB<<3; // *8 |
---|
196 | uint32_t index_max = index_min+memory_size; |
---|
197 | |
---|
198 | std::cout << " * type : " << type << std::endl |
---|
199 | << " * memory_size : " << memory_size << std::endl |
---|
200 | << " * index_min : " << index_min << std::endl |
---|
201 | << " * index_max : " << index_max << std::endl; |
---|
202 | |
---|
203 | morpheo::behavioural::Tdcache_data_t data_insert = data<<index_min; // the data is aligned at LSB |
---|
204 | |
---|
205 | // std::cout << "read :" << std::endl |
---|
206 | // << " * context : " << context << std::endl |
---|
207 | // << std::hex |
---|
208 | // << " * address : " << address << std::endl |
---|
209 | // << " * LSB : " << LSB << std::endl |
---|
210 | // << " * MSB : " << MSB << std::endl |
---|
211 | // << std::dec |
---|
212 | // << " * index_min : " << index_min << std::endl |
---|
213 | // << " * index_max : " << index_max << std::endl |
---|
214 | // << " * type : " << type << std::endl; |
---|
215 | |
---|
216 | if (index_max > _size_word) |
---|
217 | TEST_KO("<Memory_t::read> illegal value of index_max : %d, size_word is %d.",index_max,_size_word); |
---|
218 | |
---|
219 | morpheo::behavioural::Tdcache_data_t data_new = morpheo::insert<morpheo::behavioural::Tdcache_data_t>(data_old, data_insert, index_max-1, index_min); |
---|
220 | |
---|
221 | _data [context][MSB] = data_new; |
---|
222 | |
---|
223 | std::cout << std::hex |
---|
224 | << " * data_old : " << data_old << std::endl |
---|
225 | << " * data_new : " << data_new << std::endl |
---|
226 | << std::dec; |
---|
227 | |
---|
228 | |
---|
229 | trace_memory_t trace; |
---|
230 | |
---|
231 | trace._cycle = simulation_cycle(); |
---|
232 | trace._context = context; |
---|
233 | trace._address = address; |
---|
234 | trace._type = type; |
---|
235 | trace._data_old = data_old; |
---|
236 | trace._data_new = data_new; |
---|
237 | |
---|
238 | _trace_memory.push_back(trace); |
---|
239 | |
---|
240 | return data_old; |
---|
241 | } |
---|
242 | |
---|
243 | private : morpheo::behavioural::Tdcache_data_t other (uint32_t context, |
---|
244 | morpheo::behavioural::Tdcache_address_t address, |
---|
245 | morpheo::behavioural::Tdcache_type_t type) |
---|
246 | { |
---|
247 | trace_memory_t trace; |
---|
248 | |
---|
249 | trace._cycle = simulation_cycle(); |
---|
250 | trace._context = context; |
---|
251 | trace._address = address; |
---|
252 | trace._type = type; |
---|
253 | trace._data_old = 0; |
---|
254 | trace._data_new = 0; |
---|
255 | |
---|
256 | _trace_memory.push_back(trace); |
---|
257 | |
---|
258 | return 0; |
---|
259 | } |
---|
260 | |
---|
261 | public : void trace (void) |
---|
262 | { |
---|
263 | for (std::list<trace_memory_t>::iterator i=_trace_memory.begin(); i!= _trace_memory.end(); i++) |
---|
264 | { |
---|
265 | std::cout << "{" << i->_cycle << "}\t" |
---|
266 | << i->_context << " - "; |
---|
267 | |
---|
268 | switch(i->_type) |
---|
269 | { |
---|
270 | case DCACHE_TYPE_LOCK : std::cout << "DCACHE_TYPE_LOCK "; break; |
---|
271 | case DCACHE_TYPE_INVALIDATE : std::cout << "DCACHE_TYPE_INVALIDATE "; break; |
---|
272 | case DCACHE_TYPE_PREFETCH : std::cout << "DCACHE_TYPE_PREFETCH "; break; |
---|
273 | case DCACHE_TYPE_FLUSH : std::cout << "DCACHE_TYPE_FLUSH "; break; |
---|
274 | case DCACHE_TYPE_SYNCHRONIZATION : std::cout << "DCACHE_TYPE_SYNCHRONIZATION"; break; |
---|
275 | case DCACHE_TYPE_LOAD_8 : std::cout << "DCACHE_TYPE_LOAD_8 "; break; |
---|
276 | case DCACHE_TYPE_LOAD_16 : std::cout << "DCACHE_TYPE_LOAD_16 "; break; |
---|
277 | case DCACHE_TYPE_LOAD_32 : std::cout << "DCACHE_TYPE_LOAD_32 "; break; |
---|
278 | case DCACHE_TYPE_LOAD_64 : std::cout << "DCACHE_TYPE_LOAD_64 "; break; |
---|
279 | case DCACHE_TYPE_STORE_8 : std::cout << "DCACHE_TYPE_STORE_8 "; break; |
---|
280 | case DCACHE_TYPE_STORE_16 : std::cout << "DCACHE_TYPE_STORE_16 "; break; |
---|
281 | case DCACHE_TYPE_STORE_32 : std::cout << "DCACHE_TYPE_STORE_32 "; break; |
---|
282 | case DCACHE_TYPE_STORE_64 : std::cout << "DCACHE_TYPE_STORE_64 "; break; |
---|
283 | } |
---|
284 | std::cout << " - " |
---|
285 | << std::hex |
---|
286 | << i->_address << " : " |
---|
287 | << i->_data_old << " -> " |
---|
288 | << i->_data_new << std::endl |
---|
289 | << std::dec; |
---|
290 | } |
---|
291 | } |
---|
292 | }; |
---|
293 | |
---|
294 | inline void test_Memory_t (void) |
---|
295 | { |
---|
296 | const uint32_t _nb_context = 4; |
---|
297 | const uint32_t _size_word = 32; |
---|
298 | const uint32_t _nb_word = 100; |
---|
299 | |
---|
300 | Memory_t * memory = new Memory_t (_nb_context, _nb_word, _size_word); |
---|
301 | |
---|
302 | memory -> access (2, 0x10, DCACHE_TYPE_STORE_32, 0xdeadbeef); |
---|
303 | memory -> access (2, 0x14, DCACHE_TYPE_STORE_16, 0xdada5678); |
---|
304 | memory -> access (2, 0x16, DCACHE_TYPE_STORE_16, 0xbead1234); |
---|
305 | memory -> access (2, 0x18, DCACHE_TYPE_STORE_8 , 0x45675681); |
---|
306 | memory -> access (2, 0x19, DCACHE_TYPE_STORE_8 , 0x1f311219); |
---|
307 | memory -> access (2, 0x1a, DCACHE_TYPE_STORE_8 , 0x2e075607); |
---|
308 | memory -> access (2, 0x1b, DCACHE_TYPE_STORE_8 , 0x19811221); |
---|
309 | |
---|
310 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_32, 0), 0xdeadbeef); |
---|
311 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x14, DCACHE_TYPE_LOAD_32, 0), 0x12345678); |
---|
312 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x18, DCACHE_TYPE_LOAD_32, 0), 0x21071981); |
---|
313 | |
---|
314 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_32, 0), 0xdeadbeef); |
---|
315 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_16, 0), 0xbeef); |
---|
316 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x12, DCACHE_TYPE_LOAD_16, 0), 0xdead); |
---|
317 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_8 , 0), 0xef); |
---|
318 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x11, DCACHE_TYPE_LOAD_8 , 0), 0xbe); |
---|
319 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x12, DCACHE_TYPE_LOAD_8 , 0), 0xad); |
---|
320 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x13, DCACHE_TYPE_LOAD_8 , 0), 0xde); |
---|
321 | |
---|
322 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_8_Z ), 0x000000ef); |
---|
323 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_8_S ), 0xffffffef); |
---|
324 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_16_Z), 0x0000beef); |
---|
325 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_16_S), 0xffffbeef); |
---|
326 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_32_Z), 0xdeadbeef); |
---|
327 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_32_S), 0xdeadbeef); |
---|
328 | |
---|
329 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_8_Z ), 0x000000ad); |
---|
330 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_8_S ), 0xffffffad); |
---|
331 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_16_Z), 0x0000dead); |
---|
332 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_16_S), 0xffffdead); |
---|
333 | |
---|
334 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x14, OPERATION_MEMORY_LOAD_8_Z ), 0x00000078); |
---|
335 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x14, OPERATION_MEMORY_LOAD_8_S ), 0x00000078); |
---|
336 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_16_Z), 0x00001981); |
---|
337 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_16_S), 0x00001981); |
---|
338 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_32_Z), 0x21071981); |
---|
339 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_32_S), 0x21071981); |
---|
340 | |
---|
341 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_8_Z ), 0x00000007); |
---|
342 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_8_S ), 0x00000007); |
---|
343 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_16_Z), 0x00002107); |
---|
344 | TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_16_S), 0x00002107); |
---|
345 | |
---|
346 | delete memory; |
---|
347 | } |
---|
348 | |
---|
349 | #endif |
---|