source: trunk/modules/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp @ 88

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

Correction of itlb access bit set and dtlb dirty bit set

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