source: trunk/modules/vci_cc_vcache_wrapper_v1/caba/source/src/vci_cc_vcache_wrapper_v1.cpp @ 48

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

Activity counter update

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