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

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

Modification for synthetisable reason

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