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

Last change on this file since 2 was 2, checked in by nipo, 14 years ago

Import TSAR modules in TSAR's own svn

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