source: trunk/modules/vci_cc_vcache_wrapper_multi/caba/source/src/vci_cc_vcache_wrapper_multi.cpp @ 40

Last change on this file since 40 was 40, checked in by gao, 14 years ago

cc_vcache_multi added

File size: 179.5 KB
Line 
1/* -*- c++ -*-
2 * File : vci_cc_vcache_wrapper_multi.cpp
3 * Copyright (c) UPMC, Lip6, SoC
4 * Authors : Alain GREINER, Yang GAO
5 *
6 * SOCLIB_LGPL_HEADER_BEGIN
7 *
8 * This file is part of SoCLib, GNU LGPLv2.1.
9 *
10 * SoCLib is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published
12 * by the Free Software Foundation; version 2.1 of the License.
13 *
14 * SoCLib is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with SoCLib; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 * SOCLIB_LGPL_HEADER_END
25 */
26
27#include <cassert>
28#include "arithmetics.h"
29#include "../include/vci_cc_vcache_wrapper_multi.h"
30
31namespace soclib { 
32namespace caba {
33
34//#define SOCLIB_MODULE_DEBUG
35#ifdef SOCLIB_MODULE_DEBUG
36namespace {
37const char *icache_fsm_state_str[] = {
38        "ICACHE_IDLE",
39        "ICACHE_BIS",       
40        "ICACHE_TLB1_READ", 
41        "ICACHE_TLB1_LL_WAIT",       
42        "ICACHE_TLB1_SC_WAIT",     
43        "ICACHE_TLB1_UPDT", 
44        "ICACHE_TLB2_READ", 
45        "ICACHE_TLB2_LL_WAIT",       
46        "ICACHE_TLB2_SC_WAIT",     
47        "ICACHE_TLB2_UPDT", 
48        "ICACHE_TLB_FLUSH", 
49        "ICACHE_CACHE_FLUSH", 
50        "ICACHE_TLB_INVAL", 
51        "ICACHE_CACHE_INVAL",
52            "ICACHE_CACHE_INVAL_PA",
53        "ICACHE_MISS_WAIT",
54        "ICACHE_UNC_WAIT", 
55        "ICACHE_MISS_UPDT", 
56        "ICACHE_ERROR", 
57        "ICACHE_CC_INVAL",
58        "ICACHE_TLB_CC_INVAL",
59    };
60const char *dcache_fsm_state_str[] = {
61        "DCACHE_IDLE",       
62        "DCACHE_BIS",     
63        "DCACHE_TLB1_READ", 
64        "DCACHE_TLB1_LL_WAIT",
65        "DCACHE_TLB1_SC_WAIT",
66        "DCACHE_TLB1_UPDT", 
67        "DCACHE_TLB2_READ", 
68        "DCACHE_TLB2_LL_WAIT",
69        "DCACHE_TLB2_SC_WAIT", 
70        "DCACHE_TLB2_UPDT",   
71        "DCACHE_CTXT_SWITCH",   
72        "DCACHE_ICACHE_FLUSH", 
73        "DCACHE_DCACHE_FLUSH", 
74        "DCACHE_ITLB_INVAL",
75        "DCACHE_DTLB_INVAL",
76        "DCACHE_ICACHE_INVAL",
77        "DCACHE_DCACHE_INVAL",
78        "DCACHE_ICACHE_INVAL_PA",
79            "DCACHE_DCACHE_INVAL_PA",
80        "DCACHE_DCACHE_SYNC",
81        "DCACHE_LL_DIRTY_WAIT",
82        "DCACHE_SC_DIRTY_WAIT", 
83        "DCACHE_WRITE_UPDT", 
84        "DCACHE_WRITE_DIRTY",
85        "DCACHE_WRITE_REQ", 
86        "DCACHE_MISS_WAIT", 
87        "DCACHE_MISS_UPDT", 
88        "DCACHE_UNC_WAIT",   
89        "DCACHE_ERROR", 
90        "DCACHE_CC_CHECK",
91        "DCACHE_CC_INVAL",
92        "DCACHE_CC_UPDT",
93        "DCACHE_CC_NOP",
94        "DCACHE_TLB_CC_INVAL",
95    };
96const char *cmd_fsm_state_str[] = {
97        "CMD_IDLE",           
98        "CMD_ITLB_READ",     
99        "CMD_ITLB_ACC_LL",
100        "CMD_ITLB_ACC_SC",     
101        "CMD_INS_MISS",     
102        "CMD_INS_UNC",     
103        "CMD_DTLB_READ", 
104        "CMD_DTLB_ACC_LL",
105        "CMD_DTLB_ACC_SC",
106        "CMD_DTLB_DIRTY_LL",
107        "CMD_DTLB_DIRTY_SC",
108        "CMD_DATA_UNC",     
109        "CMD_DATA_MISS",   
110        "CMD_DATA_WRITE",   
111    };
112const char *rsp_fsm_state_str[] = {
113        "RSP_IDLE",                 
114        "RSP_ITLB_READ",             
115        "RSP_ITLB_ACC_LL",
116        "RSP_ITLB_ACC_SC",               
117        "RSP_INS_MISS",   
118        "RSP_INS_UNC",           
119        "RSP_DTLB_READ", 
120        "RSP_DTLB_ACC_LL",
121        "RSP_DTLB_ACC_SC",         
122        "RSP_DTLB_DIRTY_LL",
123        "RSP_DTLB_DIRTY_SC",
124        "RSP_DATA_MISS",             
125        "RSP_DATA_UNC",             
126        "RSP_DATA_WRITE",   
127    };
128const char *tgt_fsm_state_str[] = {
129        "TGT_IDLE",
130        "TGT_UPDT_WORD",
131        "TGT_UPDT_DATA",
132        "TGT_REQ_BROADCAST",
133        "TGT_REQ_ICACHE",
134        "TGT_REQ_DCACHE",
135        "TGT_RSP_BROADCAST",
136        "TGT_RSP_ICACHE",
137        "TGT_RSP_DCACHE",
138    }; 
139const char *inval_itlb_fsm_state_str[] = {
140        "INVAL_ITLB_IDLE",       
141        "INVAL_ITLB_CHECK"  , 
142        "INVAL_ITLB_INVAL",     
143        "INVAL_ITLB_CLEAR",           
144    };
145const char *inval_dtlb_fsm_state_str[] = {
146        "INVAL_DTLB_IDLE",       
147        "INVAL_DTLB_CHECK", 
148        "INVAL_DTLB_INVAL",   
149        "INVAL_DTLB_CLEAR",         
150    };
151const char *cleanup_fsm_state_str[] = {
152        "CLEANUP_CMD",
153            "CLEANUP_ICACHE_RSP",
154        "CLEANUP_DCACHE_RSP",
155    };
156}
157#endif
158
159#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcVCacheWrapperMulti<vci_param, iss_t>
160
161using soclib::common::uint32_log2;
162
163/***********************************************/
164tmpl(/**/)::VciCcVCacheWrapperMulti(
165    sc_module_name name,
166    int proc_id,
167    const soclib::common::MappingTable &mtp,
168    const soclib::common::MappingTable &mtc,
169    const soclib::common::IntTab &initiator_index_rw,
170    const soclib::common::IntTab &initiator_index_c,
171    const soclib::common::IntTab &target_index,
172    size_t itlb_ways,
173    size_t itlb_sets,
174    size_t dtlb_ways,
175    size_t dtlb_sets,
176    size_t icache_ways,
177    size_t icache_sets,
178    size_t icache_words,
179    size_t dcache_ways,
180    size_t dcache_sets,
181    size_t dcache_words,
182    size_t wbuf_nwords,
183    size_t wbuf_nlines )
184/***********************************************/
185    : soclib::caba::BaseModule(name),
186
187      p_clk("clk"),
188      p_resetn("resetn"),
189      p_vci_ini_rw("vci_ini_rw"),
190      p_vci_ini_c("vci_ini_c"),
191      p_vci_tgt("vci_tgt"),
192
193      m_cacheability_table(mtp.getCacheabilityTable()),
194      m_segment(mtc.getSegment(target_index)),
195      m_iss(this->name(), proc_id),
196      m_srcid_rw(mtp.indexForId(initiator_index_rw)),
197      m_srcid_c(mtp.indexForId(initiator_index_c)),
198
199      m_itlb_ways(itlb_ways),
200      m_itlb_sets(itlb_sets),
201
202      m_dtlb_ways(dtlb_ways),
203      m_dtlb_sets(dtlb_sets),
204
205      m_icache_ways(icache_ways),
206      m_icache_sets(icache_sets),
207      m_icache_yzmask((~0)<<(uint32_log2(icache_words) + 2)),
208      m_icache_words(icache_words),
209
210      m_dcache_ways(dcache_ways),
211      m_dcache_sets(dcache_sets),
212      m_dcache_yzmask((~0)<<(uint32_log2(dcache_words) + 2)),
213      m_dcache_words(dcache_words),
214
215      m_wbuf_nlines(wbuf_nlines),
216      m_paddr_nbits(vci_param::N),
217
218      icache_tlb(itlb_ways,itlb_sets,vci_param::N),
219      dcache_tlb(dtlb_ways,dtlb_sets,vci_param::N),
220
221      r_dcache_fsm("r_dcache_fsm"),
222      r_dcache_paddr_save("r_dcache_paddr_save"),
223      r_dcache_wdata_save("r_dcache_wdata_save"),
224      r_dcache_rdata_save("r_dcache_rdata_save"),
225      r_dcache_type_save("r_dcache_type_save"),
226      r_dcache_be_save("r_dcache_be_save"),
227      r_dcache_cached_save("r_dcache_cached_save"),
228      r_dcache_tlb_paddr("r_dcache_tlb_paddr"),
229      r_dcache_miss_req("r_dcache_miss_req"),
230      r_dcache_unc_req("r_dcache_unc_req"),
231      r_dcache_write_req("r_dcache_write_req"),
232      r_dcache_tlb_read_req("r_dcache_tlb_read_req"),
233      r_dcache_tlb_ll_acc_req("r_dcache_tlb_ll_acc_req"),
234      r_dcache_tlb_sc_acc_req("r_dcache_tlb_sc_acc_req"),
235      r_dcache_tlb_ll_dirty_req("r_dcache_tlb_ll_dirty_req"),
236      r_dcache_tlb_sc_dirty_req("r_dcache_tlb_sc_dirty_req"),
237      r_dcache_tlb_ptba_read("r_dcache_tlb_ptba_read"),
238      r_dcache_xtn_req("r_dcache_xtn_req"),
239
240      r_icache_fsm("r_icache_fsm"),
241      r_icache_paddr_save("r_icache_paddr_save"),
242      r_icache_miss_req("r_icache_miss_req"),
243      r_icache_unc_req("r_icache_unc_req"),
244      r_icache_tlb_read_req("r_icache_tlb_read_req"),
245      r_icache_tlb_ll_req("r_icache_tlb_ll_req"),
246      r_icache_tlb_sc_req("r_icache_tlb_sc_req"),
247
248      r_vci_cmd_fsm("r_vci_cmd_fsm"),
249      r_vci_cmd_min("r_vci_cmd_min"),
250      r_vci_cmd_max("r_vci_cmd_max"),
251      r_vci_cmd_cpt("r_vci_cmd_cpt"),
252
253      r_vci_rsp_fsm("r_vci_rsp_fsm"),
254      r_vci_rsp_cpt("r_vci_rsp_cpt"),
255      r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
256      r_vci_rsp_data_error("r_vci_rsp_data_error"),
257
258      r_vci_tgt_fsm("r_vci_tgt_fsm"),
259      r_tgt_addr("r_tgt_addr"),
260      r_tgt_word("r_tgt_word"),
261      r_tgt_update("r_tgt_update"),
262      r_tgt_broadcast("r_tgt_broadcast"),
263      r_tgt_srcid("r_tgt_srcid"),
264      r_tgt_pktid("r_tgt_pktid"),
265      r_tgt_trdid("r_tgt_trdid"),
266      r_tgt_icache_req("r_tgt_icache_req"),
267      r_tgt_dcache_req("r_tgt_dcache_req"),
268      r_cleanup_fsm("r_cleanup_fsm"),
269
270      r_wbuf("wbuf", wbuf_nwords, wbuf_nlines ),
271      r_icache("icache", icache_ways, icache_sets, icache_words),
272      r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
273{
274    r_icache_miss_buf = new data_t[icache_words];
275    r_dcache_miss_buf = new data_t[dcache_words];
276    r_tgt_buf         = new data_t[dcache_words];
277    r_tgt_val         = new bool[dcache_words];
278
279    SC_METHOD(transition);
280    dont_initialize();
281    sensitive << p_clk.pos();
282 
283    SC_METHOD(genMoore);
284    dont_initialize();
285    sensitive << p_clk.neg();
286
287    typename iss_t::CacheInfo cache_info;
288    cache_info.has_mmu = true;
289    cache_info.icache_line_size = icache_words*sizeof(data_t);
290    cache_info.icache_assoc = icache_ways;
291    cache_info.icache_n_lines = icache_sets;
292    cache_info.dcache_line_size = dcache_words*sizeof(data_t);
293    cache_info.dcache_assoc = dcache_ways;
294    cache_info.dcache_n_lines = dcache_sets;
295    m_iss.setCacheInfo(cache_info);
296}
297
298/////////////////////////////////////
299tmpl(/**/)::~VciCcVCacheWrapperMulti()
300/////////////////////////////////////
301{
302    delete [] r_icache_miss_buf;
303    delete [] r_dcache_miss_buf;
304    delete [] r_tgt_val;
305    delete [] r_tgt_buf;
306}
307
308////////////////////////
309tmpl(void)::print_cpi()
310////////////////////////
311{
312    std::cout << name() << " CPI = " 
313        << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;
314}
315
316////////////////////////
317tmpl(void)::print_stats()
318////////////////////////
319{
320    float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
321    std::cout << name() << std::endl
322              << "- CPI                    = " << (float)m_cpt_total_cycles/run_cycles << std::endl
323              << "- READ RATE              = " << (float)m_cpt_read/run_cycles << std::endl
324              << "- WRITE RATE             = " << (float)m_cpt_write/run_cycles << std::endl
325              << "- UNCACHED READ RATE     = " << (float)m_cpt_unc_read/m_cpt_read << std::endl
326              << "- CACHED WRITE RATE      = " << (float)m_cpt_write_cached/m_cpt_write << std::endl
327              << "- IMISS_RATE             = " << (float)m_cpt_ins_miss/m_cpt_ins_read << std::endl   
328              << "- DMISS RATE             = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl
329              << "- INS MISS COST          = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl
330              << "- IMISS TRANSACTION      = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl
331              << "- DMISS COST             = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl
332              << "- DMISS TRANSACTION      = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl
333              << "- UNC COST               = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl
334              << "- UNC TRANSACTION        = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl
335              << "- WRITE COST             = " << (float)m_cost_write_frz/m_cpt_write << std::endl
336              << "- WRITE TRANSACTION      = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl
337              << "- WRITE LENGTH           = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl
338              << "- INS TLB MISS RATE      = " << (float)m_cpt_ins_tlb_miss/m_cpt_ins_tlb_read << std::endl
339              << "- DATA TLB MISS RATE     = " << (float)m_cpt_data_tlb_miss/m_cpt_data_tlb_read << std::endl
340              << "- ITLB MISS TRANSACTION  = " << (float)m_cost_itlbmiss_transaction/m_cpt_itlbmiss_transaction << std::endl
341              << "- ITLB WRITE TRANSACTION = " << (float)m_cost_itlb_write_transaction/m_cpt_itlb_write_transaction << std::endl
342              << "- ITLB MISS COST         = " << (float)m_cost_ins_tlb_miss_frz/(m_cpt_ins_tlb_miss+m_cpt_ins_tlb_write_et) << std::endl
343              << "- DTLB MISS TRANSACTION  = " << (float)m_cost_dtlbmiss_transaction/m_cpt_dtlbmiss_transaction << std::endl
344              << "- DTLB WRITE TRANSACTION = " << (float)m_cost_dtlb_write_transaction/m_cpt_dtlb_write_transaction << std::endl
345              << "- DTLB MISS COST         = " << (float)m_cost_data_tlb_miss_frz/(m_cpt_data_tlb_miss+m_cpt_data_tlb_write_et+m_cpt_data_tlb_write_dirty) << std::endl;
346}
347
348/*************************************************/
349tmpl(void)::transition()
350/*************************************************/
351{
352    if ( ! p_resetn.read() ) 
353    {
354        m_iss.reset();
355
356        r_dcache_fsm = DCACHE_IDLE;
357        r_icache_fsm = ICACHE_IDLE;
358        r_vci_cmd_fsm = CMD_IDLE;
359        r_vci_rsp_fsm = RSP_IDLE;
360        r_vci_tgt_fsm = TGT_IDLE;
361        r_inval_itlb_fsm = INVAL_ITLB_IDLE;         
362        r_inval_dtlb_fsm = INVAL_DTLB_IDLE;     
363        r_cleanup_fsm = CLEANUP_CMD;
364
365        // write buffer & caches
366        r_wbuf.reset();
367        r_icache.reset();
368        r_dcache.reset();
369
370        icache_tlb.reset();   
371        dcache_tlb.reset();   
372
373        r_mmu_mode = ALL_DEACTIVE;
374        r_mmu_params = (uint32_log2(m_dtlb_ways) << 29)   | (uint32_log2(m_dtlb_sets) << 25)   |
375                       (uint32_log2(m_dcache_ways) << 22) | (uint32_log2(m_dcache_sets) << 18) |
376                       (uint32_log2(m_itlb_ways) << 15)   | (uint32_log2(m_itlb_sets) << 11)   |
377                       (uint32_log2(m_icache_ways) << 8)  | (uint32_log2(m_icache_sets) << 4)  |
378                       (uint32_log2(m_icache_words * 4));
379        r_mmu_release = (uint32_t)(1 << 16) | 0x1;
380
381        r_icache_miss_req          = false;
382        r_icache_unc_req           = false;
383        r_icache_tlb_read_req      = false;
384        r_icache_tlb_first_req     = false;
385        r_icache_tlb_ll_req        = false;
386        r_icache_tlb_sc_req        = false;
387        r_icache_tlb_sc_fail       = false;
388
389        r_dcache_miss_req          = false;
390        r_dcache_unc_req           = false;
391        r_dcache_write_req         = false;
392        r_dcache_tlb_read_req      = false;
393        r_dcache_tlb_first_req     = false;
394        r_dcache_tlb_ll_acc_req    = false;
395        r_dcache_tlb_sc_acc_req    = false;
396        r_dcache_tlb_ll_dirty_req  = false;
397        r_dcache_tlb_sc_dirty_req  = false;
398        r_dcache_tlb_sc_fail       = false;
399        r_dcache_tlb_ptba_read     = false;
400        r_dcache_xtn_req           = false;
401
402        r_icache_cleanup_req       = false;
403        r_icache_cleanup_type      = NONE;
404   
405        r_dcache_cleanup_req       = false;
406        r_dcache_cleanup_type      = NONE; 
407 
408        r_tgt_icache_req           = false;
409        r_tgt_dcache_req           = false;
410        r_tgt_icache_rsp           = false;
411        r_tgt_dcache_rsp           = false;
412        r_ccinval_itlb_cpt         = 0; 
413        r_ccinval_dtlb_cpt         = 0; 
414
415        r_icache_cc_hit_t          = false;
416        r_dcache_cc_hit_t          = false;
417
418        r_tgt_broadcast            = false;
419        r_tgt_update               = false; 
420 
421        r_icache_inval_rsp         = false;
422        r_dcache_inval_rsp         = false;
423
424        r_icache_tlb_inval_req     = false;   
425        r_itlb_cc_check_end        = false;
426        r_icache_inval_tlb_rsp     = false;
427       
428        r_dcache_tlb_inval_req     = false;   
429        r_dtlb_cc_check_end        = false;
430        r_dcache_inval_tlb_rsp     = false;
431
432        r_dcache_dirty_save      = false;
433        r_dcache_hit_p_save      = false;
434
435        r_vci_rsp_ins_error      = false;
436        r_vci_rsp_data_error     = false;
437
438        r_icache_id1_save        = 0;
439        r_icache_ppn_save        = 0;
440        r_icache_vpn_save        = 0;
441        r_itlb_translation_valid = false;
442
443        r_dcache_id1_save        = 0;
444        r_dcache_ppn_save        = 0;
445        r_dcache_vpn_save        = 0;
446        r_dtlb_translation_valid = false;
447
448        r_icache_ptba_ok         = false;
449        r_dcache_ptba_ok         = false;
450
451        r_icache_error_type      = MMU_NONE;
452        r_dcache_error_type      = MMU_NONE;
453
454        // activity counters
455        m_cpt_dcache_data_read  = 0;
456        m_cpt_dcache_data_write = 0;
457        m_cpt_dcache_dir_read   = 0;
458        m_cpt_dcache_dir_write  = 0;
459        m_cpt_icache_data_read  = 0;
460        m_cpt_icache_data_write = 0;
461        m_cpt_icache_dir_read   = 0;
462        m_cpt_icache_dir_write  = 0;
463
464            m_cpt_frz_cycles   = 0;
465        m_cpt_total_cycles = 0;
466
467        m_cpt_read         = 0;
468        m_cpt_write        = 0;
469        m_cpt_data_miss    = 0;
470        m_cpt_ins_miss     = 0;
471        m_cpt_unc_read     = 0;
472        m_cpt_write_cached = 0;
473        m_cpt_ins_read     = 0; 
474
475        m_cost_write_frz     = 0;
476        m_cost_data_miss_frz = 0;
477        m_cost_unc_read_frz  = 0;
478        m_cost_ins_miss_frz  = 0;
479
480        m_cpt_imiss_transaction = 0;
481        m_cpt_dmiss_transaction = 0;
482        m_cpt_unc_transaction   = 0;
483        m_cpt_write_transaction = 0;
484
485        m_cost_imiss_transaction   = 0;
486        m_cost_dmiss_transaction   = 0;
487        m_cost_unc_transaction     = 0;
488        m_cost_write_transaction   = 0;
489        m_length_write_transaction = 0;
490
491        m_cpt_ins_tlb_read         = 0;             
492        m_cpt_ins_tlb_miss         = 0;             
493        m_cpt_ins_tlb_write_et     = 0;         
494
495        m_cpt_data_tlb_read        = 0;           
496        m_cpt_data_tlb_miss        = 0;           
497        m_cpt_data_tlb_write_et    = 0;       
498        m_cpt_data_tlb_write_dirty = 0;   
499
500        m_cost_ins_tlb_miss_frz    = 0;     
501        m_cost_data_tlb_miss_frz   = 0;     
502
503        m_cpt_itlbmiss_transaction   = 0;   
504        m_cpt_itlb_write_transaction = 0; 
505        m_cpt_dtlbmiss_transaction   = 0; 
506        m_cpt_dtlb_write_transaction = 0; 
507 
508        m_cost_itlbmiss_transaction   = 0;   
509        m_cost_itlb_write_transaction = 0; 
510        m_cost_dtlbmiss_transaction   = 0;   
511        m_cost_dtlb_write_transaction = 0; 
512        return;
513    }
514
515#ifdef SOCLIB_MODULE_DEBUG
516std::cout << name() << "cycle = " << m_cpt_total_cycles 
517          << " tgt fsm: " << tgt_fsm_state_str[r_vci_tgt_fsm]
518          << " dcache fsm: " << dcache_fsm_state_str[r_dcache_fsm]
519          << " icache fsm: " << icache_fsm_state_str[r_icache_fsm]
520          << " cmd fsm: " << cmd_fsm_state_str[r_vci_cmd_fsm]
521          << " rsp fsm: " << rsp_fsm_state_str[r_vci_rsp_fsm] << std::endl
522          << " itlb inval fsm: " << inval_itlb_fsm_state_str[r_inval_itlb_fsm]
523          << " dtlb inval fsm: " << inval_dtlb_fsm_state_str[r_inval_dtlb_fsm]
524          << " cleanup fsm: " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
525#endif
526
527    m_cpt_total_cycles++;
528
529    typename iss_t::InstructionRequest ireq = ISS_IREQ_INITIALIZER;
530    typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
531
532    typename iss_t::DataRequest dreq = ISS_DREQ_INITIALIZER;
533    typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER;
534
535    m_iss.getRequests( ireq, dreq );
536
537#ifdef SOCLIB_MODULE_DEBUG
538    std::cout << name() << " Instruction Request: " << ireq << std::endl;
539    std::cout << name() << " Data Request: " << dreq << std::endl;
540#endif
541
542    /////////////////////////////////////////////////////////////////////
543    // The TGT_FSM controls the following ressources:
544    // - r_vci_tgt_fsm
545    // - r_tgt_buf[nwords]
546    // - r_tgt_val[nwords]
547    // - r_tgt_update
548    // - r_tgt_word
549    // - r_tgt_addr
550    // - r_tgt_srcid
551    // - r_tgt_trdid
552    // - r_tgt_pktid
553    // All VCI commands must be CMD_WRITE.
554    // If the VCI address offset is null, the command is an invalidate
555    // request. It is an update request otherwise.
556    // The VCI_TGT FSM stores the external request arguments in the
557    // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req
558    // & r_tgt_dcache_req flip-flops to signal the external request to
559    // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
560    // of the update or invalidate request in the RSP state.
561    // -  for an invalidate request the VCI packet length is 1 word.
562    // The WDATA field contains the line index (i.e. the Z & Y fields).
563    // -  for an update request the VCI packet length is (n+2) words.
564    // The WDATA field of the first VCI word contains the line number.
565    // The WDATA field of the second VCI word contains the word index.
566    // The WDATA field of the n following words contains the values.
567    // -  for both invalidate & update requests, the VCI response
568    // is one single word.
569    // In case of errors in the VCI command packet, the simulation
570    // is stopped with an error message.
571    /////////////////////////////////////////////////////////////////////
572   
573    switch(r_vci_tgt_fsm) {
574    //////////////
575    case TGT_IDLE:
576    {
577        if ( p_vci_tgt.cmdval.read() ) 
578        {
579            paddr_t address = p_vci_tgt.address.read();
580
581            if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE) 
582            {
583                std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
584                std::cout << "the received VCI command is not a write" << std::endl;
585                exit(0);
586            }
587
588            // multi-update or multi-invalidate for data type
589            if ( ( address != 0x3 ) && ( ! m_segment.contains(address)) ) 
590            {
591                std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
592                std::cout << "out of segment VCI command received for a multi-updt or multi-inval request" << std::endl;
593                exit(0);
594            }
595
596            r_tgt_srcid = p_vci_tgt.srcid.read();
597            r_tgt_trdid = p_vci_tgt.trdid.read();
598            r_tgt_pktid = p_vci_tgt.pktid.read();
599            r_tgt_plen  = p_vci_tgt.plen.read(); 
600            r_tgt_addr  = (paddr_t)(p_vci_tgt.be.read() & 0x3) << 32 |
601                                      (paddr_t)p_vci_tgt.wdata.read() * m_dcache_words * 4; 
602
603            if ( address == 0x3 ) // broadcast invalidate for data or instruction type
604            {
605                if ( ! p_vci_tgt.eop.read() ) 
606                {
607                    std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
608                    std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
609                    exit(0);
610                }
611                r_tgt_update = false; 
612                r_tgt_broadcast = true; 
613                r_vci_tgt_fsm = TGT_REQ_BROADCAST;
614                m_cpt_cc_broadcast++;
615            }
616            else                // multi-update or multi-invalidate for data type
617            {
618                r_tgt_broadcast = false; 
619                paddr_t cell = address - m_segment.baseAddress();   
620
621                if (cell == 0)                      // invalidate   
622                {                         
623                    if ( ! p_vci_tgt.eop.read() ) 
624                    {
625                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
626                        std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
627                        exit(0);
628                    }
629                    r_tgt_update = false; 
630                    r_vci_tgt_fsm = TGT_REQ_DCACHE;
631                    m_cpt_cc_inval++ ;
632                }
633                else if (cell == 4)                // update
634                {                               
635                    if ( p_vci_tgt.eop.read() ) 
636                    {
637                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
638                        std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
639                        exit(0);
640                    }
641                    r_tgt_update = true; 
642                    r_vci_tgt_fsm = TGT_UPDT_WORD;
643                    m_cpt_cc_update++ ;
644                }     
645                        else if (cell == 8)
646                        {
647                    if ( ! p_vci_tgt.eop.read() ) 
648                    {
649                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
650                        std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
651                        exit(0);
652                    }
653                    r_tgt_update = false; 
654                    r_vci_tgt_fsm = TGT_REQ_ICACHE;
655                    m_cpt_cc_inval++ ;
656                        }
657            } // end if address   
658        } // end if cmdval
659        break;
660    }
661    ///////////////////
662    case TGT_UPDT_WORD:
663    {
664        if (p_vci_tgt.cmdval.read()) 
665        {
666            if ( p_vci_tgt.eop.read() ) 
667            {
668                std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
669                std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
670                exit(0);
671            }
672            for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_val[i] = false;
673            r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
674            r_vci_tgt_fsm = TGT_UPDT_DATA;
675        }
676        break;
677    }
678    ///////////////////
679    case TGT_UPDT_DATA:
680    {
681        if (p_vci_tgt.cmdval.read()) 
682        {
683            size_t word = r_tgt_word.read();
684            if (word >= m_dcache_words) 
685            {
686                std::cout << "error in component VCI_CC_VCACHE_WRAPPER_MULTI " << name() << std::endl;
687                std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
688                exit(0);
689            }
690            r_tgt_buf[word] = p_vci_tgt.wdata.read();
691            if(p_vci_tgt.be.read())    r_tgt_val[word] = true;
692            r_tgt_word = word + 1;
693            if (p_vci_tgt.eop.read())  r_vci_tgt_fsm = TGT_REQ_DCACHE;
694        }
695        break;
696    }
697    ////////////////////////
698    case TGT_REQ_BROADCAST:
699    {
700        if ( !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() ) 
701        {
702            r_vci_tgt_fsm = TGT_RSP_BROADCAST; 
703            r_tgt_icache_req = true;
704            r_tgt_dcache_req = true;
705        }
706        break;
707    }
708    /////////////////////
709    case TGT_REQ_ICACHE:
710    {
711        if ( !r_tgt_icache_req.read() ) 
712        {
713            r_vci_tgt_fsm = TGT_RSP_ICACHE; 
714            r_tgt_icache_req = true;
715        }
716        break;
717    }
718    /////////////////////
719    case TGT_REQ_DCACHE:
720    {
721        if ( !r_tgt_dcache_req.read() ) 
722        {
723            r_vci_tgt_fsm = TGT_RSP_DCACHE; 
724            r_tgt_dcache_req = true;
725        }
726        break;
727    }
728    ///////////////////////
729    case TGT_RSP_BROADCAST:
730    {
731        // no response
732        if ( !r_tgt_icache_rsp.read() && !r_tgt_dcache_rsp.read() 
733          && !r_ccinval_itlb_cpt.read() && !r_ccinval_dtlb_cpt.read() 
734          && !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() )
735        {
736            r_vci_tgt_fsm = TGT_IDLE;
737            break;
738        }
739
740        if ( p_vci_tgt.rspack.read() && !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() ) 
741        {
742            if ( r_tgt_icache_rsp )
743            {
744                r_tgt_icache_rsp = false;
745                break;
746            }
747            if ( r_tgt_dcache_rsp )
748            {
749                r_tgt_dcache_rsp = false;
750                break;
751            }
752            if ( r_ccinval_itlb_cpt )
753            {
754                r_ccinval_itlb_cpt = r_ccinval_itlb_cpt - 1;
755                break;
756            }
757            if ( r_ccinval_dtlb_cpt )
758            {
759                r_ccinval_dtlb_cpt = r_ccinval_dtlb_cpt - 1;
760                break;
761            }
762        }       
763        break;
764    }
765    /////////////////////
766    case TGT_RSP_ICACHE:
767    {
768        if ( (p_vci_tgt.rspack.read() || !r_tgt_icache_rsp.read()) && !r_tgt_icache_req.read() ) 
769        {
770            r_vci_tgt_fsm = TGT_IDLE;
771            r_tgt_icache_rsp = false; 
772        }
773        break;
774    }
775    /////////////////////
776    case TGT_RSP_DCACHE:
777    {
778        if ( (p_vci_tgt.rspack.read() || !r_tgt_dcache_rsp.read()) && !r_tgt_dcache_req.read() )
779        {
780            r_vci_tgt_fsm = TGT_IDLE;
781            r_tgt_dcache_rsp = false; 
782        }
783        break;
784    }
785    } // end switch TGT_FSM
786
787    ////////////////////////////////////////////////////////////////////////////////////////
788    //      ICACHE_FSM
789    //
790    // There is 9 mutually exclusive conditions to exit the IDLE state.
791    // Four configurations corresponding to an XTN request from processor,
792    // - Flush TLB (in case of Context switch) => TLB_FLUSH state
793    // - Flush cache => CACHE_FLUSH state
794    // - Invalidate a TLB entry => TLB_INVAL state
795    // - Invalidate a cache line => CACHE_INVAL state
796    // Five configurations corresponding to various TLB or cache MISS :
797    // - TLB miss(in case hit_p miss) => TLB1_READ state
798    // - TLB miss(in case hit_p hit) => TLB2_READ state
799    // - Hit in TLB but VPN changed => BIS state
800    // - Cached read miss => MISS_REQ state
801    // - Uncache read miss => UNC_REQ state
802    //
803    // In case of MISS, the controller writes a request in the r_icache_paddr_save register
804    // and sets the corresponding request flip-flop : r_icache_tlb_read_req, r_icache_miss_req
805    // or r_icache_unc_req. These request flip-flops are reset by the VCI_RSP controller
806    // when the response is ready in the ICACHE buffer.
807    //
808    // The DCACHE FSM signals XTN processor requests using the r_dcache_xtn_req flip-flop.
809    // The request opcod and the address to be invalidated are transmitted
810    // in the r_dcache_paddr_save & r_dcache_wdata_save registers respectively.
811    // The request flip-flop is reset by the ICACHE_FSM when the operation is completed.
812    //
813    // The r_vci_rsp_ins_error flip-flop is set by the VCI_RSP FSM and reset
814    // by the ICACHE-FSM in the ICACHE_ERROR state.
815    //
816    //-----------------------------------------------------------------------------------
817    // Instruction TLB:
818    // 
819    // - int        ET          (00: unmapped; 01: unused or PTD)
820    //                          (10: PTE new;  11: PTE old      )
821    // - bool       cachable    (cached bit)
822    // - bool       writable    (** not used alwayse false)
823    // - bool       executable  (executable bit)
824    // - bool       user        (access in user mode allowed)
825    // - bool       global      (PTE not invalidated by a TLB flush)
826    // - bool       dirty       (** not used alwayse false)
827    // - uint32_t   vpn         (virtual page number)
828    // - uint32_t   ppn         (physical page number)
829    ////////////////////////////////////////////////////////////////////////////////////////
830
831    switch(r_icache_fsm) {
832
833    ////////////////
834    case ICACHE_IDLE:
835    {
836        pte_info_t  icache_pte_info;
837        paddr_t     tlb_ipaddr     = 0;        // physical address obtained from TLB                               
838        paddr_t     spc_ipaddr     = 0;        // physical adress obtained from PPN_save (speculative)                         
839        data_t      icache_ins     = 0;        // read instruction
840        bool        icache_hit_c   = false;    // Cache hit
841        bool        icache_cached  = false;    // cacheable access (read)
842        bool        icache_hit_t   = false;    // hit on 4Kilo TLB
843        bool        icache_hit_x   = false;    // VPN unmodified (can use spc_dpaddr)
844        bool        icache_hit_p   = false;    // PTP unmodified (can skip first level page table walk)
845        size_t      icache_tlb_way = 0;        // selected way (in case of cache hit)
846        size_t      icache_tlb_set = 0;        // selected set (Y field in address)
847        paddr_t     icache_tlb_nline = 0;      // TLB NLINE
848
849        // Decoding processor XTN requests
850        // They are sent by DCACHE FSM 
851
852        if (r_dcache_xtn_req)
853        {
854            if ( ireq.valid ) m_cost_ins_miss_frz++;
855
856            if ((int)r_dcache_type_save == (int)iss_t::XTN_PTPR) 
857            {
858                r_icache_way = 0;
859                r_icache_set = 0;
860                r_icache_fsm = ICACHE_TLB_FLUSH;   
861                break;
862            }
863            if ((int)r_dcache_type_save == (int)iss_t::XTN_ICACHE_FLUSH)
864            {
865                r_icache_way = 0;
866                r_icache_set = 0;
867                r_icache_fsm = ICACHE_CACHE_FLUSH;   
868                break;
869            }
870            if ((int)r_dcache_type_save == (int)iss_t::XTN_ITLB_INVAL) 
871            {
872                r_icache_fsm = ICACHE_TLB_INVAL;   
873                break;
874            }
875            if ((int)r_dcache_type_save == (int)iss_t::XTN_ICACHE_INVAL) 
876            {
877                r_icache_fsm = ICACHE_CACHE_INVAL;   
878                break;
879            }
880            if ((int)r_dcache_type_save == (int)iss_t::XTN_MMU_ICACHE_PA_INV) 
881            {
882                r_icache_fsm = ICACHE_CACHE_INVAL_PA;   
883                break;
884            }
885        } // end if xtn_req
886
887        // external request from broadcast
888        if ( r_tgt_icache_req )
889        {
890            if ( ireq.valid ) m_cost_ins_miss_frz++;
891            r_icache_fsm = ICACHE_CC_INVAL;
892            r_icache_fsm_save = r_icache_fsm;
893            break;
894        }
895
896        // icache_hit_t, icache_hit_x, icache_hit_p
897        // icache_pte_info, icache_tlb_way, icache_tlb_set & ipaddr & cacheability
898        // - If MMU activated : cacheability is defined by the cachable bit in the TLB
899        // - If MMU not activated : cacheability is defined by the segment table.
900
901        if ( !(r_mmu_mode.read() & INS_TLB_MASK) )   // MMU not activated
902        {
903            icache_hit_t  = true;         
904            icache_hit_x  = true;         
905            icache_hit_p  = true;         
906            tlb_ipaddr    = ireq.addr;
907            spc_ipaddr    = ireq.addr;
908            icache_cached = m_cacheability_table[ireq.addr];
909        } 
910        else                                                                // MMU activated
911        { 
912            m_cpt_ins_tlb_read++;
913            icache_hit_t = icache_tlb.cctranslate(ireq.addr, &tlb_ipaddr, &icache_pte_info, 
914                                                  &icache_tlb_nline, &icache_tlb_way, &icache_tlb_set); 
915            icache_hit_x   = (((vaddr_t)r_icache_vpn_save << PAGE_K_NBITS) == (ireq.addr & ~PAGE_K_MASK)) && r_itlb_translation_valid;
916            icache_hit_p   = (((ireq.addr >> PAGE_M_NBITS) == r_icache_id1_save) && r_icache_ptba_ok); 
917            spc_ipaddr     = ((paddr_t)r_icache_ppn_save << PAGE_K_NBITS) | (paddr_t)(ireq.addr & PAGE_K_MASK);
918            icache_cached  = icache_pte_info.c; 
919        }
920
921        if ( !(r_mmu_mode.read() & INS_CACHE_MASK) )   // cache not actived
922        {
923            icache_cached = false;
924        }
925
926        if ( ireq.valid ) 
927        {
928            m_cpt_icache_dir_read += m_icache_ways;
929            m_cpt_icache_data_read += m_icache_ways;
930
931            // icache_hit_c & icache_ins
932            if ( icache_cached )    // using speculative physical address for cached access
933            {
934                icache_hit_c = r_icache.read(spc_ipaddr, &icache_ins);
935            }
936            else                    // using actual physical address for uncached access
937            {
938                icache_hit_c = ( r_vci_rsp_ins_ok && (tlb_ipaddr == (paddr_t)r_icache_paddr_save) );
939                icache_ins = r_icache_miss_buf[0];
940            }
941
942            if ( r_mmu_mode.read() & INS_TLB_MASK ) 
943            {
944                if ( icache_hit_t ) 
945                {
946                    // check access rights
947                    if ( !icache_pte_info.u && (ireq.mode == iss_t::MODE_USER)) 
948                    {
949                        r_icache_error_type = MMU_READ_PRIVILEGE_VIOLATION; 
950                        r_icache_bad_vaddr = ireq.addr;
951                        irsp.valid = true;
952                        irsp.error = true;
953                        irsp.instruction = 0;
954                        break;
955                    }
956                    if ( !icache_pte_info.x ) 
957                    {
958                        r_icache_error_type = MMU_READ_EXEC_VIOLATION; 
959                        r_icache_bad_vaddr = ireq.addr;
960                        irsp.valid = true;
961                        irsp.error = true;
962                        irsp.instruction = 0;
963                        break;
964                    }
965                }
966
967                // update LRU, save ppn, vpn and page type
968                if ( icache_hit_t )
969                { 
970                    icache_tlb.setlru(icache_tlb_way,icache_tlb_set);     
971                    r_icache_ppn_save = tlb_ipaddr >> PAGE_K_NBITS;
972                    r_icache_vpn_save = ireq.addr >> PAGE_K_NBITS;
973                    r_icache_tlb_nline = icache_tlb_nline;
974                    r_itlb_translation_valid = true;
975                }
976                else
977                {
978                    r_itlb_translation_valid = false;
979                }
980
981            } // end if MMU activated
982
983            // compute next state
984            if ( !icache_hit_t && !icache_hit_p )      // TLB miss
985            {
986                // walk page table  level 1
987                r_icache_paddr_save = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((ireq.addr>>PAGE_M_NBITS)<<2);
988                r_icache_tlb_read_req = true;
989                r_icache_tlb_first_req = true;
990                r_vci_rsp_ins_ok = false;
991                r_icache_vaddr_req = ireq.addr;
992                r_icache_fsm = ICACHE_TLB1_READ;
993                m_cpt_ins_tlb_miss++;
994                m_cost_ins_tlb_miss_frz++;
995            }
996            else if ( !icache_hit_t && icache_hit_p )  // TLB Miss with possibility of bypass first level page
997            {
998                // walk page table level 2
999                r_icache_paddr_save = (paddr_t)r_icache_ptba_save | 
1000                                      (paddr_t)(((ireq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
1001                r_icache_tlb_read_req = true;
1002                r_icache_tlb_first_req = false;
1003                r_vci_rsp_ins_ok = false;
1004                r_icache_vaddr_req = ireq.addr;
1005                r_icache_fsm = ICACHE_TLB2_READ;
1006                m_cpt_ins_tlb_miss++;
1007                m_cost_ins_tlb_miss_frz++;
1008            }
1009            else if ( icache_hit_t && !icache_hit_x && icache_cached ) // cached access with an ucorrect speculative physical address
1010            {
1011                r_icache_paddr_save = tlb_ipaddr;   // save actual physical address for BIS
1012                r_icache_vaddr_req = ireq.addr;
1013                r_icache_fsm = ICACHE_BIS;
1014                m_cost_ins_miss_frz++;
1015            }
1016            else    // cached or uncached access with a correct speculative physical address
1017            {   
1018                m_cpt_ins_read++;     
1019                if ( !icache_hit_c ) 
1020                {
1021                    m_cpt_ins_miss++;
1022                    m_cost_ins_miss_frz++;
1023                    if ( icache_cached ) 
1024                    {
1025                        r_icache_miss_req = true;
1026                        r_vci_rsp_ins_ok = false;
1027                        r_icache_paddr_save = spc_ipaddr; 
1028                        r_icache_vaddr_req = ireq.addr;
1029                        r_icache_fsm = ICACHE_MISS_WAIT;
1030                    } 
1031                    else 
1032                    {
1033                        r_icache_unc_req = true;
1034                        r_vci_rsp_ins_ok = false;
1035                        r_icache_paddr_save = tlb_ipaddr;
1036                        r_icache_vaddr_req = ireq.addr; 
1037                        r_icache_fsm = ICACHE_UNC_WAIT;
1038                    } 
1039                } 
1040                else 
1041                {
1042                    r_vci_rsp_ins_ok = false;
1043                    r_icache_fsm = ICACHE_IDLE;
1044                }
1045                irsp.valid = icache_hit_c;
1046                irsp.instruction = icache_ins;
1047            } // end if next states
1048           
1049        } // end if ireq.valid
1050        break;
1051    }
1052    ////////////////
1053    case ICACHE_BIS: 
1054    {
1055        // external cache invalidate request
1056        if ( r_tgt_icache_req )
1057        {
1058            if ( ireq.valid ) m_cost_ins_miss_frz++;
1059            r_icache_fsm = ICACHE_CC_INVAL;
1060            r_icache_fsm_save = r_icache_fsm;
1061            break;
1062        }
1063
1064        // using page is invalidated
1065        if ( r_icache_inval_tlb_rsp )
1066        {
1067            if ( ireq.valid ) m_cost_ins_miss_frz++;
1068            r_icache_inval_tlb_rsp = false;
1069            r_icache_fsm = ICACHE_IDLE;
1070            break;
1071        }
1072
1073        data_t      icache_ins   = 0;
1074        bool        icache_hit_c = false;
1075        bool        icache_hit_t = false;
1076        paddr_t     tlb_ipaddr   = 0;
1077
1078        // processor address translation
1079        icache_hit_t = icache_tlb.translate(ireq.addr, &tlb_ipaddr);
1080
1081        // test if processor request modified
1082        if ( (tlb_ipaddr == r_icache_paddr_save.read()) && ireq.valid && icache_hit_t ) // unmodified & valid
1083        {
1084            // acces is always cached in this state
1085            icache_hit_c = r_icache.read(r_icache_paddr_save, &icache_ins);
1086            m_cpt_ins_read++;
1087     
1088            if ( !icache_hit_c )
1089            {
1090                r_icache_miss_req = true;
1091                r_vci_rsp_ins_ok = false;
1092                r_icache_fsm = ICACHE_MISS_WAIT;
1093                m_cpt_ins_miss++;
1094                m_cost_ins_miss_frz++;
1095            } 
1096            else
1097            {
1098                r_icache_fsm = ICACHE_IDLE; 
1099            }
1100
1101            irsp.valid = icache_hit_c;
1102                if (irsp.valid)
1103                    assert((r_icache_vaddr_req.read() == ireq.addr) &&
1104                        "vaddress should not be modified while ICACHE_BIS");
1105            irsp.error = false;
1106            irsp.instruction = icache_ins;
1107        }
1108        else
1109        {
1110            irsp.valid = false;
1111            irsp.error = false;
1112            irsp.instruction = 0;
1113            r_icache_fsm = ICACHE_IDLE;
1114        }
1115        break;
1116    }
1117    //////////////////////
1118    case ICACHE_TLB1_READ:
1119    {
1120        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
1121
1122        // external cache invalidate request
1123        if ( r_tgt_icache_req )
1124        {
1125            r_icache_fsm = ICACHE_CC_INVAL;
1126            r_icache_fsm_save = r_icache_fsm;
1127            break;
1128        }
1129
1130        // cleanup PTD in L2, because it's not keep in L1
1131                if ( r_icache_cleanup_req ) break;
1132
1133        if ( r_vci_rsp_ins_ok ) // vci response
1134        {
1135                if (r_icache_vaddr_req.read() != ireq.addr || !ireq.valid) 
1136                {
1137                    /* request modified, drop response and restart */
1138                    r_icache_ptba_ok = false;
1139                if ( r_icache_inval_tlb_rsp )   r_icache_inval_tlb_rsp = false;
1140                if ( r_vci_rsp_ins_error )      r_vci_rsp_ins_error = false;
1141                    r_icache_fsm = ICACHE_IDLE;
1142                    break;
1143                }
1144
1145            if ( !r_icache_inval_tlb_rsp ) // vci response
1146            { 
1147                if ( !r_vci_rsp_ins_error ) // vci response ok
1148                { 
1149                    if ( !(r_icache_miss_buf[0] >> PTE_V_SHIFT) ) // unmapped
1150                    {
1151                            r_icache_ptba_ok    = false;       
1152                        r_icache_error_type = MMU_READ_PT1_UNMAPPED; 
1153                        r_icache_bad_vaddr  = r_icache_vaddr_req.read();
1154                        r_icache_fsm        = ICACHE_ERROR;
1155                    }
1156                        else if ( (r_icache_miss_buf[0] & PTE_T_MASK ) >> PTE_T_SHIFT ) // PTD
1157                        {
1158                        r_icache_ptba_ok       = true; 
1159                        r_icache_ptba_save     = (paddr_t)(r_icache_miss_buf[0] & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS; 
1160                        r_icache_id1_save      = r_icache_vaddr_req.read() >> PAGE_M_NBITS;
1161                        r_icache_paddr_save    = (paddr_t)(r_icache_miss_buf[0] & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
1162                                                 (paddr_t)(((r_icache_vaddr_req.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 
1163                        r_icache_tlb_read_req  = true;
1164                        r_icache_tlb_first_req = false;
1165                        r_vci_rsp_ins_ok       = false;
1166                        r_icache_fsm           = ICACHE_TLB2_READ;
1167
1168                        // cleanup PTD in L2, because it's not keep in L1
1169                        r_icache_cleanup_req = true;
1170                        r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
1171                        r_icache_cleanup_type = TLB_CLEANUP;
1172                        }       
1173                        else        // PTE
1174                        {
1175                        r_icache_ptba_ok = false;
1176                       
1177                            if ( (m_srcid_rw >> 4) == ((r_icache_miss_buf[0] & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
1178                            {
1179                                if ( (r_icache_miss_buf[0] & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
1180                                {
1181                                r_icache_pte_update = r_icache_miss_buf[0];
1182                                r_vci_rsp_ins_ok    = false;
1183                                r_icache_fsm        = ICACHE_TLB1_UPDT;
1184                                }
1185                                else
1186                                {
1187                                r_icache_pte_update = r_icache_miss_buf[0] | PTE_L_MASK;
1188                                r_icache_tlb_ll_req = true;
1189                                r_vci_rsp_ins_ok    = false;
1190                                r_icache_fsm        = ICACHE_TLB1_LL_WAIT;
1191                                m_cpt_ins_tlb_write_et++;
1192                                }
1193                        }
1194                            else // remotely
1195                            {
1196                                if ( (r_icache_miss_buf[0] & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
1197                                {
1198                                r_icache_pte_update = r_icache_miss_buf[0];
1199                                r_vci_rsp_ins_ok    = false;
1200                                r_icache_fsm        = ICACHE_TLB1_UPDT;
1201                                }
1202                                else
1203                                {
1204                                r_icache_pte_update = r_icache_miss_buf[0] | PTE_R_MASK;
1205                                r_icache_tlb_ll_req = true;
1206                                r_vci_rsp_ins_ok    = false;
1207                                r_icache_fsm        = ICACHE_TLB1_LL_WAIT;
1208                                m_cpt_ins_tlb_write_et++;
1209                                }
1210                            }
1211                        }
1212                }
1213                else        // vci response error
1214                {
1215                    r_icache_fsm = ICACHE_ERROR;
1216                    r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;   
1217                    r_icache_bad_vaddr = ireq.addr;
1218                }
1219            }
1220
1221            if ( r_icache_inval_tlb_rsp ) // TLB miss read response and invalidation
1222            {
1223                if ( r_vci_rsp_ins_error ) 
1224                {
1225                    r_icache_inval_tlb_rsp = false;
1226                    r_icache_error_type = MMU_READ_PT1_UNMAPPED;   
1227                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
1228                    r_icache_fsm = ICACHE_ERROR;
1229                } 
1230                else 
1231                {
1232                    r_icache_inval_tlb_rsp = false;
1233                    r_icache_cleanup_req = true;
1234                    r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
1235                    r_icache_cleanup_type = TLB_CLEANUP;
1236                    r_icache_fsm = ICACHE_IDLE; 
1237                } 
1238            }
1239        }
1240        break;
1241    }
1242    ///////////////////////
1243    case ICACHE_TLB1_LL_WAIT:
1244    {
1245        // external cache invalidate request
1246        if ( r_tgt_icache_req )
1247        {
1248            r_icache_fsm = ICACHE_CC_INVAL;
1249            r_icache_fsm_save = r_icache_fsm;
1250            break;
1251        }
1252
1253            if ( r_vci_rsp_ins_ok )
1254            {
1255            if ( r_vci_rsp_ins_error ) // VCI response ko
1256            {
1257                r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;   
1258                r_icache_bad_vaddr = ireq.addr;
1259                r_icache_fsm = ICACHE_ERROR;
1260
1261                        if (r_icache_inval_tlb_rsp) r_icache_inval_tlb_rsp = false;
1262            }
1263                else
1264                {
1265                    if ( !(r_icache_miss_buf[0] >> PTE_V_SHIFT) )       // unmapped
1266                    {
1267                    r_icache_error_type = MMU_READ_PT1_UNMAPPED;       
1268                    r_icache_bad_vaddr  = ireq.addr;
1269                    r_icache_fsm        = ICACHE_ERROR;
1270
1271                            if (r_icache_inval_tlb_rsp) r_icache_inval_tlb_rsp = false;
1272                    }
1273                else if ( r_icache_inval_tlb_rsp )
1274                {
1275                        r_icache_inval_tlb_rsp = false;
1276                        r_icache_fsm = ICACHE_IDLE;
1277                }
1278                        else
1279                        {
1280                            r_icache_tlb_sc_req = true;
1281                    r_vci_rsp_ins_ok    = false;
1282                    r_icache_pte_update = r_icache_miss_buf[0] | r_icache_pte_update.read();
1283                    r_icache_fsm        = ICACHE_TLB1_SC_WAIT; 
1284                        }
1285                }
1286            }
1287            break;
1288    }
1289    ///////////////////////
1290    case ICACHE_TLB1_SC_WAIT:
1291    {
1292        // external cache invalidate request
1293        if ( r_tgt_icache_req )
1294        {
1295            r_icache_fsm = ICACHE_CC_INVAL;
1296            r_icache_fsm_save = r_icache_fsm;
1297            break;
1298        }
1299
1300        if ( r_vci_rsp_ins_ok ) // VCI response ko
1301        {
1302            if ( r_vci_rsp_ins_error ) // VCI response ko
1303                {
1304                r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;   
1305                r_icache_bad_vaddr  = ireq.addr; 
1306                r_icache_fsm        = ICACHE_ERROR;
1307
1308                        if (r_icache_inval_tlb_rsp) r_icache_inval_tlb_rsp = false;
1309                }
1310            else
1311            {
1312                if ( r_icache_inval_tlb_rsp )
1313                {
1314                        r_icache_inval_tlb_rsp = false;
1315                    if (r_icache_tlb_sc_fail) r_icache_tlb_sc_fail = false;
1316                        r_icache_fsm = ICACHE_IDLE;
1317                }
1318                    else if ( r_icache_tlb_sc_fail )
1319                    {
1320                    r_icache_tlb_ll_req = true;
1321                    r_icache_tlb_sc_fail = false;
1322                    r_vci_rsp_ins_ok = false;
1323                        r_icache_fsm = ICACHE_TLB1_LL_WAIT; 
1324                    }
1325                    else 
1326                    {
1327                    r_vci_rsp_ins_ok = false;
1328                        r_icache_fsm = ICACHE_TLB1_UPDT; 
1329                    }
1330            }
1331        }
1332            break;
1333    }
1334    //////////////////////
1335    case ICACHE_TLB1_UPDT:
1336    {
1337        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
1338
1339        // external cache invalidate request
1340        if ( r_tgt_icache_req )
1341        {
1342            r_icache_fsm = ICACHE_CC_INVAL;
1343            r_icache_fsm_save = r_icache_fsm;
1344            break;
1345        }
1346
1347        if ( !r_icache_inval_tlb_rsp && !r_icache_cleanup_req )
1348        {
1349            paddr_t victim_index = 0;
1350            r_icache_cleanup_req = icache_tlb.update1(r_icache_pte_update,r_icache_vaddr_req.read(),(r_icache_paddr_save.read() >> (uint32_log2(m_icache_words)+2)),&victim_index);
1351            r_icache_cleanup_line = victim_index;
1352            r_icache_cleanup_type = TLB_CLEANUP; 
1353            r_icache_fsm = ICACHE_IDLE;
1354        }
1355       
1356        // TLB update and invalidate same PTE
1357        if ( r_icache_inval_tlb_rsp )                                 
1358        {
1359            r_icache_inval_tlb_rsp = false;
1360            r_icache_fsm = ICACHE_IDLE;
1361        }
1362        break;
1363    }
1364    /////////////////////
1365    case ICACHE_TLB2_READ:
1366    {
1367        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
1368
1369        // external cache invalidate request
1370        if ( r_tgt_icache_req )
1371        {
1372            r_icache_fsm = ICACHE_CC_INVAL;
1373            r_icache_fsm_save = r_icache_fsm;
1374            break;
1375        }
1376
1377        if ( r_vci_rsp_ins_ok ) // vci response
1378        {
1379                if (r_icache_vaddr_req.read() != ireq.addr || !ireq.valid) 
1380                {
1381                    /* request modified, drop response and restart */
1382                    r_icache_ptba_ok = false;
1383                if ( r_icache_inval_tlb_rsp )   r_icache_inval_tlb_rsp = false;
1384                if ( r_vci_rsp_ins_error )      r_vci_rsp_ins_error = false;
1385                    r_icache_fsm = ICACHE_IDLE;
1386                    break;
1387                }
1388
1389            if ( !r_icache_inval_tlb_rsp ) // vci response
1390            {
1391                if ( !r_vci_rsp_ins_error ) // VCI response ok       
1392                {
1393                        if ( !(r_icache_miss_buf[0] >> PTE_V_SHIFT) ) // unmapped
1394                        {
1395                        r_icache_error_type = MMU_READ_PT2_UNMAPPED; 
1396                        r_icache_bad_vaddr  = r_icache_vaddr_req.read();
1397                        r_icache_fsm = ICACHE_ERROR;
1398                        }
1399                        else
1400                        {
1401                            if ( (m_srcid_rw >> 4) == ((r_icache_miss_buf[0] & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
1402                            {
1403                                if ( (r_icache_miss_buf[0] & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
1404                                {
1405                                r_vci_rsp_ins_ok    = false;
1406                                r_icache_fsm        = ICACHE_TLB2_UPDT;
1407                                r_icache_pte_update = r_icache_miss_buf[0];
1408                                }
1409                                else
1410                                {
1411                                r_icache_pte_update = r_icache_miss_buf[0] | PTE_L_MASK;
1412                                r_icache_tlb_ll_req = true;
1413                                r_vci_rsp_ins_ok    = false;
1414                                r_icache_fsm        = ICACHE_TLB2_LL_WAIT;
1415                                m_cpt_ins_tlb_write_et++;
1416                                }
1417                        }
1418                            else // remotely
1419                            {
1420                                if ( (r_icache_miss_buf[0] & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
1421                                {
1422                                r_vci_rsp_ins_ok    = false;
1423                                r_icache_fsm        = ICACHE_TLB2_UPDT;
1424                                r_icache_pte_update = r_icache_miss_buf[0];
1425                                }
1426                                else
1427                                {
1428                                r_icache_pte_update = r_icache_miss_buf[0] | PTE_R_MASK;
1429                                r_icache_tlb_ll_req = true;
1430                                r_vci_rsp_ins_ok    = false;
1431                                r_icache_fsm        = ICACHE_TLB2_LL_WAIT;
1432                                m_cpt_ins_tlb_write_et++;
1433                                }
1434                            }
1435                        }
1436                }
1437                else    // VCI response error
1438                {
1439                    r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
1440                    r_icache_bad_vaddr = ireq.addr;
1441                    r_icache_fsm = ICACHE_ERROR;
1442                }
1443            }
1444
1445            if ( r_icache_inval_tlb_rsp ) // TLB miss read response and invalidation
1446            {
1447                if ( r_vci_rsp_ins_error ) 
1448                {
1449                    r_icache_inval_tlb_rsp = false;
1450                    r_icache_error_type = MMU_READ_PT2_UNMAPPED;   
1451                    r_icache_bad_vaddr = ireq.addr;
1452                    r_icache_fsm = ICACHE_ERROR;
1453                } 
1454                else 
1455                {
1456                    if (r_icache_cleanup_req) break;
1457                    r_icache_inval_tlb_rsp = false;
1458                    r_icache_cleanup_req = true;
1459                    r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
1460                    r_icache_cleanup_type = TLB_CLEANUP;
1461                    r_icache_fsm = ICACHE_IDLE; 
1462                } 
1463            }
1464        }
1465        break;
1466    }
1467    ///////////////////////
1468    case ICACHE_TLB2_LL_WAIT:
1469    {
1470        // external cache invalidate request
1471        if ( r_tgt_icache_req )
1472        {
1473            r_icache_fsm = ICACHE_CC_INVAL;
1474            r_icache_fsm_save = r_icache_fsm;
1475            break;
1476        }
1477
1478            if ( r_vci_rsp_ins_ok )
1479            {
1480            if ( r_vci_rsp_ins_error ) // VCI response ko
1481            {
1482                r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;   
1483                r_icache_bad_vaddr = ireq.addr;
1484                r_icache_fsm = ICACHE_ERROR;
1485
1486                if (r_icache_inval_tlb_rsp) r_icache_inval_tlb_rsp = false;
1487            }
1488                else
1489                {
1490                    if ( !(r_icache_miss_buf[0] >> PTE_V_SHIFT) )       // unmapped
1491                    {
1492                    r_icache_error_type = MMU_READ_PT2_UNMAPPED;       
1493                    r_icache_bad_vaddr  = ireq.addr;
1494                    r_icache_fsm        = ICACHE_ERROR;
1495
1496                    if (r_icache_inval_tlb_rsp) r_icache_inval_tlb_rsp = false;
1497                    }
1498                else if ( r_icache_inval_tlb_rsp )
1499                {
1500                        r_icache_inval_tlb_rsp = false;
1501                        r_icache_fsm = ICACHE_IDLE;
1502                }
1503                        else
1504                        {
1505                            r_icache_tlb_sc_req = true;
1506                    r_vci_rsp_ins_ok    = false;
1507                    r_icache_pte_update = r_icache_miss_buf[0] | r_icache_pte_update.read();
1508                    r_icache_fsm        = ICACHE_TLB2_SC_WAIT; 
1509                        }
1510                }
1511            }
1512            break;
1513    }
1514    ///////////////////////
1515    case ICACHE_TLB2_SC_WAIT:
1516    {
1517        // external cache invalidate request
1518        if ( r_tgt_icache_req )
1519        {
1520            r_icache_fsm = ICACHE_CC_INVAL;
1521            r_icache_fsm_save = r_icache_fsm;
1522            break;
1523        }
1524
1525        if ( r_vci_rsp_ins_ok ) // VCI response
1526        {
1527            if ( r_vci_rsp_ins_error ) // VCI response ko
1528                {
1529                r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;   
1530                r_icache_bad_vaddr  = ireq.addr; 
1531                r_icache_fsm        = ICACHE_ERROR;
1532
1533                if (r_icache_inval_tlb_rsp) r_icache_inval_tlb_rsp = false;
1534                }
1535            else
1536            {
1537                if ( r_icache_inval_tlb_rsp )
1538                {
1539                        r_icache_inval_tlb_rsp = false;
1540                    if (r_icache_tlb_sc_fail) r_icache_tlb_sc_fail = false;
1541                        r_icache_fsm = ICACHE_IDLE;
1542                }
1543                    else if ( r_icache_tlb_sc_fail )
1544                    {
1545                    r_icache_tlb_ll_req = true;
1546                    r_icache_tlb_sc_fail = false;
1547                    r_vci_rsp_ins_ok = false;
1548                        r_icache_fsm = ICACHE_TLB2_LL_WAIT; 
1549                    }
1550                    else 
1551                    {
1552                    r_vci_rsp_ins_ok = false;
1553                        r_icache_fsm = ICACHE_TLB2_UPDT; 
1554                    }
1555            }
1556        }
1557            break;
1558    }
1559    /////////////////////
1560    case ICACHE_TLB2_UPDT: 
1561    {
1562        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
1563
1564        // external cache invalidate request
1565        if ( r_tgt_icache_req )
1566        {
1567            r_icache_fsm = ICACHE_CC_INVAL;
1568            r_icache_fsm_save = r_icache_fsm;
1569            break;
1570        }
1571
1572        if ( !r_icache_inval_tlb_rsp && !r_icache_cleanup_req )
1573        {
1574            paddr_t victim_index = 0;
1575            r_icache_cleanup_req = icache_tlb.update1(r_icache_pte_update,r_icache_miss_buf[1],r_icache_vaddr_req.read(),(r_icache_paddr_save.read() >> (uint32_log2(m_icache_words)+2)),&victim_index);
1576            r_icache_cleanup_line = victim_index;
1577            r_icache_cleanup_type = TLB_CLEANUP; 
1578            r_icache_fsm = ICACHE_IDLE;
1579        }
1580
1581        // TLB update and invalidate same PTE
1582        if ( r_icache_inval_tlb_rsp )                           
1583        {
1584            r_icache_inval_tlb_rsp = false;
1585            r_icache_fsm = ICACHE_IDLE;
1586        }
1587        break;
1588    }
1589    /////////////////////////////
1590    case ICACHE_TLB_FLUSH:
1591    {
1592        size_t way = r_icache_way;
1593        size_t set = r_icache_set;
1594        bool clean = false;
1595
1596        m_cost_ins_tlb_flush_frz++;
1597        // 4K page size TLB flush leads to cleanup req to data cache
1598        if ( !r_icache_cleanup_req )    // last cleanup finish
1599        {
1600            paddr_t victim_index = 0;
1601            for ( ; way < m_itlb_ways; way++)
1602            {
1603                for ( ; set < m_itlb_sets; set++)
1604                {
1605                    if(icache_tlb.checkcleanup1(way, set, &victim_index))
1606                    {
1607                        clean = true;
1608                        r_icache_cleanup_req = true;
1609                        r_icache_cleanup_line = victim_index;
1610                        r_icache_cleanup_type = TLB_CLEANUP;
1611                        r_icache_way = way + ((set+1)/m_itlb_sets);
1612                        r_icache_set = (set+1) % m_itlb_sets;
1613                        break;
1614                    }
1615                }
1616                if (clean) break;
1617            }
1618
1619            if (way == m_itlb_ways)
1620            {
1621                r_dcache_xtn_req = false;
1622                r_itlb_translation_valid = false;
1623                r_icache_ptba_ok = false;
1624                r_icache_fsm = ICACHE_IDLE;
1625                break;
1626            }
1627        }
1628        break;
1629    }
1630    ////////////////////////
1631    case ICACHE_CACHE_FLUSH:
1632    {
1633        // external cache invalidate request
1634        if ( r_tgt_icache_req )
1635        {
1636            r_icache_fsm = ICACHE_CC_INVAL;
1637            r_icache_fsm_save = r_icache_fsm;
1638            break;
1639        }
1640
1641        size_t way = r_icache_way;
1642        size_t set = r_icache_set;
1643        bool clean = false;
1644
1645        m_cost_ins_cache_flush_frz++;
1646
1647        // cache flush and send cleanup to external
1648        if ( !r_icache_cleanup_req )
1649        {
1650            paddr_t victim_index = 0;
1651            for ( ; way < m_icache_ways; way++ )
1652            {   
1653                for ( ; set < m_icache_sets; set++ )
1654                {   
1655                    if ( r_icache.flush(way, set, &victim_index) )
1656                    {
1657                        clean = true;
1658                        r_icache_cleanup_req = true;
1659                        r_icache_cleanup_line = victim_index;
1660                        r_icache_cleanup_type = CACHE_CLEANUP;
1661                        r_icache_way = way + ((set+1)/m_icache_sets);
1662                        r_icache_set = (set+1) % m_icache_sets;
1663                        break;
1664                    }
1665                }
1666                if (clean) break;
1667            }
1668            if (way == m_icache_ways)
1669            {
1670                r_dcache_xtn_req = false;
1671                r_icache_fsm = ICACHE_IDLE;
1672                break;
1673            }
1674        }
1675        break;
1676    }
1677    /////////////////////
1678    case ICACHE_TLB_INVAL: 
1679    {
1680        paddr_t victim_index = 0;
1681
1682        if ( !r_icache_cleanup_req )
1683        {
1684            r_icache_cleanup_req = icache_tlb.inval1(r_dcache_wdata_save,&victim_index);
1685            r_icache_cleanup_type = TLB_CLEANUP;
1686            r_icache_cleanup_line = victim_index;
1687            r_dcache_xtn_req = false;
1688            r_itlb_translation_valid = false;
1689            r_icache_ptba_ok = false;
1690            r_icache_fsm = ICACHE_IDLE;
1691        }
1692        break;
1693        }
1694    ////////////////////////
1695    case ICACHE_CACHE_INVAL:
1696    {
1697        // external cache invalidate request
1698        if ( r_tgt_icache_req )
1699        {
1700            r_icache_fsm = ICACHE_CC_INVAL;
1701            r_icache_fsm_save = r_icache_fsm;
1702            break;
1703        }
1704       
1705        paddr_t ipaddr = 0;                     
1706        bool    icache_hit_t = false;
1707
1708        if ( !r_icache_cleanup_req )
1709        {
1710            if ( r_mmu_mode.read() & INS_TLB_MASK ) 
1711            {
1712                icache_hit_t = icache_tlb.translate(r_dcache_wdata_save, &ipaddr); 
1713            } 
1714            else 
1715            {
1716                ipaddr = (paddr_t)r_dcache_wdata_save;
1717                icache_hit_t = true;
1718            }
1719            if ( icache_hit_t )
1720            {
1721                // invalidate and cleanup if necessary
1722                r_icache_cleanup_req = r_icache.inval(ipaddr);
1723                r_icache_cleanup_line = ipaddr >> (uint32_log2(m_icache_words) + 2);
1724                r_icache_cleanup_type = CACHE_CLEANUP;
1725            }
1726            r_dcache_xtn_req = false; 
1727            r_icache_fsm = ICACHE_IDLE;
1728        }
1729        break;
1730    }
1731    ////////////////////////
1732    case ICACHE_CACHE_INVAL_PA:
1733    {
1734        // external cache invalidate request
1735        if ( r_tgt_icache_req )
1736        {
1737            r_icache_fsm = ICACHE_CC_INVAL;
1738            r_icache_fsm_save = r_icache_fsm;
1739            break;
1740        }
1741       
1742        paddr_t ipaddr = (paddr_t)r_mmu_word_hi.read() << 32 | r_mmu_word_lo.read();
1743
1744        if ( !r_icache_cleanup_req )
1745        {   
1746            // invalidate and cleanup if necessary
1747            r_icache_cleanup_req = r_icache.inval(ipaddr);
1748            r_icache_cleanup_line = ipaddr >> (uint32_log2(m_icache_words) + 2);   
1749            r_icache_cleanup_type = CACHE_CLEANUP; 
1750            r_dcache_xtn_req = false; 
1751            r_icache_fsm = ICACHE_IDLE;
1752        }
1753        break;
1754    }
1755    ///////////////////////
1756    case ICACHE_MISS_WAIT:
1757    {
1758        m_cost_ins_miss_frz++;
1759
1760        // external cache invalidate request
1761        if ( r_tgt_icache_req )     
1762        {
1763            r_icache_fsm = ICACHE_CC_INVAL;
1764            r_icache_fsm_save = r_icache_fsm;
1765            break;
1766        }
1767
1768        if ( r_vci_rsp_ins_ok )
1769        {
1770            if ( r_vci_rsp_ins_error ) 
1771            {
1772                r_icache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 
1773                r_icache_bad_vaddr = ireq.addr;
1774                r_icache_fsm = ICACHE_ERROR;
1775       
1776                if ( r_icache_inval_tlb_rsp ) r_icache_inval_tlb_rsp = false;
1777                if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1778                    break;
1779            }
1780       
1781            if ( r_icache_inval_tlb_rsp ) // Miss read response and tlb invalidation
1782            {
1783                        if ( r_icache_cleanup_req ) break;
1784                r_icache_cleanup_req = true;
1785                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
1786                r_icache_cleanup_type = CACHE_CLEANUP; 
1787                r_icache_fsm = ICACHE_IDLE;
1788                r_icache_inval_tlb_rsp = false;
1789                if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1790                m_cost_ins_tlb_miss_frz++;
1791                break;
1792            }
1793       
1794            if ( r_icache_inval_rsp ) // Miss read response and tlb invalidation
1795            {
1796                        if ( r_icache_cleanup_req ) break;
1797                r_icache_cleanup_req = true;
1798                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
1799                r_icache_cleanup_type = CACHE_CLEANUP; 
1800                r_icache_fsm = ICACHE_IDLE;
1801                r_icache_inval_rsp = false;
1802                break;
1803            }
1804            r_icache_fsm = ICACHE_MISS_UPDT; 
1805        }       
1806        break;
1807    }
1808    ////////////////////
1809    case ICACHE_UNC_WAIT:
1810    {
1811        m_cost_ins_miss_frz++;
1812        // external cache invalidate request
1813        if ( r_tgt_icache_req ) 
1814        {
1815            r_icache_fsm = ICACHE_CC_INVAL;
1816            r_icache_fsm_save = r_icache_fsm;
1817            break;
1818        }
1819
1820        if ( r_vci_rsp_ins_ok )
1821        {
1822            if ( r_vci_rsp_ins_error ) 
1823            {
1824                r_icache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS;   
1825                r_icache_bad_vaddr = ireq.addr;
1826                r_icache_fsm = ICACHE_ERROR;
1827       
1828                if ( r_icache_inval_tlb_rsp ) r_icache_inval_tlb_rsp = false;
1829                    break;
1830            }
1831       
1832            if ( r_icache_inval_tlb_rsp ) // Miss read response and tlb invalidation
1833            {
1834                r_icache_inval_tlb_rsp = false;
1835                r_icache_fsm = ICACHE_IDLE;
1836                    break;
1837            }
1838
1839            // Miss read response and no invalidation
1840            r_icache_fsm = ICACHE_IDLE;
1841        }       
1842        break;
1843    }
1844    //////////////////////
1845    case ICACHE_MISS_UPDT:
1846    {
1847        if ( ireq.valid ) m_cost_ins_miss_frz++;
1848
1849        // external cache invalidate request
1850        if ( r_tgt_icache_req )   
1851        {
1852            r_icache_fsm = ICACHE_CC_INVAL;
1853            r_icache_fsm_save = r_icache_fsm;
1854            break;
1855        }
1856
1857        if ( r_icache_inval_tlb_rsp ) // tlb invalidation
1858        {
1859            if ( r_icache_cleanup_req ) break;
1860            r_icache_cleanup_req = true;
1861            r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2);
1862            r_icache_cleanup_type = CACHE_CLEANUP;
1863            r_icache_inval_tlb_rsp = false;
1864            if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1865            r_icache_fsm = ICACHE_IDLE;
1866            break;
1867        }
1868
1869        if ( !r_icache_cleanup_req ) // Miss update and no invalidation
1870        {
1871            if ( r_icache_inval_rsp )   // invalidation
1872            {
1873                r_icache_cleanup_req = true;
1874                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2);
1875                r_icache_cleanup_type = CACHE_CLEANUP;
1876                r_icache_inval_rsp = false;
1877                r_icache_fsm = ICACHE_IDLE;
1878            }
1879            else
1880            {
1881                data_t* buf = r_icache_miss_buf;
1882                paddr_t  victim_index = 0;
1883                m_cpt_icache_dir_write++;
1884                m_cpt_icache_data_write++;
1885
1886                r_icache_cleanup_req = r_icache.update(r_icache_paddr_save.read(), buf, &victim_index);
1887                r_icache_cleanup_line = victim_index;         
1888                r_icache_cleanup_type = CACHE_CLEANUP;           
1889                r_icache_fsm = ICACHE_IDLE;
1890            }
1891        }
1892        break;
1893    }
1894    ///////////////////
1895    case ICACHE_ERROR:
1896    {
1897        r_vci_rsp_ins_error = false;
1898        irsp.valid = true;
1899        irsp.error = true;
1900        irsp.instruction = 0; 
1901        r_icache_fsm = ICACHE_IDLE;
1902        break;
1903    }
1904    /////////////////////
1905    case ICACHE_CC_INVAL: 
1906    {                       
1907        if ( ireq.valid ) m_cost_ins_miss_frz++;
1908        m_cpt_icache_dir_read += m_icache_ways;
1909
1910        // invalidate cache
1911        if( (( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) ) && 
1912            ((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_icache_words<<2)-1))) ) 
1913        {
1914            r_icache_inval_rsp = true;
1915            r_tgt_icache_rsp = false; 
1916        } 
1917        else 
1918        {
1919            r_tgt_icache_rsp = r_icache.inval(r_tgt_addr.read());
1920        }
1921
1922        if ( r_tgt_broadcast )
1923        {
1924                    // ins tlb invalidate verification   
1925            r_icache_tlb_inval_req = true;
1926            r_icache_fsm = ICACHE_TLB_CC_INVAL;
1927        }
1928        else
1929        {
1930            r_tgt_icache_req = false;       
1931            r_icache_fsm = r_icache_fsm_save;
1932        }   
1933        break;
1934    }
1935    /////////////////////////
1936    case ICACHE_TLB_CC_INVAL:
1937    {
1938        if ( ireq.valid ) m_cost_ins_miss_frz++;     
1939
1940            if ( r_icache_tlb_inval_req ) break;
1941
1942        // invalidate cache
1943        if( (( r_icache_fsm_save == ICACHE_TLB1_READ )   || ( r_icache_fsm_save == ICACHE_TLB2_READ )    ||
1944             ( r_icache_fsm_save == ICACHE_TLB1_LL_WAIT )|| ( r_icache_fsm_save == ICACHE_TLB2_LL_WAIT ) ||
1945             ( r_icache_fsm_save == ICACHE_TLB1_SC_WAIT )|| ( r_icache_fsm_save == ICACHE_TLB2_SC_WAIT ) || 
1946             ( r_icache_fsm_save == ICACHE_TLB1_UPDT )   || ( r_icache_fsm_save == ICACHE_TLB2_UPDT ))   && 
1947            ((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) == r_tgt_addr.read()) ) 
1948        {
1949            r_icache_inval_tlb_rsp = true;
1950        } 
1951        else if (((r_icache_fsm_save == ICACHE_BIS)||(r_icache_fsm_save == ICACHE_MISS_WAIT) ||
1952           /*  (r_icache_fsm_save == ICACHE_UNC_WAIT)|| */(r_icache_fsm_save == ICACHE_MISS_UPDT)) && 
1953            (r_icache_tlb_nline == (paddr_t)(r_tgt_addr.read() >> (uint32_log2(m_icache_words)+2))))
1954        {
1955            r_icache_inval_tlb_rsp = true;
1956        }
1957
1958        if( (( r_icache_fsm_save == ICACHE_TLB1_LL_WAIT )|| ( r_icache_fsm_save == ICACHE_TLB2_LL_WAIT ) ||
1959             ( r_icache_fsm_save == ICACHE_TLB1_SC_WAIT )|| ( r_icache_fsm_save == ICACHE_TLB2_SC_WAIT ) || 
1960             ( r_icache_fsm_save == ICACHE_TLB1_UPDT )   || ( r_icache_fsm_save == ICACHE_TLB2_UPDT ))   && 
1961            ((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) == r_tgt_addr.read()) ) 
1962        {
1963            if ( !r_icache_cc_hit_t ) r_ccinval_itlb_cpt = r_ccinval_itlb_cpt + 1;
1964        } 
1965
1966        r_tgt_icache_req = false;
1967            r_itlb_translation_valid = false;
1968        r_icache_ptba_ok = false;       
1969        r_icache_fsm = r_icache_fsm_save;
1970        break;
1971    }
1972    } // end switch r_icache_fsm
1973
1974#ifdef SOCLIB_MODULE_DEBUG
1975    std::cout << name() << " Instruction Response: " << irsp << std::endl;
1976#endif
1977
1978    ////////////////////////////////////////////////////////////////////////////////////
1979    //      INVAL ITLB CHECK FSM
1980    ////////////////////////////////////////////////////////////////////////////////////////
1981    switch(r_inval_itlb_fsm) {
1982    /////////////////////
1983    case INVAL_ITLB_IDLE:
1984    {
1985        if ( r_icache_tlb_inval_req )
1986        {
1987            paddr_t ipaddr;
1988            r_ccinval_itlb_way = 0; 
1989            r_ccinval_itlb_set = 0;
1990            r_ccinval_itlb_cpt = 0;
1991            r_icache_cc_hit_t = icache_tlb.translate(ireq.addr, &ipaddr);
1992            r_inval_itlb_fsm = INVAL_ITLB_CHECK;   
1993        }   
1994        break;
1995    }
1996    ////////////////////////////
1997    case INVAL_ITLB_CHECK:
1998    {
1999        size_t way = r_ccinval_itlb_way; 
2000        size_t set = r_ccinval_itlb_set;
2001        bool end = false; 
2002     
2003        // r_tgt_addr is number of line
2004        bool tlb_hit = icache_tlb.cccheck((r_tgt_addr.read() >> (uint32_log2(m_icache_words)+2)),way, set, &way, &set, &end); 
2005   
2006        if ( tlb_hit )
2007        {
2008            r_ccinval_itlb_way = way; 
2009            r_ccinval_itlb_set = set;
2010            r_itlb_cc_check_end = end;
2011            r_ccinval_itlb_cpt = r_ccinval_itlb_cpt + 1;
2012            r_inval_itlb_fsm = INVAL_ITLB_INVAL;   
2013        }       
2014        else
2015        {
2016            r_inval_itlb_fsm = INVAL_ITLB_CLEAR;   
2017        }
2018        break;
2019    }
2020    /////////////////////////
2021    case INVAL_ITLB_INVAL:
2022    {
2023        //m_cost_ins_tlb_inval_frz++;
2024 
2025        icache_tlb.ccinval(r_ccinval_itlb_way, r_ccinval_itlb_set);
2026
2027        if ( !r_itlb_cc_check_end )
2028        {
2029            r_inval_itlb_fsm = INVAL_ITLB_CHECK; 
2030        }
2031        else
2032        {
2033            r_inval_itlb_fsm = INVAL_ITLB_CLEAR;   
2034        }
2035        break;
2036    }
2037    ////////////////////
2038    case INVAL_ITLB_CLEAR:
2039    {
2040        r_icache_tlb_inval_req = false;
2041        r_itlb_cc_check_end = false;
2042        r_ccinval_itlb_way = 0; 
2043        r_ccinval_itlb_set = 0; 
2044        r_inval_itlb_fsm = INVAL_ITLB_IDLE;   
2045        break;
2046    }
2047    } // end switch r_inval_itlb_fsm
2048
2049    ////////////////////////////////////////////////////////////////////////////////////
2050    //      DCACHE FSM
2051    //
2052    // Both the Cacheability Table, and the MMU cached bit are used to define
2053    // the cacheability.
2054    //
2055    // There is 14 mutually exclusive conditions to exit the IDLE state.
2056    // Seven configurations corresponding to an XTN request from processor:
2057    // - Context switch => CTXT_SWITCH state
2058    // - Flush dcache => DCACHE_FLUSH state
2059    // - Flush icache => ICACHE_FLUSH state
2060    // - Invalidate a dtlb entry => DTLB_INVAL state
2061    // - Invalidate a itlb entry => ITLB_INVAL state
2062    // - Invalidate a dcache line => DCACHE_INVAL state
2063    // - Invalidate a icache line => ICACHE_INVAL state
2064    // Seven configurations corresponding to various read miss or write requests:
2065    // - TLB miss(in case hit_p miss) => TLB1_READ state
2066    // - TLB miss(in case hit_p hit) => TLB2_READ state
2067    // - Hit in TLB but VPN changed => BIS state
2068    // - Cached read miss => MISS_REQ state
2069    // - Uncache read miss => UNC_REQ state
2070    // - Write hit => WRITE_UPDT state
2071    // - Write miss => WRITE_REQ
2072    //
2073    // The r_vci_rsp_data_error flip-flop is set by the VCI_RSP controller and reset
2074    // by DCACHE-FSM when its state is in DCACHE_ERROR.
2075    //---------------------------------------------------------------------
2076    // Data TLB:
2077    // 
2078    // - int        ET          (00: unmapped; 01: unused or PTD)
2079    //                          (10: PTE new;  11: PTE old      )
2080    // - bool       cachable    (cached bit)
2081    // - bool       writable    (writable bit)
2082    // - bool       executable  (** not used alwayse false)
2083    // - bool       user        (access in user mode allowed)
2084    // - bool       global      (PTE not invalidated by a TLB flush)
2085    // - bool       dirty       (page has been modified)
2086    // - uint32_t   vpn         (virtual page number)
2087    // - uint32_t   ppn         (physical page number)
2088    ////////////////////////////////////////////////////////////////////////////////////////
2089
2090    switch (r_dcache_fsm) {
2091
2092    //////////////////////
2093    case DCACHE_WRITE_REQ:
2094    {
2095        if ( r_tgt_dcache_req ) // external request
2096        {
2097            r_dcache_fsm = DCACHE_CC_CHECK;
2098            r_dcache_fsm_save = r_dcache_fsm;
2099            break;
2100        }
2101
2102        if ( !r_wbuf.wok(r_dcache_paddr_save) )
2103        {
2104            m_cost_write_frz++;
2105            drsp.valid = false;
2106            drsp.rdata = 0;
2107            break;
2108        }     
2109        // The next state and the processor request parameters are computed
2110        // as in the DCACHE_IDLE state (see below ...)
2111    }
2112    /////////////////
2113    case DCACHE_IDLE:
2114    {
2115        // external cache invalidate request
2116        if ( r_tgt_dcache_req )   
2117        {
2118            r_dcache_fsm = DCACHE_CC_CHECK;
2119            r_dcache_fsm_save = DCACHE_IDLE;
2120            if ( dreq.valid ) m_cost_data_miss_frz++;
2121            break;
2122        }       
2123
2124        if (dreq.valid) 
2125        {
2126            pte_info_t  dcache_pte_info;
2127            int         xtn_opcod      = (int)dreq.addr/4;
2128            paddr_t     tlb_dpaddr     = 0;        // physical address obtained from TLB
2129            paddr_t     spc_dpaddr     = 0;        // physical adress obtained from PPN_save (speculative)
2130            bool        dcache_hit_t   = false;    // hit on 4Kilo TLB
2131            bool        dcache_hit_x   = false;    // VPN unmodified (can use spc_dpaddr)
2132            bool        dcache_hit_p   = false;    // PTP unmodified (can skip first level page table walk)
2133            bool        dcache_hit_c   = false;    // Cache hit
2134            size_t      dcache_tlb_way = 0;        // selected way (in case of cache hit)
2135            size_t      dcache_tlb_set = 0;        // selected set (Y field in address)
2136            data_t      dcache_rdata   = 0;        // read data
2137            bool        dcache_cached  = false;    // cacheable access (read or write)
2138            paddr_t     dcache_tlb_nline = 0;       // TLB NLINE
2139
2140            m_cpt_dcache_data_read += m_dcache_ways;
2141            m_cpt_dcache_dir_read += m_dcache_ways;
2142
2143            // Decoding READ XTN requests from processor
2144            // They are executed in this DCACHE_IDLE state
2145
2146            if (dreq.type == iss_t::XTN_READ) 
2147            {
2148                switch(xtn_opcod) {
2149                case iss_t::XTN_INS_ERROR_TYPE:
2150                    drsp.rdata = (uint32_t)r_icache_error_type;
2151                    r_icache_error_type = MMU_NONE;
2152                    drsp.valid = true;
2153                    drsp.error = false;
2154                    break;
2155                case iss_t::XTN_DATA_ERROR_TYPE:
2156                    drsp.rdata = (uint32_t)r_dcache_error_type;
2157                    r_dcache_error_type = MMU_NONE;
2158                    drsp.valid = true;
2159                    drsp.error = false;
2160                    break;
2161                case iss_t::XTN_INS_BAD_VADDR:
2162                    drsp.rdata = (uint32_t)r_icache_bad_vaddr;       
2163                    drsp.valid = true;
2164                    drsp.error = false;
2165                    break;
2166                case iss_t::XTN_DATA_BAD_VADDR:
2167                    drsp.rdata = (uint32_t)r_dcache_bad_vaddr;       
2168                    drsp.valid = true;
2169                    drsp.error = false;
2170                    break;
2171                case iss_t::XTN_PTPR:
2172                    drsp.rdata = (uint32_t)r_mmu_ptpr;
2173                    drsp.valid = true;
2174                    drsp.error = false;
2175                    break;
2176                case iss_t::XTN_TLB_MODE:
2177                    drsp.rdata = (uint32_t)r_mmu_mode;
2178                    drsp.valid = true;
2179                    drsp.error = false;
2180                    break;
2181                case iss_t::XTN_MMU_PARAMS:
2182                    drsp.rdata = (uint32_t)r_mmu_params;
2183                    drsp.valid = true;
2184                    drsp.error = false;
2185                    break;
2186                case iss_t::XTN_MMU_RELEASE:
2187                    drsp.rdata = (uint32_t)r_mmu_release;
2188                    drsp.valid = true;
2189                    drsp.error = false;
2190                    break;
2191                case iss_t::XTN_MMU_WORD_LO:
2192                    drsp.rdata = (uint32_t)r_mmu_word_lo;
2193                    drsp.valid = true;
2194                    drsp.error = false;
2195                    break;
2196                case iss_t::XTN_MMU_WORD_HI:
2197                    drsp.rdata = (uint32_t)r_mmu_word_hi;
2198                    drsp.valid = true;
2199                    drsp.error = false;
2200                    break;
2201                default:
2202                    r_dcache_error_type = MMU_READ_UNDEFINED_XTN; 
2203                    r_dcache_bad_vaddr  = dreq.addr;
2204                    drsp.valid = true;
2205                    drsp.error = true;
2206                    break;
2207                }
2208                r_dcache_fsm = DCACHE_IDLE;
2209                break;
2210            }
2211
2212            // Decoding WRITE XTN requests from processor
2213            // If there is no privilege violation, they are not executed in this DCACHE_IDLE state,
2214            // but in the next state, because they generally require access to the caches or the TLBs
2215
2216            if (dreq.type == iss_t::XTN_WRITE) 
2217            {
2218                drsp.valid = false;
2219                drsp.error = false;
2220                drsp.rdata = 0;
2221                r_dcache_wdata_save = dreq.wdata;   
2222                switch(xtn_opcod) {     
2223
2224                case iss_t::XTN_PTPR:       // context switch : checking the kernel mode
2225                                            // both instruction & data TLBs must be flushed
2226                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
2227                    {
2228                        r_mmu_ptpr = dreq.wdata;
2229                        r_icache_error_type = MMU_NONE;
2230                        r_dcache_error_type = MMU_NONE;
2231                        r_dcache_type_save = dreq.addr/4; 
2232                        r_dcache_xtn_req = true;
2233                        r_dcache_fsm = DCACHE_CTXT_SWITCH;
2234                    } 
2235                    else 
2236                    { 
2237                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
2238                        r_dcache_bad_vaddr  = dreq.addr;
2239                        drsp.valid = true;
2240                        drsp.error = true;
2241                        r_dcache_fsm = DCACHE_IDLE;
2242                    }
2243                    break;
2244
2245                case iss_t::XTN_TLB_MODE:     // modifying TLBs mode : checking the kernel mode
2246                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
2247                    {
2248                        r_mmu_mode = (int)dreq.wdata;
2249                        drsp.valid = true;
2250                    } 
2251                    else 
2252                    {
2253                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
2254                        r_dcache_bad_vaddr  = dreq.addr;
2255                        drsp.valid = true;
2256                        drsp.error = true;
2257                    }
2258                    r_dcache_fsm = DCACHE_IDLE;
2259                    break;
2260
2261                case iss_t::XTN_DTLB_INVAL:     //  checking the kernel mode
2262                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
2263                    {
2264                        r_dcache_fsm = DCACHE_DTLB_INVAL; 
2265                    } 
2266                    else 
2267                    {
2268                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
2269                        r_dcache_bad_vaddr  = dreq.addr;
2270                        drsp.valid = true;
2271                        drsp.error = true;
2272                        r_dcache_fsm = DCACHE_IDLE;
2273                    }
2274                    break;
2275
2276                case iss_t::XTN_ITLB_INVAL:     //  checking the kernel mode
2277                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
2278                    {
2279                        r_dcache_xtn_req = true;
2280                        r_dcache_type_save = dreq.addr/4;
2281                        r_dcache_fsm = DCACHE_ITLB_INVAL; 
2282                    } 
2283                    else 
2284                    {
2285                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
2286                        r_dcache_bad_vaddr  = dreq.addr;
2287                        drsp.valid = true;
2288                        drsp.error = true;
2289                        r_dcache_fsm = DCACHE_IDLE;
2290                    }
2291                    break;
2292
2293                case iss_t::XTN_DCACHE_INVAL:   // cache inval can be executed in user mode.
2294                    r_dcache_fsm = DCACHE_DCACHE_INVAL;
2295                    break;
2296
2297                case iss_t::XTN_MMU_DCACHE_PA_INV:   // cache inval can be executed in user mode.
2298                    r_dcache_fsm = DCACHE_DCACHE_INVAL_PA;
2299                    break;
2300
2301                case iss_t::XTN_DCACHE_FLUSH:   // cache flush can be executed in user mode.
2302                    r_dcache_way = 0;
2303                    r_dcache_set = 0;
2304                    r_dcache_fsm = DCACHE_DCACHE_FLUSH; 
2305                    break;
2306
2307                case iss_t::XTN_ICACHE_INVAL:   // cache inval can be executed in user mode.
2308                    r_dcache_type_save = dreq.addr/4; 
2309                    r_dcache_xtn_req = true;
2310                    r_dcache_fsm = DCACHE_ICACHE_INVAL; 
2311                    break;
2312
2313                case iss_t::XTN_MMU_ICACHE_PA_INV:   // cache inval can be executed in user mode.
2314                    r_dcache_type_save = dreq.addr/4; 
2315                    r_dcache_xtn_req = true;
2316                    r_dcache_fsm = DCACHE_ICACHE_INVAL_PA; 
2317                    break;
2318
2319                case iss_t::XTN_ICACHE_FLUSH:   // cache flush can be executed in user mode.
2320                    r_dcache_type_save = dreq.addr/4; 
2321                    r_dcache_xtn_req = true; 
2322                    r_dcache_fsm = DCACHE_ICACHE_FLUSH;
2323                    break;
2324
2325                case iss_t::XTN_SYNC:           // cache synchronization can be executed in user mode.
2326                    if (r_wbuf.rok())
2327                    {
2328                        r_dcache_fsm = DCACHE_DCACHE_SYNC; 
2329                    }
2330                    else
2331                    {
2332                        drsp.valid = true;
2333                        r_dcache_fsm = DCACHE_IDLE;
2334                    }
2335                            break;
2336
2337                case iss_t::XTN_MMU_WORD_LO: // modifying MMU misc registers
2338                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
2339                    {
2340                        r_mmu_word_lo = (int)dreq.wdata;
2341                        drsp.valid = true;
2342                    } 
2343                    else 
2344                    {
2345                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
2346                        r_dcache_bad_vaddr  = dreq.addr;
2347                        drsp.valid = true;
2348                        drsp.error = true;
2349                    }
2350                    r_dcache_fsm = DCACHE_IDLE;
2351                    break;
2352
2353                case iss_t::XTN_MMU_WORD_HI: // modifying MMU misc registers
2354                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
2355                    {
2356                        r_mmu_word_hi = (int)dreq.wdata;
2357                        drsp.valid = true;
2358                    } 
2359                    else 
2360                    {
2361                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
2362                        r_dcache_bad_vaddr  = dreq.addr;
2363                        drsp.valid = true;
2364                        drsp.error = true;
2365                    }
2366                    r_dcache_fsm = DCACHE_IDLE;
2367                    break;
2368
2369                default:
2370                    r_dcache_error_type = MMU_WRITE_UNDEFINED_XTN; 
2371                    r_dcache_bad_vaddr  = dreq.addr;
2372                    drsp.valid = true;
2373                    drsp.error = true;
2374                    r_dcache_fsm = DCACHE_IDLE;
2375                    break;
2376                } // end switch xtn_opcod
2377
2378                break;
2379            } // end if XTN_WRITE
2380
2381            // Evaluating dcache_hit_t, dcache_hit_x, dcache_hit_p, dcache_hit_c,
2382            // dcache_pte_info, dcache_tlb_way, dcache_tlb_set & dpaddr & cacheability
2383            // - If MMU activated : cacheability is defined by the cachable bit in the TLB
2384            // - If MMU not activated : cacheability is defined by the segment table.
2385
2386            if ( !(r_mmu_mode.read() & DATA_TLB_MASK) ) // MMU not activated
2387            {
2388                dcache_hit_t  = true;       
2389                dcache_hit_x  = true;   
2390                dcache_hit_p  = true; 
2391                tlb_dpaddr    = dreq.addr; 
2392                spc_dpaddr    = dreq.addr;   
2393                dcache_cached = m_cacheability_table[dreq.addr] && 
2394                                ((dreq.type != iss_t::DATA_LL)  && (dreq.type != iss_t::DATA_SC) &&
2395                                 (dreq.type != iss_t::XTN_READ) && (dreq.type != iss_t::XTN_WRITE));     
2396            } 
2397            else                                                            // MMU activated
2398            {
2399                m_cpt_data_tlb_read++;
2400                dcache_hit_t  = dcache_tlb.cctranslate(dreq.addr, &tlb_dpaddr, &dcache_pte_info, &dcache_tlb_nline, 
2401                                                       &dcache_tlb_way, &dcache_tlb_set);
2402                dcache_hit_x  = (((vaddr_t)r_dcache_vpn_save << PAGE_K_NBITS) == (dreq.addr & ~PAGE_K_MASK)) && r_dtlb_translation_valid; 
2403                dcache_hit_p  = (((dreq.addr >> PAGE_M_NBITS) == r_dcache_id1_save) && r_dcache_ptba_ok );
2404                spc_dpaddr    = ((paddr_t)r_dcache_ppn_save << PAGE_K_NBITS) | (paddr_t)((dreq.addr & PAGE_K_MASK));
2405                dcache_cached = dcache_pte_info.c &&
2406                                 ((dreq.type != iss_t::DATA_LL)  && (dreq.type != iss_t::DATA_SC) &&
2407                                  (dreq.type != iss_t::XTN_READ) && (dreq.type != iss_t::XTN_WRITE));     
2408            }
2409
2410            if ( !(r_mmu_mode.read() & DATA_CACHE_MASK) )   // cache not actived
2411            {
2412                dcache_cached = false;
2413            }
2414
2415            // dcache_hit_c & dcache_rdata
2416            if ( dcache_cached )    // using speculative physical address for cached access
2417            {
2418                dcache_hit_c = r_dcache.read(spc_dpaddr, &dcache_rdata);
2419            } 
2420            else                    // using actual physical address for uncached access
2421            {
2422                dcache_hit_c = ((tlb_dpaddr == (paddr_t)r_dcache_paddr_save) && r_vci_rsp_data_ok ); 
2423                dcache_rdata = r_dcache_miss_buf[0];
2424            }
2425
2426            if ( r_mmu_mode.read() & DATA_TLB_MASK ) 
2427            {
2428                // Checking access rights
2429                if ( dcache_hit_t ) 
2430                {
2431                    if (!dcache_pte_info.u && (dreq.mode == iss_t::MODE_USER)) 
2432                    {
2433                        if ((dreq.type == iss_t::DATA_READ)||(dreq.type == iss_t::DATA_LL))
2434                        {
2435                            r_dcache_error_type = MMU_READ_PRIVILEGE_VIOLATION;
2436                        }
2437                        else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
2438                        {
2439                            r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2440                        } 
2441                        r_dcache_bad_vaddr = dreq.addr;
2442                        drsp.valid = true;
2443                        drsp.error = true;
2444                        drsp.rdata = 0;
2445                        r_dcache_fsm = DCACHE_IDLE;
2446                        break;
2447                    }
2448                    if (!dcache_pte_info.w && ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))) 
2449                    {
2450                        r_dcache_error_type = MMU_WRITE_ACCES_VIOLATION; 
2451                        r_dcache_bad_vaddr = dreq.addr;
2452                        drsp.valid = true;
2453                        drsp.error = true;
2454                        drsp.rdata = 0;
2455                        r_dcache_fsm = DCACHE_IDLE;
2456                        break;
2457                    }
2458                }
2459
2460                // update LRU, save ppn, vpn and page type
2461                if ( dcache_hit_t ) 
2462                {
2463                    dcache_tlb.setlru(dcache_tlb_way,dcache_tlb_set); 
2464                    r_dcache_ppn_save = tlb_dpaddr >> PAGE_K_NBITS;
2465                    r_dcache_vpn_save = dreq.addr >> PAGE_K_NBITS;
2466                    r_dcache_tlb_nline = dcache_tlb_nline;
2467                    r_dtlb_translation_valid = true;
2468                }
2469                else
2470                {
2471                    r_dtlb_translation_valid = false;
2472                }
2473
2474            } // end if MMU activated
2475
2476            // compute next state
2477            if ( !dcache_hit_p && !dcache_hit_t )  // TLB miss
2478            {
2479                // walk page table level 1
2480                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2481                r_dcache_tlb_read_req = true;
2482                r_dcache_tlb_first_req = true;
2483                r_vci_rsp_data_ok = false;
2484                r_dcache_fsm = DCACHE_TLB1_READ;
2485                m_cpt_data_tlb_miss++;
2486                m_cost_data_tlb_miss_frz++;
2487            }
2488            else if ( dcache_hit_p && !dcache_hit_t )  // TLB Miss with possibility of bypass first level page
2489            {
2490                // walk page table level 2
2491                r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save | 
2492                                     (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3); 
2493                r_dcache_tlb_read_req = true;
2494                r_dcache_tlb_first_req = false;
2495                r_vci_rsp_data_ok = false;
2496                r_dcache_fsm = DCACHE_TLB2_READ;
2497                m_cpt_data_tlb_miss++;
2498                m_cost_data_tlb_miss_frz++;
2499            }
2500            else if ( dcache_hit_t && !dcache_hit_x && dcache_cached )// cached access with an ucorrect speculative physical address
2501            {
2502                r_dcache_hit_p_save = dcache_hit_p;
2503                r_dcache_fsm = DCACHE_BIS;
2504                m_cost_data_miss_frz++;
2505            }
2506            else  // cached or uncached access with a correct speculative physical address
2507            {
2508                switch( dreq.type ) {
2509                    case iss_t::DATA_READ:
2510                    case iss_t::DATA_LL:
2511                    case iss_t::DATA_SC:
2512                        m_cpt_read++;
2513                        if ( dcache_hit_c ) 
2514                        {
2515                            r_vci_rsp_data_ok = false;
2516                            r_dcache_fsm = DCACHE_IDLE;
2517                            drsp.valid = true;
2518                            drsp.rdata = dcache_rdata;
2519                        } 
2520                        else 
2521                        {
2522                            if ( dcache_cached ) 
2523                            {
2524                                r_dcache_miss_req = true;
2525                                r_vci_rsp_data_ok = false;
2526                                r_dcache_fsm = DCACHE_MISS_WAIT;
2527                                m_cpt_data_miss++;
2528                                m_cost_data_miss_frz++;
2529                            } 
2530                            else 
2531                            {
2532                                r_dcache_unc_req = true;
2533                                r_vci_rsp_data_ok = false;
2534                                r_dcache_fsm = DCACHE_UNC_WAIT;
2535                                m_cpt_unc_read++;
2536                                m_cost_unc_read_frz++;
2537                            }
2538                        }
2539                        break;
2540                    case iss_t::DATA_WRITE:
2541                        m_cpt_write++;
2542                        if ( dcache_cached ) m_cpt_write_cached++;
2543
2544                        if ( dcache_hit_c && dcache_cached )    // cache update required
2545                        {
2546                            r_dcache_fsm = DCACHE_WRITE_UPDT;
2547
2548                        } 
2549                        else if ( !dcache_pte_info.d && (r_mmu_mode.read() & DATA_TLB_MASK) )   // dirty bit update required
2550                        {
2551                            if (dcache_tlb.getpagesize(dcache_tlb_way, dcache_tlb_set)) 
2552                            {
2553                                r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
2554                                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2555                                r_dcache_tlb_ll_dirty_req = true;
2556                                r_vci_rsp_data_ok = false;
2557                                r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2558                                m_cpt_data_tlb_write_dirty++;
2559                            }
2560                            else
2561                            {   
2562                                if (dcache_hit_p) 
2563                                {
2564                                    r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
2565                                    r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save | (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
2566                                    r_dcache_tlb_ll_dirty_req = true;
2567                                    r_vci_rsp_data_ok = false;
2568                                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2569                                    m_cpt_data_tlb_write_dirty++;
2570                                }
2571                                else    // get PTBA to calculate the physical address of PTE
2572                                {
2573                                    r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
2574                                    r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2575                                    r_dcache_tlb_read_req = true;
2576                                    r_dcache_tlb_first_req = true;
2577                                    r_dcache_tlb_ptba_read = true;
2578                                    r_vci_rsp_data_ok = false;
2579                                    r_dcache_fsm = DCACHE_TLB1_READ;
2580                                }
2581                            }
2582                            m_cost_data_tlb_miss_frz++;
2583                        }
2584                        else                                    // no cache update, not dirty bit update
2585                        {
2586                            r_dcache_fsm = DCACHE_WRITE_REQ;
2587                            drsp.valid = true;
2588                            drsp.rdata = 0;
2589                        }
2590                        break;
2591                    default:
2592                        break;
2593                } // end switch dreq.type
2594            } // end if next states
2595
2596            // save values for the next states
2597            r_dcache_paddr_save   = tlb_dpaddr;
2598            r_dcache_type_save    = dreq.type;
2599            r_dcache_wdata_save   = dreq.wdata;
2600            r_dcache_be_save      = dreq.be;
2601            r_dcache_rdata_save   = dcache_rdata;
2602            r_dcache_cached_save  = dcache_cached;
2603            r_dcache_dirty_save   = dcache_pte_info.d;
2604            r_dcache_tlb_set_save = dcache_tlb_set;
2605            r_dcache_tlb_way_save = dcache_tlb_way;
2606
2607        } // end if dreq.valid
2608        else 
2609        {   
2610            r_dcache_fsm = DCACHE_IDLE;
2611        }
2612        break;
2613    }
2614    /////////////////
2615    case DCACHE_BIS:
2616    {
2617        // external cache invalidate request
2618        if ( r_tgt_dcache_req )   
2619        {
2620            r_dcache_fsm = DCACHE_CC_CHECK;
2621            r_dcache_fsm_save = r_dcache_fsm;
2622            if ( dreq.valid ) m_cost_data_miss_frz++;
2623            break;
2624        }
2625
2626        if ( r_dcache_inval_tlb_rsp )
2627        {
2628            r_dcache_inval_tlb_rsp = false;
2629            r_dcache_fsm = DCACHE_IDLE;
2630            if ( dreq.valid ) m_cost_data_miss_frz++;
2631            break;
2632        }
2633
2634        data_t      dcache_rdata = 0;
2635        bool        dcache_hit_c = false;
2636        bool        dcache_hit_t = false;
2637        paddr_t     tlb_dpaddr   = 0; 
2638
2639        // processor address translation
2640        dcache_hit_t = dcache_tlb.translate(dreq.addr, &tlb_dpaddr);
2641
2642        if ( (tlb_dpaddr == r_dcache_paddr_save.read()) && dreq.valid && dcache_hit_t )     // unmodified & valid
2643        {
2644            // acces always cached in this state
2645            dcache_hit_c = r_dcache.read(r_dcache_paddr_save, &dcache_rdata);
2646           
2647            if ( dreq.type == iss_t::DATA_READ )  // cached read
2648            {
2649                m_cpt_read++;
2650                if ( !dcache_hit_c ) 
2651                {
2652                    r_dcache_miss_req = true;
2653                    r_vci_rsp_data_ok = false;
2654                    r_dcache_fsm = DCACHE_MISS_WAIT;
2655                    m_cpt_data_miss++;
2656                    m_cost_data_miss_frz++;
2657                }
2658                else
2659                {
2660                    r_dcache_fsm = DCACHE_IDLE;
2661                }
2662                drsp.valid = dcache_hit_c;
2663                drsp.error = false;
2664                drsp.rdata = dcache_rdata;
2665            }
2666            else    // cached write
2667            {
2668                m_cpt_write++;
2669                m_cpt_write_cached++;
2670                if ( dcache_hit_c )    // cache update required
2671                {
2672                        r_dcache_rdata_save = dcache_rdata;
2673                    r_dcache_fsm = DCACHE_WRITE_UPDT;
2674           
2675                } 
2676                else if ( !r_dcache_dirty_save && (r_mmu_mode.read() & DATA_TLB_MASK) )   // dirty bit update required
2677                {
2678                    if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save)) 
2679                    {
2680                        r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
2681                        r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2682                        r_dcache_tlb_ll_dirty_req = true;
2683                        r_vci_rsp_data_ok = false;
2684                        r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2685                        m_cpt_data_tlb_write_dirty++;
2686                    }
2687                    else
2688                    {   
2689                        if (r_dcache_hit_p_save) 
2690                        {
2691                            r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
2692                            r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save|(paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
2693                            r_dcache_tlb_ll_dirty_req = true;
2694                            r_vci_rsp_data_ok = false;
2695                            r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2696                            m_cpt_data_tlb_write_dirty++;
2697                        }
2698                        else
2699                        {
2700                            r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
2701                            r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2702                            r_dcache_tlb_read_req = true;
2703                            r_dcache_tlb_first_req = true;
2704                            r_dcache_tlb_ptba_read = true;
2705                            r_vci_rsp_data_ok = false;
2706                            r_dcache_fsm = DCACHE_TLB1_READ;
2707                        }
2708                    }
2709                    m_cost_data_tlb_miss_frz++;
2710                }
2711                else                                    // no cache update, not dirty bit update
2712                {
2713                    r_dcache_fsm = DCACHE_WRITE_REQ;
2714                    drsp.valid = true;
2715                    drsp.rdata = 0;
2716                }
2717            }
2718        }
2719        else
2720        {
2721            drsp.valid = false;
2722            drsp.error = false;
2723            drsp.rdata = 0;
2724            r_dcache_fsm = DCACHE_IDLE;
2725        }
2726        break;
2727    }
2728    //////////////////////////
2729    case DCACHE_LL_DIRTY_WAIT:
2730    {
2731        // external cache invalidate request
2732        if ( r_tgt_dcache_req )   
2733        {
2734            r_dcache_fsm = DCACHE_CC_CHECK;
2735            r_dcache_fsm_save = r_dcache_fsm;
2736            //m_cost_data_waste_wait_frz++;
2737            break;
2738        }
2739
2740        if ( r_vci_rsp_data_ok )
2741        {
2742            if ( r_vci_rsp_data_error ) // VCI response ko
2743            {
2744                if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save)) 
2745                {
2746                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;     
2747                }
2748                else
2749                {
2750                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;     
2751                }
2752                r_dcache_bad_vaddr = dreq.addr;
2753                r_dcache_fsm = DCACHE_ERROR;
2754 
2755                        if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
2756                        if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
2757            }
2758            else
2759            {
2760                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
2761                {
2762                        if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
2763                        { 
2764                            r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;       
2765                        }
2766                        else
2767                        {
2768                            r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;       
2769                        }
2770                    r_dcache_bad_vaddr = dreq.addr;
2771                    r_dcache_fsm = DCACHE_ERROR;
2772
2773                            if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
2774                            if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
2775                }
2776                else if ( r_dcache_inval_tlb_rsp )
2777                {
2778                    r_dcache_inval_tlb_rsp = false;
2779                    r_dcache_fsm = DCACHE_IDLE;
2780                    m_cost_data_tlb_miss_frz++;
2781                }
2782                    else if ( r_dcache_inval_rsp )
2783                    {
2784                        r_dcache_inval_rsp = false;
2785                        r_dcache_fsm = DCACHE_IDLE;
2786                    }
2787                    else
2788                    {
2789                        r_dcache_tlb_sc_dirty_req = true;
2790                    r_vci_rsp_data_ok = false;
2791                    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
2792                    r_dcache_fsm = DCACHE_SC_DIRTY_WAIT; 
2793                    }
2794            }
2795        }
2796        break;
2797    }
2798    //////////////////////////
2799    case DCACHE_SC_DIRTY_WAIT:
2800    {
2801        // external cache invalidate request
2802        if ( r_tgt_dcache_req )   
2803        {
2804            r_dcache_fsm = DCACHE_CC_CHECK;
2805            r_dcache_fsm_save = r_dcache_fsm;
2806            //m_cost_data_waste_wait_frz++;
2807            break;
2808        }
2809
2810        if ( r_vci_rsp_data_ok ) // VCI response
2811        {
2812            if ( r_vci_rsp_data_error ) // VCI response ko
2813                {
2814                    if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
2815                    {
2816                        r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;   
2817                    }
2818                    else
2819                    {
2820                        r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;   
2821                    }
2822                    r_dcache_bad_vaddr = dreq.addr;
2823                    r_dcache_fsm = DCACHE_ERROR; 
2824
2825                        if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
2826                        if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
2827            }
2828            else
2829            {
2830                // Using tlb entry is invalidated
2831                if ( r_dcache_inval_tlb_rsp )
2832                {
2833                    r_dcache_inval_tlb_rsp = false;
2834                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
2835                    r_dcache_fsm = DCACHE_IDLE;
2836                    m_cost_data_tlb_miss_frz++;
2837                }
2838                    else if ( r_dcache_inval_rsp )
2839                    {
2840                        r_dcache_inval_rsp = false;
2841                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
2842                        r_dcache_fsm = DCACHE_IDLE;
2843                    }
2844                    else if ( r_dcache_tlb_sc_fail )
2845                    {
2846                    r_dcache_tlb_ll_dirty_req = true;
2847                    r_dcache_tlb_sc_fail = false;
2848                    r_vci_rsp_data_ok = false;
2849                        r_dcache_fsm = DCACHE_LL_DIRTY_WAIT; 
2850                    }
2851                else 
2852                {
2853                    r_vci_rsp_data_ok = false;
2854                    r_dcache_fsm = DCACHE_WRITE_DIRTY; 
2855                }
2856            }
2857        }
2858        break;
2859    }
2860    //////////////////////
2861    case DCACHE_TLB1_READ:
2862    {
2863        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
2864
2865        // external cache invalidate request
2866        if ( r_tgt_dcache_req )   
2867        {
2868            r_dcache_fsm = DCACHE_CC_CHECK;
2869            r_dcache_fsm_save = r_dcache_fsm;
2870            break;
2871        }       
2872
2873        if ( r_dcache_cleanup_req ) break;
2874
2875        if ( r_vci_rsp_data_ok ) // VCI response ok
2876        {
2877            if ( r_vci_rsp_data_error )
2878            {   
2879                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
2880                {
2881                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
2882                }
2883                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
2884                {
2885                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
2886                } 
2887                r_dcache_bad_vaddr = dreq.addr;
2888                r_dcache_fsm = DCACHE_ERROR; 
2889               
2890                        if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
2891                        if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;     
2892                        break;
2893            }
2894
2895            if ( r_dcache_inval_tlb_rsp )  // TLB miss response and invalidation
2896            {
2897                r_dcache_fsm = DCACHE_IDLE;
2898                r_dcache_cleanup_req = true;
2899                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
2900                r_dcache_cleanup_type = TLB_CLEANUP;
2901                r_dcache_inval_tlb_rsp = false;
2902                        break;
2903            }
2904
2905                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
2906                {
2907                r_dcache_ptba_ok    = false;
2908                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
2909                {
2910                    r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
2911                }
2912                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
2913                {
2914                    r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
2915                } 
2916                r_dcache_bad_vaddr  = dreq.addr;
2917                r_dcache_fsm        = DCACHE_ERROR;
2918                }
2919                else if ( (r_dcache_miss_buf[0] & PTE_T_MASK) >> PTE_T_SHIFT ) // PTD
2920                {
2921                r_dcache_ptba_ok   = true;
2922                r_dcache_ptba_save = (paddr_t)(r_dcache_miss_buf[0] & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS; 
2923                r_dcache_id1_save  = dreq.addr >> PAGE_M_NBITS;
2924                r_dcache_tlb_paddr = (paddr_t)(r_dcache_miss_buf[0] & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | 
2925                                     (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
2926                r_vci_rsp_data_ok = false;
2927                if ( r_dcache_tlb_ptba_read )
2928                {
2929                    r_dcache_tlb_ptba_read = false;
2930                    r_dcache_tlb_ll_dirty_req = true;
2931                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2932                    m_cpt_data_tlb_write_dirty++;
2933                }
2934                else
2935                {
2936                    r_dcache_tlb_read_req = true;
2937                    r_dcache_tlb_first_req = false;
2938                    r_dcache_fsm = DCACHE_TLB2_READ;
2939                }
2940
2941                // cleanup PTD in L2, because it's not keep in L1
2942                r_dcache_cleanup_req = true;
2943                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
2944                r_dcache_cleanup_type = TLB_CLEANUP;
2945
2946                }
2947                else    // PTE
2948                {
2949                r_dcache_ptba_ok = false;
2950                    if ( (m_srcid_rw >> 4) == ((r_dcache_tlb_paddr.read() & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
2951                    {
2952                        if ( (r_dcache_miss_buf[0] & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
2953                        {
2954                        r_dcache_pte_update = r_dcache_miss_buf[0];
2955                        r_vci_rsp_data_ok   = false;
2956                        r_dcache_fsm        = DCACHE_TLB1_UPDT;
2957                        }
2958                        else
2959                        {
2960                        r_dcache_pte_update = r_dcache_miss_buf[0] | PTE_L_MASK;
2961                        r_dcache_tlb_ll_acc_req = true;
2962                        r_vci_rsp_data_ok = false;
2963                        r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
2964                        m_cpt_ins_tlb_write_et++;
2965                        }
2966                }
2967                    else // remotely
2968                    {
2969                        if ( (r_dcache_miss_buf[0] & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
2970                        {
2971                        r_dcache_pte_update = r_dcache_miss_buf[0];
2972                        r_vci_rsp_data_ok   = false;
2973                        r_dcache_fsm        = DCACHE_TLB1_UPDT;
2974                        }
2975                        else
2976                        {
2977                        r_dcache_pte_update = r_dcache_miss_buf[0] | PTE_R_MASK;
2978                        r_dcache_tlb_ll_acc_req = true;
2979                        r_vci_rsp_data_ok = false;
2980                        r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
2981                        m_cpt_ins_tlb_write_et++;
2982                        }
2983                    }
2984                }
2985        }
2986        break;
2987    }
2988    ///////////////////////
2989    case DCACHE_TLB1_LL_WAIT:
2990    {
2991        // external cache invalidate request
2992        if ( r_tgt_dcache_req )   
2993        {
2994            r_dcache_fsm = DCACHE_CC_CHECK;
2995            r_dcache_fsm_save = r_dcache_fsm;
2996            break;
2997        }   
2998
2999            if ( r_vci_rsp_data_ok )
3000            {
3001            if ( r_vci_rsp_data_error ) // VCI response ko
3002            {
3003                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3004                {
3005                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
3006                }
3007                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3008                {
3009                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
3010                } 
3011                r_dcache_bad_vaddr = dreq.addr;
3012                r_dcache_fsm = DCACHE_ERROR; 
3013
3014                        if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3015            }
3016                else
3017                {
3018                    if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )       // unmapped
3019                    {
3020                    if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3021                    {
3022                        r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
3023                    }
3024                    else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3025                    {
3026                        r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
3027                    } 
3028                    r_dcache_bad_vaddr  = dreq.addr;
3029                    r_dcache_fsm        = DCACHE_ERROR;
3030
3031                            if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3032                    }
3033                else if ( r_dcache_inval_tlb_rsp )
3034                {
3035                    r_dcache_inval_tlb_rsp = false;
3036                    r_dcache_fsm = DCACHE_IDLE;
3037                    m_cost_data_tlb_miss_frz++;
3038                }
3039                        else
3040                        {
3041                            r_dcache_tlb_sc_acc_req = true;
3042                    r_vci_rsp_data_ok = false;
3043                    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
3044                    r_dcache_fsm = DCACHE_TLB1_SC_WAIT; 
3045                        }
3046                }
3047            }
3048            break;
3049    }
3050    ///////////////////////
3051    case DCACHE_TLB1_SC_WAIT:
3052    {
3053        // external cache invalidate request
3054        if ( r_tgt_dcache_req )   
3055        {
3056            r_dcache_fsm = DCACHE_CC_CHECK;
3057            r_dcache_fsm_save = r_dcache_fsm;
3058            break;
3059        }   
3060
3061        if ( r_vci_rsp_data_ok ) // VCI response ko
3062        {
3063            if ( r_vci_rsp_data_error ) // VCI response ko
3064                {
3065                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3066                {
3067                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
3068                }
3069                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3070                {
3071                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
3072                } 
3073                    r_dcache_bad_vaddr = dreq.addr;
3074                    r_dcache_fsm = DCACHE_ERROR; 
3075
3076                        if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3077                }
3078            else
3079            {
3080                // Using tlb entry is invalidated
3081                if ( r_dcache_inval_tlb_rsp )
3082                {
3083                    r_dcache_inval_tlb_rsp = false;
3084                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3085                    r_dcache_fsm = DCACHE_IDLE;
3086                    m_cost_data_tlb_miss_frz++;
3087                }
3088                    else if ( r_dcache_tlb_sc_fail )
3089                    {
3090                    r_dcache_tlb_ll_acc_req = true;
3091                    r_dcache_tlb_sc_fail = false;
3092                    r_vci_rsp_data_ok = false;
3093                        r_dcache_fsm = DCACHE_TLB1_LL_WAIT; 
3094                    }
3095                    else
3096                    {
3097                    r_vci_rsp_data_ok = false;
3098                        r_dcache_fsm = DCACHE_TLB1_UPDT; 
3099                    }
3100            }
3101        }
3102            break;
3103    }
3104    //////////////////////
3105    case DCACHE_TLB1_UPDT: 
3106    {
3107        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3108
3109        // external cache invalidate request
3110        if ( r_tgt_dcache_req )   
3111        {
3112            r_dcache_fsm = DCACHE_CC_CHECK;
3113            r_dcache_fsm_save = r_dcache_fsm;
3114            //m_cost_data_waste_wait_frz++;
3115            break;
3116        }
3117       
3118        // TLB update and invalidate different PTE
3119        if ( !r_dcache_inval_tlb_rsp && !r_dcache_cleanup_req)
3120        {
3121            paddr_t victim_index = 0;
3122            r_dcache_cleanup_req = dcache_tlb.update1(r_dcache_pte_update,dreq.addr,(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)),&victim_index);
3123            r_dcache_cleanup_line = victim_index;
3124            r_dcache_cleanup_type = TLB_CLEANUP; 
3125            r_dcache_fsm = DCACHE_IDLE;
3126        }
3127
3128        // TLB update and invalidate same PTE
3129        if ( r_dcache_inval_tlb_rsp )                                 
3130        {
3131            r_dcache_inval_tlb_rsp = false;
3132            r_dcache_fsm = DCACHE_IDLE;
3133        }
3134        break;
3135    }
3136    /////////////////////
3137    case DCACHE_TLB2_READ:
3138    {
3139        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3140
3141        // external cache invalidate request
3142        if ( r_tgt_dcache_req )   
3143        {
3144            r_dcache_fsm = DCACHE_CC_CHECK;
3145            r_dcache_fsm_save = r_dcache_fsm;
3146            break;
3147        }       
3148
3149        if ( r_vci_rsp_data_ok ) // VCI response ok
3150        {
3151            if ( r_vci_rsp_data_error )
3152            {
3153                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3154                {
3155                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
3156                }
3157                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3158                {
3159                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
3160                } 
3161                r_dcache_bad_vaddr = dreq.addr;
3162                r_dcache_fsm = DCACHE_ERROR;
3163
3164                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3165                        if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;     
3166                        break;
3167            }   
3168
3169            if ( r_dcache_inval_tlb_rsp )  // TLB miss response and invalidation
3170            {
3171                if (r_dcache_cleanup_req) break;
3172                r_dcache_fsm = DCACHE_IDLE; 
3173                r_dcache_cleanup_req = true;
3174                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
3175                r_dcache_cleanup_type = TLB_CLEANUP;
3176                r_dcache_inval_tlb_rsp = false;
3177                        break;
3178            }
3179
3180                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
3181                {
3182                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3183                {
3184                    r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
3185                }
3186                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3187                {
3188                    r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
3189                } 
3190                r_dcache_bad_vaddr  = dreq.addr;
3191                r_dcache_fsm        = DCACHE_ERROR;
3192                }
3193                else if ( (r_dcache_miss_buf[0] & PTE_T_MASK) >> PTE_T_SHIFT ) // PTD
3194                {
3195                r_dcache_pte_update = r_dcache_miss_buf[0];
3196                r_vci_rsp_data_ok = false;
3197                    r_dcache_fsm = DCACHE_TLB2_UPDT;
3198                }
3199            else
3200            {
3201                    if ( (m_srcid_rw >> 4) == ((r_dcache_tlb_paddr.read() & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
3202                    {
3203                        if ( (r_dcache_miss_buf[0] & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
3204                        {
3205                        r_dcache_pte_update = r_dcache_miss_buf[0];
3206                        r_vci_rsp_data_ok   = false;
3207                        r_dcache_fsm        = DCACHE_TLB2_UPDT;
3208                        }
3209                        else
3210                        {
3211                        r_dcache_pte_update = r_dcache_miss_buf[0] | PTE_L_MASK;
3212                        r_dcache_tlb_ll_acc_req = true;
3213                        r_vci_rsp_data_ok = false; 
3214                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3215                        m_cpt_ins_tlb_write_et++;
3216                        }
3217                }
3218                    else // remotely
3219                    {
3220                        if ( (r_dcache_miss_buf[0] & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
3221                        {
3222                        r_dcache_pte_update = r_dcache_miss_buf[0];
3223                        r_vci_rsp_data_ok   = false;
3224                        r_dcache_fsm        = DCACHE_TLB2_UPDT;
3225                        }
3226                        else
3227                        {
3228                        r_dcache_pte_update = r_dcache_miss_buf[0] | PTE_R_MASK;
3229                        r_dcache_tlb_ll_acc_req = true;
3230                        r_vci_rsp_data_ok = false;
3231                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3232                        m_cpt_ins_tlb_write_et++;
3233                        }
3234                    }
3235            }
3236        } 
3237        break;
3238    }
3239    ///////////////////////
3240    case DCACHE_TLB2_LL_WAIT:
3241    {
3242        // external cache invalidate request
3243        if ( r_tgt_dcache_req )   
3244        {
3245            r_dcache_fsm = DCACHE_CC_CHECK;
3246            r_dcache_fsm_save = r_dcache_fsm;
3247            break;
3248        }   
3249
3250            if ( r_vci_rsp_data_ok )
3251            {
3252            if ( r_vci_rsp_data_error ) // VCI response ko
3253            {
3254                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3255                {
3256                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
3257                }
3258                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3259                {
3260                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
3261                } 
3262                r_dcache_bad_vaddr = dreq.addr;
3263                r_dcache_fsm = DCACHE_ERROR; 
3264               
3265                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3266            }
3267                else
3268                {
3269                    if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )       // unmapped
3270                    {
3271                    if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3272                    {
3273                        r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
3274                    }
3275                    else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3276                    {
3277                        r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
3278                    } 
3279                    r_dcache_bad_vaddr = dreq.addr;
3280                    r_dcache_fsm = DCACHE_ERROR;
3281
3282                    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3283                    }
3284                else if ( r_dcache_inval_tlb_rsp )
3285                {
3286                    r_dcache_inval_tlb_rsp = false;
3287                    r_dcache_fsm = DCACHE_IDLE;
3288                    m_cost_data_tlb_miss_frz++;
3289                }
3290                        else
3291                        {
3292                            r_dcache_tlb_sc_acc_req = true;
3293                    r_vci_rsp_data_ok = false;
3294                    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
3295                    r_dcache_fsm = DCACHE_TLB2_SC_WAIT; 
3296                        }
3297                }
3298            }
3299            break;
3300    }
3301    ///////////////////////
3302    case DCACHE_TLB2_SC_WAIT:
3303    {
3304        // external cache invalidate request
3305        if ( r_tgt_dcache_req )   
3306        {
3307            r_dcache_fsm = DCACHE_CC_CHECK;
3308            r_dcache_fsm_save = r_dcache_fsm;
3309            break;
3310        } 
3311
3312        if ( r_vci_rsp_data_ok ) // VCI response
3313        {
3314            if ( r_vci_rsp_data_error ) // VCI response ko
3315                {
3316                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3317                {
3318                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
3319                }
3320                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3321                {
3322                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
3323                } 
3324                    r_dcache_bad_vaddr = dreq.addr;
3325                    r_dcache_fsm = DCACHE_ERROR; 
3326
3327                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3328                }
3329            else
3330            {
3331                // Using tlb entry is invalidated
3332                if ( r_dcache_inval_tlb_rsp )
3333                {
3334                    r_dcache_inval_tlb_rsp = false;
3335                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3336                    r_dcache_fsm = DCACHE_IDLE;
3337                    m_cost_data_tlb_miss_frz++;
3338                }
3339                    else if ( r_dcache_tlb_sc_fail )
3340                    {
3341                    r_dcache_tlb_ll_acc_req = true;
3342                    r_dcache_tlb_sc_fail = false;
3343                    r_vci_rsp_data_ok = false;
3344                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT; 
3345                    }
3346                    else 
3347                    {
3348                    r_vci_rsp_data_ok = false;
3349                        r_dcache_fsm = DCACHE_TLB2_UPDT; 
3350                    }
3351            }
3352        }
3353            break;
3354    }
3355    //////////////////////
3356    case DCACHE_TLB2_UPDT: 
3357    {
3358        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3359
3360        // external cache invalidate request
3361        if ( r_tgt_dcache_req )   
3362        {
3363            r_dcache_fsm = DCACHE_CC_CHECK;
3364            r_dcache_fsm_save = r_dcache_fsm;
3365            break;
3366        }       
3367
3368        // TLB update and invalidate different PTE
3369        if ( !r_dcache_inval_tlb_rsp && !r_dcache_cleanup_req)
3370        {
3371            paddr_t victim_index = 0;
3372            r_dcache_cleanup_req = dcache_tlb.update1(r_dcache_pte_update,r_dcache_miss_buf[1],dreq.addr,(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)),&victim_index);
3373            r_dcache_cleanup_line = victim_index;
3374            r_dcache_cleanup_type = TLB_CLEANUP; 
3375            r_dcache_fsm = DCACHE_IDLE;
3376        }
3377
3378        // TLB update and invalidate same PTE
3379        if ( r_dcache_inval_tlb_rsp )                                 
3380        {
3381            r_dcache_inval_tlb_rsp = false;
3382            r_dcache_fsm = DCACHE_IDLE;
3383        }
3384        break;
3385    }
3386    //////////////////////////
3387    case DCACHE_CTXT_SWITCH:
3388    {
3389        size_t way = r_dcache_way;
3390        size_t set = r_dcache_set;
3391        bool clean = false;
3392
3393        m_cost_data_tlb_flush_frz++
3394;
3395        // 4K page size TLB flush leads to cleanup req 
3396        if ( !r_dcache_cleanup_req )    // last cleanup finish
3397        {
3398            paddr_t victim_index = 0;
3399            for ( ; way < m_dtlb_ways; way++)
3400            {
3401                for ( ; set < m_dtlb_sets; set++)
3402                {
3403                    if(dcache_tlb.checkcleanup1(way, set, &victim_index))
3404                    {
3405                        clean = true;
3406                        r_dcache_cleanup_req = true;
3407                        r_dcache_cleanup_line = victim_index;
3408                        r_dcache_cleanup_type = TLB_CLEANUP;
3409                        r_dcache_way = way + ((set+1)/m_dtlb_sets);
3410                        r_dcache_set = (set+1) % m_dtlb_sets;
3411                        break;
3412                    }
3413                }
3414                if (clean) break;
3415            }
3416
3417            if ((way == m_dtlb_ways) && (!r_dcache_xtn_req))
3418            {
3419                r_dcache_fsm = DCACHE_IDLE;
3420                r_dtlb_translation_valid = false;
3421                r_dcache_ptba_ok = false;
3422                drsp.valid = true;
3423                break;
3424            }
3425        }
3426        break;
3427    }
3428    ////////////////////////
3429    case DCACHE_ICACHE_FLUSH:
3430    case DCACHE_ICACHE_INVAL:
3431    case DCACHE_ITLB_INVAL:
3432    {
3433        if ( !r_dcache_xtn_req ) 
3434        {
3435            r_dcache_fsm = DCACHE_IDLE;
3436            drsp.valid = true;
3437        }
3438        break;
3439    }
3440    ////////////////////////
3441    case DCACHE_DCACHE_FLUSH:
3442    {
3443        m_cost_data_cache_flush_frz++;
3444
3445        // external cache invalidate request
3446        if ( r_tgt_dcache_req )   
3447        {
3448            r_dcache_fsm = DCACHE_CC_CHECK;
3449            r_dcache_fsm_save = r_dcache_fsm;
3450            m_cost_data_waste_wait_frz++;
3451            break;
3452        } 
3453        size_t way = r_dcache_way;
3454        size_t set = r_dcache_set;
3455        bool clean = false;
3456       
3457        // cache flush and send cleanup to external
3458        if ( !r_dcache_cleanup_req )
3459        {
3460            paddr_t victim_index = 0;
3461            for ( ; way < m_dcache_ways; way++ )
3462            {   
3463                for ( ; set < m_dcache_sets; set++ )
3464                { 
3465                    if ( r_dcache.flush(way, set, &victim_index) )
3466                    {
3467                        clean = true;
3468                        r_dcache_cleanup_req = true;
3469                        r_dcache_cleanup_line = victim_index;
3470                        r_dcache_cleanup_type = CACHE_CLEANUP;
3471                        r_dcache_way = way + ((set+1)/m_dcache_sets);
3472                        r_dcache_set = (set+1) % m_dcache_sets;
3473                        break;
3474                    }
3475                }
3476                if (clean) break;
3477            }
3478
3479            if ( way == m_dcache_ways ) 
3480            {
3481                r_dcache_fsm = DCACHE_IDLE;
3482                drsp.valid = true;
3483                break;
3484            }
3485        }
3486        break;
3487    }
3488    //////////////////////
3489    case DCACHE_DTLB_INVAL: 
3490    {
3491        paddr_t victim_index = 0;
3492
3493        if ( !r_dcache_cleanup_req )
3494        {
3495            r_dcache_cleanup_req = dcache_tlb.inval1(r_dcache_wdata_save, &victim_index);
3496            r_dcache_cleanup_type = TLB_CLEANUP;
3497            r_dcache_cleanup_line = victim_index;
3498            r_dtlb_translation_valid = false;
3499            r_dcache_ptba_ok = false;
3500            r_dcache_fsm = DCACHE_IDLE;
3501            drsp.valid = true;
3502        }
3503        break;
3504    }
3505    ////////////////////////
3506    case DCACHE_DCACHE_INVAL:
3507    {
3508        // external cache invalidate request
3509        if ( r_tgt_dcache_req )   
3510        {
3511            r_dcache_fsm = DCACHE_CC_CHECK;
3512            r_dcache_fsm_save = r_dcache_fsm;
3513            m_cost_data_waste_wait_frz++;
3514            break;
3515        } 
3516
3517        m_cpt_dcache_dir_read += m_dcache_ways;
3518        vaddr_t invadr = dreq.wdata;
3519        paddr_t dpaddr = 0;
3520        bool dcache_hit_t = false; 
3521
3522        if ( !r_dcache_cleanup_req )
3523        {
3524            if ( r_mmu_mode.read() & DATA_TLB_MASK ) 
3525            {
3526                dcache_hit_t = dcache_tlb.translate(invadr, &dpaddr); 
3527            } 
3528            else 
3529            {
3530                dpaddr = invadr; 
3531                dcache_hit_t = true;
3532            }
3533
3534            if ( dcache_hit_t )
3535            {
3536                r_dcache_cleanup_req = r_dcache.inval(dpaddr);
3537                r_dcache_cleanup_type = CACHE_CLEANUP;
3538                r_dcache_cleanup_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
3539            }
3540            r_dcache_fsm = DCACHE_IDLE;
3541            drsp.valid = true;
3542        }
3543        break;
3544    }
3545    ////////////////////////
3546    case DCACHE_DCACHE_INVAL_PA:
3547    {
3548        // external cache invalidate request
3549        if ( r_tgt_dcache_req )   
3550        {
3551            r_dcache_fsm = DCACHE_CC_CHECK;
3552            r_dcache_fsm_save = r_dcache_fsm;
3553            m_cost_data_waste_wait_frz++;
3554            break;
3555        } 
3556
3557        m_cpt_dcache_dir_read += m_dcache_ways;
3558        paddr_t dpaddr = (paddr_t)r_mmu_word_hi.read() << 32 | r_mmu_word_lo.read();
3559
3560        if ( !r_dcache_cleanup_req )
3561        {
3562            r_dcache_cleanup_req = r_dcache.inval(dpaddr);
3563            r_dcache_cleanup_type = CACHE_CLEANUP;
3564            r_dcache_cleanup_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
3565            r_dcache_fsm = DCACHE_IDLE;
3566            drsp.valid = true;
3567        }
3568        break;
3569    }
3570    /////////////////////////
3571    case DCACHE_DCACHE_SYNC:
3572    {
3573        if ( r_wbuf.empty() ) 
3574        {
3575            drsp.valid = true;
3576            r_dcache_fsm = DCACHE_IDLE;
3577        }   
3578        break;
3579    }
3580    /////////////////////
3581    case DCACHE_MISS_WAIT:
3582    {
3583        // external cache invalidate request
3584        if ( r_tgt_dcache_req ) 
3585        {
3586            r_dcache_fsm = DCACHE_CC_CHECK;
3587            r_dcache_fsm_save = r_dcache_fsm;
3588            m_cost_cc_wait_frz++;
3589            break;
3590        }
3591
3592        if ( r_vci_rsp_data_ok )
3593        {
3594            if ( r_vci_rsp_data_error ) 
3595            {
3596                r_dcache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 
3597                r_dcache_bad_vaddr = dreq.addr;
3598                r_dcache_fsm = DCACHE_ERROR;
3599
3600                        if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3601                        if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
3602                        break;
3603            }       
3604
3605            if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
3606            {
3607                if ( r_dcache_cleanup_req ) break;
3608                r_dcache_cleanup_req = true;
3609                r_dcache_cleanup_type = CACHE_CLEANUP;
3610                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
3611                r_dcache_fsm = DCACHE_IDLE;
3612                r_dcache_inval_tlb_rsp = false;
3613                if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
3614                        break;
3615            }   
3616
3617                if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
3618                {
3619                if ( r_dcache_cleanup_req ) break;
3620                r_dcache_cleanup_req = true;
3621                r_dcache_cleanup_type = CACHE_CLEANUP;
3622                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
3623                r_dcache_fsm = DCACHE_IDLE;
3624                r_dcache_inval_rsp = false;
3625                        break;     
3626            }
3627                // Miss read response and no tlb invalidation   
3628            r_dcache_fsm = DCACHE_MISS_UPDT;
3629        }
3630        break;
3631    }
3632    /////////////////////
3633    case DCACHE_MISS_UPDT:
3634    {
3635        // external cache invalidate request
3636        if ( r_tgt_dcache_req ) 
3637        {
3638            r_dcache_fsm = DCACHE_CC_CHECK;
3639            r_dcache_fsm_save = r_dcache_fsm;
3640            break;
3641        }
3642
3643        if ( r_dcache_inval_tlb_rsp ) // tlb invalidation
3644        {
3645            if ( r_dcache_cleanup_req ) break;
3646            r_dcache_cleanup_req = true;
3647            r_dcache_cleanup_type = CACHE_CLEANUP;           
3648            r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
3649            r_dcache_inval_tlb_rsp = false;
3650            r_dcache_inval_rsp = false;
3651            r_dcache_fsm = DCACHE_IDLE;
3652            break;
3653        }
3654
3655        // Using tlb entry is in the invalidated cache line 
3656        if ( r_dcache_inval_rsp )
3657        {
3658            if ( r_dcache_cleanup_req ) break;
3659            r_dcache_cleanup_req = true;
3660            r_dcache_cleanup_type = CACHE_CLEANUP;           
3661            r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
3662            r_dcache_inval_rsp = false;
3663            r_dcache_fsm = DCACHE_IDLE;
3664            m_cost_data_tlb_miss_frz++;
3665            break;
3666        }
3667
3668        if ( !r_dcache_cleanup_req ) // Miss update and no invalidation
3669        {
3670            paddr_t  victim_index = 0;
3671            r_dcache_cleanup_req = r_dcache.update(r_dcache_paddr_save.read(), r_dcache_miss_buf, &victim_index);
3672            r_dcache_cleanup_line = victim_index;
3673            r_dcache_cleanup_type = CACHE_CLEANUP;
3674            r_dcache_fsm = DCACHE_IDLE;
3675        }
3676        break;
3677    }
3678    //////////////////////
3679    case DCACHE_UNC_WAIT:
3680    {
3681        // external cache invalidate request
3682        if ( r_tgt_dcache_req ) 
3683        {
3684            r_dcache_fsm = DCACHE_CC_CHECK;
3685            r_dcache_fsm_save = r_dcache_fsm;
3686            break;
3687        }
3688
3689        if ( r_vci_rsp_data_ok )
3690        {
3691            if ( r_vci_rsp_data_error ) 
3692            {
3693                r_dcache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 
3694                r_dcache_bad_vaddr = dreq.addr;
3695                r_dcache_fsm = DCACHE_ERROR;
3696
3697                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3698                        break;
3699            }
3700
3701            if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
3702            {
3703                r_dcache_inval_tlb_rsp = false;
3704            }
3705
3706            if (dreq.type == iss_t::DATA_SC) 
3707                {
3708                // Simulate an invalidate request
3709                        r_dcache_cleanup_req = r_dcache.inval(r_dcache_paddr_save);
3710                r_dcache_cleanup_type = CACHE_CLEANUP;
3711                        r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words)+2);
3712            }           
3713                r_dcache_fsm = DCACHE_IDLE;       
3714        }
3715        break;
3716    }
3717    ///////////////////////
3718    case DCACHE_WRITE_UPDT:
3719    {
3720        bool write_hit = false;
3721        data_t mask = vci_param::be2mask(r_dcache_be_save.read());
3722        data_t wdata = (mask & r_dcache_wdata_save) | (~mask & r_dcache_rdata_save);
3723        write_hit = r_dcache.write(r_dcache_paddr_save, wdata);
3724        assert(write_hit && "Write on miss ignores data");
3725
3726        if ( !r_dcache_dirty_save && (r_mmu_mode.read() & DATA_TLB_MASK) )   
3727        {
3728            if ( dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save) ) // 2M page size, one level page table
3729            {
3730                r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
3731                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
3732                r_dcache_tlb_ll_dirty_req = true;
3733                r_vci_rsp_data_ok = false;
3734                r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
3735                m_cpt_data_tlb_write_dirty++;
3736            }
3737            else
3738            {   
3739                if (r_dcache_hit_p_save) 
3740                {
3741                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
3742                    r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save|(paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
3743                    r_dcache_tlb_ll_dirty_req = true;
3744                    r_vci_rsp_data_ok = false;
3745                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
3746                    m_cpt_data_tlb_write_dirty++;
3747                }
3748                else
3749                {
3750                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
3751                    r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
3752                    r_dcache_tlb_ptba_read = true;
3753                    r_dcache_tlb_read_req = true;
3754                    r_dcache_tlb_first_req = true;
3755                    r_vci_rsp_data_ok = false;
3756                    r_dcache_fsm = DCACHE_TLB1_READ;
3757                }
3758            }       
3759        }
3760        else
3761        {
3762            r_dcache_fsm = DCACHE_WRITE_REQ;
3763            drsp.valid = true;
3764            drsp.rdata = 0;
3765        }
3766        break;
3767    }
3768    ////////////////////////
3769    case DCACHE_WRITE_DIRTY:
3770    {
3771        m_cost_data_tlb_miss_frz++;
3772
3773        // external cache invalidate request
3774        if ( r_tgt_dcache_req ) 
3775        {
3776            r_dcache_fsm = DCACHE_CC_CHECK;
3777            r_dcache_fsm_save = r_dcache_fsm;
3778            //m_cost_data_waste_wait_frz++;
3779            break;
3780        }
3781
3782        if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
3783        {
3784            r_dcache_fsm = DCACHE_IDLE;
3785            r_dcache_inval_tlb_rsp = false;
3786                break;
3787        }
3788        dcache_tlb.setdirty(r_dcache_tlb_way_save, r_dcache_tlb_set_save);
3789        r_dcache_fsm = DCACHE_WRITE_REQ;
3790        drsp.valid = true;
3791        drsp.rdata = 0;
3792        break;
3793    }
3794    /////////////////
3795    case DCACHE_ERROR:
3796    {
3797        r_vci_rsp_data_error = false;
3798        drsp.valid = true;
3799        drsp.error = true;
3800        drsp.rdata = 0;
3801        r_dcache_fsm = DCACHE_IDLE;
3802        break;
3803    }   
3804    /////////////////////
3805    case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
3806    {
3807        m_cpt_dcache_dir_read += m_dcache_ways;
3808        m_cpt_dcache_data_read += m_dcache_ways;
3809
3810        m_cost_cc_wait_frz++;
3811
3812        if (( /*( r_dcache_fsm_save == DCACHE_UNC_WAIT ) ||*/
3813                 ( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && 
3814           ( (r_dcache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1)))) 
3815        {
3816            r_dcache_inval_rsp = true;
3817            r_tgt_dcache_rsp = r_tgt_update;
3818
3819            if ( r_tgt_broadcast )
3820            {
3821                r_dcache_tlb_inval_req = true;
3822                r_dcache_fsm = DCACHE_TLB_CC_INVAL;       
3823            }
3824            else
3825            {
3826                r_tgt_dcache_req = false;
3827                r_dcache_fsm = r_dcache_fsm_save;       
3828            }   
3829        } 
3830        else
3831        { 
3832            data_t dcache_rdata = 0;
3833            bool dcache_hit = r_dcache.read(r_tgt_addr.read(), &dcache_rdata);   
3834
3835            if ( dcache_hit )
3836            {
3837                if ( r_tgt_update ) // update
3838                {
3839                    r_dcache_fsm = DCACHE_CC_UPDT;
3840                } 
3841                else                // invalidate
3842                {
3843                    r_dcache_fsm = DCACHE_CC_INVAL;
3844                }
3845            }
3846            else                    // nothing
3847            {
3848                r_dcache_fsm = DCACHE_CC_NOP;
3849            }
3850        }
3851        break;
3852    }
3853    ///////////////////
3854    case DCACHE_CC_UPDT:    // update directory and data cache       
3855    {
3856        m_cpt_dcache_dir_write++;
3857        m_cpt_dcache_data_write++;
3858        m_cost_cc_wait_frz++;
3859
3860        data_t* buf = r_tgt_buf;
3861        for( size_t i = 0; i < m_dcache_words; i++ )
3862        {
3863            if( r_tgt_val[i] ) r_dcache.write( r_tgt_addr.read() + i*4, buf[i] );
3864        }
3865        r_tgt_dcache_req = false;
3866        r_tgt_dcache_rsp = true;
3867        r_dcache_fsm = r_dcache_fsm_save;
3868        break;
3869    }
3870    /////////////////////
3871    case DCACHE_CC_INVAL:   // invalidate a cache line
3872    {
3873        m_cost_cc_wait_frz++;
3874        r_tgt_dcache_rsp = r_dcache.inval(r_tgt_addr.read());
3875        if ( r_tgt_broadcast )
3876        {
3877            r_dcache_tlb_inval_req = true;
3878            r_dcache_fsm = DCACHE_TLB_CC_INVAL;       
3879        }
3880        else
3881        {
3882            r_tgt_dcache_req = false;
3883            r_dcache_fsm = r_dcache_fsm_save;       
3884        }   
3885        break;
3886    }
3887    ///////////////////
3888    case DCACHE_CC_NOP:     // no external hit
3889    {
3890        m_cost_cc_wait_frz++;
3891        r_tgt_dcache_rsp = r_tgt_update;
3892        if ( r_tgt_broadcast )
3893        {
3894            r_dcache_tlb_inval_req = true;
3895            r_dcache_fsm = DCACHE_TLB_CC_INVAL;       
3896        }
3897        else
3898        {
3899            r_tgt_dcache_req = false;
3900            r_dcache_fsm = r_dcache_fsm_save;       
3901        }   
3902        break;
3903    }   
3904    /////////////////////////
3905    case DCACHE_TLB_CC_INVAL:
3906    {
3907        paddr_t dcache_tlb_nline = 0;
3908        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;       
3909
3910            if ( r_dcache_tlb_inval_req ) break;
3911
3912        if( (( r_dcache_fsm_save == DCACHE_TLB1_READ )     || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
3913             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )  || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
3914             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )  || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
3915             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )     || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )        ||
3916             ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT ) || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )    ||
3917                 ( r_dcache_fsm_save == DCACHE_WRITE_DIRTY )) && 
3918           ((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) == r_tgt_addr.read()) ) 
3919        {
3920            r_dcache_inval_tlb_rsp = true;
3921        } 
3922
3923        if (((r_dcache_fsm_save == DCACHE_BIS)||(r_dcache_fsm_save == DCACHE_MISS_WAIT) ||
3924             (r_dcache_fsm_save == DCACHE_UNC_WAIT)||(r_dcache_fsm_save == DCACHE_MISS_UPDT)) && 
3925             (r_dcache_tlb_nline == (paddr_t)(r_tgt_addr.read() & ~((m_dcache_words<<2)-1))))
3926        {
3927            r_dcache_inval_tlb_rsp = true;
3928        }
3929
3930        if( (( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )  || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
3931             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )  || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
3932             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )     || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )        ||
3933             ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT ) || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )    ||
3934                 ( r_dcache_fsm_save == DCACHE_WRITE_DIRTY )) && 
3935           ((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) == r_tgt_addr.read()) ) 
3936        {
3937            if ( !r_dcache_cc_hit_t ) 
3938            {
3939                r_ccinval_dtlb_cpt = r_ccinval_dtlb_cpt + 1;
3940            }
3941        } 
3942
3943        r_tgt_dcache_req = false;
3944            r_dtlb_translation_valid = false;
3945        r_dcache_ptba_ok = false;       
3946        r_dcache_fsm = r_dcache_fsm_save;
3947        break;
3948    }
3949    } // end switch r_dcache_fsm
3950
3951#ifdef SOCLIB_MODULE_DEBUG
3952    std::cout << name() << " Data Response: " << drsp << std::endl;
3953#endif
3954
3955    ////////////////////////////////////////////////////////////////////////////////////
3956    //      INVAL DTLB CHECK FSM
3957    ////////////////////////////////////////////////////////////////////////////////////////
3958    switch(r_inval_dtlb_fsm) {
3959    /////////////////////
3960    case INVAL_DTLB_IDLE:
3961    {   
3962        if ( r_dcache_tlb_inval_req )
3963        {
3964            paddr_t dpaddr;
3965            r_ccinval_dtlb_way = 0;
3966            r_ccinval_dtlb_set = 0;
3967            r_ccinval_dtlb_cpt = 0;
3968            r_dcache_cc_hit_t = dcache_tlb.translate(dreq.addr, &dpaddr);
3969            r_inval_dtlb_fsm = INVAL_DTLB_CHECK;   
3970        }   
3971        break;
3972    }   
3973    //////////////////////
3974    case INVAL_DTLB_CHECK:
3975    {
3976        size_t way = r_ccinval_dtlb_way; 
3977        size_t set = r_ccinval_dtlb_set;
3978        bool end = false;
3979
3980        bool tlb_hit = dcache_tlb.cccheck((r_tgt_addr.read() >> (uint32_log2(m_dcache_words)+2)), way, set, &way, &set, &end);
3981   
3982        if ( tlb_hit )
3983        {
3984            r_ccinval_dtlb_way = way; 
3985            r_ccinval_dtlb_set = set;
3986            r_dtlb_cc_check_end = end;
3987            r_ccinval_dtlb_cpt = r_ccinval_dtlb_cpt + 1;
3988            r_inval_dtlb_fsm = INVAL_DTLB_INVAL;   
3989        }       
3990        else
3991        {
3992            r_inval_dtlb_fsm = INVAL_DTLB_CLEAR;   
3993        }
3994        break;
3995    }
3996    /////////////////////////
3997    case INVAL_DTLB_INVAL:
3998    {
3999        dcache_tlb.ccinval(r_ccinval_dtlb_way, r_ccinval_dtlb_set);
4000        if ( !r_dtlb_cc_check_end )
4001        {
4002            r_inval_dtlb_fsm = INVAL_DTLB_CHECK; 
4003        }
4004        else
4005        {
4006            r_inval_dtlb_fsm = INVAL_DTLB_CLEAR;   
4007        }
4008        break;
4009    }
4010    ////////////////////
4011    case INVAL_DTLB_CLEAR:
4012    {
4013        r_dcache_tlb_inval_req = false;
4014        r_dtlb_cc_check_end = false;
4015        r_ccinval_dtlb_way = 0; 
4016        r_ccinval_dtlb_set = 0; 
4017        r_inval_dtlb_fsm = INVAL_DTLB_IDLE;   
4018        break;
4019    }   
4020    } // end switch r_inval_itlb_fsm
4021
4022    if ( r_dcache_fsm == DCACHE_WRITE_REQ )
4023    {
4024        r_wbuf.write(true, r_dcache_paddr_save.read(), r_dcache_be_save.read(), r_dcache_wdata_save); 
4025    }
4026    else
4027    {
4028        r_wbuf.write(false, 0, 0, 0);
4029    }
4030
4031    /////////// execute one iss cycle /////////////////////////////////
4032    {
4033    uint32_t it = 0;
4034    for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if(p_irq[i].read()) it |= (1<<i);
4035    m_iss.executeNCycles(1, irsp, drsp, it);
4036    }
4037
4038    ////////////// number of frozen cycles //////////////////////////
4039    if ( (ireq.valid && !irsp.valid) || (dreq.valid && !drsp.valid) )
4040    {
4041        m_cpt_frz_cycles++;
4042    }
4043
4044    ////////////////////////////////////////////////////////////////////////////
4045    // This CLEANUP FSM controls the transmission of the cleanup transactions
4046    // on the coherence network. It controls the following ressources:
4047    // - r_cleanup_fsm
4048    // - r_dcache_cleanup_req reset
4049    // - r_icache_cleanup_req reset
4050    //
4051    // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM
4052    // 1 - Instruction Cleanup  : r_icache_cleanup_req
4053    // 2 - Data Cleanup         : r_dcache_cleanup_req
4054    // In case of simultaneous requests, the data request have highest priority.
4055    // There is only one cleanup transaction at a given time (sequencial behavior)
4056    // because the same FSM controls both command & response.
4057    // The the r_icache_cleanup_req & r_dcache_cleanup_req are reset only
4058    // when the response packet is received.
4059    // Error handling :
4060    // As the coherence trafic is controled by hardware, errors are not reported
4061    // to software : In case of errors, the simulation stops.
4062    ////////////////////////////////////////////////////////////////////////////
4063
4064    switch (r_cleanup_fsm) {
4065    ////////////////// 
4066    case CLEANUP_CMD:
4067    {
4068        if ( p_vci_ini_c.cmdack.read() )
4069        {
4070            if ( r_icache_cleanup_req ) 
4071                {
4072                    r_cleanup_fsm = CLEANUP_ICACHE_RSP;
4073                }       
4074            else if ( r_dcache_cleanup_req ) 
4075                {
4076                    r_cleanup_fsm = CLEANUP_DCACHE_RSP;
4077                }
4078            }   
4079        break;
4080    }
4081    ////////////////////////
4082    case CLEANUP_ICACHE_RSP:
4083    {
4084        if ( ! p_vci_ini_c.rspval.read() )
4085            break;
4086        assert( p_vci_ini_c.reop.read() && ((p_vci_ini_c.rtrdid.read() == 1)||(p_vci_ini_c.rtrdid.read() == 3)) &&
4087                "illegal VCI response packet for icache cleanup");
4088        assert( (p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL) &&
4089                "error in response packet for icache cleanup");
4090
4091        r_icache_cleanup_req = false;
4092        r_cleanup_fsm = CLEANUP_CMD;
4093        break;
4094    }
4095    /////////////////////////           
4096    case CLEANUP_DCACHE_RSP:
4097    {
4098        if ( ! p_vci_ini_c.rspval.read() )
4099            break;
4100        assert( p_vci_ini_c.reop.read() && ((p_vci_ini_c.rtrdid.read() == 0)||(p_vci_ini_c.rtrdid.read() == 2)) &&
4101                "illegal VCI response packet for dcache cleanup");
4102        assert( (p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL) &&
4103                "error in response packet for dcache cleanup");
4104
4105        r_dcache_cleanup_req = false;
4106        r_cleanup_fsm = CLEANUP_CMD;
4107        break;
4108    }
4109    } // end switch r_cleanup_fsm
4110
4111    ////////////////////////////////////////////////////////////////////////////
4112    //     VCI_CMD FSM
4113    //
4114    // This FSM handles requests from both the DCACHE controler
4115    // (request registers) and the ICACHE controler (request registers).
4116    // There is 10 VCI transaction types :
4117    // - INS_TLB_READ
4118    // - INS_TLB_WRITE
4119    // - INS_MISS
4120    // - INS_UNC_MISS
4121    // - DATA_TLB_READ
4122    // - DATA_TLB_WRITE
4123    // - DATA_TLB_DIRTY
4124    // - DATA_MISS
4125    // - DATA_UNC
4126    // - DATA_WRITE
4127    // The ICACHE requests have the highest priority.
4128    // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM and RSP_FSM
4129    // exit simultaneously the IDLE state.
4130    //////////////////////////////////////////////////////////////////////////////
4131
4132    switch (r_vci_cmd_fsm) {
4133   
4134    case CMD_IDLE:
4135        if (r_icache_tlb_read_req && r_wbuf.miss( r_icache_paddr_save ))           
4136        {           
4137            r_vci_cmd_fsm = CMD_ITLB_READ;
4138            r_icache_tlb_read_req = false;
4139            m_cpt_itlbmiss_transaction++; 
4140        } 
4141        else if (r_icache_tlb_ll_req && r_wbuf.miss( r_icache_paddr_save ))     
4142        { 
4143            r_vci_cmd_fsm = CMD_ITLB_ACC_LL;
4144            r_icache_tlb_ll_req = false;
4145            //m_cpt_itlb_write_transaction++;
4146        } 
4147        else if (r_icache_tlb_sc_req && r_wbuf.miss( r_icache_paddr_save ))     
4148        { 
4149            r_vci_cmd_fsm = CMD_ITLB_ACC_SC;
4150            r_icache_tlb_sc_req = false;
4151            //m_cpt_itlb_write_transaction++;
4152        } 
4153        else if (r_icache_miss_req && r_wbuf.miss( r_icache_paddr_save )) 
4154        {   
4155            r_vci_cmd_fsm = CMD_INS_MISS;
4156            r_icache_miss_req = false;
4157            m_cpt_imiss_transaction++; 
4158        }
4159        else if (r_icache_unc_req && r_wbuf.miss( r_icache_paddr_save )) 
4160        {   
4161            r_vci_cmd_fsm = CMD_INS_UNC;
4162            r_icache_unc_req = false;
4163            m_cpt_imiss_transaction++; 
4164        } 
4165        else if (r_dcache_tlb_read_req && r_wbuf.miss( r_dcache_tlb_paddr )) 
4166        {           
4167            r_vci_cmd_fsm = CMD_DTLB_READ;
4168            r_dcache_tlb_read_req = false;
4169            m_cpt_dtlbmiss_transaction++; 
4170        } 
4171        else if (r_dcache_tlb_ll_acc_req && r_wbuf.miss( r_dcache_tlb_paddr )) 
4172        { 
4173            r_vci_cmd_fsm = CMD_DTLB_ACC_LL;
4174            r_dcache_tlb_ll_acc_req = false;
4175            m_cpt_dtlb_write_transaction++; 
4176        } 
4177        else if (r_dcache_tlb_sc_acc_req && r_wbuf.miss( r_dcache_tlb_paddr )) 
4178        { 
4179            r_vci_cmd_fsm = CMD_DTLB_ACC_SC;
4180            r_dcache_tlb_sc_acc_req = false;
4181            m_cpt_dtlb_write_transaction++; 
4182        } 
4183        else if (r_dcache_tlb_ll_dirty_req && r_wbuf.miss( r_dcache_tlb_paddr )) 
4184        { 
4185            r_vci_cmd_fsm = CMD_DTLB_DIRTY_LL;
4186            r_dcache_tlb_ll_dirty_req = false;
4187            m_cpt_dtlb_write_transaction++; 
4188        } 
4189        else if (r_dcache_tlb_sc_dirty_req && r_wbuf.miss( r_dcache_tlb_paddr )) 
4190        { 
4191            r_vci_cmd_fsm = CMD_DTLB_DIRTY_SC;
4192            r_dcache_tlb_sc_dirty_req = false;
4193            m_cpt_dtlb_write_transaction++; 
4194        } 
4195        else if (r_dcache_miss_req && r_wbuf.miss( r_dcache_paddr_save )) 
4196        {
4197            r_vci_cmd_fsm = CMD_DATA_MISS;
4198            r_dcache_miss_req = false;
4199            m_cpt_dmiss_transaction++; 
4200        }
4201        else if (r_dcache_unc_req && r_wbuf.miss( r_dcache_paddr_save )) 
4202        {
4203            r_vci_cmd_fsm = CMD_DATA_UNC;
4204            r_dcache_unc_req = false;
4205            m_cpt_unc_transaction++; 
4206        }       
4207        else if ( r_wbuf.rok() )
4208        {
4209            r_vci_cmd_fsm = CMD_DATA_WRITE;
4210            r_vci_cmd_cpt = r_wbuf.getMin();
4211            r_vci_cmd_min = r_wbuf.getMin();
4212            r_vci_cmd_max = r_wbuf.getMax(); 
4213            m_cpt_write_transaction++; 
4214            m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1);
4215        }
4216
4217        break;
4218
4219    case CMD_DATA_WRITE:
4220        if ( p_vci_ini_rw.cmdack.read() ) 
4221        {
4222            r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
4223            if (r_vci_cmd_cpt == r_vci_cmd_max) 
4224            {
4225                r_vci_cmd_fsm = CMD_IDLE;
4226                r_wbuf.sent();
4227            }
4228        }
4229        break;
4230
4231    default:
4232        if ( p_vci_ini_rw.cmdack.read() )
4233        { 
4234            r_vci_cmd_fsm = CMD_IDLE;
4235        }
4236        break;
4237
4238    } // end  switch r_vci_cmd_fsm
4239
4240    //////////////////////////////////////////////////////////////////////////
4241    //      VCI_RSP FSM
4242    //
4243    // This FSM is synchronized with the VCI_CMD FSM, as both FSMs exit the
4244    // IDLE state simultaneously.
4245    //////////////////////////////////////////////////////////////////////////
4246
4247    switch (r_vci_rsp_fsm) {
4248
4249    case RSP_IDLE:
4250            if ( p_vci_ini_rw.rspval.read() )
4251            {   
4252            r_vci_rsp_cpt = 0;
4253                if ( (p_vci_ini_rw.rtrdid.read() & 0x30) == 0x30 )         // DCACHE write response
4254            {
4255                r_vci_rsp_fsm = RSP_DATA_WRITE;
4256            }           
4257            else if (( p_vci_ini_rw.rtrdid.read() == TYPE_INS_TLB_1 ) || 
4258                     ( p_vci_ini_rw.rtrdid.read() == TYPE_INS_TLB_2 ))         // ITLB miss response
4259            {           
4260                r_vci_rsp_fsm = RSP_ITLB_READ;
4261            } 
4262            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_INS_LL_ACC )       // ITLB linked load response
4263            {   
4264                r_vci_rsp_fsm = RSP_ITLB_ACC_LL;
4265            } 
4266            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_INS_SC_ACC )       // ITLB linked load response
4267            {   
4268                r_vci_rsp_fsm = RSP_ITLB_ACC_SC;
4269            }         
4270            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_INS_MISS )         // ICACHE cached miss response
4271            {   
4272                r_vci_rsp_fsm = RSP_INS_MISS;
4273            }
4274            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_INS_UNC )          // ICACHE uncached miss response
4275            {   
4276                r_vci_rsp_fsm = RSP_INS_UNC;
4277            } 
4278            else if (( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_TLB_1 ) || 
4279                     ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_TLB_2 ))     // ITLB miss response
4280            {
4281                r_vci_rsp_fsm = RSP_DTLB_READ; 
4282            }
4283            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_LL_ACC )    // DTLB access bits linked load response
4284            {
4285                r_vci_rsp_fsm = RSP_DTLB_ACC_LL; 
4286            }
4287            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_SC_ACC )    // DTLB access bits store conditional response
4288            {
4289                r_vci_rsp_fsm = RSP_DTLB_ACC_SC; 
4290            }
4291            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_LL_D )  // DTLB dirty bit linked load response
4292            {
4293                r_vci_rsp_fsm = RSP_DTLB_DIRTY_LL; 
4294            }
4295            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_SC_D )  // DTLB dirty bit store conditional response
4296            {
4297                r_vci_rsp_fsm = RSP_DTLB_DIRTY_SC; 
4298            }
4299            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_MISS )         // DCACHE read request
4300            {
4301                r_vci_rsp_fsm = RSP_DATA_MISS;
4302            }
4303            else if ( p_vci_ini_rw.rtrdid.read() == TYPE_DATA_UNC )          // DCACHE uncached read request
4304            {
4305                r_vci_rsp_fsm = RSP_DATA_UNC;
4306            }
4307        }
4308        break;
4309
4310    case RSP_ITLB_READ:
4311        m_cost_itlbmiss_transaction++;
4312        if ( ! p_vci_ini_rw.rspval.read() )
4313            break;
4314
4315        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
4316        r_icache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
4317        if ( p_vci_ini_rw.reop.read() ) 
4318        {
4319            if ( r_icache_tlb_first_req )
4320            {
4321                r_icache_tlb_first_req = false; 
4322                assert( (r_vci_rsp_cpt == 0)  &&
4323                    "illegal VCI response packet for data read uncached");
4324            }
4325/*
4326            else
4327            {
4328                assert( (r_vci_rsp_cpt == 1)  &&
4329                       "The VCI response packet for instruction miss is too short");
4330            }
4331*/
4332            r_vci_rsp_ins_ok = true;
4333            r_vci_rsp_fsm = RSP_IDLE;
4334        } 
4335        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
4336        {
4337            r_vci_rsp_ins_error = true;
4338        }
4339        break;
4340
4341    case RSP_ITLB_ACC_LL:
4342        if ( ! p_vci_ini_rw.rspval.read() )
4343            break;
4344
4345        assert(p_vci_ini_rw.reop.read() &&
4346               "illegal VCI response packet for ll tlb");
4347
4348        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4349        {
4350            r_vci_rsp_ins_error = true;
4351        }
4352            else
4353            {
4354                r_icache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
4355            }
4356        r_vci_rsp_ins_ok = true;
4357        r_vci_rsp_fsm = RSP_IDLE;
4358            break;
4359
4360    case RSP_ITLB_ACC_SC:
4361        if ( ! p_vci_ini_rw.rspval.read() )
4362            break;
4363
4364        assert(p_vci_ini_rw.reop.read() &&
4365               "illegal VCI response packet for sc tlb");
4366
4367        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4368        {
4369            r_vci_rsp_ins_error = true;
4370        }
4371            else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
4372            {
4373            r_icache_tlb_sc_fail = true;
4374            }
4375        r_vci_rsp_ins_ok = true;
4376        r_vci_rsp_fsm = RSP_IDLE;
4377            break;
4378
4379    case RSP_INS_MISS:
4380        m_cost_imiss_transaction++;
4381        if ( ! p_vci_ini_rw.rspval.read() )
4382            break;
4383
4384        assert( (r_vci_rsp_cpt < m_icache_words) && 
4385               "The VCI response packet for instruction miss is too long");
4386        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
4387        r_icache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
4388
4389        if ( p_vci_ini_rw.reop.read() ) 
4390        {
4391            assert( (r_vci_rsp_cpt == m_icache_words - 1) &&
4392                       "The VCI response packet for instruction miss is too short");
4393            r_vci_rsp_ins_ok = true;
4394            r_vci_rsp_fsm = RSP_IDLE;
4395        } 
4396        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
4397        {
4398            r_vci_rsp_ins_error = true;
4399        }
4400        break;
4401
4402    case RSP_INS_UNC:
4403        m_cost_imiss_transaction++;
4404        if ( ! p_vci_ini_rw.rspval.read() )
4405            break;
4406
4407        assert(p_vci_ini_rw.reop.read() &&
4408               "illegal VCI response packet for uncached instruction");
4409
4410        r_icache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
4411        r_vci_rsp_ins_ok = true;
4412        r_vci_rsp_fsm = RSP_IDLE;
4413
4414        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
4415        {
4416            r_vci_rsp_ins_error = true;
4417        }
4418        break;
4419
4420    case RSP_DTLB_READ:
4421        m_cost_dtlbmiss_transaction++;
4422        if ( ! p_vci_ini_rw.rspval.read() )
4423            break;
4424
4425        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
4426        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
4427        if ( p_vci_ini_rw.reop.read() ) 
4428        {
4429            if ( r_dcache_tlb_first_req )
4430            {
4431                r_dcache_tlb_first_req = false;
4432                assert( (r_vci_rsp_cpt == 0)  &&
4433                    "illegal VCI response packet for data read uncached");
4434            }
4435/*
4436            else
4437            {
4438                assert( (r_vci_rsp_cpt == 1)  &&
4439                       "The VCI response packet for instruction miss is too short");
4440            }
4441*/
4442            r_vci_rsp_data_ok = true;
4443            r_vci_rsp_fsm = RSP_IDLE;
4444        } 
4445        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
4446        {
4447            r_vci_rsp_data_error = true;
4448        }
4449        break;
4450
4451    case RSP_DTLB_ACC_LL:
4452        if ( ! p_vci_ini_rw.rspval.read() )
4453            break;
4454
4455        assert(p_vci_ini_rw.reop.read() &&
4456               "illegal VCI response packet for ll tlb");
4457
4458        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4459        {
4460            r_vci_rsp_data_error = true;
4461        }
4462            else
4463            {
4464                r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
4465            }
4466        r_vci_rsp_data_ok = true;
4467        r_vci_rsp_fsm = RSP_IDLE;
4468            break;
4469
4470    case RSP_DTLB_ACC_SC:
4471        if ( ! p_vci_ini_rw.rspval.read() )
4472            break;
4473
4474        assert(p_vci_ini_rw.reop.read() &&
4475               "illegal VCI response packet for sc tlb");
4476
4477        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4478        {
4479            r_vci_rsp_data_error = true;
4480        }
4481            else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
4482            {
4483            r_dcache_tlb_sc_fail = true;
4484            }
4485        r_vci_rsp_data_ok = true;
4486        r_vci_rsp_fsm = RSP_IDLE;
4487            break;
4488
4489    case RSP_DTLB_DIRTY_LL:
4490        if ( ! p_vci_ini_rw.rspval.read() )
4491            break;
4492
4493        assert(p_vci_ini_rw.reop.read() &&
4494               "illegal VCI response packet for ll tlb");
4495
4496        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4497        {
4498            r_vci_rsp_data_error = true;
4499        }
4500            else
4501            {
4502                r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
4503            }
4504        r_vci_rsp_data_ok = true;
4505        r_vci_rsp_fsm = RSP_IDLE;
4506            break;
4507
4508    case RSP_DTLB_DIRTY_SC:
4509        if ( ! p_vci_ini_rw.rspval.read() )
4510            break;
4511
4512        assert(p_vci_ini_rw.reop.read() &&
4513               "illegal VCI response packet for sc tlb");
4514
4515        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4516        {
4517            r_vci_rsp_data_error = true;
4518        }
4519            else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
4520            {
4521            r_dcache_tlb_sc_fail = true;
4522            }
4523        r_vci_rsp_data_ok = true;
4524        r_vci_rsp_fsm = RSP_IDLE;
4525            break;
4526
4527    case RSP_DATA_UNC:
4528        m_cost_unc_transaction++;
4529        if ( ! p_vci_ini_rw.rspval.read() ) 
4530            break;
4531
4532        assert(p_vci_ini_rw.reop.read() &&
4533               "illegal VCI response packet for data read uncached");
4534
4535        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4536        {
4537            r_vci_rsp_data_error = true;
4538        }
4539        else
4540        {
4541            r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
4542            r_vci_rsp_data_ok = true;
4543        }
4544        r_vci_rsp_fsm = RSP_IDLE;
4545        break;
4546
4547    case RSP_DATA_MISS:
4548        m_cost_dmiss_transaction++;
4549        if ( ! p_vci_ini_rw.rspval.read() )
4550            break;
4551
4552        assert(r_vci_rsp_cpt != m_dcache_words &&
4553               "illegal VCI response packet for data read miss");
4554
4555        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
4556        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
4557        if ( p_vci_ini_rw.reop.read() ) 
4558        {
4559            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
4560                    "illegal VCI response packet for data read miss");
4561            r_vci_rsp_data_ok = true;
4562            r_vci_rsp_fsm = RSP_IDLE;
4563        } 
4564        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
4565        {
4566            r_vci_rsp_data_error = true;
4567        }
4568        break;
4569
4570    case RSP_DATA_WRITE:
4571        m_cost_write_transaction++;
4572        if ( ! p_vci_ini_rw.rspval.read() )
4573            break;
4574
4575        if ( p_vci_ini_rw.reop.read() ) 
4576        {
4577            r_vci_rsp_fsm = RSP_IDLE;
4578                r_wbuf.completed( p_vci_ini_rw.rtrdid.read() & 0x0f );           
4579        }
4580        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL ) 
4581        {
4582            m_iss.setWriteBerr();
4583        }
4584        break; 
4585    } // end switch r_vci_rsp_fsm
4586} // end transition()
4587
4588///////////////////////
4589tmpl(void)::genMoore()
4590///////////////////////
4591{
4592    switch ( r_cleanup_fsm.read() ) {
4593
4594    case CLEANUP_CMD:
4595            p_vci_ini_c.rspack  = false;
4596        p_vci_ini_c.cmdval  = r_icache_cleanup_req || r_dcache_cleanup_req;
4597        if ( r_icache_cleanup_req ) 
4598            {
4599                p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words<<2);
4600            if ( r_icache_cleanup_type == TLB_CLEANUP )
4601            {   
4602                p_vci_ini_c.trdid  = 3; // ins TLB cleanup
4603            }
4604            else
4605            {
4606                p_vci_ini_c.trdid  = 1; // ins cleanup       
4607            }               
4608            }
4609        else 
4610            {                                   
4611                p_vci_ini_c.address = r_dcache_cleanup_line.read() * (m_dcache_words<<2);
4612            if ( r_dcache_cleanup_type == TLB_CLEANUP )
4613            {   
4614                p_vci_ini_c.trdid  = 2; // data TLB cleanup
4615            }
4616            else
4617            {
4618                p_vci_ini_c.trdid  = 0; // data cleanup       
4619            }               
4620            }
4621        p_vci_ini_c.wdata  = 0;
4622        p_vci_ini_c.be     = 0xF;
4623        p_vci_ini_c.plen   = 4;
4624        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
4625        p_vci_ini_c.pktid  = 0;
4626        p_vci_ini_c.srcid  = m_srcid_c;
4627        p_vci_ini_c.cons   = false;
4628        p_vci_ini_c.wrap   = false;
4629        p_vci_ini_c.contig = false;
4630        p_vci_ini_c.clen   = 0;
4631        p_vci_ini_c.cfixed = false;
4632        p_vci_ini_c.eop = true;
4633        break;
4634
4635    case CLEANUP_ICACHE_RSP:
4636    case CLEANUP_DCACHE_RSP:
4637        p_vci_ini_c.rspack  = true;
4638        p_vci_ini_c.cmdval  = false;
4639        p_vci_ini_c.address = 0;
4640        p_vci_ini_c.wdata   = 0;
4641        p_vci_ini_c.be      = 0;
4642        p_vci_ini_c.plen    = 0;
4643        p_vci_ini_c.cmd     = vci_param::CMD_NOP;
4644        p_vci_ini_c.trdid   = 0;
4645        p_vci_ini_c.pktid   = 0;
4646        p_vci_ini_c.srcid   = m_srcid_c;
4647        p_vci_ini_c.cons    = false;
4648        p_vci_ini_c.wrap    = false;
4649        p_vci_ini_c.contig  = false;
4650        p_vci_ini_c.clen    = 0;
4651        p_vci_ini_c.cfixed  = false;
4652        p_vci_ini_c.eop     = false;
4653        break;
4654    } // end switch r_cleanup_fsm
4655
4656    // VCI initiator response
4657    p_vci_ini_rw.rspack = ( r_vci_rsp_fsm != RSP_IDLE );
4658
4659    // VCI initiator command
4660    p_vci_ini_rw.pktid  = 0;
4661    p_vci_ini_rw.srcid  = m_srcid_rw;
4662    p_vci_ini_rw.cons   = false;
4663    p_vci_ini_rw.wrap   = false;
4664    p_vci_ini_rw.contig = true;
4665    p_vci_ini_rw.clen   = 0;
4666    p_vci_ini_rw.cfixed = false;
4667   
4668    switch (r_vci_cmd_fsm) {
4669
4670    case CMD_IDLE:
4671        p_vci_ini_rw.cmdval  = false;
4672        p_vci_ini_rw.address = 0;
4673        p_vci_ini_rw.wdata   = 0;
4674        p_vci_ini_rw.be      = 0;
4675        p_vci_ini_rw.trdid   = 0;
4676        p_vci_ini_rw.plen    = 0;
4677        p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
4678        p_vci_ini_rw.eop     = false;
4679        break;
4680
4681    case CMD_ITLB_READ:     
4682        p_vci_ini_rw.cmdval  = true;
4683        p_vci_ini_rw.wdata   = 0;
4684        p_vci_ini_rw.be      = 0xF;
4685        if ( r_icache_tlb_first_req )
4686        { 
4687            p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
4688            p_vci_ini_rw.trdid = TYPE_INS_TLB_1; // ins TLB uncached read
4689            p_vci_ini_rw.plen  = 4;
4690        }
4691        else
4692        { 
4693            p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
4694            p_vci_ini_rw.trdid = TYPE_INS_TLB_2; // ins TLB cached read 2 words
4695            p_vci_ini_rw.plen  = 8; 
4696        }
4697        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
4698        p_vci_ini_rw.eop     = true;
4699        break;
4700
4701    case CMD_ITLB_ACC_LL:
4702        p_vci_ini_rw.cmdval  = true;
4703        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
4704        p_vci_ini_rw.wdata   = 0;
4705        p_vci_ini_rw.be      = 0xF;
4706        p_vci_ini_rw.trdid   = TYPE_INS_LL_ACC; // ins TLB uncached read
4707        p_vci_ini_rw.plen    = 4;
4708        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
4709        p_vci_ini_rw.eop     = true;
4710        break;
4711
4712    case CMD_ITLB_ACC_SC:
4713        p_vci_ini_rw.cmdval  = true;
4714        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
4715        p_vci_ini_rw.wdata   = r_icache_pte_update.read();
4716        p_vci_ini_rw.be      = 0xF;
4717        p_vci_ini_rw.trdid   = TYPE_INS_SC_ACC; // ins TLB uncached read
4718        p_vci_ini_rw.plen    = 4;
4719        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
4720        p_vci_ini_rw.eop     = true;
4721        break; 
4722
4723    case CMD_INS_MISS:
4724        p_vci_ini_rw.cmdval  = true;
4725        p_vci_ini_rw.address = r_icache_paddr_save.read() & m_icache_yzmask;
4726        p_vci_ini_rw.wdata   = 0;
4727        p_vci_ini_rw.be      = 0xF;
4728        p_vci_ini_rw.trdid   = TYPE_INS_MISS;
4729        p_vci_ini_rw.plen    = m_icache_words << 2;
4730        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
4731        p_vci_ini_rw.eop     = true;
4732        break;
4733
4734    case CMD_INS_UNC:
4735        p_vci_ini_rw.cmdval  = true;
4736        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
4737        p_vci_ini_rw.wdata   = 0;
4738        p_vci_ini_rw.be      = 0xF;
4739        p_vci_ini_rw.trdid   = TYPE_INS_UNC;
4740        p_vci_ini_rw.plen    = 4;
4741        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
4742        p_vci_ini_rw.eop     = true;
4743        break;
4744
4745    case CMD_DTLB_READ:     
4746        p_vci_ini_rw.cmdval  = true;
4747        p_vci_ini_rw.wdata   = 0;
4748        p_vci_ini_rw.be      = 0xF;
4749        if ( r_dcache_tlb_first_req ) 
4750        {
4751            p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
4752            p_vci_ini_rw.trdid = TYPE_DATA_TLB_1; // data TLB uncached read
4753            p_vci_ini_rw.plen  = 4;
4754        }
4755        else
4756        { 
4757            p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
4758            p_vci_ini_rw.trdid = TYPE_DATA_TLB_2; // data TLB cached read 2 words
4759            p_vci_ini_rw.plen  = 8; 
4760        }
4761        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
4762        p_vci_ini_rw.eop     = true;
4763        break;
4764
4765    case CMD_DTLB_ACC_LL:
4766        p_vci_ini_rw.cmdval  = true;
4767        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
4768        p_vci_ini_rw.wdata   = 0;
4769        p_vci_ini_rw.be      = 0xF;
4770        p_vci_ini_rw.trdid   = TYPE_DATA_LL_ACC; // data TLB uncached read
4771        p_vci_ini_rw.plen    = 4;
4772        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
4773        p_vci_ini_rw.eop     = true;
4774        break;
4775
4776    case CMD_DTLB_ACC_SC:
4777        p_vci_ini_rw.cmdval  = true;
4778        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
4779        p_vci_ini_rw.wdata   = r_dcache_pte_update.read();
4780        p_vci_ini_rw.be      = 0xF;
4781        p_vci_ini_rw.trdid   = TYPE_DATA_SC_ACC; // data TLB uncached read
4782        p_vci_ini_rw.plen    = 4;
4783        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
4784        p_vci_ini_rw.eop     = true;
4785        break; 
4786
4787    case CMD_DTLB_DIRTY_LL:
4788        p_vci_ini_rw.cmdval  = true;
4789        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
4790        p_vci_ini_rw.wdata   = 0;
4791        p_vci_ini_rw.be      = 0xF;
4792        p_vci_ini_rw.trdid   = TYPE_DATA_LL_D; // data TLB uncached read
4793        p_vci_ini_rw.plen    = 4;
4794        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
4795        p_vci_ini_rw.eop     = true;
4796        break;
4797
4798    case CMD_DTLB_DIRTY_SC:
4799        p_vci_ini_rw.cmdval  = true;
4800        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
4801        p_vci_ini_rw.wdata   = r_dcache_pte_update.read();
4802        p_vci_ini_rw.be      = 0xF;
4803        p_vci_ini_rw.trdid   = TYPE_DATA_SC_D; // data TLB uncached read
4804        p_vci_ini_rw.plen    = 4;
4805        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
4806        p_vci_ini_rw.eop     = true;
4807        break; 
4808
4809    case CMD_DATA_UNC:
4810        p_vci_ini_rw.cmdval  = true;
4811        p_vci_ini_rw.address = r_dcache_paddr_save.read() & ~0x3;
4812        p_vci_ini_rw.trdid   = TYPE_DATA_UNC;
4813        p_vci_ini_rw.plen    = 4;
4814        p_vci_ini_rw.eop     = true;
4815        switch(r_dcache_type_save) {
4816        case iss_t::DATA_READ:
4817            p_vci_ini_rw.wdata = 0;
4818            p_vci_ini_rw.be    = r_dcache_be_save.read();
4819            p_vci_ini_rw.cmd   = vci_param::CMD_READ;
4820            break;
4821        case iss_t::DATA_LL:
4822            p_vci_ini_rw.wdata = 0;
4823            p_vci_ini_rw.be    = 0xF;
4824            p_vci_ini_rw.cmd   = vci_param::CMD_LOCKED_READ;
4825            break;
4826        case iss_t::DATA_SC:
4827            p_vci_ini_rw.wdata = r_dcache_wdata_save.read();
4828            p_vci_ini_rw.be    = 0xF;
4829            p_vci_ini_rw.cmd   = vci_param::CMD_STORE_COND;
4830            break;
4831        default:
4832            assert("this should not happen");
4833        }
4834        break;
4835
4836    case CMD_DATA_WRITE:
4837        p_vci_ini_rw.cmdval  = true;
4838        p_vci_ini_rw.address = r_wbuf.getAddress(r_vci_cmd_cpt);
4839        p_vci_ini_rw.wdata   = r_wbuf.getData(r_vci_cmd_cpt);
4840        p_vci_ini_rw.be      = r_wbuf.getBe(r_vci_cmd_cpt);
4841        p_vci_ini_rw.trdid   = (r_wbuf.getIndex() | 0x30); // data cache write
4842        p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
4843        p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
4844        p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
4845        break;
4846
4847    case CMD_DATA_MISS:
4848        p_vci_ini_rw.cmdval  = true;
4849        p_vci_ini_rw.address = r_dcache_paddr_save.read() & m_dcache_yzmask;
4850        p_vci_ini_rw.wdata   = 0;
4851        p_vci_ini_rw.be      = 0xF;
4852        p_vci_ini_rw.trdid   = TYPE_DATA_MISS;
4853        p_vci_ini_rw.plen    = m_dcache_words << 2;
4854        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
4855        p_vci_ini_rw.eop     = true;
4856        break;
4857    } // end switch r_vci_cmd_fsm
4858
4859    // VCI_TGT
4860    switch ( r_vci_tgt_fsm.read() ) {
4861
4862    case TGT_IDLE:
4863    case TGT_UPDT_WORD:
4864    case TGT_UPDT_DATA:
4865        p_vci_tgt.cmdack  = true;
4866        p_vci_tgt.rspval  = false;
4867        break;
4868
4869    case TGT_RSP_BROADCAST:
4870        p_vci_tgt.cmdack  = false;
4871        p_vci_tgt.rspval  = !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() && 
4872                            ( r_tgt_icache_rsp | r_tgt_dcache_rsp | r_ccinval_itlb_cpt | r_ccinval_dtlb_cpt );
4873        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4874        p_vci_tgt.rpktid  = r_tgt_pktid.read();
4875        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4876        p_vci_tgt.rdata   = 0;
4877        p_vci_tgt.rerror  = 0;
4878        p_vci_tgt.reop    = true;
4879        break;
4880
4881    case TGT_RSP_ICACHE:
4882        p_vci_tgt.cmdack  = false;
4883        p_vci_tgt.rspval  = !r_tgt_icache_req.read() && r_tgt_icache_rsp.read();
4884        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4885        p_vci_tgt.rpktid  = r_tgt_pktid.read();
4886        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4887        p_vci_tgt.rdata   = 0;
4888        p_vci_tgt.rerror  = 0;
4889        p_vci_tgt.reop    = true;
4890        break;
4891
4892    case TGT_RSP_DCACHE:
4893        p_vci_tgt.cmdack  = false;
4894        p_vci_tgt.rspval  = !r_tgt_dcache_req.read() && r_tgt_dcache_rsp.read();
4895        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4896        p_vci_tgt.rpktid  = r_tgt_pktid.read();
4897        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4898        p_vci_tgt.rdata   = 0;
4899        p_vci_tgt.rerror  = 0;
4900        p_vci_tgt.reop    = true;
4901        break;
4902
4903    case TGT_REQ_BROADCAST:
4904    case TGT_REQ_ICACHE:
4905    case TGT_REQ_DCACHE:
4906        p_vci_tgt.cmdack  = false;
4907        p_vci_tgt.rspval  = false;
4908        break;
4909
4910    } // end switch TGT_FSM
4911
4912#ifdef SOCLIB_MODULE_DEBUG
4913   std::cout << name() 
4914             << "Moore:" << std::hex
4915             << "p_vci_ini_rw.cmdval:" << p_vci_ini_rw.cmdval
4916             << "p_vci_ini_rw.address:" << p_vci_ini_rw.address
4917             << "p_vci_ini_rw.wdata:" << p_vci_ini_rw.wdata
4918             << "p_vci_ini_rw.cmd:" << p_vci_ini_rw.cmd
4919             << "p_vci_ini_rw.eop:" << p_vci_ini_rw.eop
4920             << std::endl;
4921
4922   std::cout << name() 
4923             << "Moore:" << std::hex
4924             << "p_vci_ini_c.cmdval:" << p_vci_ini_c.cmdval
4925             << "p_vci_ini_c.address:" << p_vci_ini_c.address
4926             << "p_vci_ini_c.cmd:" << p_vci_ini_c.cmd
4927             << "p_vci_ini_c.eop:" << p_vci_ini_c.eop
4928             << std::endl;
4929
4930   std::cout << name() 
4931             << "Moore:" << std::hex
4932             << "p_vci_tgt.cmdack:" << p_vci_tgt.cmdack
4933             << "p_vci_tgt.rspval:" << p_vci_tgt.rspval
4934             << "p_vci_tgt.rsrcid:" << p_vci_tgt.rsrcid
4935             << "p_vci_tgt.rtrdid:" << p_vci_tgt.rtrdid
4936             << "p_vci_tgt.reop:" << p_vci_tgt.reop
4937             << std::endl;
4938
4939#endif
4940}
4941
4942}}
4943
4944// Local Variables:
4945// tab-width: 4
4946// c-basic-offset: 4
4947// c-file-offsets:((innamespace . 0)(inline-open . 0))
4948// indent-tabs-mode: nil
4949// End:
4950
4951// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
4952
4953
Note: See TracBrowser for help on using the repository browser.