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

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

Check/update the dirty bit on SC too

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