source: trunk/modules/vci_cc_vcache_wrapper_v1/caba/source/src/vci_cc_vcache_wrapper_v1.cpp @ 49

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

Activity counter update

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