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

Last change on this file since 119 was 119, checked in by gao, 13 years ago

Modification for synthetisable reason

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