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

Last change on this file since 68 was 68, checked in by bouyer, 14 years ago

A SC cause the dcache entry to be updated by the memcache, and the
tlb entry to be invalidated. So just go back to DCACHE_IDLE to redo a lookup.
Assert that the data is not in dcache in CC_CHECK when we're not going
to update/invalidate the cache or tlb.
Drop DCACHE_WRITE_DIRTY state, it's not used any more.

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