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 @ 122

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

Modif for performance :
1) Load Store Unit : store send request to valid exeception
2) Commit_unit : retire can bypass store
3) Commit_unit : add stat to manage store instruction
4) Load Store Unit and Load Store Pointer Manager : add store_queue_ptr_read
5) Fix lot of bug

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