source: trunk/modules/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp @ 48

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

Activity counter update

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