source: trunk/modules/vci_cc_vcache_wrapper2_multi/caba/source/src/vci_cc_vcache_wrapper2_multi.cpp @ 37

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

Bug correction

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