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

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

SC don't generate invalidations and cleanup any more, add treatment of coherence requests in blocking fsm states

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