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

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

Import TSAR modules in TSAR's own svn

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