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

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

Correction of dirty bit and access bit in data cache

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