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

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

Delete the evaluation codes for speedup simulation

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