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

Last change on this file since 73 was 73, checked in by bouyer, 14 years ago

Fix several issues regarding management of the r_dcache_in_itlb/r_dcache_in_dtlb
arrays:

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