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

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

Activity counter update

  • 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.5 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        m_cost_ins_tlb_sw_frz++;
1643
1644        // 4K page size TLB flush leads to cleanup req to data cache
1645        if ( !r_dcache_itlb_cleanup_req )    // last cleanup finish
1646        {
1647            paddr_t victim_index = 0;
1648            for ( ; way < m_itlb_ways; way++)
1649            {
1650                for ( ; set < m_itlb_sets; set++)
1651                {
1652                    if(icache_tlb.checkcleanup(way, set, &victim_index))
1653                    {
1654                        clean = true;
1655                        r_dcache_itlb_cleanup_req = true;
1656                        r_dcache_itlb_cleanup_line = victim_index;
1657                        r_icache_way = way + ((set+1)/m_itlb_sets);
1658                        r_icache_set = (set+1) % m_itlb_sets;
1659                        break;
1660                    }
1661                }
1662                if (clean) break;
1663            }
1664
1665            if (way == m_itlb_ways)
1666            {
1667                r_dcache_xtn_req = false;
1668                r_itlb_translation_valid = false;
1669                r_icache_ptba_ok = false;
1670                r_icache_fsm = ICACHE_IDLE;
1671                break;
1672            }
1673        }
1674        break;
1675    }
1676    /////////////////////
1677    case ICACHE_TLB_FLUSH:
1678    {   
1679        // data cache flush leads to ins tlb flush, flush all tlb entry
1680        icache_tlb.flush(true);    // global entries are invalidated
1681        r_dcache_xtn_req = false;
1682        r_itlb_translation_valid = false;
1683        r_icache_ptba_ok = false;
1684        r_icache_fsm = ICACHE_IDLE;
1685        break;
1686    }
1687    ////////////////////////
1688    case ICACHE_CACHE_FLUSH:
1689    {
1690        // external cache invalidate request
1691        if ( r_tgt_icache_req )
1692        {
1693            r_icache_fsm = ICACHE_CC_INVAL;
1694            r_icache_fsm_save = r_icache_fsm;
1695            break;
1696        }
1697
1698        size_t way = r_icache_way;
1699        size_t set = r_icache_set;
1700        bool clean = false;
1701
1702        // cache flush and send cleanup to external
1703        if ( !r_icache_cleanup_req )
1704        {
1705            paddr_t victim_index = 0;
1706            for ( ; way < m_icache_ways; way++ )
1707            {   
1708                for ( ; set < m_icache_sets; set++ )
1709                {   
1710                    if ( r_icache.flush(way, set, &victim_index) )
1711                    {
1712                        clean = true;
1713                        r_icache_cleanup_req = true;
1714                        r_icache_cleanup_line = victim_index;
1715                        m_cpt_cc_cleanup_ins++;
1716                        r_icache_way = way + ((set+1)/m_icache_sets);
1717                        r_icache_set = (set+1) % m_icache_sets;
1718                        break;
1719                    }
1720                }
1721                if (clean) break;
1722            }
1723            if (way == m_icache_ways)
1724            {
1725                r_dcache_xtn_req = false;
1726                r_icache_fsm = ICACHE_IDLE;
1727                break;
1728            }
1729        }
1730        break;
1731    }
1732    /////////////////////
1733    case ICACHE_TLB_INVAL: 
1734    {
1735        paddr_t victim_index = 0;
1736
1737        if ( !r_dcache_itlb_cleanup_req )
1738        {
1739            r_dcache_itlb_cleanup_req = icache_tlb.inval(r_dcache_wdata_save, &victim_index);
1740            r_dcache_itlb_cleanup_line = victim_index;
1741            m_cpt_cc_cleanup_ins++;
1742            r_dcache_xtn_req = false;
1743            r_itlb_translation_valid = false;
1744            r_icache_ptba_ok = false;
1745            r_icache_fsm = ICACHE_IDLE;
1746        }
1747        break;
1748    }
1749    ////////////////////////
1750    case ICACHE_CACHE_INVAL:
1751    {   
1752        // external cache invalidate request
1753        if ( r_tgt_icache_req )
1754        {
1755            r_icache_fsm = ICACHE_CC_INVAL;
1756            r_icache_fsm_save = r_icache_fsm;
1757            break;
1758        }
1759
1760        paddr_t ipaddr = 0;                     
1761        bool    icache_hit_t = false;
1762
1763        if ( !r_icache_cleanup_req )
1764        {   
1765            if ( r_mmu_mode.read() & INS_TLB_MASK )
1766            {
1767                icache_hit_t = icache_tlb.translate(r_dcache_wdata_save, &ipaddr);
1768            }
1769            else
1770            {
1771                ipaddr = (paddr_t)r_dcache_wdata_save;
1772                icache_hit_t = true;
1773            }
1774            if ( icache_hit_t )
1775            {
1776                // invalidate and cleanup if necessary
1777                r_icache_cleanup_req = r_icache.inval(ipaddr);
1778                r_icache_cleanup_line = ipaddr >> (uint32_log2(m_icache_words) + 2); 
1779                m_cpt_cc_cleanup_ins++;
1780            }
1781            r_dcache_xtn_req = false;
1782            r_icache_fsm = ICACHE_IDLE;
1783        }
1784        break;
1785    }
1786    ////////////////////////
1787    case ICACHE_CACHE_INVAL_PA:
1788    {
1789        // external cache invalidate request
1790        if ( r_tgt_icache_req )
1791        {
1792            r_icache_fsm = ICACHE_CC_INVAL;
1793            r_icache_fsm_save = r_icache_fsm;
1794            break;
1795        }
1796       
1797        paddr_t ipaddr = (paddr_t)r_mmu_word_hi.read() << 32 | r_mmu_word_lo.read();
1798
1799        if ( !r_icache_cleanup_req )
1800        {   
1801            // invalidate and cleanup if necessary
1802            r_icache_cleanup_req = r_icache.inval(ipaddr);
1803            r_icache_cleanup_line = ipaddr >> (uint32_log2(m_icache_words) + 2); 
1804            m_cpt_cc_cleanup_ins++;
1805            r_dcache_xtn_req = false;
1806            r_icache_fsm = ICACHE_IDLE;
1807        }
1808        break;
1809    }
1810    ///////////////////////
1811    case ICACHE_MISS_WAIT:
1812    {
1813        m_cost_ins_miss_frz++;
1814
1815        // external cache invalidate request
1816        if ( r_tgt_icache_req )     
1817        {
1818            r_icache_fsm = ICACHE_CC_INVAL;
1819            r_icache_fsm_save = r_icache_fsm;
1820            break;
1821        }
1822
1823        // external tlb invalidate request
1824        if ( r_dcache_itlb_inval_req )
1825        {
1826            r_itlb_inval_req = true;
1827            r_icache_fsm = ICACHE_TLB_CC_INVAL;
1828            r_icache_fsm_save = r_icache_fsm;
1829            break;
1830        }
1831       
1832        if ( !r_icache_miss_req )
1833        {
1834            if ( r_vci_rsp_ins_error )
1835            {
1836                r_icache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS;
1837                r_icache_bad_vaddr = ireq.addr;
1838                r_icache_fsm = ICACHE_ERROR;
1839
1840                if ( r_icache_inval_tlb_rsp ) r_icache_inval_tlb_rsp = false;
1841                if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1842                break;
1843            }
1844
1845            if ( r_icache_inval_tlb_rsp ) // Miss read response and tlb invalidation
1846            {
1847                if ( r_icache_cleanup_req ) break;
1848                r_icache_cleanup_req = true;
1849                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2);
1850                m_cpt_cc_cleanup_ins++;
1851                r_icache_fsm = ICACHE_IDLE;
1852                r_icache_inval_tlb_rsp = false;
1853                if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1854                break;
1855            }
1856       
1857            if ( r_icache_inval_rsp ) // Miss read response and tlb invalidation
1858            {
1859                if ( r_icache_cleanup_req ) break;
1860                r_icache_cleanup_req = true;
1861                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
1862                m_cpt_cc_cleanup_ins++;
1863                r_icache_fsm = ICACHE_IDLE;
1864                r_icache_inval_rsp = false;
1865                break;
1866            }
1867            r_icache_fsm = ICACHE_MISS_UPDT; 
1868        }       
1869        break;
1870    }
1871    ////////////////////
1872    case ICACHE_UNC_WAIT:
1873    {
1874        // external cache invalidate request
1875        if ( r_tgt_icache_req )
1876        {
1877            r_icache_fsm = ICACHE_CC_INVAL;
1878            r_icache_fsm_save = r_icache_fsm;
1879            break;
1880        }
1881
1882        // external tlb invalidate request
1883        if ( r_dcache_itlb_inval_req )
1884        {
1885            r_itlb_inval_req = true;
1886            r_icache_fsm = ICACHE_TLB_CC_INVAL;
1887            r_icache_fsm_save = r_icache_fsm;
1888            break;
1889        }
1890
1891        if ( !r_icache_unc_req )
1892        {
1893            if ( r_vci_rsp_ins_error )
1894            {
1895                r_icache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS;   
1896                r_icache_bad_vaddr = ireq.addr;
1897                r_icache_fsm = ICACHE_ERROR;
1898
1899                if ( r_icache_inval_tlb_rsp ) r_icache_inval_tlb_rsp = false;
1900                //if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1901                break;
1902            }
1903
1904            if ( r_icache_inval_tlb_rsp ) // Miss read response and tlb invalidation
1905            {
1906                r_icache_inval_tlb_rsp = false;
1907                r_icache_fsm = ICACHE_IDLE;
1908                break;
1909            }
1910
1911            // Miss read response and no invalidation
1912            r_icache_buf_unc_valid = true;
1913            r_icache_fsm = ICACHE_IDLE;
1914        }       
1915        break;
1916    }
1917    //////////////////////
1918    case ICACHE_MISS_UPDT:
1919    {
1920        m_cost_ins_miss_frz++;
1921
1922        // external cache invalidate request
1923        if ( r_tgt_icache_req )   
1924        {
1925            r_icache_fsm = ICACHE_CC_INVAL;
1926            r_icache_fsm_save = r_icache_fsm;
1927            break;
1928        }
1929
1930        // external tlb invalidate request
1931        if ( r_dcache_itlb_inval_req )
1932        {
1933            r_itlb_inval_req = true;
1934            r_icache_fsm = ICACHE_TLB_CC_INVAL;
1935            r_icache_fsm_save = r_icache_fsm;
1936            break;
1937        }
1938
1939        if ( r_icache_inval_tlb_rsp ) // tlb invalidation
1940        {
1941            if ( r_icache_cleanup_req ) break;
1942            r_icache_cleanup_req = true;
1943            r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2);
1944            m_cpt_cc_cleanup_ins++;
1945            r_icache_inval_tlb_rsp = false;
1946            if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
1947            r_icache_fsm = ICACHE_IDLE;
1948            break;
1949        }
1950
1951        if ( !r_icache_cleanup_req ) // Miss update and no invalidation
1952        {
1953            if ( r_icache_inval_rsp ) // invalidation
1954            {
1955                r_icache_cleanup_req = true;
1956                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2);
1957                m_cpt_cc_cleanup_ins++;
1958                r_icache_fsm = ICACHE_IDLE;
1959                r_icache_inval_rsp = false;
1960            }
1961            else
1962            {
1963                data_t* buf = r_icache_miss_buf;
1964                paddr_t  victim_index = 0;
1965                m_cpt_icache_dir_write++;
1966                m_cpt_icache_data_write++;
1967
1968                r_icache_cleanup_req = r_icache.update(r_icache_paddr_save.read(), buf, &victim_index);
1969                r_icache_cleanup_line = victim_index;                        m_cpt_cc_cleanup_ins++;
1970                r_icache_fsm = ICACHE_IDLE;
1971            }
1972        }
1973        break;
1974    }
1975    ///////////////////
1976    case ICACHE_ERROR:
1977    {
1978        r_vci_rsp_ins_error = false;
1979        r_dcache_rsp_itlb_error = false;
1980        irsp.valid = true;
1981        irsp.error = true;
1982        irsp.instruction = 0;
1983        r_icache_fsm = ICACHE_IDLE;
1984        break;
1985    }
1986    /////////////////////
1987    case ICACHE_CC_INVAL: 
1988    {                       
1989        m_cpt_icache_dir_read += m_icache_ways;
1990        /* activity counter */
1991        if ( (( r_icache_fsm_save == ICACHE_BIS ) ||( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) ) && ( ireq.valid ) )       
1992        {
1993            m_cost_ins_miss_frz++;
1994        }
1995        if( (( r_icache_fsm_save == ICACHE_TLB1_READ )   || ( r_icache_fsm_save == ICACHE_TLB2_READ )    ||
1996             ( r_icache_fsm_save == ICACHE_TLB1_WRITE )  || ( r_icache_fsm_save == ICACHE_TLB2_WRITE ) ||
1997             ( r_icache_fsm_save == ICACHE_TLB1_UPDT )   || ( r_icache_fsm_save == ICACHE_TLB2_UPDT ))   && (ireq.valid) )
1998        {
1999            m_cost_ins_tlb_miss_frz++;
2000        }
2001
2002        // invalidate cache
2003        if( (( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) /*||
2004             ( r_icache_fsm_save == ICACHE_UNC_WAIT )*/ ) &&
2005            ((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_icache_words<<2)-1))) )
2006        {
2007            r_icache_inval_rsp = true;
2008            r_tgt_icache_rsp = false;
2009        }
2010        else
2011        {
2012            r_tgt_icache_rsp = r_icache.inval(r_tgt_addr.read());
2013        }
2014        r_tgt_icache_req = false;
2015        r_icache_fsm = r_icache_fsm_save;
2016        break;
2017    }
2018    /////////////////////////
2019    case ICACHE_TLB_CC_INVAL:
2020    {
2021        /* activity counter */
2022        if ( (( r_icache_fsm_save == ICACHE_BIS ) ||( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) ) && ( ireq.valid ) )       
2023        {
2024            m_cost_ins_miss_frz++;
2025        }
2026        if( (( r_icache_fsm_save == ICACHE_TLB1_READ )   || ( r_icache_fsm_save == ICACHE_TLB2_READ )    ||
2027             ( r_icache_fsm_save == ICACHE_TLB1_WRITE )  || ( r_icache_fsm_save == ICACHE_TLB2_WRITE ) ||
2028             ( r_icache_fsm_save == ICACHE_TLB1_UPDT )   || ( r_icache_fsm_save == ICACHE_TLB2_UPDT ))   && (ireq.valid) )
2029        {
2030            m_cost_ins_tlb_miss_frz++;
2031        }
2032
2033        if ( r_itlb_inval_req ) break;
2034        // invalidate cache
2035        if( (( r_icache_fsm_save == ICACHE_TLB1_READ ) || ( r_icache_fsm_save == ICACHE_TLB2_READ )  ||
2036          /* ( r_icache_fsm_save == ICACHE_TLB1_WRITE )|| ( r_icache_fsm_save == ICACHE_TLB2_WRITE ) ||*/
2037             ( r_icache_fsm_save == ICACHE_TLB1_UPDT ) || ( r_icache_fsm_save == ICACHE_TLB2_UPDT )) &&
2038            (((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) >> (uint32_log2(m_icache_words) + 2) ) == r_dcache_itlb_inval_line.read()) )
2039        {
2040            r_icache_inval_tlb_rsp = true;
2041        }
2042        else if (((r_icache_fsm_save == ICACHE_BIS)||(r_icache_fsm_save == ICACHE_MISS_WAIT) ||
2043               /* (r_icache_fsm_save == ICACHE_UNC_WAIT)||*/(r_icache_fsm_save == ICACHE_MISS_UPDT)) &&
2044                (r_icache_tlb_nline.read() == r_dcache_itlb_inval_line.read()))
2045        {
2046            r_icache_inval_tlb_rsp = true;
2047        }
2048        r_dcache_itlb_inval_req = false;
2049        r_itlb_translation_valid = false;
2050        r_icache_ptba_ok = false;
2051        r_icache_fsm = r_icache_fsm_save;
2052        break;
2053    }
2054    } // end switch r_icache_fsm
2055
2056#ifdef SOCLIB_MODULE_DEBUG
2057    std::cout << name() << " Instruction Response: " << irsp << std::endl;
2058#endif
2059
2060    ////////////////////////////////////////////////////////////////////////////////////
2061    //      INVAL ITLB CHECK FSM
2062    ////////////////////////////////////////////////////////////////////////////////////////
2063    switch(r_inval_itlb_fsm) {
2064    /////////////////////
2065    case INVAL_ITLB_IDLE:
2066    {
2067        if ( r_itlb_inval_req )
2068        {
2069            r_ccinval_itlb_way = 0;
2070            r_ccinval_itlb_set = 0;
2071            r_inval_itlb_fsm = INVAL_ITLB_CHECK;   
2072            m_cost_ins_tlb_inval_frz++;
2073        }   
2074        break;
2075    }
2076    ////////////////////////////
2077    case INVAL_ITLB_CHECK:
2078    {
2079        m_cost_ins_tlb_inval_frz++;
2080
2081        size_t way = r_ccinval_itlb_way;
2082        size_t set = r_ccinval_itlb_set;
2083        bool end = false;       
2084        bool tlb_hit = icache_tlb.cccheck(r_dcache_itlb_inval_line.read(), way, set, &way, &set, &end);
2085   
2086        if ( tlb_hit )
2087        {
2088            r_ccinval_itlb_way = way;
2089            r_ccinval_itlb_set = set;
2090            r_itlb_cc_check_end = end;
2091            r_inval_itlb_fsm = INVAL_ITLB_INVAL;
2092            m_cpt_ins_tlb_inval++;   
2093        }       
2094        else
2095        {
2096            r_inval_itlb_fsm = INVAL_ITLB_CLEAR;   
2097        }
2098        break;
2099    }
2100    /////////////////////////
2101    case INVAL_ITLB_INVAL:
2102    {
2103        m_cost_ins_tlb_inval_frz++;
2104 
2105        icache_tlb.ccinval(r_ccinval_itlb_way, r_ccinval_itlb_set);
2106
2107        if ( !r_itlb_cc_check_end )
2108        {
2109            r_inval_itlb_fsm = INVAL_ITLB_CHECK;
2110        }
2111        else
2112        {
2113            r_inval_itlb_fsm = INVAL_ITLB_CLEAR;   
2114        }
2115        break;
2116    }
2117    ////////////////////
2118    case INVAL_ITLB_CLEAR:
2119    {
2120        r_itlb_inval_req = false;
2121        r_itlb_cc_check_end = false;
2122        r_ccinval_itlb_way = 0;
2123        r_ccinval_itlb_set = 0;
2124        r_inval_itlb_fsm = INVAL_ITLB_IDLE;   
2125        m_cost_ins_tlb_inval_frz++;
2126        break;
2127    }
2128    } // end switch r_inval_itlb_fsm
2129
2130    ////////////////////////////////////////////////////////////////////////////////////
2131    //      DCACHE FSM
2132    //
2133    // Both the Cacheability Table, and the MMU cached bit are used to define
2134    // the cacheability.
2135    //
2136    // There is 14 mutually exclusive conditions to exit the IDLE state.
2137    // Seven configurations corresponding to an XTN request from processor:
2138    // - Context switch => CTXT_SWITCH state
2139    // - Flush dcache => DCACHE_FLUSH state
2140    // - Flush icache => ICACHE_FLUSH state
2141    // - Invalidate a dtlb entry => DTLB_INVAL state
2142    // - Invalidate a itlb entry => ITLB_INVAL state
2143    // - Invalidate a dcache line => DCACHE_INVAL state
2144    // - Invalidate a icache line => ICACHE_INVAL state
2145    // Seven configurations corresponding to various read miss or write requests:
2146    // - TLB miss(in case hit_p miss) => TLB1_READ state
2147    // - TLB miss(in case hit_p hit) => TLB2_READ state
2148    // - Hit in TLB but VPN changed => BIS state
2149    // - Cached read miss => MISS_REQ state
2150    // - Uncache read miss => UNC_REQ state
2151    // - Write hit => WRITE_UPDT state
2152    // - Write miss => WRITE_REQ
2153    //
2154    // The r_vci_rsp_data_error flip-flop is set by the VCI_RSP controller and reset
2155    // by DCACHE-FSM when its state is in DCACHE_ERROR.
2156    //---------------------------------------------------------------------
2157    // Data TLB:
2158    // 
2159    // - int        ET          (00: unmapped; 01: unused or PTD)
2160    //                          (10: PTE new;  11: PTE old      )
2161    // - bool       cachable    (cached bit)
2162    // - bool       writable    (writable bit)
2163    // - bool       executable  (** not used alwayse false)
2164    // - bool       user        (access in user mode allowed)
2165    // - bool       global      (PTE not invalidated by a TLB flush)
2166    // - bool       dirty       (page has been modified)
2167    // - uint32_t   vpn         (virtual page number)
2168    // - uint32_t   ppn         (physical page number)
2169    ////////////////////////////////////////////////////////////////////////////////////////
2170
2171    switch (r_dcache_fsm) {
2172    //////////////////////
2173    case DCACHE_WRITE_REQ:
2174    {
2175        // external cache invalidate request
2176        if ( r_tgt_dcache_req )
2177        {
2178            r_dcache_fsm = DCACHE_CC_CHECK;
2179            r_dcache_fsm_save = r_dcache_fsm;
2180            break;
2181        }
2182
2183        // try to post the write request in the write buffer
2184        if ( !r_dcache_write_req )     // no previous write transaction     
2185        {
2186            if ( r_wbuf.wok(r_dcache_paddr_save) )   // write request in the same cache line
2187            {   
2188                r_wbuf.write(r_dcache_paddr_save.read(), r_dcache_be_save.read(), r_dcache_wdata_save);
2189                // closing the write packet if uncached
2190                if ( !r_dcache_cached_save )
2191                {
2192                    r_dcache_write_req = true;
2193                }
2194            }
2195            else
2196            {    // close the write packet if write request not in the same cache line
2197                r_dcache_write_req = true;
2198                m_cost_write_frz++;
2199                break;  //  posting not possible : stay in DCACHE_WRITEREQ state
2200            }
2201        }
2202        else     //  previous write transaction not completed
2203        {
2204            m_cost_write_frz++;
2205            break;  //  posting not possible : stay in DCACHE_WRITEREQ state
2206        }
2207
2208        // close the write packet if the next processor request is not a write
2209        if ( !dreq.valid || (dreq.type != iss_t::DATA_WRITE))
2210        {
2211            r_dcache_write_req = true;
2212        }
2213       
2214        // The next state and the processor request parameters are computed
2215        // as in the DCACHE_IDLE state (see below ...)
2216    }
2217    /////////////////
2218    case DCACHE_IDLE:
2219    {
2220        // external cache invalidate request
2221        if ( r_tgt_dcache_req )   
2222        {
2223            r_dcache_fsm = DCACHE_CC_CHECK;
2224            r_dcache_fsm_save = DCACHE_IDLE;
2225            break;
2226        }       
2227
2228        // ins tlb cleanup
2229        if ( r_dcache_itlb_cleanup_req )
2230        {
2231            r_dcache_fsm = DCACHE_ITLB_CLEANUP;
2232            break;
2233        }   
2234        // ins tlb miss
2235        if ( r_itlb_read_dcache_req )
2236        {
2237            if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++;         
2238            data_t rsp_itlb_miss;
2239            data_t rsp_itlb_ppn;
2240
2241            bool itlb_hit_dcache = r_dcache.read(r_icache_paddr_save, &rsp_itlb_miss);
2242            if ( r_itlb_k_read_dcache && itlb_hit_dcache )
2243            {   
2244                r_itlb_k_read_dcache = false;
2245                bool itlb_hit_ppn = r_dcache.read(r_icache_paddr_save.read()+4, &rsp_itlb_ppn);
2246                assert(itlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
2247            }
2248
2249            m_cpt_dcache_data_read += m_dcache_ways;
2250            m_cpt_dcache_dir_read += m_dcache_ways;
2251
2252            if ( itlb_hit_dcache )  // ins TLB request hits in data cache
2253            {
2254                if (!((rsp_itlb_miss & PTE_T_MASK ) >> PTE_T_SHIFT)) m_cpt_ins_tlb_hit_dcache++;                   
2255                r_dcache_rsp_itlb_miss = rsp_itlb_miss;
2256                r_dcache_rsp_itlb_ppn = rsp_itlb_ppn;
2257                r_itlb_read_dcache_req = false;
2258                r_dcache_fsm = DCACHE_IDLE;
2259               
2260                // set TLB bit if it's a PTE
2261                if ( !((rsp_itlb_miss & PTE_T_MASK ) >> PTE_T_SHIFT) )
2262                {
2263                    r_dcache.setinbit(r_icache_paddr_save, r_dcache_in_itlb, true);
2264                }
2265            }
2266            else                    // ins TLB request miss in data cache
2267            {
2268                r_dcache_itlb_read_req = true;
2269                r_dcache_fsm = DCACHE_ITLB_READ;
2270            }
2271        }
2272        else if ( r_itlb_acc_dcache_req ) // ins tlb write access bit
2273        {
2274            bool write_hit = r_dcache.write(r_icache_paddr_save, r_icache_pte_update);
2275            assert(write_hit && "Write on miss ignores data");
2276            r_dcache_itlb_ll_acc_req = true;
2277            r_dcache_fsm = DCACHE_ITLB_LL_WAIT;         
2278            m_cpt_dcache_data_write++;     
2279        }
2280        else if (dreq.valid)
2281        {
2282            pte_info_t  dcache_pte_info;
2283            int         xtn_opcod        = (int)dreq.addr/4;
2284            paddr_t     tlb_dpaddr       = 0;        // physical address obtained from TLB
2285            paddr_t     spc_dpaddr       = 0;        // physical adress obtained from PPN_save (speculative)
2286            bool        dcache_hit_t     = false;    // hit on 4Kilo TLB
2287            bool        dcache_hit_x     = false;    // VPN unmodified (can use spc_dpaddr)
2288            bool        dcache_hit_p     = false;    // PTP unmodified (can skip first level page table walk)
2289            bool        dcache_hit_c     = false;    // Cache hit
2290            bool        dcache_cached    = false;    // cacheable access (read or write)
2291            size_t      dcache_tlb_way   = 0;        // selected way (in case of cache hit)
2292            size_t      dcache_tlb_set   = 0;        // selected set (Y field in address)
2293            data_t      dcache_rdata     = 0;        // read data
2294            paddr_t     dcache_tlb_nline = 0;       // TLB NLINE
2295
2296            m_cpt_dcache_data_read += m_dcache_ways;
2297            m_cpt_dcache_dir_read += m_dcache_ways;
2298
2299            // Decoding READ XTN requests from processor
2300            // They are executed in this DCACHE_IDLE state
2301
2302            if (dreq.type == iss_t::XTN_READ)
2303            {
2304                switch(xtn_opcod) {
2305                case iss_t::XTN_INS_ERROR_TYPE:
2306                    drsp.rdata = (uint32_t)r_icache_error_type;
2307                    r_icache_error_type = MMU_NONE;
2308                    drsp.valid = true;
2309                    drsp.error = false;
2310                    break;
2311                case iss_t::XTN_DATA_ERROR_TYPE:
2312                    drsp.rdata = (uint32_t)r_dcache_error_type;
2313                    r_dcache_error_type = MMU_NONE;
2314                    drsp.valid = true;
2315                    drsp.error = false;
2316                    break;
2317                case iss_t::XTN_INS_BAD_VADDR:
2318                    drsp.rdata = (uint32_t)r_icache_bad_vaddr;       
2319                    drsp.valid = true;
2320                    drsp.error = false;
2321                    break;
2322                case iss_t::XTN_DATA_BAD_VADDR:
2323                    drsp.rdata = (uint32_t)r_dcache_bad_vaddr;       
2324                    drsp.valid = true;
2325                    drsp.error = false;
2326                    break;
2327                case iss_t::XTN_PTPR:
2328                    drsp.rdata = (uint32_t)r_mmu_ptpr;
2329                    drsp.valid = true;
2330                    drsp.error = false;
2331                    break;
2332                case iss_t::XTN_TLB_MODE:
2333                    drsp.rdata = (uint32_t)r_mmu_mode;
2334                    drsp.valid = true;
2335                    drsp.error = false;
2336                    break;
2337                case iss_t::XTN_MMU_PARAMS:
2338                    drsp.rdata = (uint32_t)r_mmu_params;
2339                    drsp.valid = true;
2340                    drsp.error = false;
2341                    break;
2342                case iss_t::XTN_MMU_RELEASE:
2343                    drsp.rdata = (uint32_t)r_mmu_release;
2344                    drsp.valid = true;
2345                    drsp.error = false;
2346                    break;
2347                case iss_t::XTN_MMU_WORD_LO:
2348                    drsp.rdata = (uint32_t)r_mmu_word_lo;
2349                    drsp.valid = true;
2350                    drsp.error = false;
2351                    break;
2352                case iss_t::XTN_MMU_WORD_HI:
2353                    drsp.rdata = (uint32_t)r_mmu_word_hi;
2354                    drsp.valid = true;
2355                    drsp.error = false;
2356                    break;
2357                default:
2358                    r_dcache_error_type = MMU_READ_UNDEFINED_XTN;
2359                    r_dcache_bad_vaddr  = dreq.addr;
2360                    drsp.valid = true;
2361                    drsp.error = true;
2362                    break;
2363                }
2364                r_dcache_fsm = DCACHE_IDLE;
2365                break;
2366            }
2367
2368            // Decoding WRITE XTN requests from processor
2369            // If there is no privilege violation, they are not executed in this DCACHE_IDLE state,
2370            // but in the next state, because they generally require access to the caches or the TLBs
2371
2372            if (dreq.type == iss_t::XTN_WRITE)
2373            {
2374                drsp.valid = false;
2375                drsp.error = false;
2376                drsp.rdata = 0;
2377                r_dcache_wdata_save = dreq.wdata;   
2378                switch(xtn_opcod) {     
2379
2380                case iss_t::XTN_PTPR:       // context switch : checking the kernel mode
2381                                            // both instruction & data TLBs must be flushed
2382                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL))
2383                    {
2384                        r_mmu_ptpr = dreq.wdata;
2385                        r_icache_error_type = MMU_NONE;
2386                        r_dcache_error_type = MMU_NONE;
2387                        r_dcache_type_save = dreq.addr/4;
2388                        r_dcache_xtn_req = true;
2389                        r_dcache_fsm = DCACHE_CTXT_SWITCH;
2390                    }
2391                    else
2392                    {
2393                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2394                        r_dcache_bad_vaddr  = dreq.addr;
2395                        drsp.valid = true;
2396                        drsp.error = true;
2397                        r_dcache_fsm = DCACHE_IDLE;
2398                    }
2399                    break;
2400
2401                case iss_t::XTN_TLB_MODE:     // modifying TLBs mode : checking the kernel mode
2402                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL))
2403                    {
2404                        r_mmu_mode = (int)dreq.wdata;
2405                        drsp.valid = true;
2406                    }
2407                    else
2408                    {
2409                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2410                        r_dcache_bad_vaddr  = dreq.addr;
2411                        drsp.valid = true;
2412                        drsp.error = true;
2413                    }
2414                    r_dcache_fsm = DCACHE_IDLE;
2415                    break;
2416
2417                case iss_t::XTN_DTLB_INVAL:     //  checking the kernel mode
2418                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL))
2419                    {
2420                        r_dcache_fsm = DCACHE_DTLB_INVAL; 
2421                    }
2422                    else
2423                    {
2424                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2425                        r_dcache_bad_vaddr  = dreq.addr;
2426                        drsp.valid = true;
2427                        drsp.error = true;
2428                        r_dcache_fsm = DCACHE_IDLE;
2429                    }
2430                    break;
2431
2432                case iss_t::XTN_ITLB_INVAL:     //  checking the kernel mode
2433                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL))
2434                    {
2435                        r_dcache_xtn_req = true;
2436                        r_dcache_type_save = dreq.addr/4;
2437                        r_dcache_fsm = DCACHE_ITLB_INVAL; 
2438                    }
2439                    else
2440                    {
2441                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2442                        r_dcache_bad_vaddr  = dreq.addr;
2443                        drsp.valid = true;
2444                        drsp.error = true;
2445                        r_dcache_fsm = DCACHE_IDLE;
2446                    }
2447                    break;
2448
2449                case iss_t::XTN_DCACHE_INVAL:   // cache inval can be executed in user mode.
2450                    r_dcache_fsm = DCACHE_DCACHE_INVAL;
2451                    break;
2452
2453                case iss_t::XTN_MMU_DCACHE_PA_INV:   // cache inval can be executed in user mode.
2454                    r_dcache_fsm = DCACHE_DCACHE_INVAL_PA;
2455                    break;
2456
2457                case iss_t::XTN_DCACHE_FLUSH:   // cache flush can be executed in user mode.
2458                    r_dcache_type_save = dreq.addr/4;
2459                    r_dcache_xtn_req = true;
2460                    r_dcache_way = 0;
2461                    r_dcache_set = 0;
2462                    r_dcache_fsm = DCACHE_DCACHE_FLUSH;
2463                    break;
2464
2465                case iss_t::XTN_ICACHE_INVAL:   // cache inval can be executed in user mode.
2466                    r_dcache_type_save = dreq.addr/4;
2467                    r_dcache_xtn_req = true;
2468                    r_dcache_fsm = DCACHE_ICACHE_INVAL;
2469                    break;
2470
2471                case iss_t::XTN_MMU_ICACHE_PA_INV:   // cache inval can be executed in user mode.
2472                    r_dcache_type_save = dreq.addr/4;
2473                    r_dcache_xtn_req = true;
2474                    r_dcache_fsm = DCACHE_ICACHE_INVAL_PA;
2475                    break;
2476
2477                case iss_t::XTN_ICACHE_FLUSH:   // cache flush can be executed in user mode.
2478                    r_dcache_type_save = dreq.addr/4;
2479                    r_dcache_xtn_req = true;
2480                    r_dcache_fsm = DCACHE_ICACHE_FLUSH;
2481                    break;
2482
2483                case iss_t::XTN_SYNC:           // cache synchronization can be executed in user mode.
2484                    if (r_wbuf.rok())
2485                    {
2486                        r_dcache_fsm = DCACHE_DCACHE_SYNC;
2487                    }
2488                    else
2489                    {
2490                        drsp.valid = true;
2491                        r_dcache_fsm = DCACHE_IDLE;
2492                    }
2493                    break;
2494
2495                case iss_t::XTN_MMU_WORD_LO: // modifying MMU misc registers
2496                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL))
2497                    {
2498                        r_mmu_word_lo = (int)dreq.wdata;
2499                        drsp.valid = true;
2500                    }
2501                    else
2502                    {
2503                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2504                        r_dcache_bad_vaddr  = dreq.addr;
2505                        drsp.valid = true;
2506                        drsp.error = true;
2507                    }
2508                    r_dcache_fsm = DCACHE_IDLE;
2509                    break;
2510
2511                case iss_t::XTN_MMU_WORD_HI: // modifying MMU misc registers
2512                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL))
2513                    {
2514                        r_mmu_word_hi = (int)dreq.wdata;
2515                        drsp.valid = true;
2516                    }
2517                    else
2518                    {
2519                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2520                        r_dcache_bad_vaddr  = dreq.addr;
2521                        drsp.valid = true;
2522                        drsp.error = true;
2523                    }
2524                    r_dcache_fsm = DCACHE_IDLE;
2525                    break;
2526
2527                  case iss_t::XTN_ICACHE_PREFETCH:
2528                  case iss_t::XTN_DCACHE_PREFETCH:
2529                    drsp.valid = true;
2530                    drsp.error = false;
2531                    break;
2532       
2533                default:
2534                    r_dcache_error_type = MMU_WRITE_UNDEFINED_XTN;
2535                    r_dcache_bad_vaddr  = dreq.addr;
2536                    drsp.valid = true;
2537                    drsp.error = true;
2538                    r_dcache_fsm = DCACHE_IDLE;
2539                    break;
2540                } // end switch xtn_opcod
2541
2542                break;
2543            } // end if XTN_WRITE
2544
2545            // Evaluating dcache_hit_t, dcache_hit_x, dcache_hit_p, dcache_hit_c,
2546            // dcache_pte_info, dcache_tlb_way, dcache_tlb_set & dpaddr & cacheability
2547            // - If MMU activated : cacheability is defined by the cachable bit in the TLB
2548            // - If MMU not activated : cacheability is defined by the segment table.
2549
2550            if ( !(r_mmu_mode.read() & DATA_TLB_MASK) ) // MMU not activated
2551            {
2552                dcache_hit_t  = true;       
2553                dcache_hit_x  = true;   
2554                dcache_hit_p  = true; 
2555                tlb_dpaddr    = dreq.addr;
2556                spc_dpaddr    = dreq.addr;   
2557                dcache_cached = m_cacheability_table[dreq.addr] &&
2558                                ((dreq.type != iss_t::DATA_LL)  && (dreq.type != iss_t::DATA_SC) &&
2559                                 (dreq.type != iss_t::XTN_READ) && (dreq.type != iss_t::XTN_WRITE));     
2560            }
2561            else                                                            // MMU activated
2562            {
2563                m_cpt_data_tlb_read++;
2564                dcache_hit_t  = dcache_tlb.cctranslate(dreq.addr, &tlb_dpaddr, &dcache_pte_info,
2565                                                       &dcache_tlb_nline, &dcache_tlb_way, &dcache_tlb_set);                 
2566                dcache_hit_x  = (((vaddr_t)r_dcache_vpn_save << PAGE_K_NBITS) == (dreq.addr & ~PAGE_K_MASK)) && r_dtlb_translation_valid;
2567                dcache_hit_p  = (((dreq.addr >> PAGE_M_NBITS) == r_dcache_id1_save) && r_dcache_ptba_ok );
2568                spc_dpaddr    = ((paddr_t)r_dcache_ppn_save << PAGE_K_NBITS) | (paddr_t)((dreq.addr & PAGE_K_MASK));
2569                dcache_cached = dcache_pte_info.c &&
2570                                ((dreq.type != iss_t::DATA_LL)  && (dreq.type != iss_t::DATA_SC) &&
2571                                 (dreq.type != iss_t::XTN_READ) && (dreq.type != iss_t::XTN_WRITE));   
2572            }
2573
2574            if ( !(r_mmu_mode.read() & DATA_CACHE_MASK) )   // cache not actived
2575            {
2576                dcache_cached = false;
2577            }
2578
2579            // dcache_hit_c & dcache_rdata
2580            if ( dcache_cached )    // using speculative physical address for cached access
2581            {
2582                dcache_hit_c = r_dcache.read(spc_dpaddr, &dcache_rdata);
2583            }
2584            else                    // using actual physical address for uncached access
2585            {
2586                dcache_hit_c = false;
2587            }
2588
2589            if ( r_mmu_mode.read() & DATA_TLB_MASK )
2590            {
2591                // Checking access rights
2592                if ( dcache_hit_t )
2593                {
2594                    if (!dcache_pte_info.u && (dreq.mode == iss_t::MODE_USER))
2595                    {
2596                        if ((dreq.type == iss_t::DATA_READ)||(dreq.type == iss_t::DATA_LL))
2597                        {
2598                            r_dcache_error_type = MMU_READ_PRIVILEGE_VIOLATION;
2599                        }
2600                        else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
2601                        {
2602                            r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
2603                        } 
2604                        r_dcache_bad_vaddr = dreq.addr;
2605                        drsp.valid = true;
2606                        drsp.error = true;
2607                        drsp.rdata = 0;
2608                        r_dcache_fsm = DCACHE_IDLE;
2609                        break;
2610                    }
2611                    if (!dcache_pte_info.w && ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC)))
2612                    {
2613                        r_dcache_error_type = MMU_WRITE_ACCES_VIOLATION; 
2614                        r_dcache_bad_vaddr = dreq.addr;
2615                        drsp.valid = true;
2616                        drsp.error = true;
2617                        drsp.rdata = 0;
2618                        r_dcache_fsm = DCACHE_IDLE;
2619                        break;
2620                    }
2621                }
2622
2623                // update LRU, save ppn, vpn and page type
2624                if ( dcache_hit_t ) {
2625                    dcache_tlb.setlru(dcache_tlb_way,dcache_tlb_set);
2626                    r_dcache_ppn_save = tlb_dpaddr >> PAGE_K_NBITS;
2627                    r_dcache_vpn_save = dreq.addr >> PAGE_K_NBITS;
2628                    r_dcache_tlb_nline = dcache_tlb_nline;
2629                    r_dtlb_translation_valid = true;
2630                }
2631                else
2632                {
2633                    r_dtlb_translation_valid = false;
2634                }
2635
2636            } // end if MMU activated
2637
2638            // compute next state
2639            if ( !dcache_hit_p && !dcache_hit_t )  // TLB miss
2640            {
2641                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2642                r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
2643                m_cpt_data_tlb_miss++;
2644                m_cost_data_tlb_miss_frz++;
2645            }
2646            else if ( dcache_hit_p && !dcache_hit_t )  // TLB Miss with possibility of bypass first level page
2647            {
2648                // walk page table level 2
2649                r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save |
2650                                     (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
2651                r_dcache_fsm = DCACHE_DTLB2_READ_CACHE;
2652                m_cpt_data_tlb_miss++;
2653                m_cost_data_tlb_miss_frz++;
2654            }
2655            else if ( dcache_hit_t && !dcache_hit_x && dcache_cached )// cached access with an ucorrect speculative physical address
2656            {
2657                r_dcache_hit_p_save = dcache_hit_p;
2658                r_dcache_fsm = DCACHE_BIS;
2659                m_cost_data_tlb_miss_frz++;
2660            }
2661            else  // cached or uncached access with a correct speculative physical address
2662            {
2663                switch( dreq.type ) {
2664                    case iss_t::DATA_READ:
2665                    case iss_t::DATA_LL:
2666                    case iss_t::DATA_SC:
2667                        m_cpt_read++;
2668                        if ( dcache_hit_c )
2669                        {
2670                            r_dcache_fsm = DCACHE_IDLE;
2671                            drsp.valid = true;
2672                            drsp.rdata = dcache_rdata;
2673                        }
2674                        else
2675                        {
2676                            if ( dcache_cached )
2677                            {
2678                                r_dcache_miss_req = true;
2679                                r_dcache_fsm = DCACHE_MISS_WAIT;
2680                                m_cpt_data_miss++;
2681                                m_cost_data_miss_frz++;
2682                            }
2683                            else
2684                            {
2685                                r_dcache_unc_req = true;
2686                                r_dcache_fsm = DCACHE_UNC_WAIT;
2687                                m_cpt_unc_read++;
2688                                m_cost_unc_read_frz++;
2689                            }
2690                        }
2691                        break;
2692/*
2693                    case iss_t::DATA_READ:
2694                        m_cpt_read++;
2695                        if ( dcache_hit_c )
2696                        {
2697                            r_dcache_buf_unc_valid = false;
2698                            r_dcache_fsm = DCACHE_IDLE;
2699                            drsp.valid = true;
2700                            drsp.rdata = dcache_rdata;
2701                        }
2702                        else
2703                        {
2704                            if ( dcache_cached )
2705                            {
2706                                r_dcache_miss_req = true;
2707                                r_dcache_fsm = DCACHE_MISS_WAIT;
2708                                m_cpt_data_miss++;
2709                                m_cost_data_miss_frz++;
2710                            }
2711                            else
2712                            {
2713                                r_dcache_unc_req = true;
2714                                r_dcache_fsm = DCACHE_UNC_WAIT;
2715                                m_cpt_unc_read++;
2716                                m_cost_unc_read_frz++;
2717                            }
2718                        }
2719                        break;
2720                    case iss_t::DATA_LL:
2721                        if (r_dcache_llsc_reserved && (r_dcache_llsc_addr_save == tlb_dpaddr) && r_dcache_buf_unc_valid)
2722                        {
2723                            r_dcache_buf_unc_valid = false;
2724                            r_dcache_fsm = DCACHE_IDLE;
2725                            drsp.valid = true;
2726                            drsp.rdata = dcache_rdata;
2727                        }
2728                        else
2729                        {
2730                            r_dcache_llsc_reserved = true;
2731                            r_dcache_llsc_addr_save = tlb_dpaddr;
2732                            r_dcache_unc_req = true;
2733                            r_dcache_fsm = DCACHE_UNC_WAIT;
2734                        }
2735                        break;
2736                    case iss_t::DATA_SC:
2737                        if (r_dcache_llsc_reserved && (r_dcache_llsc_addr_save == tlb_dpaddr))
2738                        {
2739                            r_dcache_llsc_reserved = false;
2740                            r_dcache_unc_req = true;
2741                            r_dcache_fsm = DCACHE_UNC_WAIT;
2742                        }
2743                        else
2744                        {   
2745                            if ( r_dcache_buf_unc_valid )
2746                            {                         
2747                                r_dcache_llsc_reserved = false;
2748                                r_dcache_buf_unc_valid = false;
2749                                drsp.valid = true;
2750                                drsp.rdata = dcache_rdata;
2751                            }
2752                            r_dcache_fsm = DCACHE_IDLE;
2753                        }                       
2754                        break;
2755*/
2756                    case iss_t::DATA_WRITE:
2757                        m_cpt_write++;
2758                        if ( dcache_cached ) m_cpt_write_cached++;
2759                        m_cost_write_frz++;
2760                        if ( dcache_hit_c && dcache_cached )    // cache update required
2761                        {
2762                            r_dcache_fsm = DCACHE_WRITE_UPDT;
2763                        }
2764                        else if ( !dcache_pte_info.d && (r_mmu_mode.read() & DATA_TLB_MASK) )   // dirty bit update required
2765                        {
2766                            m_cpt_data_tlb_update_dirty++;
2767                            m_cost_data_tlb_update_dirty_frz++;
2768                            if ( dcache_tlb.getpagesize(dcache_tlb_way, dcache_tlb_set) )       // 2M page size, one level page table
2769                            {
2770                                r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
2771                                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2772                                r_dcache_tlb_ll_dirty_req = true;
2773                                r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2774                            }
2775                            else        // 4k page size, two levels page table
2776                            {   
2777                                if (dcache_hit_p)
2778                                {
2779                                    r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
2780                                    r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save | (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
2781                                    r_dcache_tlb_ll_dirty_req = true;
2782                                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2783                                }
2784                                else    // get PTBA to calculate the physical address of PTE
2785                                {
2786                                    r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
2787                                    r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2788                                    r_dcache_tlb_ptba_read = true;
2789                                    r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
2790                                }
2791                            }
2792                        }
2793                        else                                    // no cache update, not dirty bit update
2794                        {
2795                            r_dcache_fsm = DCACHE_WRITE_REQ;
2796                            drsp.valid = true;
2797                            drsp.rdata = 0;
2798                        }
2799                        break;
2800                    default:
2801                        break;
2802                } // end switch dreq.type
2803            } // end if next states
2804
2805            // save values for the next states
2806            r_dcache_paddr_save   = tlb_dpaddr;
2807            r_dcache_type_save    = dreq.type;
2808            r_dcache_wdata_save   = dreq.wdata;
2809            r_dcache_be_save      = dreq.be;
2810            r_dcache_rdata_save   = dcache_rdata;
2811            r_dcache_cached_save  = dcache_cached;
2812            r_dcache_dirty_save   = dcache_pte_info.d;
2813            r_dcache_tlb_set_save = dcache_tlb_set;
2814            r_dcache_tlb_way_save = dcache_tlb_way;
2815
2816        } // end if dreq.valid
2817        else
2818        {   
2819            r_dcache_fsm = DCACHE_IDLE;
2820        }
2821
2822        // processor request are not accepted in the WRITE_REQ state
2823        // when the write buffer is not writeable
2824
2825        if ((r_dcache_fsm == DCACHE_WRITE_REQ) &&
2826            (r_dcache_write_req || !r_wbuf.wok(r_dcache_paddr_save)))
2827        {
2828            drsp.valid = false;
2829        }
2830        break;
2831    }
2832    /////////////////
2833    case DCACHE_BIS:
2834    {
2835        // external cache invalidate request
2836        if ( r_tgt_dcache_req )   
2837        {
2838            r_dcache_fsm = DCACHE_CC_CHECK;
2839            r_dcache_fsm_save = r_dcache_fsm;
2840            if ( dreq.valid ) m_cost_data_miss_frz++;
2841            break;
2842        }
2843
2844        // Using tlb entry is invalidated
2845        if ( r_dcache_inval_tlb_rsp )
2846        {
2847            r_dcache_inval_tlb_rsp = false;
2848            r_dcache_fsm = DCACHE_IDLE;
2849            if ( dreq.valid ) m_cost_data_miss_frz++;
2850            break;
2851        }
2852
2853        data_t  dcache_rdata = 0;
2854        bool    dcache_hit_c = false;
2855        bool    dcache_hit_t = false;
2856        paddr_t tlb_dpaddr   = 0;
2857
2858        dcache_hit_t = dcache_tlb.translate(dreq.addr, &tlb_dpaddr);
2859
2860        if ( (tlb_dpaddr == r_dcache_paddr_save.read()) && dreq.valid && dcache_hit_t )
2861        {
2862            // acces always cached in this state
2863            dcache_hit_c = r_dcache.read(r_dcache_paddr_save, &dcache_rdata);
2864           
2865            if ( dreq.type == iss_t::DATA_READ )  // cached read
2866            {
2867                m_cpt_read++;
2868                if ( !dcache_hit_c )
2869                {
2870                    r_dcache_miss_req = true;
2871                    r_dcache_fsm = DCACHE_MISS_WAIT;
2872                    m_cpt_data_miss++;
2873                    m_cost_data_miss_frz++;
2874                }
2875                else
2876                {
2877                    r_dcache_fsm = DCACHE_IDLE;
2878                }
2879                drsp.valid = dcache_hit_c;
2880                drsp.error = false;
2881                drsp.rdata = dcache_rdata;
2882            }
2883            else    // cached write
2884            {
2885                m_cpt_write++;
2886                m_cpt_write_cached++;
2887                if ( dcache_hit_c )    // cache update required
2888                {
2889                    r_dcache_rdata_save = dcache_rdata;
2890                    r_dcache_fsm = DCACHE_WRITE_UPDT;
2891                }
2892                else if (!r_dcache_dirty_save && (r_mmu_mode.read() & DATA_TLB_MASK))   // dirty bit update required
2893                {
2894                    m_cpt_data_tlb_update_dirty++;
2895                    m_cost_data_tlb_update_dirty_frz++;                         
2896                    if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
2897                    {
2898                        r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
2899                        r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2900                        r_dcache_tlb_ll_dirty_req = true;
2901                        r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2902                    }
2903                    else
2904                    {   
2905                        if (r_dcache_hit_p_save)
2906                        {
2907                            r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
2908                            r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save|(paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
2909                            r_dcache_tlb_ll_dirty_req = true;
2910                            r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
2911                        }
2912                        else
2913                        {
2914                            r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
2915                            r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
2916                            r_dcache_tlb_ptba_read = true;
2917                            r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
2918                        }
2919                    }
2920                }
2921                else                                    // no cache update, not dirty bit update
2922                {
2923                    r_dcache_fsm = DCACHE_WRITE_REQ;
2924                    drsp.valid = true;
2925                    drsp.rdata = 0;
2926                }
2927            }
2928        }
2929        else
2930        {
2931            drsp.valid = false;
2932            drsp.error = false;
2933            drsp.rdata = 0;
2934            r_dcache_fsm = DCACHE_IDLE;
2935        }
2936        break;
2937    }
2938    //////////////////////////
2939    case DCACHE_LL_DIRTY_WAIT:
2940    {
2941        m_cost_data_tlb_update_dirty_frz++;
2942
2943        // external cache invalidate request
2944        if ( r_tgt_dcache_req )   
2945        {
2946            r_dcache_fsm = DCACHE_CC_CHECK;
2947            r_dcache_fsm_save = r_dcache_fsm;
2948            break;
2949        }
2950
2951        if (!r_dcache_tlb_ll_dirty_req)
2952        {
2953            if ( r_vci_rsp_data_error ) // VCI response ko
2954            {
2955                if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
2956                {
2957                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;     
2958                }
2959                else
2960                {
2961                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;     
2962                }
2963                r_dcache_bad_vaddr = dreq.addr;
2964                r_dcache_fsm = DCACHE_ERROR;
2965
2966                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
2967                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
2968            }
2969            else
2970            {
2971                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
2972                {
2973                    if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
2974                    {
2975                        r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;       
2976                    }
2977                    else
2978                    {
2979                        r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;       
2980                    }
2981                    r_dcache_bad_vaddr = dreq.addr;
2982                    r_dcache_fsm = DCACHE_ERROR;
2983
2984                    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
2985                    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
2986                }
2987                else if ( r_dcache_inval_tlb_rsp )
2988                {
2989                    r_dcache_inval_tlb_rsp = false;
2990                    r_dcache_fsm = DCACHE_IDLE;
2991                }
2992                else if ( r_dcache_inval_rsp )
2993                {
2994                    r_dcache_inval_rsp = false;
2995                    r_dcache_fsm = DCACHE_IDLE;
2996                }
2997                else
2998                {
2999                    r_dcache_tlb_sc_dirty_req = true;
3000                    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
3001                    r_dcache_fsm = DCACHE_SC_DIRTY_WAIT;
3002                }
3003            }
3004        }
3005        break;
3006    }
3007    //////////////////////////
3008    case DCACHE_SC_DIRTY_WAIT:
3009    {
3010        m_cost_data_tlb_update_dirty_frz++;         
3011        // external cache invalidate request
3012        if ( r_tgt_dcache_req )   
3013        {
3014            r_dcache_fsm = DCACHE_CC_CHECK;
3015            r_dcache_fsm_save = r_dcache_fsm;
3016            break;
3017        }
3018
3019        if ( !r_dcache_tlb_sc_dirty_req )
3020        {
3021            if ( r_vci_rsp_data_error ) // VCI response ko
3022            {
3023                if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
3024                {
3025                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;   
3026                }
3027                else
3028                {
3029                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;   
3030                }
3031                r_dcache_bad_vaddr = dreq.addr;
3032                r_dcache_fsm = DCACHE_ERROR;
3033
3034                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3035                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;                         
3036            }
3037            else
3038            {
3039                // Using tlb entry is invalidated
3040                if ( r_dcache_inval_tlb_rsp )
3041                {
3042                    r_dcache_inval_tlb_rsp = false;
3043                    r_dcache_fsm = DCACHE_IDLE;
3044                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3045                }
3046                else if ( r_dcache_inval_rsp )
3047                {
3048                    r_dcache_inval_rsp = false;
3049                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3050                    r_dcache_fsm = DCACHE_IDLE;
3051                }
3052                else if ( r_dcache_tlb_sc_fail )
3053                {
3054                    r_dcache_tlb_ll_dirty_req = true;
3055                    r_dcache_tlb_sc_fail = false;
3056                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
3057                    m_cpt_data_tlb_update_dirty++;
3058                }
3059                else
3060                {
3061                    r_dcache_fsm = DCACHE_WRITE_DIRTY;
3062                }
3063            }
3064        }
3065        break;
3066    }
3067    ////////////////////////////
3068    case DCACHE_DTLB1_READ_CACHE:
3069    {
3070        m_cost_data_tlb_miss_frz++;
3071
3072        // external cache invalidate request
3073        if ( r_tgt_dcache_req )   
3074        {
3075            r_dcache_fsm = DCACHE_CC_CHECK;
3076            r_dcache_fsm_save = r_dcache_fsm;
3077            break;
3078        }       
3079
3080        // Using tlb entry is invalidated
3081        if ( r_dcache_inval_tlb_rsp )
3082        {
3083            r_dcache_inval_tlb_rsp = false;
3084            r_dcache_fsm = DCACHE_IDLE;
3085            break;
3086        }
3087
3088        data_t tlb_data = 0;
3089        bool write_hit = false;
3090        bool tlb_hit_cache = r_dcache.read(r_dcache_tlb_paddr, &tlb_data);
3091
3092        // DTLB request hit in cache
3093        if ( tlb_hit_cache )
3094        {
3095            if ( !(tlb_data >> PTE_V_SHIFT) )   // unmapped
3096            {
3097                r_dcache_ptba_ok    = false;
3098                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3099                {
3100                    r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
3101                }
3102                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3103                {
3104                    r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
3105                } 
3106                r_dcache_bad_vaddr  = dreq.addr;
3107                r_dcache_fsm        = DCACHE_ERROR;
3108            }
3109            else if ( (tlb_data & PTE_T_MASK) >> PTE_T_SHIFT )  // PTD
3110            {
3111                r_dcache_ptba_ok   = true;
3112                r_dcache_ptba_save = (paddr_t)(tlb_data & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS; 
3113                r_dcache_id1_save  = dreq.addr >> PAGE_M_NBITS;
3114                r_dcache_tlb_paddr = (paddr_t)(tlb_data & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
3115                                     (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
3116                if ( r_dcache_tlb_ptba_read )
3117                {
3118                    r_dcache_tlb_ptba_read = false;
3119                    write_hit = r_dcache.write(((paddr_t)(tlb_data & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
3120                                                (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3)), r_dcache_pte_update);
3121                    //assert(write_hit && "Write on miss ignores data");
3122                    r_dcache_tlb_ll_dirty_req = true;
3123                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
3124                    m_cpt_dcache_data_write++;
3125                    m_cost_data_tlb_update_dirty_frz++;
3126                }
3127                else
3128                {
3129                    r_dcache_fsm = DCACHE_DTLB2_READ_CACHE;
3130                }
3131            }
3132            else        // PTE
3133            {
3134                m_cpt_data_tlb_hit_dcache++;
3135                r_dcache_ptba_ok = false;
3136                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
3137                {
3138                    if ( (tlb_data & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
3139                    {
3140                        r_dcache_pte_update = tlb_data;
3141                        r_dcache_fsm = DCACHE_TLB1_UPDT;
3142                    }
3143                    else
3144                    {
3145                        r_dcache_pte_update = tlb_data | PTE_L_MASK;
3146                        r_dcache_tlb_ll_acc_req = true;
3147                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_L_MASK)); 
3148                        assert(write_hit && "Write on miss ignores data"); 
3149                        r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
3150                        m_cpt_dcache_data_write++;
3151                        m_cpt_data_tlb_update_acc++;
3152                        m_cost_data_tlb_update_acc_frz++;
3153                    }
3154                }
3155                else // remotely
3156                {
3157                    if ( (tlb_data & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
3158                    {
3159                        r_dcache_pte_update = tlb_data;
3160                        r_dcache_fsm = DCACHE_TLB1_UPDT;
3161                    }
3162                    else
3163                    {
3164                        r_dcache_pte_update = tlb_data | PTE_R_MASK;
3165                        r_dcache_tlb_ll_acc_req = true;
3166                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_R_MASK)); 
3167                        assert(write_hit && "Write on miss ignores data"); 
3168                        r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
3169                        m_cpt_dcache_data_write++;
3170                        m_cpt_data_tlb_update_acc++;
3171                        m_cost_data_tlb_update_acc_frz++;
3172                    }
3173                }
3174            }
3175        }
3176        else
3177        {
3178            // DTLB request miss in cache and walk page table level 1
3179            r_dcache_tlb_read_req = true;
3180            r_dcache_fsm = DCACHE_TLB1_READ;
3181        }
3182        break;
3183    }
3184    ///////////////////////
3185    case DCACHE_TLB1_LL_WAIT:
3186    {
3187        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3188        m_cost_data_tlb_update_acc_frz++;           
3189        // external cache invalidate request
3190        if ( r_tgt_dcache_req )   
3191        {
3192            r_dcache_fsm = DCACHE_CC_CHECK;
3193            r_dcache_fsm_save = r_dcache_fsm;
3194            break;
3195        }
3196
3197        if (!r_dcache_tlb_ll_acc_req)
3198        {
3199            if ( r_vci_rsp_data_error ) // VCI response ko
3200            {
3201                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3202                {
3203                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
3204                }
3205                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3206                {
3207                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
3208                }
3209                r_dcache_bad_vaddr = dreq.addr;
3210                r_dcache_fsm = DCACHE_ERROR;
3211
3212                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3213                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;             
3214            }
3215            else
3216            {
3217                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
3218                {
3219                    if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3220                    {
3221                        r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
3222                    }
3223                    else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3224                    {
3225                        r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
3226                    } 
3227                    r_dcache_bad_vaddr  = dreq.addr;
3228                    r_dcache_fsm        = DCACHE_ERROR;
3229
3230                    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3231                    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
3232                }
3233                else if ( r_dcache_inval_tlb_rsp )
3234                {
3235                    r_dcache_inval_tlb_rsp = false;
3236                    r_dcache_fsm = DCACHE_IDLE;
3237                }
3238                else if ( r_dcache_inval_rsp )
3239                {
3240                    r_dcache_inval_rsp = false;
3241                    r_dcache_fsm = DCACHE_IDLE;
3242                }
3243                else
3244                {
3245                    r_dcache_tlb_sc_acc_req = true;
3246                    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
3247                    r_dcache_fsm = DCACHE_TLB1_SC_WAIT;
3248                }
3249            }
3250        }
3251        break;
3252    }
3253    ///////////////////////
3254    case DCACHE_TLB1_SC_WAIT:
3255    {
3256        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3257        m_cost_data_tlb_update_acc_frz++;           
3258        // external cache invalidate request
3259        if ( r_tgt_dcache_req )   
3260        {
3261            r_dcache_fsm = DCACHE_CC_CHECK;
3262            r_dcache_fsm_save = r_dcache_fsm;
3263            break;
3264        }
3265
3266        if ( !r_dcache_tlb_sc_acc_req )
3267        {
3268            if ( r_vci_rsp_data_error ) // VCI response ko
3269            {
3270                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3271                {
3272                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
3273                }
3274                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3275                {
3276                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
3277                }
3278                r_dcache_bad_vaddr = dreq.addr;
3279                r_dcache_fsm = DCACHE_ERROR;
3280
3281                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3282                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;     
3283            }
3284            else
3285            {
3286                // Using tlb entry is invalidated
3287                if ( r_dcache_inval_tlb_rsp )
3288                {
3289                    r_dcache_inval_tlb_rsp = false;
3290                    r_dcache_fsm = DCACHE_IDLE;
3291                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3292                }
3293                else if ( r_dcache_inval_rsp )
3294                {
3295                    r_dcache_inval_rsp = false;
3296                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3297                    r_dcache_fsm = DCACHE_IDLE;
3298                }
3299                else if ( r_dcache_tlb_sc_fail )
3300                {
3301                    r_dcache_tlb_sc_fail = false;
3302                    r_dcache_tlb_ll_acc_req = true;
3303                    r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
3304                    m_cpt_data_tlb_update_acc++;
3305                }
3306                else
3307                {
3308                    r_dcache_fsm = DCACHE_TLB1_UPDT;
3309                }
3310            }
3311        }
3312        break;
3313    }
3314    //////////////////////
3315    case DCACHE_TLB1_READ:
3316    {
3317        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3318
3319        // external cache invalidate request
3320        if ( r_tgt_dcache_req )   
3321        {
3322            r_dcache_fsm = DCACHE_CC_CHECK;
3323            r_dcache_fsm_save = r_dcache_fsm;
3324            break;
3325        }       
3326
3327        if ( !r_dcache_tlb_read_req )
3328        {       
3329            if ( r_vci_rsp_data_error ) // VCI response ko
3330            {
3331                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3332                {
3333                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
3334                }
3335                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3336                {
3337                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
3338                }
3339                r_dcache_bad_vaddr = dreq.addr;
3340                r_dcache_fsm = DCACHE_ERROR;
3341
3342                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3343                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;     
3344                break;
3345            }
3346
3347            if ( r_dcache_inval_tlb_rsp )  // TLB miss response and invalidation
3348            {
3349                r_dcache_fsm = DCACHE_IDLE;
3350                r_dcache_inval_tlb_rsp = false;
3351                break;
3352            }
3353
3354            if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
3355            {
3356                if ( r_dcache_cleanup_req ) break;
3357                r_dcache_cleanup_req = true;
3358                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
3359                m_cpt_cc_cleanup_data++;
3360                r_dcache_fsm = DCACHE_IDLE;
3361                r_dcache_inval_rsp = false;
3362                break;
3363            }
3364
3365            // TLB miss response and no invalidation
3366            r_dcache_fsm = DCACHE_TLB1_READ_UPDT;
3367        }
3368        break;
3369    }
3370    //////////////////////////
3371    case DCACHE_TLB1_READ_UPDT:
3372    {
3373        m_cost_data_tlb_miss_frz++;
3374
3375        // external cache invalidate request
3376        if ( r_tgt_dcache_req )   
3377        {
3378            r_dcache_fsm = DCACHE_CC_CHECK;
3379            r_dcache_fsm_save = r_dcache_fsm;
3380            break;
3381        }       
3382
3383        // Using tlb entry is invalidated
3384        if ( r_dcache_inval_tlb_rsp )
3385        {
3386            r_dcache_inval_tlb_rsp = false;
3387            r_dcache_fsm = DCACHE_IDLE;
3388            break;
3389        }
3390
3391        if ( !r_dcache_cleanup_req ) // Miss update and no invalidation
3392        {
3393            // update dcache
3394            data_t   rsp_dtlb_miss = 0;
3395            paddr_t  victim_index = 0;
3396            bool write_hit = false;
3397            size_t way = 0;
3398            size_t set = 0;
3399
3400            // Using tlb entry is in the invalidated cache line 
3401            if ( r_dcache_inval_rsp )
3402            {
3403                r_dcache_cleanup_req = true;
3404                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2);
3405                m_cpt_cc_cleanup_data++;       
3406                r_dcache_fsm = DCACHE_IDLE;
3407                r_dcache_inval_rsp = false;
3408                break;
3409            }
3410
3411            bool cleanup_req = r_dcache.find(r_dcache_tlb_paddr, r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
3412           
3413            if ( cleanup_req )
3414            {       
3415                // ins tlb invalidate verification   
3416                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
3417                r_dcache_itlb_inval_line = victim_index;
3418                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
3419
3420                // data tlb invalidate verification
3421                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set];
3422                r_dcache_dtlb_inval_line = victim_index;
3423                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
3424
3425                r_dcache_cleanup_req = true;
3426                r_dcache_cleanup_line = victim_index;
3427                m_cpt_cc_cleanup_data++;
3428                r_dcache_fsm = DCACHE_TLB_CC_INVAL;
3429                r_dcache_fsm_save = r_dcache_fsm;
3430                break;
3431            }
3432
3433            r_dcache.update(r_dcache_tlb_paddr, way, set, r_dcache_miss_buf);
3434            r_dcache.read(r_dcache_tlb_paddr, &rsp_dtlb_miss); 
3435            m_cpt_data_tlb_occup_cache++;
3436
3437            if ( !(rsp_dtlb_miss >> PTE_V_SHIFT) )      // unmapped
3438            {
3439                r_dcache_ptba_ok    = false;
3440                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3441                {
3442                    r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
3443                }
3444                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3445                {
3446                    r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
3447                }
3448                r_dcache_bad_vaddr  = dreq.addr;
3449                r_dcache_fsm        = DCACHE_ERROR;
3450            }
3451            else if ( (rsp_dtlb_miss & PTE_T_MASK) >> PTE_T_SHIFT ) // PTD
3452            {
3453                r_dcache_ptba_ok   = true;
3454                r_dcache_ptba_save = (paddr_t)(rsp_dtlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS; 
3455                r_dcache_id1_save  = dreq.addr >> PAGE_M_NBITS;
3456                r_dcache_tlb_paddr = (paddr_t)(rsp_dtlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
3457                                     (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
3458                if ( r_dcache_tlb_ptba_read )
3459                {
3460                    r_dcache_tlb_ptba_read = false;
3461                    write_hit = r_dcache.write(((paddr_t)(rsp_dtlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
3462                                                (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3)),r_dcache_pte_update);
3463                    //assert(write_hit && "Write on miss ignores data");
3464                    r_dcache_tlb_ll_dirty_req = true;
3465                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
3466                    m_cpt_dcache_data_write++;
3467                    m_cpt_data_tlb_update_dirty++;
3468                    m_cost_data_tlb_update_dirty_frz++;
3469                }
3470                else
3471                {
3472                    r_dcache_fsm = DCACHE_DTLB2_READ_CACHE;
3473                }
3474            }
3475            else        // PTE
3476            {
3477                r_dcache_ptba_ok = false;
3478                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
3479                {
3480                    if ( (rsp_dtlb_miss & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
3481                    {
3482                        r_dcache_pte_update = rsp_dtlb_miss;
3483                        r_dcache_fsm        = DCACHE_TLB1_UPDT;
3484                    }
3485                    else
3486                    {
3487                        r_dcache_pte_update = rsp_dtlb_miss | PTE_L_MASK;
3488                        r_dcache_tlb_ll_acc_req = true;
3489                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_L_MASK)); 
3490                        assert(write_hit && "Write on miss ignores data"); 
3491                        r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
3492                        m_cpt_dcache_data_write++;
3493                        m_cpt_data_tlb_update_acc++;
3494                        m_cost_data_tlb_update_acc_frz++;
3495                    }
3496                }
3497                else // remotely
3498                {
3499                    if ( (rsp_dtlb_miss & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
3500                    {
3501                        r_dcache_pte_update = rsp_dtlb_miss;
3502                        r_dcache_fsm        = DCACHE_TLB1_UPDT;
3503                    }
3504                    else
3505                    {
3506                        r_dcache_pte_update = rsp_dtlb_miss | PTE_R_MASK;
3507                        r_dcache_tlb_ll_acc_req = true;
3508                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_R_MASK)); 
3509                        assert(write_hit && "Write on miss ignores data"); 
3510                        r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
3511                        m_cpt_dcache_data_write++;
3512                        m_cpt_data_tlb_update_acc++;
3513                        m_cost_data_tlb_update_acc_frz++;
3514                    }
3515                }
3516            }
3517        }
3518        break;
3519    }
3520    //////////////////////
3521    case DCACHE_TLB1_UPDT:
3522    {
3523        m_cost_data_tlb_miss_frz++;
3524
3525        // external cache invalidate request
3526        if ( r_tgt_dcache_req )   
3527        {
3528            r_dcache_fsm = DCACHE_CC_CHECK;
3529            r_dcache_fsm_save = r_dcache_fsm;
3530            break;
3531        }       
3532
3533        if ( !r_dcache_inval_tlb_rsp && !r_dcache_inval_rsp )
3534        {
3535            paddr_t victim_index = 0;
3536            if (dcache_tlb.update(r_dcache_pte_update,dreq.addr,(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)),&victim_index))
3537            {
3538                r_dcache.setinbit((paddr_t)victim_index*m_dcache_words*2, r_dcache_in_dtlb, false);
3539            }
3540            r_dcache.setinbit(r_dcache_tlb_paddr, r_dcache_in_dtlb, true);
3541            r_dcache_fsm = DCACHE_IDLE;
3542        }
3543        else 
3544        {
3545            if ( r_dcache_inval_tlb_rsp ) r_dcache_inval_tlb_rsp = false;
3546            if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
3547            r_dcache_fsm = DCACHE_IDLE;
3548        }
3549        break;
3550    }
3551    /////////////////////////////
3552    case DCACHE_DTLB2_READ_CACHE:
3553    {
3554        m_cost_data_tlb_miss_frz++;
3555
3556        // external cache invalidate request
3557        if ( r_tgt_dcache_req )   
3558        {
3559            r_dcache_fsm = DCACHE_CC_CHECK;
3560            r_dcache_fsm_save = r_dcache_fsm;
3561            break;
3562        }       
3563
3564        // Using tlb entry is invalidated
3565        if ( r_dcache_inval_tlb_rsp )
3566        {
3567            r_dcache_inval_tlb_rsp = false;
3568            r_dcache_fsm = DCACHE_IDLE;
3569            break;
3570        }
3571
3572        data_t tlb_data = 0;
3573        data_t tlb_data_ppn = 0;
3574        bool write_hit = false;
3575        bool tlb_hit_cache = r_dcache.read(r_dcache_tlb_paddr, &tlb_data);
3576
3577        if ( tlb_hit_cache )
3578        {
3579            bool tlb_hit_ppn = r_dcache.read(r_dcache_tlb_paddr.read()+4, &tlb_data_ppn);
3580            assert(tlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
3581        }
3582
3583        // DTLB request hit in cache
3584        if ( tlb_hit_cache )
3585        {
3586            if ( !(tlb_data >> PTE_V_SHIFT) )   // unmapped
3587            {
3588                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3589                {
3590                    r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
3591                }
3592                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3593                {
3594                    r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
3595                }
3596                r_dcache_bad_vaddr  = dreq.addr;
3597                r_dcache_fsm        = DCACHE_ERROR;
3598            }
3599            else if ( (tlb_data & PTE_T_MASK) >> PTE_T_SHIFT ) //PTD
3600            {
3601                r_dcache_pte_update = tlb_data;
3602                r_dcache_ppn_update = tlb_data_ppn;
3603                r_dcache_fsm = DCACHE_TLB2_UPDT;
3604            }
3605            else
3606            {
3607                m_cpt_data_tlb_hit_dcache++;
3608                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
3609                {
3610                    if ( (tlb_data & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
3611                    {
3612                        r_dcache_pte_update = tlb_data;
3613                        r_dcache_ppn_update = tlb_data_ppn;
3614                        r_dcache_fsm        = DCACHE_TLB2_UPDT;
3615                    }
3616                    else
3617                    {
3618                        r_dcache_pte_update = tlb_data | PTE_L_MASK;
3619                        r_dcache_ppn_update = tlb_data_ppn;
3620                        r_dcache_tlb_ll_acc_req = true;
3621                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_L_MASK)); 
3622                        assert(write_hit && "Write on miss ignores data"); 
3623                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3624                        m_cpt_dcache_data_write++;
3625                        m_cpt_data_tlb_update_acc++;
3626                        m_cost_data_tlb_update_acc_frz++;
3627                    }
3628                }
3629                else // remotely
3630                {
3631                    if ( (tlb_data & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
3632                    {
3633                        r_dcache_pte_update = tlb_data;
3634                        r_dcache_ppn_update = tlb_data_ppn;
3635                        r_dcache_fsm        = DCACHE_TLB2_UPDT;
3636                    }
3637                    else
3638                    {
3639                        r_dcache_pte_update = tlb_data | PTE_R_MASK;
3640                        r_dcache_ppn_update = tlb_data_ppn;
3641                        r_dcache_tlb_ll_acc_req = true;
3642                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_R_MASK)); 
3643                        assert(write_hit && "Write on miss ignores data"); 
3644                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3645                        m_cpt_dcache_data_write++;
3646                        m_cpt_data_tlb_update_acc++;
3647                        m_cost_data_tlb_update_acc_frz++;
3648                    }
3649                }
3650            }
3651        }
3652        else
3653        {
3654            // DTLB request miss in cache and walk page table level 2
3655            r_dcache_tlb_read_req = true;
3656            r_dcache_fsm = DCACHE_TLB2_READ;
3657        }
3658        break;
3659    }
3660    ///////////////////////
3661    case DCACHE_TLB2_LL_WAIT:
3662    {
3663        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3664        m_cost_data_tlb_update_acc_frz++;
3665
3666        // external cache invalidate request
3667        if ( r_tgt_dcache_req )   
3668        {
3669            r_dcache_fsm = DCACHE_CC_CHECK;
3670            r_dcache_fsm_save = r_dcache_fsm;
3671            break;
3672        }
3673
3674        if (!r_dcache_tlb_ll_acc_req)
3675        {
3676            if ( r_vci_rsp_data_error ) // VCI response ko
3677            {
3678                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3679                {
3680                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
3681                }
3682                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3683                {
3684                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
3685                }
3686                r_dcache_bad_vaddr = dreq.addr;
3687                r_dcache_fsm = DCACHE_ERROR;
3688
3689                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3690                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
3691            }
3692            else
3693            {
3694                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
3695                {
3696                    if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3697                    {
3698                        r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
3699                    }
3700                    else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3701                    {
3702                        r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
3703                    }
3704                    r_dcache_bad_vaddr = dreq.addr;
3705                    r_dcache_fsm = DCACHE_ERROR;
3706
3707                    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3708                    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
3709                }
3710                else if ( r_dcache_inval_tlb_rsp )
3711                {
3712                    r_dcache_inval_tlb_rsp = false;
3713                    r_dcache_fsm = DCACHE_IDLE;
3714                }
3715                else if ( r_dcache_inval_rsp )
3716                {
3717                    r_dcache_inval_rsp = false;
3718                    r_dcache_fsm = DCACHE_IDLE;
3719                }
3720                else
3721                {
3722                    r_dcache_tlb_sc_acc_req = true;
3723                    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
3724                    r_dcache_fsm = DCACHE_TLB2_SC_WAIT;
3725                }
3726            }
3727        }
3728        break;
3729    }
3730    ///////////////////////
3731    case DCACHE_TLB2_SC_WAIT:
3732    {
3733        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
3734        m_cost_data_tlb_update_acc_frz++;           
3735        // external cache invalidate request
3736        if ( r_tgt_dcache_req )   
3737        {
3738            r_dcache_fsm = DCACHE_CC_CHECK;
3739            r_dcache_fsm_save = r_dcache_fsm;
3740            break;
3741        }
3742
3743        if ( !r_dcache_tlb_sc_acc_req )
3744        {
3745            if ( r_vci_rsp_data_error ) // VCI response ko
3746            {
3747                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3748                {
3749                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
3750                }
3751                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3752                {
3753                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
3754                }
3755                r_dcache_bad_vaddr = dreq.addr;
3756                r_dcache_fsm = DCACHE_ERROR;
3757
3758                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3759                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;     
3760            }
3761            else
3762            {
3763                // Using tlb entry is invalidated
3764                if ( r_dcache_inval_tlb_rsp )
3765                {
3766                    r_dcache_inval_tlb_rsp = false;
3767                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3768                    r_dcache_fsm = DCACHE_IDLE;
3769                }
3770                else if ( r_dcache_inval_rsp )
3771                {
3772                    r_dcache_inval_rsp = false;
3773                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
3774                    r_dcache_fsm = DCACHE_IDLE;
3775                }
3776                else if ( r_dcache_tlb_sc_fail )
3777                {
3778                    r_dcache_tlb_ll_acc_req = true;
3779                    r_dcache_tlb_sc_fail = false;
3780                    r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3781                    m_cpt_data_tlb_update_acc++;
3782                }
3783                else
3784                {
3785                    r_dcache_fsm = DCACHE_TLB2_UPDT;
3786                }
3787            }
3788        }
3789        break;
3790    }
3791    /////////////////////
3792    case DCACHE_TLB2_READ:
3793    {
3794        m_cost_data_tlb_miss_frz++;
3795
3796        // external cache invalidate request
3797        if ( r_tgt_dcache_req )   
3798        {
3799            r_dcache_fsm = DCACHE_CC_CHECK;
3800            r_dcache_fsm_save = r_dcache_fsm;
3801            break;
3802        }       
3803
3804        if ( !r_dcache_tlb_read_req )
3805        {
3806            if ( r_vci_rsp_data_error ) // VCI response ko
3807            {
3808                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3809                {
3810                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
3811                }
3812                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3813                {
3814                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
3815                }
3816                r_dcache_bad_vaddr = dreq.addr;
3817                r_dcache_fsm = DCACHE_ERROR;
3818
3819                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
3820                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
3821                break;
3822            }   
3823
3824            if ( r_dcache_inval_tlb_rsp )  // TLB miss response and invalidation
3825            {
3826                r_dcache_fsm = DCACHE_IDLE;
3827                r_dcache_inval_tlb_rsp = false;
3828                break;
3829            } 
3830
3831            if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
3832            {
3833                if ( r_dcache_cleanup_req ) break;
3834                r_dcache_cleanup_req = true;
3835                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
3836                m_cpt_cc_cleanup_data++;
3837                r_dcache_fsm = DCACHE_IDLE;
3838                r_dcache_inval_rsp = false;
3839                break;
3840            }
3841
3842            // TLB miss response and no invalidation
3843            r_dcache_fsm = DCACHE_TLB2_READ_UPDT;
3844        }       
3845        break;
3846    }
3847    //////////////////////////
3848    case DCACHE_TLB2_READ_UPDT:
3849    {
3850        m_cost_data_tlb_miss_frz++;
3851
3852        // external cache invalidate request
3853        if ( r_tgt_dcache_req )   
3854        {
3855            r_dcache_fsm = DCACHE_CC_CHECK;
3856            r_dcache_fsm_save = r_dcache_fsm;
3857            break;
3858        }       
3859
3860        // Using tlb entry is invalidated
3861        if ( r_dcache_inval_tlb_rsp )
3862        {
3863            r_dcache_inval_tlb_rsp = false;
3864            r_dcache_fsm = DCACHE_IDLE;
3865            break;
3866        }
3867
3868        if ( !r_dcache_cleanup_req )
3869        {
3870            // update cache
3871            data_t rsp_dtlb_miss;
3872            data_t tlb_data_ppn;
3873            bool write_hit = false;
3874            paddr_t  victim_index = 0;
3875            size_t way = 0;
3876            size_t set = 0;
3877
3878            // Using tlb entry is in the invalidated cache line 
3879            if ( r_dcache_inval_rsp )
3880            {
3881                r_dcache_cleanup_req = true;
3882                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
3883                m_cpt_cc_cleanup_data++;
3884                r_dcache_fsm = DCACHE_IDLE;
3885                r_dcache_inval_rsp = false;
3886                break;
3887            }
3888
3889            bool cleanup_req = r_dcache.find(r_dcache_tlb_paddr, r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
3890
3891            if ( cleanup_req )
3892            {       
3893                // ins tlb invalidate verification   
3894                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
3895                r_dcache_itlb_inval_line = victim_index;
3896                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
3897
3898                // data tlb invalidate verification
3899                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set];
3900                r_dcache_dtlb_inval_line = victim_index;
3901                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
3902
3903                r_dcache_cleanup_req = true;
3904                r_dcache_cleanup_line = victim_index;
3905                m_cpt_cc_cleanup_data++;
3906                r_dcache_fsm = DCACHE_TLB_CC_INVAL;
3907                r_dcache_fsm_save = r_dcache_fsm;
3908                break;
3909            }
3910
3911            r_dcache.update(r_dcache_tlb_paddr, way, set, r_dcache_miss_buf);
3912            r_dcache.read(r_dcache_tlb_paddr, &rsp_dtlb_miss);
3913            m_cpt_data_tlb_occup_cache++;
3914
3915            bool tlb_hit_ppn = r_dcache.read(r_dcache_tlb_paddr.read()+4, &tlb_data_ppn);
3916            assert(tlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
3917
3918            if ( !(rsp_dtlb_miss >> PTE_V_SHIFT) )      // unmapped
3919            {
3920                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
3921                {
3922                    r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
3923                }
3924                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
3925                {
3926                    r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
3927                } 
3928                r_dcache_bad_vaddr  = dreq.addr;
3929                r_dcache_fsm        = DCACHE_ERROR;
3930            }
3931            else if ( (rsp_dtlb_miss & PTE_T_MASK) >> PTE_T_SHIFT ) // PTD
3932            {
3933                r_dcache_pte_update = rsp_dtlb_miss;
3934                r_dcache_ppn_update = tlb_data_ppn;
3935                r_dcache_fsm = DCACHE_TLB2_UPDT;
3936            }
3937            else
3938            {
3939                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
3940                {
3941                    if ( (rsp_dtlb_miss & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
3942                    {
3943                        r_dcache_pte_update = rsp_dtlb_miss;
3944                        r_dcache_ppn_update = tlb_data_ppn;
3945                        r_dcache_fsm        = DCACHE_TLB2_UPDT;
3946                    }
3947                    else
3948                    {
3949                        r_dcache_pte_update = rsp_dtlb_miss | PTE_L_MASK;
3950                        r_dcache_ppn_update = tlb_data_ppn;
3951                        r_dcache_tlb_ll_acc_req = true;
3952                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_L_MASK)); 
3953                        assert(write_hit && "Write on miss ignores data"); 
3954                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3955                        m_cpt_dcache_data_write++;
3956                        m_cpt_data_tlb_update_acc++;
3957                        m_cost_data_tlb_update_acc_frz++;
3958                    }
3959                }
3960                else // remotely
3961                {
3962                    if ( (rsp_dtlb_miss & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
3963                    {
3964                        r_dcache_pte_update = rsp_dtlb_miss;
3965                        r_dcache_ppn_update = tlb_data_ppn;
3966                        r_dcache_fsm        = DCACHE_TLB2_UPDT;
3967                    }
3968                    else
3969                    {
3970                        r_dcache_pte_update = rsp_dtlb_miss | PTE_R_MASK;
3971                        r_dcache_ppn_update = tlb_data_ppn;
3972                        r_dcache_tlb_ll_acc_req = true;
3973                        write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_R_MASK)); 
3974                        assert(write_hit && "Write on miss ignores data"); 
3975                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
3976                        m_cpt_dcache_data_write++;
3977                        m_cpt_data_tlb_update_acc++;
3978                        m_cost_data_tlb_update_acc_frz++;
3979                    }
3980                }
3981            }
3982        }
3983        break;
3984    }
3985    //////////////////////
3986    case DCACHE_TLB2_UPDT: 
3987    {
3988        m_cost_data_tlb_miss_frz++;
3989
3990        // external cache invalidate request
3991        if ( r_tgt_dcache_req )   
3992        {
3993            r_dcache_fsm = DCACHE_CC_CHECK;
3994            r_dcache_fsm_save = r_dcache_fsm;
3995            break;
3996        }       
3997
3998        if ( !r_dcache_inval_tlb_rsp && !r_dcache_inval_rsp )
3999        {
4000            paddr_t victim_index = 0;
4001            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))
4002            {
4003                r_dcache.setinbit((paddr_t)victim_index*m_dcache_words*2, r_dcache_in_dtlb, false);
4004            }
4005            r_dcache.setinbit(r_dcache_tlb_paddr, r_dcache_in_dtlb, true);
4006            r_dcache_fsm = DCACHE_IDLE;
4007        }
4008        else 
4009        {
4010            if ( r_dcache_inval_tlb_rsp ) r_dcache_inval_tlb_rsp = false;
4011            if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
4012            r_dcache_fsm = DCACHE_IDLE;
4013        }
4014        break;
4015    }
4016    ///////////////////////
4017    case DCACHE_CTXT_SWITCH:
4018    {
4019        // TLB flush leads to cleanup corresponding data cache line
4020        m_cost_data_tlb_sw_frz++;
4021
4022        paddr_t victim_index = 0;
4023        size_t way = 0;
4024        size_t set = 0;
4025
4026        if ( r_dcache_itlb_cleanup_req )
4027        {   
4028            r_dcache.setinbit(((paddr_t)r_dcache_itlb_cleanup_line.read()*m_dcache_words*2), r_dcache_in_itlb, false);
4029            r_dcache_itlb_cleanup_req = false;
4030        }
4031
4032        for ( way = 0; way < m_dtlb_ways; way++)
4033        {
4034            for ( set = 0; set < m_dtlb_sets; set++)
4035            {
4036                if(dcache_tlb.checkcleanup(way, set, &victim_index))
4037                {
4038                    r_dcache.setinbit((paddr_t)(victim_index << (m_dcache_words+2)), r_dcache_in_dtlb, false);
4039                }
4040            }
4041        }
4042
4043        if ( !r_dcache_xtn_req )
4044        {
4045            r_dcache_fsm = DCACHE_IDLE;
4046            r_dtlb_translation_valid = false;
4047            r_dcache_ptba_ok = false;
4048            drsp.valid = true;
4049        }
4050        break;
4051    }
4052    ////////////////////////
4053    case DCACHE_ICACHE_FLUSH:
4054    case DCACHE_ICACHE_INVAL:
4055    case DCACHE_ICACHE_INVAL_PA:
4056    case DCACHE_ITLB_INVAL:
4057    {
4058        if ( !r_dcache_xtn_req )
4059        {
4060            r_dcache_fsm = DCACHE_IDLE;
4061            drsp.valid = true;
4062        }
4063        break;
4064    }
4065    ////////////////////////
4066    case DCACHE_DCACHE_FLUSH:
4067    {
4068        // external cache invalidate request
4069        if ( r_tgt_dcache_req )   
4070        {
4071            r_dcache_fsm = DCACHE_CC_CHECK;
4072            r_dcache_fsm_save = r_dcache_fsm;
4073            break;
4074        } 
4075        size_t way = r_dcache_way;
4076        size_t set = r_dcache_set;
4077        bool clean = false;
4078       
4079        m_cost_data_cache_flush_frz++;
4080
4081        // cache flush and send cleanup to external
4082        if ( !r_dcache_cleanup_req )
4083        {
4084            paddr_t victim_index = 0;
4085            for ( ; way < m_dcache_ways; way++ )
4086            {   
4087                for ( ; set < m_dcache_sets; set++ )
4088                { 
4089                    if ( r_dcache.flush(way, set, &victim_index) )
4090                    {
4091                        clean = true;
4092                        r_dcache_cleanup_req = true;
4093                        r_dcache_cleanup_line = victim_index;
4094                        m_cpt_cc_cleanup_data++;
4095                        r_dcache_way = way + ((set+1)/m_dcache_sets);
4096                        r_dcache_set = (set+1) % m_dcache_sets;
4097                        break;
4098                    }
4099                }
4100                if (clean) break;
4101            }
4102
4103            if ((way == m_dcache_ways) && !r_dcache_xtn_req )
4104            {
4105                // data TLB flush
4106                dcache_tlb.flush(true);      // global entries are not invalidated
4107                r_dtlb_translation_valid = false;
4108                r_dcache_ptba_ok = false;
4109
4110                for (size_t line = 0; line < m_dcache_ways*m_dcache_sets; line++)
4111                {
4112                    r_dcache_in_itlb[line] = false;
4113                    r_dcache_in_dtlb[line] = false;
4114                }
4115
4116                r_dcache_fsm = DCACHE_IDLE;
4117                drsp.valid = true;
4118                break;
4119            }
4120        }
4121        break;
4122    }
4123    //////////////////////
4124    case DCACHE_DTLB_INVAL:
4125    {
4126        paddr_t victim_index = 0;
4127        // clean indicate data tlb bit
4128        if ( dcache_tlb.inval(r_dcache_wdata_save, &victim_index) )
4129        { 
4130            r_dcache.setinbit((paddr_t)(victim_index << (m_dcache_words+2)), r_dcache_in_dtlb, false);
4131        }
4132        r_dtlb_translation_valid = false;
4133        r_dcache_ptba_ok = false;
4134        r_dcache_fsm = DCACHE_IDLE;
4135        drsp.valid = true;
4136        break;
4137    }
4138    ////////////////////////
4139    case DCACHE_DCACHE_INVAL:
4140    {
4141        // external cache invalidate request
4142        if ( r_tgt_dcache_req )   
4143        {
4144            r_dcache_fsm = DCACHE_CC_CHECK;
4145            r_dcache_fsm_save = r_dcache_fsm;
4146            break;
4147        } 
4148
4149        m_cpt_dcache_dir_read += m_dcache_ways;
4150        vaddr_t invadr = dreq.wdata;
4151        paddr_t dpaddr = 0;
4152        bool dcache_hit_t = false;
4153        size_t way = 0;
4154        size_t set = 0;
4155
4156        if ( !r_dcache_cleanup_req )
4157        {
4158            if ( r_mmu_mode.read() & DATA_TLB_MASK )
4159            {
4160                dcache_hit_t = dcache_tlb.translate(invadr, &dpaddr);
4161            }
4162            else
4163            {
4164                dpaddr = invadr; 
4165                dcache_hit_t = true;
4166            }
4167
4168            if ( dcache_hit_t )
4169            {
4170                r_dcache_cleanup_req = r_dcache.inval(dpaddr, &way, &set);
4171                r_dcache_cleanup_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
4172                m_cpt_cc_cleanup_data++;
4173               
4174                if ( r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set] )
4175                {       
4176                    // ins tlb invalidate verification
4177                    r_dcache_itlb_inval_req = r_dcache_in_itlb[way*m_dcache_sets+set];
4178                    r_dcache_itlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
4179                    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4180               
4181                    // data tlb invalidate verification
4182                    r_dcache_dtlb_inval_req = r_dcache_in_dtlb[way*m_dcache_sets+set];
4183                    r_dcache_dtlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
4184                    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4185                    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4186                    r_dcache_fsm_save = r_dcache_fsm;
4187                    break;
4188                }
4189            }
4190            r_dcache_fsm = DCACHE_IDLE;
4191            drsp.valid = true;
4192        }
4193        break;
4194    }
4195    ////////////////////////
4196    case DCACHE_DCACHE_INVAL_PA:
4197    {
4198        // external cache invalidate request
4199        if ( r_tgt_dcache_req )   
4200        {
4201            r_dcache_fsm = DCACHE_CC_CHECK;
4202            r_dcache_fsm_save = r_dcache_fsm;
4203            break;
4204        } 
4205        m_cpt_dcache_dir_read += m_dcache_ways;
4206        paddr_t dpaddr = (paddr_t)r_mmu_word_hi.read() << 32 | r_mmu_word_lo.read();
4207        size_t way = 0;
4208        size_t set = 0;
4209
4210        if ( !r_dcache_cleanup_req )
4211        {
4212            r_dcache_cleanup_req = r_dcache.inval(dpaddr, &way, &set);
4213            r_dcache_cleanup_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
4214            m_cpt_cc_cleanup_data++;
4215           
4216            if ( r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set] )
4217            {   
4218                // ins tlb invalidate verification
4219                r_dcache_itlb_inval_req = r_dcache_in_itlb[way*m_dcache_sets+set];
4220                r_dcache_itlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
4221                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4222           
4223                // data tlb invalidate verification
4224                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[way*m_dcache_sets+set];
4225                r_dcache_dtlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
4226                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4227                r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4228                r_dcache_fsm_save = r_dcache_fsm;
4229                break;
4230            }
4231            r_dcache_fsm = DCACHE_IDLE;
4232            drsp.valid = true;
4233        }
4234        break;
4235    }
4236    /////////////////////////
4237    case DCACHE_DCACHE_SYNC:
4238    {
4239        if ( !r_dcache_write_req )
4240        {
4241            r_dcache_write_req = r_wbuf.rok();
4242            drsp.valid = true;
4243            r_dcache_fsm = DCACHE_IDLE;
4244        }   
4245        break;
4246    }
4247    /////////////////////
4248    case DCACHE_MISS_WAIT:
4249    {
4250        m_cost_data_miss_frz++;
4251
4252        // external cache invalidate request
4253        if ( r_tgt_dcache_req )
4254        {
4255            r_dcache_fsm = DCACHE_CC_CHECK;
4256            r_dcache_fsm_save = r_dcache_fsm;
4257            break;
4258        }
4259
4260        if ( !r_dcache_miss_req )
4261        {
4262            if ( r_vci_rsp_data_error )
4263            {
4264                r_dcache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS;
4265                r_dcache_bad_vaddr = dreq.addr;
4266                r_dcache_fsm = DCACHE_ERROR;
4267
4268                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
4269                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
4270                break;
4271            }
4272
4273            if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
4274            {
4275                if ( r_dcache_cleanup_req ) break;
4276                r_dcache_cleanup_req = true;
4277                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
4278                m_cpt_cc_cleanup_data++;
4279                r_dcache_fsm = DCACHE_IDLE;
4280                r_dcache_inval_tlb_rsp = false;
4281                if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
4282                break;
4283            }   
4284
4285            if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
4286            {
4287                if ( r_dcache_cleanup_req ) break;
4288                r_dcache_cleanup_req = true;
4289                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
4290                m_cpt_cc_cleanup_data++;
4291                r_dcache_fsm = DCACHE_IDLE;
4292                r_dcache_inval_rsp = false;
4293                break;
4294            }
4295            // Miss read response and no tlb invalidation
4296            r_dcache_fsm = DCACHE_MISS_UPDT;
4297        }       
4298        break;
4299    }
4300    /////////////////////
4301    case DCACHE_MISS_UPDT:
4302    {
4303        m_cost_data_miss_frz++;
4304
4305        // external cache invalidate request
4306        if ( r_tgt_dcache_req )
4307        {
4308            r_dcache_fsm = DCACHE_CC_CHECK;
4309            r_dcache_fsm_save = r_dcache_fsm;
4310            break;
4311        }
4312
4313        if ( r_dcache_inval_tlb_rsp ) // tlb invalidation
4314        {
4315            if ( r_dcache_cleanup_req ) break;
4316            r_dcache_cleanup_req = true;
4317            r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
4318            m_cpt_cc_cleanup_data++;
4319            r_dcache_inval_tlb_rsp = false;
4320            r_dcache_inval_rsp = false;
4321            r_dcache_fsm = DCACHE_IDLE;
4322            break;
4323        }
4324
4325        if (!r_dcache_cleanup_req ) // Miss update and no invalidation
4326        {
4327            paddr_t  victim_index = 0;
4328            size_t way = 0;
4329            size_t set = 0;
4330
4331            // Using tlb entry is in the invalidated cache line 
4332            if ( r_dcache_inval_rsp )
4333            {
4334                r_dcache_cleanup_req = true;
4335                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
4336                m_cpt_cc_cleanup_data++;
4337                r_dcache_fsm = DCACHE_IDLE;
4338                r_dcache_inval_rsp = false;
4339                break;
4340            }
4341
4342            bool cleanup_req = r_dcache.find(r_dcache_paddr_save.read(), r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
4343
4344            if ( cleanup_req )
4345            {       
4346                // ins tlb invalidate verification   
4347                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
4348                r_dcache_itlb_inval_line = victim_index;
4349                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4350
4351                // data tlb invalidate verification
4352                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set];
4353                r_dcache_dtlb_inval_line = victim_index;
4354                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4355
4356                r_dcache_cleanup_req = true;
4357                r_dcache_cleanup_line = victim_index;
4358                m_cpt_cc_cleanup_data++;
4359                if ( r_dcache_in_itlb[m_dcache_sets*way+set] || r_dcache_in_dtlb[m_dcache_sets*way+set] )
4360                {
4361                    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4362                    r_dcache_fsm_save = r_dcache_fsm;
4363                    break;
4364                }
4365            }
4366            m_cpt_dcache_dir_write++;
4367            m_cpt_dcache_data_write++;
4368            r_dcache.update(r_dcache_paddr_save.read(), way, set, r_dcache_miss_buf);
4369            r_dcache_fsm = DCACHE_IDLE;
4370        }
4371        break;
4372    }
4373    //////////////////////
4374    case DCACHE_UNC_WAIT:
4375    {
4376        m_cost_unc_read_frz++;
4377
4378        // external cache invalidate request
4379        if ( r_tgt_dcache_req )
4380        {
4381            r_dcache_fsm = DCACHE_CC_CHECK;
4382            r_dcache_fsm_save = r_dcache_fsm;
4383            break;
4384        }
4385
4386        if ( !r_dcache_unc_req )
4387        {
4388            if ( r_vci_rsp_data_error )
4389            {
4390                r_dcache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS;
4391                r_dcache_bad_vaddr = dreq.addr;
4392                r_dcache_fsm = DCACHE_ERROR;
4393
4394                if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
4395                break;
4396            }
4397
4398            if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
4399            {
4400                r_dcache_inval_tlb_rsp = false;
4401            }
4402
4403            if(dreq.type == iss_t::DATA_SC)
4404            {
4405                size_t way = 0;
4406                size_t set = 0;
4407                // Simulate an invalidate request
4408                r_dcache_cleanup_req = r_dcache.inval(r_dcache_paddr_save, &way, &set);
4409                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words)+2);
4410                m_cpt_cc_cleanup_data++;
4411               
4412                if ( r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set] )
4413                {       
4414                    // ins tlb invalidate verification
4415                    r_dcache_itlb_inval_req = r_dcache_in_itlb[way*m_dcache_sets+set];
4416                    r_dcache_itlb_inval_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words)+2);
4417                    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4418               
4419                    // data tlb invalidate verification
4420                    r_dcache_dtlb_inval_req = r_dcache_in_dtlb[way*m_dcache_sets+set];
4421                    r_dcache_dtlb_inval_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words)+2);
4422                    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4423                    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4424                    r_dcache_fsm_save = r_dcache_fsm;
4425                    break;
4426                }
4427
4428            }           
4429            drsp.valid = true;
4430            drsp.rdata = r_dcache_miss_buf[0];
4431            r_dcache_fsm = DCACHE_IDLE;
4432        }       
4433        break;
4434    }
4435    ///////////////////////
4436    case DCACHE_WRITE_UPDT:
4437    {
4438        m_cost_write_frz++;
4439        m_cpt_dcache_data_write++;
4440        size_t way = 0;
4441        size_t set = 0;
4442        bool write_hit = false;
4443        data_t mask = vci_param::be2mask(r_dcache_be_save.read());
4444        data_t wdata = (mask & r_dcache_wdata_save) | (~mask & r_dcache_rdata_save);
4445        write_hit = r_dcache.write(r_dcache_paddr_save, wdata, &way, &set);
4446        assert(write_hit && "Write on miss ignores data");
4447       
4448        if (r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[m_dcache_sets*way+set])
4449        {
4450            // ins tlb invalidate verification   
4451            r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
4452            r_dcache_itlb_inval_line = (r_dcache.get_tag(way, set) * m_dcache_sets) + set;
4453            r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4454
4455            // data tlb invalidate verification
4456            r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set];
4457            r_dcache_dtlb_inval_line = (r_dcache.get_tag(way, set) * m_dcache_sets) + set;
4458            r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4459
4460            r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4461            r_dcache_fsm_save = r_dcache_fsm;
4462            break;
4463        }
4464
4465        if ( !r_dcache_dirty_save && (r_mmu_mode.read() & DATA_TLB_MASK) )   
4466        {
4467            m_cpt_data_tlb_update_dirty++;
4468            m_cost_data_tlb_update_dirty_frz++;
4469            if ( dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save) ) // 2M page size, one level page table
4470            {               
4471                r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
4472                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
4473                r_dcache_tlb_ll_dirty_req = true;
4474                r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;         
4475            }
4476            else
4477            {   
4478                if (r_dcache_hit_p_save)
4479                {
4480                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
4481                    r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save|(paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
4482                    r_dcache_tlb_ll_dirty_req = true;
4483                    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
4484                }
4485                else
4486                {
4487                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
4488                    r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
4489                    r_dcache_tlb_ptba_read = true;
4490                    r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
4491                }
4492            }
4493        }
4494        else
4495        {
4496            r_dcache_fsm = DCACHE_WRITE_REQ;
4497            drsp.valid = true;
4498            drsp.rdata = 0;
4499        }
4500        break;
4501    }
4502    ////////////////////////
4503    case DCACHE_WRITE_DIRTY:
4504    {
4505        m_cost_data_tlb_update_dirty_frz++;
4506
4507        // external cache invalidate request
4508        if ( r_tgt_dcache_req )
4509        {
4510            r_dcache_fsm = DCACHE_CC_CHECK;
4511            r_dcache_fsm_save = r_dcache_fsm;
4512            break;
4513        }
4514
4515        if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
4516        {
4517            r_dcache_fsm = DCACHE_IDLE;
4518            r_dcache_inval_tlb_rsp = false;
4519            break;
4520        }
4521
4522        if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
4523        {
4524            r_dcache_fsm = DCACHE_IDLE;
4525            r_dcache_inval_rsp = false;
4526            break;         
4527        }
4528
4529        m_cpt_dcache_data_write++;
4530        r_dcache.write(r_dcache_tlb_paddr, r_dcache_pte_update);
4531        dcache_tlb.setdirty(r_dcache_tlb_way_save, r_dcache_tlb_set_save);
4532        r_dcache_fsm = DCACHE_WRITE_REQ;
4533        drsp.valid = true;
4534        drsp.rdata = 0;
4535        break;
4536    }
4537    /////////////////
4538    case DCACHE_ERROR:
4539    {
4540        r_vci_rsp_data_error = false;
4541        drsp.valid = true;
4542        drsp.error = true;
4543        drsp.rdata = 0;
4544        r_dcache_fsm = DCACHE_IDLE;
4545        break;
4546    }   
4547    //////////////////////
4548    case DCACHE_ITLB_READ:
4549    {
4550       if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++;
4551
4552        // external cache invalidate request
4553        if ( r_tgt_dcache_req )
4554        {
4555            r_dcache_fsm = DCACHE_CC_CHECK;
4556            r_dcache_fsm_save = r_dcache_fsm;
4557            break;
4558        }
4559
4560        if ( !r_dcache_itlb_read_req ) // vci response ok
4561        { 
4562            if ( r_vci_rsp_data_error )
4563            {
4564                r_dcache_rsp_itlb_error = true;
4565                r_itlb_read_dcache_req = false;
4566                r_vci_rsp_data_error = false;
4567                r_dcache_fsm = DCACHE_IDLE;
4568
4569                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
4570                break;
4571            }
4572
4573            if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
4574            {
4575                if ( r_dcache_cleanup_req ) break;
4576                r_dcache_cleanup_req = true;
4577                r_dcache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
4578                m_cpt_cc_cleanup_data++;
4579                r_dcache_fsm = DCACHE_IDLE;
4580                r_dcache_inval_rsp = false;
4581                break;
4582            }
4583
4584            r_dcache_fsm = DCACHE_ITLB_UPDT;
4585        }
4586        break;         
4587    }
4588    //////////////////////
4589    case DCACHE_ITLB_UPDT:
4590    {
4591        if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++; 
4592
4593        // external cache invalidate request
4594        if ( r_tgt_dcache_req )
4595        {
4596            r_dcache_fsm = DCACHE_CC_CHECK;
4597            r_dcache_fsm_save = r_dcache_fsm;
4598            break;
4599        }
4600
4601        if ( !r_dcache_cleanup_req )
4602        {
4603            data_t rsp_itlb_miss = 0;
4604            data_t rsp_itlb_ppn = 0;
4605
4606            paddr_t  victim_index = 0;
4607            size_t way = 0;
4608            size_t set = 0;
4609
4610            if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
4611            {
4612                r_dcache_cleanup_req = true;
4613                r_dcache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2); 
4614                m_cpt_cc_cleanup_data++;
4615                r_dcache_fsm = DCACHE_IDLE;
4616                r_dcache_inval_rsp = false;
4617                break;
4618            }           
4619 
4620            bool cleanup = r_dcache.find(r_icache_paddr_save, r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
4621
4622            if ( cleanup )
4623            {       
4624                // ins tlb invalidate verification   
4625                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
4626                r_dcache_itlb_inval_line = victim_index;
4627                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4628
4629                // data tlb invalidate verification
4630                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set];
4631                r_dcache_dtlb_inval_line = victim_index;
4632                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4633
4634                r_dcache_cleanup_req = true;
4635                r_dcache_cleanup_line = victim_index;
4636                m_cpt_cc_cleanup_data++;
4637                if ( r_dcache_in_itlb[m_dcache_sets*way+set] || r_dcache_in_dtlb[m_dcache_sets*way+set] )
4638                {
4639                    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4640                    r_dcache_fsm_save = r_dcache_fsm;
4641                    break;
4642                }
4643            }
4644
4645            r_dcache.update(r_icache_paddr_save, way, set, r_dcache_miss_buf);
4646
4647            r_dcache.setinbit(r_icache_paddr_save, r_dcache_in_itlb, true);
4648            bool itlb_hit_dcache = r_dcache.read(r_icache_paddr_save, &rsp_itlb_miss); 
4649            m_cpt_ins_tlb_occup_cache++;
4650
4651            if ( r_itlb_k_read_dcache && itlb_hit_dcache )
4652            {   
4653                r_itlb_k_read_dcache = false;
4654                bool itlb_hit_ppn = r_dcache.read(r_icache_paddr_save.read()+4, &rsp_itlb_ppn);
4655                assert(itlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
4656            }
4657
4658            r_dcache_rsp_itlb_miss = rsp_itlb_miss;
4659            r_dcache_rsp_itlb_ppn = rsp_itlb_ppn;
4660            r_dcache_rsp_itlb_error = false;   
4661            r_itlb_read_dcache_req = false;
4662            r_dcache_fsm = DCACHE_IDLE;
4663        }
4664        break;
4665    }
4666    //////////////////////////
4667    case DCACHE_ITLB_LL_WAIT:
4668    {
4669        if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++;         
4670        // external cache invalidate request
4671        if ( r_tgt_dcache_req )   
4672        {
4673            r_dcache_fsm = DCACHE_CC_CHECK;
4674            r_dcache_fsm_save = r_dcache_fsm;
4675            break;
4676        }
4677
4678        if (!r_dcache_itlb_ll_acc_req)
4679        {
4680            if ( r_vci_rsp_data_error ) // VCI response ko
4681            {
4682                r_dcache_rsp_itlb_error = true; 
4683                r_vci_rsp_data_error = false;
4684                r_itlb_acc_dcache_req = false;
4685                r_dcache_fsm = DCACHE_IDLE;
4686                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;     
4687            }
4688            else
4689            {
4690                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )   // unmapped
4691                {
4692                    r_dcache_rsp_itlb_error = true; 
4693                    r_itlb_acc_dcache_req = false;
4694                    r_dcache_fsm = DCACHE_IDLE;
4695                    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
4696                }
4697                else if ( r_dcache_inval_rsp )
4698                {
4699                    r_dcache_inval_rsp = false;
4700                    r_dcache_fsm = DCACHE_IDLE;
4701                }
4702                else
4703                {
4704                    r_dcache_itlb_sc_acc_req = true;
4705                    r_icache_pte_update = r_dcache_miss_buf[0] | r_icache_pte_update.read();   
4706                    r_dcache_fsm = DCACHE_ITLB_SC_WAIT;
4707                }
4708            }
4709        }
4710        break;
4711    }
4712    //////////////////////////
4713    case DCACHE_ITLB_SC_WAIT:
4714    {
4715        if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++;         
4716        // external cache invalidate request
4717        if ( r_tgt_dcache_req )   
4718        {
4719            r_dcache_fsm = DCACHE_CC_CHECK;
4720            r_dcache_fsm_save = r_dcache_fsm;
4721            break;
4722        }
4723       
4724        if ( !r_dcache_itlb_sc_acc_req )
4725        {
4726            if ( r_vci_rsp_data_error ) // VCI response ko
4727            {
4728                r_dcache_rsp_itlb_error = true; 
4729                r_vci_rsp_data_error = false;
4730                r_itlb_acc_dcache_req = false;
4731                r_dcache_fsm = DCACHE_IDLE;
4732                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;             
4733            }
4734            else
4735            {
4736                if ( r_dcache_inval_rsp )
4737                {
4738                    r_dcache_inval_rsp = false;
4739                    r_dcache_fsm = DCACHE_IDLE;
4740                    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
4741                }
4742                else if ( r_dcache_tlb_sc_fail )
4743                {
4744                    r_dcache_tlb_sc_fail = false;
4745                    r_dcache_itlb_ll_acc_req = true;
4746                    r_dcache_fsm = DCACHE_ITLB_LL_WAIT;
4747                }
4748                else
4749                {
4750                    r_itlb_acc_dcache_req = false;
4751                    r_dcache_fsm = DCACHE_IDLE;
4752                }
4753            }
4754        }
4755        break;
4756    }
4757    /////////////////////
4758    case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
4759    {
4760        m_cpt_dcache_dir_read += m_dcache_ways;
4761        m_cpt_dcache_data_read += m_dcache_ways;
4762
4763        /* activity counter */
4764        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )       
4765        {
4766            m_cost_data_miss_frz++;
4767        }
4768        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
4769             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
4770             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
4771             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
4772             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
4773             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )) && (dreq.valid) )
4774        {
4775            m_cost_data_tlb_miss_frz++;
4776        }
4777
4778        // DCACHE_TLB1_LL_WAIT  DCACHE_TLB1_SC_WAIT  DCACHE_LL_DIRTY_WAIT  DCACHE_WRITE_DIRTY DCACHE_ITLB_LL_WAIT  DCACHE_ITLB_SC_WAIT
4779        // DCACHE_TLB2_LL_WAIT  DCACHE_TLB2_SC_WAIT  DCACHE_SC_DIRTY_WAIT
4780        if((( /*( r_dcache_fsm_save == DCACHE_UNC_WAIT ) ||*/
4781             ( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) &&
4782           ( (r_dcache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))))
4783        || (( ( r_dcache_fsm_save == DCACHE_TLB1_READ )      || ( r_dcache_fsm_save == DCACHE_TLB2_READ )      ||
4784             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT ) || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT ) ||
4785             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )      || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )         /* ||
4786             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )   || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )   ||
4787             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )   || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )   ||
4788             ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT )  || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )  ||
4789             ( r_dcache_fsm_save == DCACHE_WRITE_DIRTY )*/ ) &&
4790           ( (r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))) )
4791        || (( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) || ( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) /*||
4792             ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT )*/ ) &&
4793           ( (r_icache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))) ) )
4794        {
4795            r_dcache_inval_rsp = true;
4796            r_tgt_dcache_req = false;
4797            if ( r_tgt_update )
4798            {    // Also send a cleanup and answer
4799                r_tgt_dcache_rsp = true;
4800            }
4801            else
4802            {            // Also send a cleanup but don't answer
4803                r_tgt_dcache_rsp = false;
4804            }
4805            r_dcache_fsm = r_dcache_fsm_save;
4806        }
4807        else
4808        {
4809            data_t dcache_rdata = 0;
4810            size_t way = 0;
4811            size_t set = 0;
4812
4813            bool dcache_hit = r_dcache.read(r_tgt_addr.read(), &dcache_rdata, &way, &set);
4814
4815            if ( dcache_hit )
4816            {
4817                if ( r_dcache_in_dtlb[m_dcache_sets*way+set] || r_dcache_in_itlb[m_dcache_sets*way+set] )
4818                {
4819                    // ins tlb invalidate verification   
4820                    r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
4821                    r_dcache_itlb_inval_line = r_tgt_addr.read() >> (uint32_log2(m_dcache_words)+2);
4822                    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
4823
4824                    // data tlb invalidate verification
4825                    r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set];
4826                    r_dcache_dtlb_inval_line = r_tgt_addr.read() >> (uint32_log2(m_dcache_words)+2);
4827                    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
4828               
4829                    r_dcache_cc_check = true;
4830                    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
4831                    break;
4832                }
4833
4834                if ( r_tgt_update ) // update
4835                {
4836                    r_dcache_fsm = DCACHE_CC_UPDT;
4837                }
4838                else                // invalidate
4839                {
4840                    r_dcache_fsm = DCACHE_CC_INVAL;
4841                }
4842            }
4843            else                    // nothing
4844            {
4845                r_dcache_fsm = DCACHE_CC_NOP;
4846            }
4847        }
4848        break;
4849    }
4850    ///////////////////
4851    case DCACHE_CC_UPDT:    // update directory and data cache       
4852    {
4853        /* activity counter */
4854        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )       
4855        {
4856            m_cost_data_miss_frz++;
4857        }
4858        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
4859             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
4860             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
4861             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
4862             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
4863             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )) && (dreq.valid) )
4864        {
4865            m_cost_data_tlb_miss_frz++;
4866        }
4867
4868        m_cpt_dcache_dir_write++;
4869        m_cpt_dcache_data_write++;
4870        data_t* buf = r_tgt_buf;
4871        for( size_t i = 0; i < m_dcache_words; i++ )
4872        {
4873            if( r_tgt_val[i] ) r_dcache.write( r_tgt_addr.read() + i*4, buf[i] );
4874        }
4875           
4876        r_tgt_dcache_req = false;
4877        r_tgt_dcache_rsp = true;
4878        r_dcache_fsm = r_dcache_fsm_save;
4879        break;
4880    }
4881    /////////////////////
4882    case DCACHE_CC_INVAL:   // invalidate a cache line
4883    {
4884        /* activity counter */
4885        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )       
4886        {
4887            m_cost_data_miss_frz++;
4888        }
4889        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
4890             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
4891             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
4892             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
4893             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
4894             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )) && (dreq.valid) )
4895        {
4896            m_cost_data_tlb_miss_frz++;
4897        }
4898
4899        r_tgt_dcache_rsp = r_dcache.inval(r_tgt_addr.read());
4900        r_tgt_dcache_req = false;
4901        r_dcache_fsm = r_dcache_fsm_save;
4902        break;
4903    }
4904    ///////////////////
4905    case DCACHE_CC_NOP:     // no external hit
4906    {
4907        /* activity counter */
4908        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )       
4909        {
4910            m_cost_data_miss_frz++;
4911        }
4912        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
4913             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
4914             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
4915             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
4916             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
4917             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )) && (dreq.valid) )
4918        {
4919            m_cost_data_tlb_miss_frz++;
4920        }
4921
4922        r_tgt_dcache_req = false;
4923        if ( r_tgt_update )
4924        {
4925            r_tgt_dcache_rsp = true;
4926        }
4927        else
4928        {
4929            r_tgt_dcache_rsp = false;
4930        }
4931
4932        r_dcache_fsm = r_dcache_fsm_save;
4933        break;
4934    }   
4935    /////////////////////////
4936    case DCACHE_TLB_CC_INVAL:
4937    {
4938        /* activity counter */
4939        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )       
4940        {
4941            m_cost_data_miss_frz++;
4942        }
4943        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
4944             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
4945             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
4946             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
4947             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
4948             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )) && (dreq.valid) )
4949        {
4950            m_cost_data_tlb_miss_frz++;
4951        }
4952
4953        if ( r_dcache_itlb_inval_req || r_dcache_dtlb_inval_req ) break;
4954
4955        if( (( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
4956             ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
4957             ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )     ||
4958             ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )     || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )     ||
4959             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )        ||
4960             ( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
4961             ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT )    || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )    ||
4962             ( r_dcache_fsm_save == DCACHE_WRITE_DIRTY )) &&
4963            (((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_dtlb_inval_line.read()) )
4964        {
4965            r_dcache_inval_tlb_rsp = true;
4966        }
4967
4968        if (((r_dcache_fsm_save == DCACHE_BIS)||(r_dcache_fsm_save == DCACHE_MISS_WAIT) ||
4969             (r_dcache_fsm_save == DCACHE_UNC_WAIT)||(r_dcache_fsm_save == DCACHE_MISS_UPDT)) &&
4970             (r_dcache_tlb_nline.read() == r_dcache_dtlb_inval_line.read()))
4971        {
4972            r_dcache_inval_tlb_rsp = true;
4973        }
4974
4975        if ( !r_dcache_cc_check )
4976        {
4977            r_dcache_fsm = r_dcache_fsm_save;
4978        }
4979        else
4980        {
4981            r_dcache_fsm = DCACHE_CC_CHECK;
4982            r_dcache_cc_check = false;
4983        }
4984        r_dtlb_translation_valid = false;
4985        r_dcache_ptba_ok = false;
4986        break;
4987    }
4988    /////////////////////////
4989    case DCACHE_ITLB_CLEANUP:
4990    {
4991        if ( dreq.valid ) m_cost_data_miss_frz++;
4992
4993        r_dcache.setinbit(((paddr_t)r_dcache_itlb_cleanup_line.read()*m_dcache_words*2), r_dcache_in_itlb, false);
4994        r_dcache_itlb_cleanup_req = false;
4995        r_dcache_fsm = DCACHE_IDLE;
4996        break;
4997    }
4998    } // end switch r_dcache_fsm
4999
5000#ifdef SOCLIB_MODULE_DEBUG
5001    std::cout << name() << " Data Response: " << drsp << std::endl;
5002#endif
5003
5004    ////////////////////////////////////////////////////////////////////////////////////
5005    //      INVAL DTLB CHECK FSM
5006    ////////////////////////////////////////////////////////////////////////////////////////
5007    switch(r_inval_dtlb_fsm) {
5008    /////////////////////
5009    case INVAL_DTLB_IDLE:
5010    {
5011        if ( r_dcache_dtlb_inval_req )
5012        {
5013            r_ccinval_dtlb_way = 0;
5014            r_ccinval_dtlb_set = 0;
5015            r_inval_dtlb_fsm = INVAL_DTLB_CHECK;   
5016            m_cost_data_tlb_inval_frz++;
5017        }   
5018        break;
5019    }
5020    ////////////////////////////
5021    case INVAL_DTLB_CHECK:
5022    {
5023        m_cost_data_tlb_inval_frz++;
5024
5025        size_t way = r_ccinval_dtlb_way;
5026        size_t set = r_ccinval_dtlb_set;
5027        bool end = false;       
5028        bool tlb_hit = dcache_tlb.cccheck(r_dcache_dtlb_inval_line.read(), way, set, &way, &set, &end);
5029   
5030        if ( tlb_hit )
5031        {
5032            r_ccinval_dtlb_way = way;
5033            r_ccinval_dtlb_set = set;
5034            r_dtlb_cc_check_end = end;
5035            r_inval_dtlb_fsm = INVAL_DTLB_INVAL;
5036            m_cpt_data_tlb_inval++;   
5037        }       
5038        else
5039        {
5040            r_inval_dtlb_fsm = INVAL_DTLB_CLEAR;   
5041        }
5042        break;
5043    }
5044    /////////////////////////
5045    case INVAL_DTLB_INVAL:
5046    {
5047        m_cost_data_tlb_inval_frz++;
5048
5049        dcache_tlb.ccinval(r_ccinval_dtlb_way, r_ccinval_dtlb_set);
5050
5051        if ( !r_dtlb_cc_check_end )
5052        {
5053            r_inval_dtlb_fsm = INVAL_DTLB_CHECK;
5054        }
5055        else
5056        {
5057            r_inval_dtlb_fsm = INVAL_DTLB_CLEAR;   
5058        }
5059        break;
5060    }
5061    ////////////////////
5062    case INVAL_DTLB_CLEAR:
5063    {
5064        r_dcache_dtlb_inval_req = false;
5065        r_dtlb_cc_check_end = false;
5066        r_ccinval_dtlb_way = 0;
5067        r_ccinval_dtlb_set = 0;
5068        r_inval_dtlb_fsm = INVAL_DTLB_IDLE;   
5069        m_cpt_data_tlb_inval++;   
5070        break;
5071    }
5072    } // end switch r_inval_itlb_fsm
5073
5074    /////////// execute one iss cycle /////////////////////////////////
5075    {
5076    uint32_t it = 0;
5077    for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if(p_irq[i].read()) it |= (1<<i);
5078    m_iss.executeNCycles(1, irsp, drsp, it);
5079    }
5080
5081    ////////////// number of frozen cycles //////////////////////////
5082    if ( (ireq.valid && !irsp.valid) || (dreq.valid && !drsp.valid) )
5083    {
5084        m_cpt_frz_cycles++;
5085    }
5086    if ( dreq.valid && !drsp.valid )
5087    {
5088        m_cpt_dcache_frz_cycles++;
5089    }
5090    for (size_t way = 0; way < m_dcache_ways; way++ )
5091    {   
5092        for (size_t set = 0; set < m_dcache_sets; set++ )
5093        {
5094            if (r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set])
5095                m_cpt_tlb_occup_dcache++;
5096        }
5097    }
5098    ////////////////////////////////////////////////////////////////////////////
5099    //     VCI_CMD FSM
5100    //
5101    // This FSM handles requests from both the DCACHE controler
5102    // (request registers) and the ICACHE controler (request registers).
5103    // There is 10 VCI transaction types :
5104    // - INS_TLB_READ
5105    // - INS_TLB_WRITE
5106    // - INS_MISS
5107    // - INS_UNC_MISS
5108    // - DATA_TLB_READ
5109    // - DATA_TLB_WRITE
5110    // - DATA_TLB_DIRTY
5111    // - DATA_MISS
5112    // - DATA_UNC
5113    // - DATA_WRITE
5114    // The ICACHE requests have the highest priority.
5115    // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM and RSP_FSM
5116    // exit simultaneously the IDLE state.
5117    //////////////////////////////////////////////////////////////////////////////
5118
5119    switch (r_vci_cmd_fsm) {
5120   
5121    case CMD_IDLE:
5122        if (r_vci_rsp_fsm != RSP_IDLE)
5123            break;
5124
5125        r_vci_cmd_cpt = 0;
5126
5127        if (r_icache_cleanup_req)
5128        {
5129            r_vci_cmd_fsm = CMD_INS_CLEANUP;
5130            m_cpt_icleanup_transaction++;
5131        }
5132        else if (r_dcache_cleanup_req)
5133        {
5134            r_vci_cmd_fsm = CMD_DATA_CLEANUP;
5135            m_cpt_dcleanup_transaction++;
5136        }
5137        else if (r_dcache_itlb_read_req)           
5138        {           
5139            r_vci_cmd_fsm = CMD_ITLB_READ;
5140            m_cpt_itlbmiss_transaction++;
5141        }
5142        else if (r_dcache_itlb_ll_acc_req)
5143        {
5144            r_vci_cmd_fsm = CMD_ITLB_ACC_LL;
5145            m_cpt_itlb_ll_transaction++;
5146        }
5147        else if (r_dcache_itlb_sc_acc_req)
5148        {
5149            r_vci_cmd_fsm = CMD_ITLB_ACC_SC;
5150            m_cpt_itlb_sc_transaction++;
5151        }
5152        else if (r_icache_miss_req)
5153        {   
5154            r_vci_cmd_fsm = CMD_INS_MISS;
5155            m_cpt_imiss_transaction++;
5156        }
5157        else if (r_icache_unc_req)
5158        {   
5159            r_vci_cmd_fsm = CMD_INS_UNC;
5160            m_cpt_icache_unc_transaction++;
5161        } 
5162        else if (r_dcache_tlb_read_req)
5163        {           
5164            r_vci_cmd_fsm = CMD_DTLB_READ;
5165            m_cpt_dtlbmiss_transaction++;
5166        }
5167        else if (r_dcache_tlb_ll_acc_req)
5168        { 
5169            r_vci_cmd_fsm = CMD_DTLB_ACC_LL;
5170            m_cpt_dtlb_ll_transaction++;
5171        }
5172        else if (r_dcache_tlb_sc_acc_req)
5173        { 
5174            r_vci_cmd_fsm = CMD_DTLB_ACC_SC;
5175            m_cpt_dtlb_sc_transaction++;
5176        }
5177        else if (r_dcache_tlb_ll_dirty_req)
5178        { 
5179            r_vci_cmd_fsm = CMD_DTLB_DIRTY_LL;
5180            m_cpt_dtlb_ll_dirty_transaction++;
5181        }
5182        else if (r_dcache_tlb_sc_dirty_req)
5183        { 
5184            r_vci_cmd_fsm = CMD_DTLB_DIRTY_SC;
5185            m_cpt_dtlb_sc_dirty_transaction++;
5186        }
5187        else if (r_dcache_write_req)
5188        {
5189            r_vci_cmd_fsm = CMD_DATA_WRITE;
5190            r_vci_cmd_cpt = r_wbuf.getMin();
5191            r_vci_cmd_min = r_wbuf.getMin();
5192            r_vci_cmd_max = r_wbuf.getMax();
5193            m_cpt_write_transaction++;
5194            m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1);
5195        }
5196        else if (r_dcache_miss_req) 
5197        {
5198            r_vci_cmd_fsm = CMD_DATA_MISS;
5199            m_cpt_dmiss_transaction++;
5200        }
5201        else if (r_dcache_unc_req) 
5202        {
5203            r_vci_cmd_fsm = CMD_DATA_UNC;
5204            m_cpt_unc_transaction++;
5205        }
5206        break;
5207
5208    case CMD_DATA_WRITE:
5209        if ( p_vci_ini_rw.cmdack.read() )
5210        {
5211            r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
5212            if (r_vci_cmd_cpt == r_vci_cmd_max)
5213            {
5214                r_vci_cmd_fsm = CMD_IDLE;
5215                r_wbuf.reset();
5216            }
5217        }
5218        break;
5219
5220    case CMD_INS_CLEANUP:
5221    case CMD_DATA_CLEANUP:
5222        if ( p_vci_ini_c.cmdack.read() )
5223        {
5224            r_vci_cmd_fsm = CMD_IDLE;
5225        }
5226        break;
5227
5228    default:
5229        if ( p_vci_ini_rw.cmdack.read() )
5230        { 
5231            r_vci_cmd_fsm = CMD_IDLE;
5232        }
5233        break;
5234
5235    } // end  switch r_vci_cmd_fsm
5236
5237    //////////////////////////////////////////////////////////////////////////
5238    //      VCI_RSP FSM
5239    //
5240    // This FSM is synchronized with the VCI_CMD FSM, as both FSMs exit the
5241    // IDLE state simultaneously.
5242    //////////////////////////////////////////////////////////////////////////
5243
5244    switch (r_vci_rsp_fsm) {
5245
5246    case RSP_IDLE:
5247        assert( !p_vci_ini_rw.rspval.read() && !p_vci_ini_c.rspval.read() && "Unexpected response" );
5248
5249        if (r_vci_cmd_fsm != CMD_IDLE)
5250            break;
5251
5252        r_vci_rsp_cpt = 0;
5253        if (r_icache_cleanup_req)            // ICACHE cleanup response
5254        {
5255            r_vci_rsp_fsm = RSP_INS_CLEANUP;
5256        }
5257        else if (r_dcache_cleanup_req)       // DCACHE cleanup response
5258        {
5259            r_vci_rsp_fsm = RSP_DATA_CLEANUP;
5260        }
5261        else if (r_dcache_itlb_read_req)          // ITLB miss response
5262        {           
5263            r_vci_rsp_fsm = RSP_ITLB_READ;
5264        }
5265        else if (r_dcache_itlb_ll_acc_req)   // ITLB linked load response
5266        {   
5267            r_vci_rsp_fsm = RSP_ITLB_ACC_LL;
5268        }
5269        else if (r_dcache_itlb_sc_acc_req)   // ITLB store conditional response
5270        {   
5271            r_vci_rsp_fsm = RSP_ITLB_ACC_SC;
5272        }
5273        else if (r_icache_miss_req)          // ICACHE cached miss response
5274        {   
5275            r_vci_rsp_fsm = RSP_INS_MISS;
5276        }
5277        else if (r_icache_unc_req)           // ICACHE uncached miss response
5278        {   
5279            r_vci_rsp_fsm = RSP_INS_UNC;
5280        } 
5281        else if (r_dcache_tlb_read_req)      // ITLB miss response
5282        {
5283            r_vci_rsp_fsm = RSP_DTLB_READ;
5284        }
5285        else if (r_dcache_tlb_ll_acc_req)    // DTLB access bits linked load response
5286        {
5287            r_vci_rsp_fsm = RSP_DTLB_ACC_LL;
5288        }
5289        else if (r_dcache_tlb_sc_acc_req)    // DTLB access bits store conditional response
5290        {
5291            r_vci_rsp_fsm = RSP_DTLB_ACC_SC;
5292        }
5293        else if (r_dcache_tlb_ll_dirty_req)  // DTLB dirty bit linked load response
5294        {
5295            r_vci_rsp_fsm = RSP_DTLB_DIRTY_LL;
5296        }
5297        else if (r_dcache_tlb_sc_dirty_req)  // DTLB dirty bit store conditional response
5298        {
5299            r_vci_rsp_fsm = RSP_DTLB_DIRTY_SC;
5300        }
5301        else if (r_dcache_write_req)         // DCACHE write response
5302        {
5303            r_vci_rsp_fsm = RSP_DATA_WRITE;
5304        }
5305        else if (r_dcache_miss_req)          // DCACHE read response
5306        {
5307            r_vci_rsp_fsm = RSP_DATA_MISS;
5308        }
5309        else if (r_dcache_unc_req)           // DCACHE uncached read response
5310        {
5311            r_vci_rsp_fsm = RSP_DATA_UNC;
5312        }
5313        break;
5314
5315    case RSP_ITLB_READ:
5316        m_cost_itlbmiss_transaction++;
5317        if ( ! p_vci_ini_rw.rspval.read() )
5318            break;
5319
5320        assert(r_vci_rsp_cpt != m_dcache_words &&
5321               "illegal VCI response packet for data read miss");
5322
5323        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
5324        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
5325        if ( p_vci_ini_rw.reop.read() )
5326        {
5327            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
5328                    "illegal VCI response packet for data read miss");
5329            r_dcache_itlb_read_req = false;
5330            r_vci_rsp_fsm = RSP_IDLE;
5331        }
5332        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5333        {
5334            r_vci_rsp_data_error = true;
5335        }
5336        break;
5337
5338    case RSP_ITLB_ACC_LL:
5339        m_cost_itlb_ll_transaction++;
5340        if ( ! p_vci_ini_rw.rspval.read() )
5341            break;
5342
5343        assert(p_vci_ini_rw.reop.read() &&
5344               "illegal VCI response packet for ll tlb");
5345
5346        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5347        {
5348            r_vci_rsp_data_error = true;
5349        }
5350        else
5351        {
5352            r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
5353        }
5354        r_dcache_itlb_ll_acc_req = false;
5355        r_vci_rsp_fsm = RSP_IDLE;
5356        break;
5357
5358    case RSP_ITLB_ACC_SC:
5359        m_cost_itlb_sc_transaction++;
5360        if ( ! p_vci_ini_rw.rspval.read() )
5361            break;
5362
5363        assert(p_vci_ini_rw.reop.read() &&
5364               "illegal VCI response packet for sc tlb");
5365
5366        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5367        {
5368            r_vci_rsp_data_error = true;
5369        }
5370        else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
5371        {
5372            r_dcache_tlb_sc_fail = true;
5373            //r_dcache_itlb_ll_acc_req = true;
5374        }
5375        r_dcache_itlb_sc_acc_req = false;
5376        r_vci_rsp_fsm = RSP_IDLE;
5377        break;
5378
5379    case RSP_INS_MISS:
5380        m_cost_imiss_transaction++;
5381        if ( ! p_vci_ini_rw.rspval.read() )
5382            break;
5383
5384        assert( (r_vci_rsp_cpt < m_icache_words) &&
5385               "The VCI response packet for instruction miss is too long");
5386        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
5387        r_icache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
5388
5389        if ( p_vci_ini_rw.reop.read() )
5390        {
5391            assert( (r_vci_rsp_cpt == m_icache_words - 1) &&
5392                       "The VCI response packet for instruction miss is too short");
5393            r_icache_miss_req = false;
5394            r_vci_rsp_fsm = RSP_IDLE;
5395               
5396        }
5397        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5398        {
5399            r_vci_rsp_ins_error = true;
5400        }
5401        break;
5402
5403    case RSP_INS_UNC:
5404        m_cost_icache_unc_transaction++;
5405        if ( ! p_vci_ini_rw.rspval.read() )
5406            break;
5407
5408        assert(p_vci_ini_rw.reop.read() &&
5409               "illegal VCI response packet for uncached instruction");
5410
5411        r_icache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
5412        r_icache_buf_unc_valid = true;
5413        r_icache_unc_req = false;
5414        r_vci_rsp_fsm = RSP_IDLE;
5415
5416        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5417        {
5418            r_vci_rsp_ins_error = true;
5419        }
5420        break;
5421
5422    case RSP_DTLB_READ:
5423        m_cost_dtlbmiss_transaction++;
5424        if ( ! p_vci_ini_rw.rspval.read() )
5425            break;
5426
5427        assert(r_vci_rsp_cpt != m_dcache_words &&
5428               "illegal VCI response packet for data read miss");
5429
5430        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
5431        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
5432        if ( p_vci_ini_rw.reop.read() )
5433        {
5434            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
5435                    "illegal VCI response packet for data read miss");
5436            r_dcache_tlb_read_req = false;
5437            r_vci_rsp_fsm = RSP_IDLE;
5438        }
5439        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5440        {
5441            r_vci_rsp_data_error = true;
5442        }
5443        break;
5444
5445    case RSP_DTLB_ACC_LL:
5446        m_cost_dtlb_ll_transaction++;
5447        if ( ! p_vci_ini_rw.rspval.read() )
5448            break;
5449
5450        assert(p_vci_ini_rw.reop.read() &&
5451               "illegal VCI response packet for ll tlb");
5452
5453        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5454        {
5455            r_vci_rsp_data_error = true;
5456        }
5457        else
5458        {
5459            r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
5460        }
5461        r_dcache_tlb_ll_acc_req = false;
5462        r_vci_rsp_fsm = RSP_IDLE;
5463        break;
5464
5465    case RSP_DTLB_ACC_SC:
5466        m_cost_dtlb_sc_transaction++;
5467        if ( ! p_vci_ini_rw.rspval.read() )
5468            break;
5469
5470        assert(p_vci_ini_rw.reop.read() &&
5471               "illegal VCI response packet for sc tlb");
5472
5473        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5474        {
5475            r_vci_rsp_data_error = true;
5476        }
5477        else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
5478        {
5479            r_dcache_tlb_sc_fail = true;
5480            //r_dcache_tlb_ll_acc_req = true;
5481        }
5482        r_dcache_tlb_sc_acc_req = false;
5483        r_vci_rsp_fsm = RSP_IDLE;
5484        break;
5485
5486    case RSP_DTLB_DIRTY_LL:
5487        m_cost_dtlb_ll_dirty_transaction++;
5488        if ( ! p_vci_ini_rw.rspval.read() )
5489            break;
5490
5491        assert(p_vci_ini_rw.reop.read() &&
5492               "illegal VCI response packet for ll tlb");
5493
5494        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5495        {
5496            r_vci_rsp_data_error = true;
5497        }
5498        else
5499        {
5500            r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
5501        }
5502        r_dcache_tlb_ll_dirty_req = false;
5503        r_vci_rsp_fsm = RSP_IDLE;
5504        break;
5505
5506    case RSP_DTLB_DIRTY_SC:
5507        m_cost_dtlb_sc_dirty_transaction++;
5508        if ( ! p_vci_ini_rw.rspval.read() )
5509            break;
5510
5511        assert(p_vci_ini_rw.reop.read() &&
5512               "illegal VCI response packet for sc tlb");
5513
5514        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5515        {
5516            r_vci_rsp_data_error = true;
5517        }
5518        else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
5519        {
5520            r_dcache_tlb_sc_fail = true;
5521            //r_dcache_tlb_ll_dirty_req = true;
5522        }
5523        r_dcache_tlb_sc_dirty_req = false;
5524        r_vci_rsp_fsm = RSP_IDLE;
5525        break;
5526
5527    case RSP_DATA_UNC:
5528        m_cost_unc_transaction++;
5529        if ( ! p_vci_ini_rw.rspval.read() )
5530            break;
5531
5532        assert(p_vci_ini_rw.reop.read() &&
5533               "illegal VCI response packet for data read uncached");
5534
5535        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5536        {
5537            r_vci_rsp_data_error = true;
5538        }
5539        else
5540        {
5541            r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
5542            r_dcache_buf_unc_valid = true;
5543        }
5544        r_dcache_unc_req = false;
5545        r_vci_rsp_fsm = RSP_IDLE;
5546        break;
5547
5548    case RSP_DATA_MISS:
5549        m_cost_dmiss_transaction++;
5550        if ( ! p_vci_ini_rw.rspval.read() )
5551            break;
5552
5553        assert(r_vci_rsp_cpt != m_dcache_words &&
5554               "illegal VCI response packet for data read miss");
5555
5556        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
5557        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
5558        if ( p_vci_ini_rw.reop.read() )
5559        {
5560            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
5561                    "illegal VCI response packet for data read miss");
5562            r_dcache_miss_req = false;
5563            r_vci_rsp_fsm = RSP_IDLE;
5564        }
5565        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5566        {
5567            r_vci_rsp_data_error = true;
5568        }
5569        break;
5570
5571    case RSP_DATA_WRITE:
5572        m_cost_write_transaction++;
5573        if ( ! p_vci_ini_rw.rspval.read() )
5574            break;
5575
5576        if ( p_vci_ini_rw.reop.read() )
5577        {
5578            r_vci_rsp_fsm = RSP_IDLE;
5579            r_dcache_write_req = false;
5580        }
5581        if ( p_vci_ini_rw.rerror.read() != vci_param::ERR_NORMAL )
5582        {
5583            m_iss.setWriteBerr();
5584        }
5585        break;
5586
5587    case RSP_INS_CLEANUP:
5588    case RSP_DATA_CLEANUP:
5589        if ( r_vci_rsp_fsm == RSP_INS_CLEANUP )
5590        {
5591            m_cost_icleanup_transaction++;
5592        }
5593        else
5594        {                                   
5595            m_cost_dcleanup_transaction++;
5596        }
5597
5598        if ( ! p_vci_ini_c.rspval.read() )
5599            break;
5600        assert( p_vci_ini_c.reop.read() &&
5601                "illegal VCI response packet for icache cleanup");
5602        assert( (p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL) &&
5603                "error in response packet for icache cleanup");
5604
5605        if ( r_vci_rsp_fsm == RSP_INS_CLEANUP )
5606        {
5607            r_icache_cleanup_req = false;
5608        }
5609        else
5610        {                                   
5611            r_dcache_cleanup_req = false;
5612        }
5613        r_vci_rsp_fsm = RSP_IDLE;
5614        break;
5615
5616    } // end switch r_vci_rsp_fsm
5617} // end transition()
5618
5619///////////////////////
5620tmpl(void)::genMoore()
5621///////////////////////
5622{
5623    // VCI initiator response
5624
5625    p_vci_ini_rw.rspack = true;
5626    p_vci_ini_c.rspack = true;
5627
5628    // VCI initiator command
5629
5630    p_vci_ini_rw.pktid  = 0;
5631    p_vci_ini_rw.srcid  = m_srcid_rw;
5632    p_vci_ini_rw.cons   = false;
5633    p_vci_ini_rw.wrap   = false;
5634    p_vci_ini_rw.contig = true;
5635    p_vci_ini_rw.clen   = 0;
5636    p_vci_ini_rw.cfixed = false;
5637
5638    p_vci_ini_c.cmdval  = false;
5639    p_vci_ini_c.address = 0;
5640    p_vci_ini_c.wdata   = 0;
5641    p_vci_ini_c.be      = 0;
5642    p_vci_ini_c.plen    = 0;
5643    p_vci_ini_c.cmd     = vci_param::CMD_NOP;
5644    p_vci_ini_c.trdid   = 0;
5645    p_vci_ini_c.pktid   = 0;
5646    p_vci_ini_c.srcid   = 0;
5647    p_vci_ini_c.cons    = false;
5648    p_vci_ini_c.wrap    = false;
5649    p_vci_ini_c.contig  = false;
5650    p_vci_ini_c.clen    = 0;
5651    p_vci_ini_c.cfixed  = false;
5652    p_vci_ini_c.eop     = false;
5653
5654    switch (r_vci_cmd_fsm) {
5655
5656    case CMD_IDLE:
5657        p_vci_ini_rw.cmdval  = false;
5658        p_vci_ini_rw.address = 0;
5659        p_vci_ini_rw.wdata   = 0;
5660        p_vci_ini_rw.be      = 0;
5661        p_vci_ini_rw.trdid   = 0;
5662        p_vci_ini_rw.plen    = 0;
5663        p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
5664        p_vci_ini_rw.eop     = false;
5665        break;
5666
5667    case CMD_ITLB_READ:     
5668        p_vci_ini_rw.cmdval  = true;
5669        p_vci_ini_rw.address = r_icache_paddr_save.read() & m_dcache_yzmask;
5670        p_vci_ini_rw.wdata   = 0;
5671        p_vci_ini_rw.be      = 0xF;
5672        p_vci_ini_rw.trdid   = 1; // via data cache cached read
5673        p_vci_ini_rw.plen    = m_dcache_words << 2;
5674        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
5675        p_vci_ini_rw.eop     = true;
5676        break;
5677
5678    case CMD_ITLB_ACC_LL:
5679        p_vci_ini_rw.cmdval  = true;
5680        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
5681        p_vci_ini_rw.wdata   = 0;
5682        p_vci_ini_rw.be      = 0xF;
5683        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5684        p_vci_ini_rw.plen    = 4;
5685        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
5686        p_vci_ini_rw.eop     = true;
5687        break;
5688
5689    case CMD_ITLB_ACC_SC:
5690        p_vci_ini_rw.cmdval  = true;
5691        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
5692        p_vci_ini_rw.wdata   = r_icache_pte_update.read();
5693        p_vci_ini_rw.be      = 0xF;
5694        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5695        p_vci_ini_rw.plen    = 4;
5696        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
5697        p_vci_ini_rw.eop     = true;
5698        break; 
5699
5700    case CMD_INS_MISS:
5701        p_vci_ini_rw.cmdval  = true;
5702        p_vci_ini_rw.address = r_icache_paddr_save.read() & m_icache_yzmask;
5703        p_vci_ini_rw.wdata   = 0;
5704        p_vci_ini_rw.be      = 0xF;
5705        p_vci_ini_rw.trdid   = 3; // ins cache cached read
5706        p_vci_ini_rw.plen    = m_icache_words << 2;
5707        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
5708        p_vci_ini_rw.eop     = true;
5709        break;
5710
5711    case CMD_INS_UNC:
5712        p_vci_ini_rw.cmdval  = true;
5713        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
5714        p_vci_ini_rw.wdata   = 0;
5715        p_vci_ini_rw.be      = 0xF;
5716        p_vci_ini_rw.trdid   = 2; // ins cache uncached read
5717        p_vci_ini_rw.plen    = 4;
5718        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
5719        p_vci_ini_rw.eop     = true;
5720        break;
5721
5722    case CMD_DTLB_READ:     
5723        p_vci_ini_rw.cmdval  = true;
5724        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & m_dcache_yzmask;
5725        p_vci_ini_rw.wdata   = 0;
5726        p_vci_ini_rw.be      = 0xF;
5727        p_vci_ini_rw.trdid   = 1; // via dcache cached read
5728        p_vci_ini_rw.plen    = m_dcache_words << 2;
5729        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
5730        p_vci_ini_rw.eop     = true;
5731        break;
5732
5733    case CMD_DTLB_ACC_LL:
5734        p_vci_ini_rw.cmdval  = true;
5735        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
5736        p_vci_ini_rw.wdata   = 0;
5737        p_vci_ini_rw.be      = 0xF;
5738        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5739        p_vci_ini_rw.plen    = 4;
5740        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
5741        p_vci_ini_rw.eop     = true;
5742        break;
5743
5744    case CMD_DTLB_ACC_SC:
5745        p_vci_ini_rw.cmdval  = true;
5746        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
5747        p_vci_ini_rw.wdata   = r_dcache_pte_update.read();
5748        p_vci_ini_rw.be      = 0xF;
5749        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5750        p_vci_ini_rw.plen    = 4;
5751        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
5752        p_vci_ini_rw.eop     = true;
5753        break; 
5754
5755    case CMD_DTLB_DIRTY_LL:
5756        p_vci_ini_rw.cmdval  = true;
5757        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
5758        p_vci_ini_rw.wdata   = 0;
5759        p_vci_ini_rw.be      = 0xF;
5760        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5761        p_vci_ini_rw.plen    = 4;
5762        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
5763        p_vci_ini_rw.eop     = true;
5764        break;
5765
5766    case CMD_DTLB_DIRTY_SC:
5767        p_vci_ini_rw.cmdval  = true;
5768        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
5769        p_vci_ini_rw.wdata   = r_dcache_pte_update.read();
5770        p_vci_ini_rw.be      = 0xF;
5771        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5772        p_vci_ini_rw.plen    = 4;
5773        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
5774        p_vci_ini_rw.eop     = true;
5775        break; 
5776
5777    case CMD_DATA_UNC:
5778        p_vci_ini_rw.cmdval  = true;
5779        p_vci_ini_rw.address = r_dcache_paddr_save.read() & ~0x3;
5780        p_vci_ini_rw.trdid   = 0; // data cache uncached read
5781        p_vci_ini_rw.plen    = 4;
5782        p_vci_ini_rw.eop     = true;
5783        switch(r_dcache_type_save) {
5784        case iss_t::DATA_READ:
5785            p_vci_ini_rw.wdata = 0;
5786            p_vci_ini_rw.be    = r_dcache_be_save.read();
5787            p_vci_ini_rw.cmd   = vci_param::CMD_READ;
5788            break;
5789        case iss_t::DATA_LL:
5790            p_vci_ini_rw.wdata = 0;
5791            p_vci_ini_rw.be    = 0xF;
5792            p_vci_ini_rw.cmd   = vci_param::CMD_LOCKED_READ;
5793            break;
5794        case iss_t::DATA_SC:
5795            p_vci_ini_rw.wdata = r_dcache_wdata_save.read();
5796            p_vci_ini_rw.be    = 0xF;
5797            p_vci_ini_rw.cmd   = vci_param::CMD_STORE_COND;
5798            break;
5799        default:
5800            assert("this should not happen");
5801        }
5802        break;
5803
5804    case CMD_DATA_WRITE:
5805        p_vci_ini_rw.cmdval  = true;
5806        p_vci_ini_rw.address = r_wbuf.getAddress(r_vci_cmd_cpt);
5807        p_vci_ini_rw.wdata   = r_wbuf.getData(r_vci_cmd_cpt);
5808        p_vci_ini_rw.be      = r_wbuf.getBe(r_vci_cmd_cpt);
5809        p_vci_ini_rw.trdid   = 0; // data cache write
5810        p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
5811        p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
5812        p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
5813        break;
5814
5815    case CMD_DATA_MISS:
5816        p_vci_ini_rw.cmdval  = true;
5817        p_vci_ini_rw.address = r_dcache_paddr_save.read() & m_dcache_yzmask;
5818        p_vci_ini_rw.wdata   = 0;
5819        p_vci_ini_rw.be      = 0xF;
5820        p_vci_ini_rw.trdid   = 1; // data cache cached read
5821        p_vci_ini_rw.plen    = m_dcache_words << 2;
5822        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
5823        p_vci_ini_rw.eop     = true;
5824        break;
5825
5826    case CMD_INS_CLEANUP:
5827    case CMD_DATA_CLEANUP:
5828        p_vci_ini_rw.cmdval = false;
5829        p_vci_ini_rw.address = 0;
5830        p_vci_ini_rw.wdata  = 0;
5831        p_vci_ini_rw.be     = 0;
5832        p_vci_ini_rw.trdid  = 0;
5833        p_vci_ini_rw.plen   = 0;
5834        p_vci_ini_rw.cmd    = vci_param::CMD_NOP;
5835        p_vci_ini_rw.eop    = false;
5836
5837        p_vci_ini_c.cmdval  = true;
5838        if ( r_vci_cmd_fsm == CMD_INS_CLEANUP )
5839        {
5840            p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words<<2);
5841            p_vci_ini_c.trdid  = 1; // cleanup instruction
5842        }
5843        else
5844        {           
5845            p_vci_ini_c.address = r_dcache_cleanup_line.read() * (m_dcache_words<<2);
5846            p_vci_ini_c.trdid  = 0; // cleanup data
5847        }
5848        p_vci_ini_c.wdata  = 0;
5849        p_vci_ini_c.be     = 0;
5850        p_vci_ini_c.plen   = 4;
5851        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
5852        p_vci_ini_c.pktid  = 0;
5853        p_vci_ini_c.srcid  = m_srcid_c;
5854        p_vci_ini_c.cons   = false;
5855        p_vci_ini_c.wrap   = false;
5856        p_vci_ini_c.contig = false;
5857        p_vci_ini_c.clen   = 0;
5858        p_vci_ini_c.cfixed = false;
5859        p_vci_ini_c.eop = true;
5860        break;
5861
5862    } // end switch r_vci_cmd_fsm
5863
5864    // VCI_TGT
5865    switch ( r_vci_tgt_fsm.read() ) {
5866
5867    case TGT_IDLE:
5868    case TGT_UPDT_WORD:
5869    case TGT_UPDT_DATA:
5870        p_vci_tgt.cmdack  = true;
5871        p_vci_tgt.rspval  = false;
5872        break;
5873
5874    case TGT_RSP_BROADCAST:
5875        p_vci_tgt.cmdack  = false;
5876        p_vci_tgt.rspval  = !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() && ( r_tgt_icache_rsp | r_tgt_dcache_rsp );
5877        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
5878        p_vci_tgt.rpktid  = r_tgt_pktid.read();
5879        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
5880        p_vci_tgt.rdata   = 0;
5881        p_vci_tgt.rerror  = 0;
5882        p_vci_tgt.reop    = true;
5883        break;
5884
5885    case TGT_RSP_ICACHE:
5886        p_vci_tgt.cmdack  = false;
5887        p_vci_tgt.rspval  = !r_tgt_icache_req.read() && r_tgt_icache_rsp.read();
5888        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
5889        p_vci_tgt.rpktid  = r_tgt_pktid.read();
5890        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
5891        p_vci_tgt.rdata   = 0;
5892        p_vci_tgt.rerror  = 0;
5893        p_vci_tgt.reop    = true;
5894        break;
5895
5896    case TGT_RSP_DCACHE:
5897        p_vci_tgt.cmdack  = false;
5898        p_vci_tgt.rspval  = !r_tgt_dcache_req.read() && r_tgt_dcache_rsp.read();
5899        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
5900        p_vci_tgt.rpktid  = r_tgt_pktid.read();
5901        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
5902        p_vci_tgt.rdata   = 0;
5903        p_vci_tgt.rerror  = 0;
5904        p_vci_tgt.reop    = true;
5905        break;
5906
5907    case TGT_REQ_BROADCAST:
5908    case TGT_REQ_ICACHE:
5909    case TGT_REQ_DCACHE:
5910        p_vci_tgt.cmdack  = false;
5911        p_vci_tgt.rspval  = false;
5912        break;
5913
5914    } // end switch TGT_FSM
5915
5916#ifdef SOCLIB_MODULE_DEBUG
5917   std::cout << name()
5918             << "Moore R/W:" << std::hex
5919             << " p_vci_ini_rw.cmdval: " << p_vci_ini_rw.cmdval
5920             << " p_vci_ini_rw.address: " << p_vci_ini_rw.address
5921             << " p_vci_ini_rw.wdata: " << p_vci_ini_rw.wdata
5922             << " p_vci_ini_rw.cmd: " << p_vci_ini_rw.cmd
5923             << " p_vci_ini_rw.eop: " << p_vci_ini_rw.eop
5924             << std::endl;
5925
5926   std::cout << name()
5927             << "Moore TGT:" << std::hex
5928             << " p_vci_tgt.rspval: " << p_vci_tgt.rspval
5929             << std::endl;
5930
5931   std::cout << name()
5932             << "Moore Cleanup:" << std::hex
5933             << " p_vci_ini_c.cmdval: " << p_vci_ini_c.cmdval
5934             << " p_vci_ini_c.address: " << p_vci_ini_c.address
5935             << " p_vci_ini_c.trdid: " << p_vci_ini_c.trdid
5936             << " p_vci_ini_c.cmd: " << p_vci_ini_c.cmd
5937             << " p_vci_ini_c.eop: " << p_vci_ini_c.eop
5938             << std::endl;
5939
5940#endif
5941}
5942
5943}}
5944
5945// Local Variables:
5946// tab-width: 4
5947// c-basic-offset: 4
5948// c-file-offsets:((innamespace . 0)(inline-open . 0))
5949// indent-tabs-mode: nil
5950// End:
5951
5952// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
5953
5954
5955
5956
5957
5958
5959
5960
5961
Note: See TracBrowser for help on using the repository browser.