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

Last change on this file since 139 was 139, checked in by gao, 13 years ago

Cleanup FSM changed

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