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

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

bug correction

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