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

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

Cleanup fsm seperated from vci fsm to evite deadlock

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