source: trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp @ 259

Last change on this file since 259 was 259, checked in by almaless, 12 years ago

Introduce ALMOS used platforms for TSAR.
See the package's README file for more information.

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