source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/src/Load_store_unit_function_speculative_load_commit_genMoore.cpp @ 136

Last change on this file since 136 was 136, checked in by rosiere, 15 years ago

1) Add new algo in ifetch queue
2) Add Cancel bit
3) new config

  • Property svn:keywords set to Id
File size: 13.0 KB
Line 
1#ifdef SYSTEMC
2//#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
3/*
4 * $Id: Load_store_unit_function_speculative_load_commit_genMoore.cpp 136 2009-10-20 18:52:15Z rosiere $
5 *
6 * [ Description ]
7 *
8 */
9
10#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/include/Load_store_unit.h"
11
12namespace morpheo                    {
13namespace behavioural {
14namespace core {
15namespace multi_execute_loop {
16namespace execute_loop {
17namespace multi_execute_unit {
18namespace execute_unit {
19namespace load_store_unit {
20
21
22#undef  FUNCTION
23#define FUNCTION "Load_store_unit::function_speculative_load_commit_genMoore"
24  void Load_store_unit::function_speculative_load_commit_genMoore (void)
25  {
26    log_begin(Load_store_unit,FUNCTION);
27    log_function(Load_store_unit,FUNCTION,_name.c_str());
28
29    if (PORT_READ(in_NRESET))
30      {
31    // ~~~~~[ Interface "memory_out" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32
33    Tcontext_t         memory_out_context_id    = 0;
34    Tcontext_t         memory_out_front_end_id  = 0;
35    Tcontext_t         memory_out_ooo_engine_id = 0;
36    Tpacket_t          memory_out_packet_id     = 0;
37    Tcontrol_t         memory_out_cancel        = 0;
38    Tcontrol_t         memory_out_write_rd      = 0;
39    Tgeneral_address_t memory_out_num_reg_rd    = 0;
40    Tgeneral_data_t    memory_out_data_rd       = 0;
41//  Tcontrol_t         memory_out_write_re      = 0;
42//  Tspecial_address_t memory_out_num_reg_re    = 0;
43//  Tspecial_data_t    memory_out_data_re       = 0;
44    Tcontrol_t         memory_out_no_sequence   = 0;
45    Texception_t       memory_out_exception     = 0;
46
47    internal_MEMORY_OUT_VAL = 0;
48
49    // Test store and load queue
50
51    log_printf(TRACE,Load_store_unit,FUNCTION,"  * Test MEMORY_OUT");
52
53    log_printf(TRACE,Load_store_unit,FUNCTION,"    * Load  queue");
54    for (internal_MEMORY_OUT_PTR=0; internal_MEMORY_OUT_PTR<_param->_size_load_queue; internal_MEMORY_OUT_PTR++)
55//     for (uin32_t i=0; (i<_param->_size_load_queue) and not (find_load); i++)
56      {
57//      internal_MEMORY_OUT_PTR = (reg_LOAD_QUEUE_PTR_READ+1)%_param->_size_load_queue;
58        internal_MEMORY_OUT_VAL = ((_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT_CHECK) or
59                                   (_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT));
60       
61        if (internal_MEMORY_OUT_VAL)
62          {
63            log_printf(TRACE,Load_store_unit,FUNCTION,"    * find : %d",internal_MEMORY_OUT_PTR);
64            internal_MEMORY_OUT_SELECT_QUEUE = (_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT_CHECK)?SELECT_LOAD_QUEUE_SPECULATIVE:SELECT_LOAD_QUEUE;
65           
66            memory_out_context_id    = _load_queue [internal_MEMORY_OUT_PTR]._context_id;
67            memory_out_front_end_id  = _load_queue [internal_MEMORY_OUT_PTR]._front_end_id;
68            memory_out_ooo_engine_id = _load_queue [internal_MEMORY_OUT_PTR]._ooo_engine_id;
69            memory_out_packet_id     = _load_queue [internal_MEMORY_OUT_PTR]._packet_id ;
70            memory_out_cancel        = _load_queue [internal_MEMORY_OUT_PTR]._cancel    ;
71            memory_out_write_rd      = _load_queue [internal_MEMORY_OUT_PTR]._write_rd  ;
72            memory_out_num_reg_rd    = _load_queue [internal_MEMORY_OUT_PTR]._num_reg_rd;
73
74            Tdcache_data_t data_old = _load_queue [internal_MEMORY_OUT_PTR]._rdata;
75            Tdcache_data_t data_new = extend<Tdcache_data_t>(_param->_size_general_data,
76                                                             data_old >> _load_queue [internal_MEMORY_OUT_PTR]._shift,
77                                                             _load_queue [internal_MEMORY_OUT_PTR]._is_load_signed,
78                                                             _load_queue [internal_MEMORY_OUT_PTR]._access_size);
79            log_printf(TRACE,Load_store_unit,FUNCTION,"    * data (old) : %.8x",data_old);
80            log_printf(TRACE,Load_store_unit,FUNCTION,"    * data (new) : %.8x",data_new);
81            log_printf(TRACE,Load_store_unit,FUNCTION,"      * address      : %.8x",_load_queue [internal_MEMORY_OUT_PTR]._address);
82            log_printf(TRACE,Load_store_unit,FUNCTION,"      * rdata        : %.8x",_load_queue [internal_MEMORY_OUT_PTR]._rdata);
83            log_printf(TRACE,Load_store_unit,FUNCTION,"      * shift        : %d",_load_queue [internal_MEMORY_OUT_PTR]._shift);
84            log_printf(TRACE,Load_store_unit,FUNCTION,"      * signed?      : %d",_load_queue [internal_MEMORY_OUT_PTR]._is_load_signed);
85            log_printf(TRACE,Load_store_unit,FUNCTION,"      * access_size  : %d",_load_queue [internal_MEMORY_OUT_PTR]._access_size);
86
87            Texception_t exception      = _load_queue [internal_MEMORY_OUT_PTR]._exception;
88            bool         have_exception = ((exception != EXCEPTION_MEMORY_NONE) and
89                                           (exception != EXCEPTION_MEMORY_MISS_SPECULATION));
90
91            // if exception, rdata content the address of load, else content read data.
92            memory_out_data_rd       = (have_exception)?data_old:data_new;
93            memory_out_exception     = (_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT_CHECK)?EXCEPTION_MEMORY_LOAD_SPECULATIVE:exception;
94
95            log_printf(TRACE,Load_store_unit,FUNCTION,"      * exception    : %d",exception);
96            log_printf(TRACE,Load_store_unit,FUNCTION,"      * exception    : %d",memory_out_exception);
97
98            break; // we have find a entry !!! stop the search
99          }
100      }
101
102    if (not internal_MEMORY_OUT_VAL)
103      {
104        log_printf(TRACE,Load_store_unit,FUNCTION,"    * Store queue");
105
106        for (uint32_t i=0; i<_param->_size_store_queue; ++i)
107          {
108            internal_MEMORY_OUT_PTR = (reg_STORE_QUEUE_PTR_READ+i)%_param->_size_store_queue;
109            // Can retire an store instruction if :
110            //  * state is commit
111            //  * none load must check this store
112
113
114            bool val_head = ((i==0) and
115                             (_store_queue [internal_MEMORY_OUT_PTR]._state       == STORE_QUEUE_COMMIT) and
116                             (_store_queue [internal_MEMORY_OUT_PTR]._send_commit == true) and
117                             (reg_STORE_QUEUE_NB_CHECK [internal_MEMORY_OUT_PTR] == 0)
118                             );
119
120            bool val_commit = ((_store_queue [internal_MEMORY_OUT_PTR]._state       != STORE_QUEUE_EMPTY) and
121                               (_store_queue [internal_MEMORY_OUT_PTR]._send_commit == false));
122
123            if (val_head or val_commit)
124              {
125                log_printf(TRACE,Load_store_unit,FUNCTION,"    * find : %d",internal_MEMORY_OUT_PTR);
126               
127                internal_MEMORY_OUT_VAL          = 1;
128                internal_MEMORY_OUT_SELECT_QUEUE = SELECT_STORE_QUEUE;
129               
130                memory_out_context_id    = _store_queue [internal_MEMORY_OUT_PTR]._context_id;
131                memory_out_front_end_id  = _store_queue [internal_MEMORY_OUT_PTR]._front_end_id;
132                memory_out_ooo_engine_id = _store_queue [internal_MEMORY_OUT_PTR]._ooo_engine_id;
133                memory_out_packet_id     = _store_queue [internal_MEMORY_OUT_PTR]._packet_id ;
134                memory_out_cancel        = _store_queue [internal_MEMORY_OUT_PTR]._cancel;
135//              memory_out_write_rd     
136//              memory_out_num_reg_rd   
137                memory_out_data_rd       = _store_queue [internal_MEMORY_OUT_PTR]._address; // to the exception
138                memory_out_exception     = _store_queue [internal_MEMORY_OUT_PTR]._exception;
139                memory_out_no_sequence   = val_commit;
140                break; // find an entry
141              }
142
143          }
144      }
145
146    // write output
147    if (_param->_have_port_context_id)
148    PORT_WRITE(out_MEMORY_OUT_CONTEXT_ID   [0], memory_out_context_id   );
149    if (_param->_have_port_front_end_id)
150    PORT_WRITE(out_MEMORY_OUT_FRONT_END_ID [0], memory_out_front_end_id );
151    if (_param->_have_port_ooo_engine_id)
152    PORT_WRITE(out_MEMORY_OUT_OOO_ENGINE_ID[0], memory_out_ooo_engine_id);
153    if (_param->_have_port_rob_ptr)
154    PORT_WRITE(out_MEMORY_OUT_PACKET_ID    [0], memory_out_packet_id    );
155//  PORT_WRITE(out_MEMORY_OUT_OPERATION    [0], memory_out_operation    );
156//  PORT_WRITE(out_MEMORY_OUT_TYPE         [0], TYPE_MEMORY             );
157    PORT_WRITE(out_MEMORY_OUT_CANCEL       [0], memory_out_cancel       );
158    PORT_WRITE(out_MEMORY_OUT_WRITE_RD     [0], memory_out_write_rd     );
159    PORT_WRITE(out_MEMORY_OUT_NUM_REG_RD   [0], memory_out_num_reg_rd   );
160    PORT_WRITE(out_MEMORY_OUT_DATA_RD      [0], memory_out_data_rd      );
161//  PORT_WRITE(out_MEMORY_OUT_WRITE_RE     [0], memory_out_write_re     );
162//  PORT_WRITE(out_MEMORY_OUT_NUM_REG_RE   [0], memory_out_num_reg_re   );
163//  PORT_WRITE(out_MEMORY_OUT_DATA_RE      [0], memory_out_data_re      );
164    PORT_WRITE(out_MEMORY_OUT_WRITE_RE     [0], 0);
165    PORT_WRITE(out_MEMORY_OUT_NUM_REG_RE   [0], 0);
166    PORT_WRITE(out_MEMORY_OUT_DATA_RE      [0], 0);
167    PORT_WRITE(out_MEMORY_OUT_EXCEPTION    [0], memory_out_exception    );
168    PORT_WRITE(out_MEMORY_OUT_NO_SEQUENCE  [0], memory_out_no_sequence  );// hack
169#ifdef DEBUG
170    PORT_WRITE(out_MEMORY_OUT_ADDRESS      [0], memory_out_data_rd);
171#else
172    PORT_WRITE(out_MEMORY_OUT_ADDRESS      [0], 0);
173#endif
174
175    // ~~~~~[ Interface "dache_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176
177    Tcontext_t        dcache_req_context_id = 0;
178    Tpacket_t         dcache_req_packet_id  = 0;
179    Tdcache_address_t dcache_req_address    = 0;
180    Tdcache_type_t    dcache_req_type       = 0;
181    Tdcache_data_t    dcache_req_wdata      = 0;
182
183    log_printf(TRACE,Load_store_unit,FUNCTION,"  * Test DCACHE_REQ");
184
185    internal_DCACHE_REQ_VAL = 0;
186
187    internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ = (*_speculative_access_queue_control)[0];
188
189    // Test store and load queue
190    if (_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._state == SPECULATIVE_ACCESS_QUEUE_WAIT_CACHE)
191      {
192        log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue [%d]",internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ);
193
194        internal_DCACHE_REQ_VAL          = 1;
195        internal_DCACHE_REQ_SELECT_QUEUE = SELECT_LOAD_QUEUE_SPECULATIVE;
196
197        if (_param->_have_port_dcache_context_id)
198          {
199            Tcontext_t context_id    = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id;
200            Tcontext_t front_end_id  = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id;
201            Tcontext_t ooo_engine_id = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id;
202           
203            dcache_req_context_id = ((ooo_engine_id<<(_param->_size_context_id + _param->_size_front_end_id )) |
204                                     (front_end_id <<(_param->_size_context_id)) |
205                                     (context_id));
206          }
207
208        dcache_req_packet_id  = DCACHE_REQ_IS_LOAD(_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._load_queue_ptr_write);
209        dcache_req_address    = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address;// & _param->_mask_address_msb;
210        dcache_req_type       = operation_to_dcache_type(_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._operation);
211
212//      log_printf(TRACE,Load_store_unit,FUNCTION,"      * address            : %.8x",_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address);
213//      log_printf(TRACE,Load_store_unit,FUNCTION,"      * mask               : %.8x",_param->_mask_address_msb);
214        log_printf(TRACE,Load_store_unit,FUNCTION,"      * dcache_req_address : %.8x",dcache_req_address);
215
216#ifdef SYSTEMC_VHDL_COMPATIBILITY
217        dcache_req_wdata      = 0;
218#endif
219      }
220    else
221      {
222        // Test an store must be commited.
223        if (_store_queue [reg_STORE_QUEUE_PTR_READ]._state == STORE_QUEUE_VALID_NO_SPECULATIVE)
224          {
225            internal_DCACHE_REQ_VAL          = 1;
226            internal_DCACHE_REQ_SELECT_QUEUE = SELECT_STORE_QUEUE;
227           
228            if (_param->_have_port_dcache_context_id)
229              {
230                Tcontext_t context_id    = _store_queue [reg_STORE_QUEUE_PTR_READ]._context_id;
231                Tcontext_t front_end_id  = _store_queue [reg_STORE_QUEUE_PTR_READ]._front_end_id;
232                Tcontext_t ooo_engine_id = _store_queue [reg_STORE_QUEUE_PTR_READ]._ooo_engine_id;
233               
234                dcache_req_context_id = ((ooo_engine_id<<(_param->_size_context_id + _param->_size_front_end_id )) |
235                                         (front_end_id <<(_param->_size_context_id)) |
236                                         (context_id));
237              }
238
239            // FIXME : il peut avoir plusieurs store avec le même paquet_id ... pour l'instant pas très grave car pas de retour (enfin seul les bus error sont des retours)
240            dcache_req_packet_id  = DCACHE_REQ_IS_STORE(reg_STORE_QUEUE_PTR_READ);
241            dcache_req_address    = _store_queue [reg_STORE_QUEUE_PTR_READ]._address;
242            dcache_req_type       = operation_to_dcache_type(_store_queue [reg_STORE_QUEUE_PTR_READ]._operation);
243            dcache_req_wdata      = _store_queue [reg_STORE_QUEUE_PTR_READ]._wdata;
244          }
245      }
246
247    if (_param->_have_port_dcache_context_id)
248    PORT_WRITE(out_DCACHE_REQ_CONTEXT_ID[0], dcache_req_context_id);
249    PORT_WRITE(out_DCACHE_REQ_PACKET_ID [0], dcache_req_packet_id );
250    PORT_WRITE(out_DCACHE_REQ_ADDRESS   [0], dcache_req_address   );
251    PORT_WRITE(out_DCACHE_REQ_TYPE      [0], dcache_req_type      );
252    PORT_WRITE(out_DCACHE_REQ_WDATA     [0], dcache_req_wdata     );
253      }
254    else
255      {
256        // Reset
257    internal_MEMORY_OUT_VAL = 0;
258//  internal_MEMORY_OUT_PTR =0
259//  internal_MEMORY_OUT_SELECT_QUEUE = SELECT_STORE_QUEUE;
260
261    internal_DCACHE_REQ_VAL = 0;
262    internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ = 0;
263//  internal_DCACHE_REQ_SELECT_QUEUE = SELECT_LOAD_QUEUE_SPECULATIVE;
264      }
265
266    // Write output
267    PORT_WRITE(out_MEMORY_OUT_VAL [0], internal_MEMORY_OUT_VAL);
268    PORT_WRITE(out_DCACHE_REQ_VAL [0], internal_DCACHE_REQ_VAL);
269
270
271    log_end(Load_store_unit,FUNCTION);
272  };
273
274}; // end namespace load_store_unit
275}; // end namespace execute_unit
276}; // end namespace multi_execute_unit
277}; // end namespace execute_loop
278}; // end namespace multi_execute_loop
279}; // end namespace core
280
281}; // end namespace behavioural
282}; // end namespace morpheo             
283#endif
284//#endif
Note: See TracBrowser for help on using the repository browser.