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

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

Active caches

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