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

Last change on this file since 55 was 55, checked in by guthmull, 14 years ago

Fix a bug in SC, add start cycle debug

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