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

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

ICACHE_SW_FLUSH/ICACHE_CACHE_FLUSH: when walking the tlb/cache looking for
entries to be flushed, reset 'set' to 0 when processing the next way.
Without this only way 0 is processed, unless the last set of way 0 is
to be flushed.

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