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

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

Forgot the vci_cc_vcache_wrapper2_multi

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