source: trunk/modules/vci_cc_vcache_wrapper_v1/caba/source/src/vci_cc_vcache_wrapper_v1.cpp.backup @ 38

Last change on this file since 38 was 38, checked in by gao, 15 years ago

cc_vcache added

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