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

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

cc_vcache added

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