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

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

debug

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