Changeset 205 for trunk/modules


Ignore:
Timestamp:
Mar 11, 2012, 6:42:17 PM (13 years ago)
Author:
alain
Message:

bug fixing

Location:
trunk/modules/vci_cc_vcache_wrapper_v4/caba/source
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/include/vci_cc_vcache_wrapper_v4.h

    r204 r205  
    100100        DCACHE_TLB_PTE2_SELECT,       
    101101        DCACHE_TLB_PTE2_UPDT,           
    102         DCACHE_TLB_SC_UPDT,           
    103         DCACHE_TLB_SC_WAIT,           
     102        DCACHE_TLB_LR_UPDT,           
     103        DCACHE_TLB_LR_WAIT,           
    104104        DCACHE_TLB_RETURN,         
    105105            // handling processor XTN requests
     
    116116        DCACHE_XTN_DC_INVAL_GO,         
    117117        DCACHE_XTN_DT_INVAL,         
    118         //handling fourth stage write
    119         DCACHE_WRITE_TLB_DIRTY,
    120         DCACHE_WRITE_CACHE_DIRTY,
    121         DCACHE_WRITE_SC_WAIT,           
    122         DCACHE_WRITE_UNC_WAIT,
     118        //handling long write (set dirty bit)
     119        DCACHE_DIRTY_TLB_SET,
     120        DCACHE_DIRTY_CACHE_SET,
     121        DCACHE_DIRTY_SC_WAIT,           
     122        DCACHE_DIRTY_UNC_WAIT,
    123123            // handling processor miss requests
    124124        DCACHE_MISS_VICTIM,
     
    129129        // handling processor unc and sc requests
    130130        DCACHE_UNC_WAIT,           
     131        DCACHE_SC_WAIT,           
    131132        // handling coherence requests
    132133        DCACHE_CC_CHECK,           
     
    263264
    264265    ////////////////////////////////////////
    265     // Variables used by print_trace()
     266    // Communication with processor ISS
    266267    ////////////////////////////////////////
    267 
    268     bool                                                                    m_ireq_valid;
    269     uint32_t                                                        m_ireq_addr;
    270     soclib::common::Iss2::ExecMode                  m_ireq_mode;
    271 
    272     bool                                                                m_irsp_valid;
    273     uint32_t                                                    m_irsp_instruction;
    274     bool                                                                m_irsp_error;
    275 
    276     bool                                                                    m_dreq_valid;
    277     uint32_t                                                        m_dreq_addr;
    278     soclib::common::Iss2::ExecMode                  m_dreq_mode;
    279     soclib::common::Iss2::DataOperationType             m_dreq_type;
    280     uint32_t                                                            m_dreq_wdata;
    281     uint8_t                                                             m_dreq_be;
    282 
    283     bool                                                                m_drsp_valid;
    284     uint32_t                                                            m_drsp_rdata;
    285     bool                                                                m_drsp_error;
     268    typename iss_t::InstructionRequest  m_ireq;
     269    typename iss_t::InstructionResponse m_irsp;
     270    typename iss_t::DataRequest         m_dreq;
     271    typename iss_t::DataResponse        m_drsp;
    286272
    287273    /////////////////////////////////////////////
     
    379365    sc_signal<bool>         r_dcache_p1_tlb_big;        // big page bit (from dtlb)
    380366    // registers written in P2 stage (used in long write)
    381     sc_signal<uint32_t>     r_dcache_p2_vaddr;          // virtual address (from proc)
    382     sc_signal<size_t>       r_dcache_p2_tlb_way;            // selected way in dtlb
    383     sc_signal<size_t>       r_dcache_p2_tlb_set;            // selected set in dtlb
    384     sc_signal<bool>         r_dcache_p2_set_dirty;          // PTE dirty bit must be set
     367    sc_signal<size_t>       r_dcache_p2_way;            // selected way in dtlb or dcache
     368    sc_signal<size_t>       r_dcache_p2_set;            // selected set in dtlb or dcache
     369    sc_signal<size_t>       r_dcache_p2_word;           // selected word in dcache
    385370    sc_signal<paddr_t>      r_dcache_p2_pte_paddr;      // PTE physical address
    386     sc_signal<size_t>       r_dcache_p2_pte_way;            // selected way in dcache
    387     sc_signal<size_t>       r_dcache_p2_pte_set;            // selected set in dcache
    388     sc_signal<size_t>       r_dcache_p2_pte_word;           // selected word in dcache
    389     sc_signal<size_t>       r_dcache_p2_pte;            // pte value read in dcache
     371    sc_signal<size_t>       r_dcache_p2_pte_value;      // PTE value
     372    sc_signal<bool>         r_dcache_p2_type_sc;            // request type (WRITE or SC)
     373    sc_signal<bool>         r_dcache_p2_sc_success;     // successful SC request
    390374   
    391375    // communication between DCACHE FSM and VCI_CMD FSM
     
    406390
    407391    // handling dcache miss
    408     sc_signal<int>          r_dcache_miss_type;                 // type of miss depending on the requester
     392    sc_signal<int>              r_dcache_miss_type;                 // type of miss depending on the requester
    409393    sc_signal<size_t>       r_dcache_miss_word;             // word index for sequencial cache update
    410394    sc_signal<size_t>       r_dcache_miss_way;              // selected way for cache update
  • trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp

    r204 r205  
    7171        "DCACHE_TLB_PTE2_SELECT",
    7272        "DCACHE_TLB_PTE2_UPDT",   
    73         "DCACHE_TLB_SC_UPDT",
    74         "DCACHE_TLB_SC_WAIT",
     73        "DCACHE_TLB_LR_UPDT",
     74        "DCACHE_TLB_LR_WAIT",
    7575        "DCACHE_TLB_RETURN",
    7676
     
    8888        "DCACHE_XTN_DT_INVAL",
    8989
    90         "DCACHE_WRITE_TLB_DIRTY",
    91         "DCACHE_WRITE_CACHE_DIRTY",
    92         "DCACHE_WRITE_SC_WAIT", 
    93         "DCACHE_WRITE_UNC_WAIT", 
     90        "DCACHE_DIRTY_TLB_SET",
     91        "DCACHE_DIRTY_CACHE_SET",
     92        "DCACHE_DIRTY_SC_WAIT", 
     93        "DCACHE_DIRTY_UNC_WAIT", 
    9494
    9595        "DCACHE_MISS_VICTIM",
     
    100100
    101101        "DCACHE_UNC_WAIT",   
     102        "DCACHE_SC_WAIT",   
    102103
    103104        "DCACHE_CC_CHECK",
     
    273274      r_dcache_p1_tlb_big("r_dcache_p1_tlb_big"),
    274275
    275       r_dcache_p2_vaddr("r_dcache_p2_vaddr"),
    276       r_dcache_p2_tlb_way("r_dcache_p2_tlb_way"),
    277       r_dcache_p2_tlb_set("r_dcache_p2_tlb_set"),
    278       r_dcache_p2_set_dirty("r_dcache_p2_set_dirty"),
     276      r_dcache_p2_way("r_dcache_p2_way"),
     277      r_dcache_p2_set("r_dcache_p2_set"),
     278      r_dcache_p2_word("r_dcache_p2_word"),
    279279      r_dcache_p2_pte_paddr("r_dcache_p2_pte_paddr"),
    280       r_dcache_p2_pte_way("r_dcache_p2_pte_way"),
    281       r_dcache_p2_pte_set("r_dcache_p2_pte_set"),
    282       r_dcache_p2_pte_word("r_dcache_p2_pte_word"),
    283       r_dcache_p2_pte("r_dcache_p2_pte"),
     280      r_dcache_p2_pte_value("r_dcache_p2_pte_value"),
     281      r_dcache_p2_type_sc("r_dcache_p2_type_sc"),
     282      r_dcache_p2_sc_success("r_dcache_p2_sc_success"),
    284283
    285284      r_dcache_vci_paddr("r_dcache_vci_paddr"),
     
    442441////////////////////////////////////
    443442{
    444     // b0 : write buffer print trace
     443    // b0 : write buffer trace
    445444    // b1 : write buffer verbose
    446     // b2 : dcache print trace
    447     // b3 : icache print trace
    448 
    449     typename iss_t::InstructionRequest  ireq;
    450     typename iss_t::InstructionResponse irsp;
    451     typename iss_t::DataRequest         dreq;
    452     typename iss_t::DataResponse        drsp;
    453 
    454     ireq.valid       = m_ireq_valid;
    455     ireq.addr        = m_ireq_addr;
    456     ireq.mode        = m_ireq_mode;
    457 
    458     irsp.valid       = m_irsp_valid;
    459     irsp.instruction = m_irsp_instruction;
    460     irsp.error       = m_irsp_error;
    461 
    462     dreq.valid       = m_dreq_valid;
    463     dreq.addr        = m_dreq_addr;
    464     dreq.mode        = m_dreq_mode;
    465     dreq.type        = m_dreq_type;
    466     dreq.wdata       = m_dreq_wdata;
    467     dreq.be          = m_dreq_be;
    468 
    469     drsp.valid       = m_drsp_valid;
    470     drsp.rdata       = m_drsp_rdata;
    471     drsp.error       = m_drsp_error;
     445    // b2 : dcache trace
     446    // b3 : icache trace
     447    // b4 : dtlb trace
     448    // b5 : itlb trace
    472449
    473450    std::cout << std::dec << "PROC " << name() << std::endl;
    474451
    475     std::cout << "  " << ireq << std::endl;
    476     std::cout << "  " << irsp << std::endl;
    477     std::cout << "  " << dreq << std::endl;
    478     std::cout << "  " << drsp << std::endl;
     452    std::cout << "  " << m_ireq << std::endl;
     453    std::cout << "  " << m_irsp << std::endl;
     454    std::cout << "  " << m_dreq << std::endl;
     455    std::cout << "  " << m_drsp << std::endl;
    479456
    480457    std::cout << "  " << icache_fsm_state_str[r_icache_fsm.read()]
     
    488465    std::cout << std::endl;
    489466
    490     if(mode & 0x1)
     467    if(mode & 0x01)
    491468    {
    492469        r_wbuf.printTrace((mode>>1)&1);
    493470    }
    494     if(mode & 0x4)
    495     {
    496         std::cout << "  Data cache" << std::endl;
     471    if(mode & 0x04)
     472    {
     473        std::cout << "  Data Cache" << std::endl;
    497474        r_dcache.printTrace();
    498475    }
    499     if(mode & 0x8)
    500     {
    501         std::cout << "  Instruction cache" << std::endl;
     476    if(mode & 0x08)
     477    {
     478        std::cout << "  Instruction Cache" << std::endl;
    502479        r_icache.printTrace();
     480    }
     481    if(mode & 0x10)
     482    {
     483        std::cout << "  Data TLB" << std::endl;
     484        r_dtlb.printTrace();
     485    }
     486    if(mode & 0x20)
     487    {
     488        std::cout << "  Instruction TLB" << std::endl;
     489        r_itlb.printTrace();
    503490    }
    504491}
     
    11851172    ///////////////////////////////////////////////////////////////////////
    11861173
    1187     typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
    1188     typename iss_t::DataRequest         dreq = ISS_DREQ_INITIALIZER;
    1189 
    1190     r_iss.getRequests(ireq, dreq);
     1174    r_iss.getRequests(m_ireq, m_dreq);
    11911175
    11921176    ////////////////////////////////////////////////////////////////////////////////////
     
    12391223    ////////////////////////////////////////////////////////////////////////////////////////
    12401224
    1241     // The default value for irsp.valid is false
    1242     typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
     1225    // default value for m_irsp.valid
     1226    m_irsp.valid = false;
    12431227
    12441228    switch( r_icache_fsm.read() )
     
    12961280
    12971281        // processor request
    1298         if ( ireq.valid )
     1282        if ( m_ireq.valid )
    12991283        {
    13001284            bool        cacheable;
     
    13021286
    13031287            // We register processor request
    1304             r_icache_vaddr_save = ireq.addr;
     1288            r_icache_vaddr_save = m_ireq.addr;
    13051289
    13061290            // speculative icache access (if cache activated)
     
    13131297            {
    13141298                paddr_t   spc_paddr = (r_icache_vci_paddr.read() & ~PAGE_K_MASK) |
    1315                                       ((paddr_t)ireq.addr & PAGE_K_MASK);
     1299                                      ((paddr_t)m_ireq.addr & PAGE_K_MASK);
    13161300
    13171301#ifdef INSTRUMENTATION
     
    13391323m_cpt_itlb_read++;
    13401324#endif
    1341                 tlb_hit = r_itlb.translate( ireq.addr,
     1325                tlb_hit = r_itlb.translate( m_ireq.addr,
    13421326                                            &tlb_paddr,
    13431327                                            &tlb_flags,
     
    13591343                // cacheability
    13601344                if ( not (r_mmu_mode.read() & INS_CACHE_MASK) ) cacheable = false;
    1361                 else     cacheable = m_cacheability_table[ireq.addr];
     1345                else     cacheable = m_cacheability_table[m_ireq.addr];
    13621346
    13631347                // physical address
    1364                 paddr = (paddr_t)ireq.addr;
     1348                paddr = (paddr_t)m_ireq.addr;
    13651349            }
    13661350            else                                                // itlb activated
     
    13761360
    13771361                    // access rights checking
    1378                     if ( not tlb_flags.u && (ireq.mode == iss_t::MODE_USER) )
     1362                    if ( not tlb_flags.u && (m_ireq.mode == iss_t::MODE_USER) )
    13791363                    {
    13801364                        r_mmu_ietr        = MMU_READ_PRIVILEGE_VIOLATION;
    1381                         r_mmu_ibvar       = ireq.addr;
    1382                         irsp.valid        = true;
    1383                         irsp.error        = true;
    1384                         irsp.instruction  = 0;
     1365                        r_mmu_ibvar       = m_ireq.addr;
     1366                        m_irsp.valid        = true;
     1367                        m_irsp.error        = true;
     1368                        m_irsp.instruction  = 0;
    13851369                        break;
    13861370                    }
     
    13881372                    {
    13891373                        r_mmu_ietr        = MMU_READ_EXEC_VIOLATION;
    1390                         r_mmu_ibvar       = ireq.addr;
    1391                         irsp.valid        = true;
    1392                         irsp.error        = true;
    1393                         irsp.instruction  = 0;
     1374                        r_mmu_ibvar       = m_ireq.addr;
     1375                        m_irsp.valid        = true;
     1376                        m_irsp.error        = true;
     1377                        m_irsp.instruction  = 0;
    13941378                        break;
    13951379                    }
     
    14491433m_cpt_ins_read++;
    14501434#endif
    1451                     irsp.valid       = true;
    1452                     irsp.instruction = cache_inst;
     1435                    m_irsp.valid       = true;
     1436                    m_irsp.instruction = cache_inst;
    14531437                }
    14541438            }
     
    14581442                r_icache_fsm      = ICACHE_UNC_WAIT;
    14591443            }
    1460         }    // end if ireq.valid
     1444        }    // end if m_ireq.valid
    14611445        break;
    14621446    }
     
    14771461        }
    14781462
    1479         if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
     1463        if ( m_ireq.valid ) m_cost_ins_tlb_miss_frz++;
    14801464
    14811465        // DCACHE FSM signals response by reseting the request flip-flop
     
    14851469            {
    14861470                r_icache_tlb_rsp_error = false;
    1487                 irsp.error             = true;
    1488                 irsp.valid             = true;
     1471                m_irsp.error             = true;
     1472                m_irsp.valid             = true;
    14891473                r_icache_fsm           = ICACHE_IDLE;
    14901474            }
     
    16381622                                           // when the selected slot is not empty
    16391623    {
    1640         if ( ireq.valid ) m_cost_ins_miss_frz++;
     1624        if ( m_ireq.valid ) m_cost_ins_miss_frz++;
    16411625
    16421626        bool    valid;
     
    16791663    case ICACHE_MISS_WAIT:      // waiting a response to a miss request from VCI_RSP FSM
    16801664    {
    1681         if ( ireq.valid ) m_cost_ins_miss_frz++;
     1665        if ( m_ireq.valid ) m_cost_ins_miss_frz++;
    16821666
    16831667        // external coherence request
     
    16931677            r_mmu_ietr = MMU_READ_DATA_ILLEGAL_ACCESS;
    16941678            r_mmu_ibvar  = r_icache_vaddr_save.read();
    1695             irsp.valid           = true;
    1696             irsp.error           = true;
     1679            m_irsp.valid           = true;
     1680            m_irsp.error           = true;
    16971681            r_vci_rsp_ins_error  = false;
    16981682            r_icache_fsm = ICACHE_IDLE;
     
    17081692    case ICACHE_MISS_UPDT:      // update the cache (one word per cycle)
    17091693    {
    1710         if ( ireq.valid ) m_cost_ins_miss_frz++;
     1694        if ( m_ireq.valid ) m_cost_ins_miss_frz++;
    17111695
    17121696        if ( r_vci_rsp_fifo_icache.rok() )      // response available
     
    17781762        {
    17791763            r_mmu_ietr          = MMU_READ_DATA_ILLEGAL_ACCESS;   
    1780             r_mmu_ibvar         = ireq.addr;
     1764            r_mmu_ibvar         = m_ireq.addr;
    17811765            r_vci_rsp_ins_error = false;
    1782             irsp.valid          = true;
    1783             irsp.error          = true;
     1766            m_irsp.valid          = true;
     1767            m_irsp.error          = true;
    17841768            r_icache_fsm        = ICACHE_IDLE;
    17851769        }
     
    17881772            vci_rsp_fifo_icache_get = true;
    17891773            r_icache_fsm            = ICACHE_IDLE;
    1790             if ( ireq.valid and (ireq.addr == r_icache_vaddr_save.read()) )  // request not modified
    1791             {
    1792                 irsp.valid       = true;
    1793                 irsp.instruction = r_vci_rsp_fifo_icache.read();
     1774            if ( m_ireq.valid and (m_ireq.addr == r_icache_vaddr_save.read()) )  // request not modified
     1775            {
     1776                m_irsp.valid       = true;
     1777                m_irsp.instruction = r_vci_rsp_fifo_icache.read();
    17941778            }
    17951779        }       
     
    18871871
    18881872    } // end switch r_icache_fsm
    1889 
    1890     // save the IREQ and IRSP fields for the print_trace() function
    1891     m_ireq_valid        = ireq.valid;
    1892     m_ireq_addr         = ireq.addr;
    1893     m_ireq_mode         = ireq.mode;
    1894    
    1895     m_irsp_valid        = irsp.valid;
    1896     m_irsp_instruction  = irsp.instruction;
    1897     m_irsp_error        = irsp.error;
    18981873
    18991874    ////////////////////////////////////////////////////////////////////////////////////
     
    19111886    //    pre-empted state.
    19121887    //
    1913     // 2/ processor requests :
     1888    // 2/ TLB miss
     1889    //    The page tables can be cacheable.
     1890    //    In case of miss in itlb or dtlb, the tlb miss is handled by a dedicated
     1891    //    sub-fsm (DCACHE_TLB_MISS state), that handle possible miss in DCACHE,
     1892    //    this sub-fsm implement the table-walk...
     1893    //
     1894    // 3/ processor requests :
    19141895    //    Processor READ, WRITE, LL or SC requests are taken in IDLE state only.
    19151896    //    The IDLE state implements a three stages pipe-line to handle write bursts:
     
    19171898    //    - The registration in wbuf and the dcache hit are computed in stage P1.
    19181899    //    - The dcache update is done in stage P2. 
    1919     //    A write operation can require a fourth stage if the dirty bit must be updated,
    1920     //    or if the TLBs must be cleared, but these "long write" operation requires 
    1921     //    to exit the IDLE stage
     1900    //    A write operation can require a "long write" operation (if the PTE dirty bit
     1901    //    must be updated) handled by a dedicated sub-fsm (DCACHE_DIRTY_TLB_SET state).
     1902    //    If a PTE is modified, the both te itlb and dtlb are selectively, but sequencially
     1903    //    cleared by a dedicated sub_fsm (DCACHE_INVAL_TLB_SCAN state).
    19221904    //    If there is no write in the pipe, dcache and dtlb are accessed in parallel,
    19231905    //    (virtual address for itlb, and speculative physical address computed during
    19241906    //    previous cycle for dcache) in order to return the data in one cycle for a read.
    1925     //    We just pay an extra cycle when the speculative access is illegal.
     1907    //    We just pay an extra cycle when the speculative access is failing.
    19261908    //
    1927     // 3/ Atomic instructions LL/SC
     1909    // 4/ Atomic instructions LL/SC
    19281910    //    The LL/SC address can be cacheable or non cacheable.
    19291911    //    The reservation registers (r_dcache_ll_valid, r_dcache_ll_vaddr and
     
    19331915    //      READ transactions (one word / one line, depending on the cacheability).
    19341916    //    - SC requests from the processor are systematically transmitted to the
    1935     //      memory cache as COMPARE&swap requests (both the data value stored in the
     1917    //      memory cache as Compare&swap requests (both the data value stored in the
    19361918    //      r_dcache_ll_data register and the new value).
     1919    //      The cache is not updated, as this is done in case of success by the
     1920    //      coherence transaction.
     1921    //      If rqired, the dirty bit is updated in PTE by a "long write".
    19371922    //
    1938     // 4/ Non cacheable access:
     1923    // 5/ Non cacheable access:
    19391924    //    This component implement a strong order between non cacheable access
    19401925    //    (read or write) : A new non cacheable VCI transaction starts only when
     
    19461931    //    pending non cacheable write transaction completes).
    19471932    //
    1948     // 5/ Error handling: 
     1933    // 6/ Error handling: 
    19491934    //    When the MMU is not activated, Read Bus Errors are synchronous events,
    19501935    //    but Write Bus Errors are asynchronous events (processor is not frozen).
     
    19591944    ////////////////////////////////////////////////////////////////////////////////////////
    19601945
    1961     // The default value for drsp.valid is false
    1962     typename iss_t::DataResponse  drsp = ISS_DRSP_INITIALIZER;
     1946    // default value for m_drsp.valid
     1947    m_drsp.valid = false;
    19631948
    19641949    switch ( r_dcache_fsm.read() )
    19651950    {
    19661951    case DCACHE_IDLE:   // There is 8 conditions to exit the IDLE state :
    1967                         // 1) Long write request (DCACHE FSM)   => DCACHE_WRITE_***
     1952                        // 1) Long write request (DCACHE FSM)   => DCACHE_DIRTY_***
    19681953                        // 2) Coherence request (TGT FSM)       => DCACHE_CC_CHECK
    19691954                        // 3) ITLB miss request (ICACHE FSM)    => DCACHE_TLB_MISS
     
    19921977        //   DCACHE_INVAL_TLB
    19931978        // - If the PTE dirty bit must be updated, we start a "long write", that is
    1994         //   blocking for the processor, because we switch to the DCACHE_WRITE_SET_DIRTY
    1995 
    1996         bool long_write_set_dirty = false;
    1997         bool tlb_inval_required   = false;
     1979        //   blocking for the processor, because we switch to the DCACHE_DIRTY_SET_DIRTY
     1980
     1981        bool long_write_set_dirty = false;      // default value
     1982        bool tlb_inval_required   = false;      // default value
    19981983
    19991984        if ( r_dcache_p1_valid.read() )         // P2 stage activated
     
    20452030            {
    20462031                long_write_set_dirty  = true;
    2047                 r_dcache_p2_vaddr     = r_dcache_p1_vaddr.read();
    2048                 r_dcache_p2_set_dirty = r_dcache_p1_set_dirty.read();
    2049                 r_dcache_p2_tlb_way   = r_dcache_p1_tlb_way.read();     
    2050                 r_dcache_p2_tlb_set   = r_dcache_p1_tlb_set.read();     
     2032                r_dcache_p2_way   = r_dcache_p1_tlb_way.read();
     2033                r_dcache_p2_set   = r_dcache_p1_tlb_set.read();
    20512034                // The PTE physical address is the concatenation of the nline value (from dtlb),
    20522035                // with the word index (obtained from the proper bits of the virtual address)
     
    20592042                {
    20602043                    r_dcache_p2_pte_paddr = (paddr_t)(r_dcache_p1_tlb_nline.read()*(m_dcache_words<<2)) |
    2061                                             (paddr_t)((r_dcache_p1_vaddr.read()>>10) & 0x3c);
     2044                                            (paddr_t)((r_dcache_p1_vaddr.read()>>9) & 0x38);
    20622045                }
    20632046            }
     
    21712154        /////////////////////////////////////////////////////////////////////////////
    21722155        // handling P0 pipe-line stage
    2173         // This stage is controlling the DCACHE FSM state register:
     2156        // This stage is controlling r_dcache_fsm and r_dcache_p0_* registers.
     2157        // The r_dcache_p0_valid flip-flop is only set in case of WRITE request.
    21742158        // - the TLB invalidate requests have the highest priority,
    21752159        // - then the long write requests,
     
    21772161        // - then the itlb miss requests,
    21782162        // - and finally the processor requests.
    2179         // A processor read request generate a dcache access using speculative PPN
    2180         // only if the write pipe-line is empty. There is an unconditionnal access
    2181         // to the dtlb, using virtual address from processor.
    2182         // The r_dcache_p0_valid value must be computed at all cycles.
    2183 
    2184         bool p0_valid = false;  // default value
     2163        // If dtlb is activated, there is an unconditionnal access to dtlb,
     2164        // for address translation.
     2165        // 1) A processor WRITE request enters the three stage pipe-line (handled
     2166        //    by the IDLE state), and can be completed by a "long write" if the
     2167        //    PTE dirty bit must be updated in dtb, dcache and RAM.
     2168        // 2) A processor READ request generate a simultaneouss access to
     2169        //    both dcache data and dcache directoty, using speculative PPN, but
     2170        //    is delayed if the write pipe-line is not empty.
     2171        //    In case of miss, we wait the VCI response in DCACHE_UNC_WAIT or
     2172        //    DCACHE_MISS_WAIT states.
     2173        // 3) A processor LL request is handled as a READ request.
     2174        // 4) A processor SC request is delayed until the write pipe-line is empty.
     2175        //    A VCI SC transaction is launched, and we wait the VCI response in
     2176        //    DCACHE_SC_WAIT state. It can be completed by a "long write" if the
     2177        //    PTE dirty bit must be updated in dtlb, dcache, and RAM.
     2178        //    The data is not modified in dcache, as it will be done by the
     2179        //    coherence transaction.   
    21852180
    21862181        // TLB inval required
     
    21892184            r_dcache_fsm_save = DCACHE_IDLE;
    21902185            r_dcache_fsm      = DCACHE_INVAL_TLB_SCAN;
     2186            r_dcache_p0_valid = false;
    21912187        }
    21922188
     
    21942190        else if ( long_write_set_dirty )
    21952191        {
    2196             r_dcache_fsm = DCACHE_WRITE_TLB_DIRTY;
     2192            r_dcache_fsm = DCACHE_DIRTY_TLB_SET;
     2193            r_dcache_p0_valid = false;
    21972194        }
    21982195
     
    22022199            r_dcache_fsm_save = DCACHE_IDLE;
    22032200            r_dcache_fsm      = DCACHE_CC_CHECK;
     2201            r_dcache_p0_valid = false;
    22042202        }       
    22052203
     
    22102208            r_dcache_tlb_vaddr  = r_icache_vaddr_save.read();
    22112209            r_dcache_fsm        = DCACHE_TLB_MISS;
     2210            r_dcache_p0_valid = false;
    22122211        }
    22132212
    22142213        // processor request
    2215         else if (dreq.valid )
     2214        else if ( m_dreq.valid )
    22162215        {
    22172216            // dcache access using speculative PPN only if pipe-line empty
     
    22282227            {
    22292228                cache_paddr = (r_dcache_p0_paddr.read() & ~PAGE_K_MASK) |
    2230                               ((paddr_t)dreq.addr & PAGE_K_MASK);
     2229                              ((paddr_t)m_dreq.addr & PAGE_K_MASK);
    22312230
    22322231                cache_hit = r_dcache.read( cache_paddr,
     
    22562255            if ( r_mmu_mode.read() & DATA_TLB_MASK )    // TLB activated
    22572256            {
    2258                 tlb_hit = r_dtlb.translate( dreq.addr,
     2257                tlb_hit = r_dtlb.translate( m_dreq.addr,
    22592258                                            &tlb_paddr,
    22602259                                            &tlb_flags,
     
    22782277
    22792278            // register the processor request
    2280             r_dcache_p0_vaddr = dreq.addr;
    2281             r_dcache_p0_be    = dreq.be;
    2282             r_dcache_p0_wdata = dreq.wdata;
     2279            r_dcache_p0_vaddr = m_dreq.addr;
     2280            r_dcache_p0_be    = m_dreq.be;
     2281            r_dcache_p0_wdata = m_dreq.wdata;
    22832282
    22842283            // Handling READ XTN requests from processor
    22852284            // They are executed in this DCACHE_IDLE state.
    22862285            // The processor must not be in user mode
    2287             if (dreq.type == iss_t::XTN_READ)
    2288             {
    2289                 int xtn_opcode = (int)dreq.addr/4;
     2286            if (m_dreq.type == iss_t::XTN_READ)
     2287            {
     2288                int xtn_opcode = (int)m_dreq.addr/4;
    22902289
    22912290                // checking processor mode:
    2292                 if (dreq.mode  == iss_t::MODE_USER)
     2291                if (m_dreq.mode  == iss_t::MODE_USER)
    22932292                {
    22942293                    r_mmu_detr = MMU_READ_PRIVILEGE_VIOLATION;
    2295                     r_mmu_dbvar  = dreq.addr;
    2296                     drsp.valid            = true;
    2297                     drsp.error            = true;
     2294                    r_mmu_dbvar  = m_dreq.addr;
     2295                    m_drsp.valid            = true;
     2296                    m_drsp.error            = true;
    22982297                    r_dcache_fsm          = DCACHE_IDLE;
    22992298                }
     
    23032302                    {
    23042303                    case iss_t::XTN_INS_ERROR_TYPE:
    2305                         drsp.rdata = r_mmu_ietr.read();
    2306                         drsp.valid = true;
     2304                        m_drsp.rdata = r_mmu_ietr.read();
     2305                        m_drsp.valid = true;
    23072306                        break;
    23082307
    23092308                    case iss_t::XTN_DATA_ERROR_TYPE:
    2310                         drsp.rdata = r_mmu_detr.read();
    2311                         drsp.valid = true;
     2309                        m_drsp.rdata = r_mmu_detr.read();
     2310                        m_drsp.valid = true;
    23122311                        break;
    23132312
    23142313                    case iss_t::XTN_INS_BAD_VADDR:
    2315                         drsp.rdata = r_mmu_ibvar.read();       
    2316                         drsp.valid = true;
     2314                        m_drsp.rdata = r_mmu_ibvar.read();       
     2315                        m_drsp.valid = true;
    23172316                        break;
    23182317
    23192318                    case iss_t::XTN_DATA_BAD_VADDR:
    2320                         drsp.rdata = r_mmu_dbvar.read();       
    2321                         drsp.valid = true;
     2319                        m_drsp.rdata = r_mmu_dbvar.read();       
     2320                        m_drsp.valid = true;
    23222321                        break;
    23232322
    23242323                    case iss_t::XTN_PTPR:
    2325                         drsp.rdata = r_mmu_ptpr.read();
    2326                         drsp.valid = true;
     2324                        m_drsp.rdata = r_mmu_ptpr.read();
     2325                        m_drsp.valid = true;
    23272326                        break;
    23282327
    23292328                    case iss_t::XTN_TLB_MODE:
    2330                         drsp.rdata = r_mmu_mode.read();
    2331                         drsp.valid = true;
     2329                        m_drsp.rdata = r_mmu_mode.read();
     2330                        m_drsp.valid = true;
    23322331                        break;
    23332332
    23342333                    case iss_t::XTN_MMU_PARAMS:
    2335                         drsp.rdata = r_mmu_params;
    2336                         drsp.valid = true;
     2334                        m_drsp.rdata = r_mmu_params;
     2335                        m_drsp.valid = true;
    23372336                        break;
    23382337
    23392338                    case iss_t::XTN_MMU_RELEASE:
    2340                         drsp.rdata = r_mmu_release;
    2341                         drsp.valid = true;
     2339                        m_drsp.rdata = r_mmu_release;
     2340                        m_drsp.valid = true;
    23422341                        break;
    23432342
    23442343                    case iss_t::XTN_MMU_WORD_LO:
    2345                         drsp.rdata = r_mmu_word_lo.read();
    2346                         drsp.valid = true;
     2344                        m_drsp.rdata = r_mmu_word_lo.read();
     2345                        m_drsp.valid = true;
    23472346                        break;
    23482347
    23492348                    case iss_t::XTN_MMU_WORD_HI:
    2350                         drsp.rdata = r_mmu_word_hi.read();
    2351                         drsp.valid = true;
     2349                        m_drsp.rdata = r_mmu_word_hi.read();
     2350                        m_drsp.valid = true;
    23522351                        break;
    23532352
    23542353                    default:
    23552354                        r_mmu_detr = MMU_READ_UNDEFINED_XTN;
    2356                         r_mmu_dbvar  = dreq.addr;
    2357                         drsp.valid = true;
    2358                         drsp.error = true;
     2355                        r_mmu_dbvar  = m_dreq.addr;
     2356                        m_drsp.valid = true;
     2357                        m_drsp.error = true;
    23592358                        break;
    23602359                    } // end switch xtn_opcode
    23612360                } // end else
     2361                r_dcache_p0_valid = false;
    23622362            } // end if XTN_READ
    23632363
     
    23682368            // Caches can be invalidated or flushed in user mode,
    23692369            // and the sync instruction can be executed in user mode
    2370             else if (dreq.type == iss_t::XTN_WRITE)
    2371             {
    2372                 int xtn_opcode      = (int)dreq.addr/4;
     2370            else if (m_dreq.type == iss_t::XTN_WRITE)
     2371            {
     2372                int xtn_opcode      = (int)m_dreq.addr/4;
    23732373                r_dcache_xtn_opcode = xtn_opcode;
    23742374
    23752375                // checking processor mode:
    2376                 if ( (dreq.mode  == iss_t::MODE_USER) &&
     2376                if ( (m_dreq.mode  == iss_t::MODE_USER) &&
    23772377                     (xtn_opcode != iss_t:: XTN_SYNC) &&
    23782378                     (xtn_opcode != iss_t::XTN_DCACHE_INVAL) &&
     
    23822382                {
    23832383                    r_mmu_detr = MMU_WRITE_PRIVILEGE_VIOLATION;
    2384                     r_mmu_dbvar  = dreq.addr;
    2385                     drsp.valid          = true;
    2386                     drsp.error          = true;
     2384                    r_mmu_dbvar  = m_dreq.addr;
     2385                    m_drsp.valid          = true;
     2386                    m_drsp.error          = true;
    23872387                    r_dcache_fsm        = DCACHE_IDLE;
    23882388                }
     
    23922392                    {     
    23932393                    case iss_t::XTN_PTPR:                       // itlb & dtlb must be flushed
    2394                         r_mmu_ptpr       = dreq.wdata;
     2394                        r_mmu_ptpr       = m_dreq.wdata;
    23952395                        r_dcache_xtn_req = true;
    23962396                        r_dcache_fsm     = DCACHE_XTN_SWITCH;
     
    23982398
    23992399                    case iss_t::XTN_TLB_MODE:                   // no cache or tlb access
    2400                         r_mmu_mode = dreq.wdata;
    2401                         drsp.valid = true;
     2400                        r_mmu_mode = m_dreq.wdata;
     2401                        m_drsp.valid = true;
    24022402                        r_dcache_fsm = DCACHE_IDLE;
    24032403                        break;
     
    24472447
    24482448                    case iss_t::XTN_MMU_WORD_LO:                // no cache or tlb access
    2449                         r_mmu_word_lo = dreq.wdata;
    2450                         drsp.valid    = true;
     2449                        r_mmu_word_lo = m_dreq.wdata;
     2450                        m_drsp.valid    = true;
    24512451                        r_dcache_fsm  = DCACHE_IDLE;
    24522452                        break;
    24532453
    24542454                    case iss_t::XTN_MMU_WORD_HI:                // no cache or tlb access
    2455                         r_mmu_word_hi = dreq.wdata;
    2456                         drsp.valid    = true;
     2455                        r_mmu_word_hi = m_dreq.wdata;
     2456                        m_drsp.valid    = true;
    24572457                        r_dcache_fsm  = DCACHE_IDLE;
    24582458                        break;
     
    24602460                    case iss_t::XTN_ICACHE_PREFETCH:            // not implemented : no action
    24612461                    case iss_t::XTN_DCACHE_PREFETCH:            // not implemented : no action
    2462                         drsp.valid   = true;
     2462                        m_drsp.valid   = true;
    24632463                        r_dcache_fsm = DCACHE_IDLE;
    24642464                        break;
     
    24662466                    default:
    24672467                        r_mmu_detr = MMU_WRITE_UNDEFINED_XTN;
    2468                         r_mmu_dbvar  = dreq.addr;
    2469                         drsp.valid = true;
    2470                         drsp.error = true;
     2468                        r_mmu_dbvar  = m_dreq.addr;
     2469                        m_drsp.valid = true;
     2470                        m_drsp.error = true;
    24712471                        r_dcache_fsm = DCACHE_IDLE;
    24722472                        break;
    24732473                    } // end switch xtn_opcode
    24742474                } // end else
     2475                r_dcache_p0_valid = false;
    24752476            } // end if XTN_WRITE
    24762477
    2477             // Handling read/write processor requests.
     2478            // Handling read/write/ll/sc processor requests.
    24782479            // The dtlb and dcache can be activated or not.
    24792480            // We compute the physical address, the cacheability, and check processor request.
     
    24982499                    // cacheability
    24992500                    if ( not (r_mmu_mode.read() & DATA_CACHE_MASK) ) cacheable = false;
    2500                     else cacheable = m_cacheability_table[dreq.addr];
     2501                    else cacheable = m_cacheability_table[m_dreq.addr];
    25012502
    25022503                    // physical address
    2503                     paddr       = (paddr_t)dreq.addr;
     2504                    paddr       = (paddr_t)m_dreq.addr;
    25042505                }
    25052506                else                                                    // dtlb activated
     
    25122513
    25132514                        // access rights checking
    2514                         if ( not tlb_flags.u and (dreq.mode == iss_t::MODE_USER))
     2515                        if ( not tlb_flags.u and (m_dreq.mode == iss_t::MODE_USER))
    25152516                        {
    2516                             if ( (dreq.type == iss_t::DATA_READ) or (dreq.type == iss_t::DATA_LL) )
     2517                            if ( (m_dreq.type == iss_t::DATA_READ) or (m_dreq.type == iss_t::DATA_LL) )
    25172518                                r_mmu_detr = MMU_READ_PRIVILEGE_VIOLATION;
    25182519                            else
    25192520                                r_mmu_detr = MMU_WRITE_PRIVILEGE_VIOLATION;
    25202521
    2521                             r_mmu_dbvar  = dreq.addr;
    2522                             drsp.valid   = true;
    2523                             drsp.error   = true;
    2524                             drsp.rdata   = 0;
     2522                            r_mmu_dbvar  = m_dreq.addr;
     2523                            m_drsp.valid   = true;
     2524                            m_drsp.error   = true;
     2525                            m_drsp.rdata   = 0;
    25252526                        }
    25262527                        else if ( not tlb_flags.w and
    2527                                   ((dreq.type == iss_t::DATA_WRITE) or
    2528                                    (dreq.type == iss_t::DATA_SC)) )
     2528                                  ((m_dreq.type == iss_t::DATA_WRITE) or
     2529                                   (m_dreq.type == iss_t::DATA_SC)) )
    25292530                        {
    25302531                            r_mmu_detr   = MMU_WRITE_ACCES_VIOLATION; 
    2531                             r_mmu_dbvar  = dreq.addr;
    2532                             drsp.valid   = true;
    2533                             drsp.error   = true;
    2534                             drsp.rdata   = 0;
     2532                            r_mmu_dbvar  = m_dreq.addr;
     2533                            m_drsp.valid   = true;
     2534                            m_drsp.error   = true;
     2535                            m_drsp.rdata   = 0;
    25352536                        }
    25362537                        else
     
    25442545                    else                                                // tlb miss
    25452546                    {
    2546                         r_dcache_tlb_vaddr   = dreq.addr;
     2547                        r_dcache_tlb_vaddr   = m_dreq.addr;
    25472548                        r_dcache_tlb_ins     = false;
    25482549                        r_dcache_fsm         = DCACHE_TLB_MISS;
     
    25502551                }    // end DTLB activated
    25512552
    2552                 if ( valid_req )        // processor request is valid
     2553                if ( valid_req )        // processor request is valid after TLB check
    25532554                {
    25542555                    // physical address and cacheability registration
     
    25622563                    // If dcache miss, we go to DCACHE_MISS_VICTIM state.
    25632564                    // If uncacheable, we go to DCACHE_UNC_WAIT state.
    2564                     if ( ((dreq.type == iss_t::DATA_READ) or (dreq.type == iss_t::DATA_LL)) and
    2565                         not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
     2565                    if ( ((m_dreq.type == iss_t::DATA_READ) or (m_dreq.type == iss_t::DATA_LL))
     2566                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
    25662567                    {
    25672568                        if ( cacheable )                        // cacheable read
     
    25962597m_cpt_data_read++;
    25972598#endif
    2598                                 drsp.valid   = true;
    2599                                 drsp.rdata   = cache_rdata;
     2599                                m_drsp.valid   = true;
     2600                                m_drsp.rdata   = cache_rdata;
    26002601                            }
    26012602                        }
     
    26032604                        {
    26042605                            r_dcache_vci_paddr    = paddr;
    2605                             r_dcache_vci_unc_be   = dreq.be;
     2606                            r_dcache_vci_unc_be   = m_dreq.be;
    26062607                            r_dcache_vci_unc_req  = true;
    26072608                            r_dcache_fsm          = DCACHE_UNC_WAIT;
     
    26092610
    26102611                        // makes reservation in case of LL
    2611                         if ( dreq.type == iss_t::DATA_LL )
     2612                        if ( m_dreq.type == iss_t::DATA_LL )
    26122613                        {
    26132614                            r_dcache_ll_valid = true;
    26142615                            r_dcache_ll_data  = cache_rdata;
    2615                             r_dcache_ll_vaddr = dreq.addr;
     2616                            r_dcache_ll_vaddr = m_dreq.addr;
    26162617                        }
     2618                        r_dcache_p0_valid = false;
    26172619                    } // end READ or LL
    26182620
    26192621                    // WRITE request:
    2620                     // The write request arguments have been registered.
     2622                    // The write request arguments have been registered in r_dcache_p0 registers.
    26212623                    // The physical address has been computed and registered.
    26222624                    // We acknowledge the processor request and activate the P1 pipeline stage.
    2623                     else if ( dreq.type == iss_t::DATA_WRITE )
     2625                    else if ( m_dreq.type == iss_t::DATA_WRITE )
    26242626                    {
    26252627
     
    26272629m_cpt_data_write++;
    26282630#endif
    2629                         p0_valid   = true;
    2630                         drsp.valid = true;
    2631                         drsp.rdata = 0;
     2631                        m_drsp.valid      = true;
     2632                        m_drsp.rdata      = 0;
     2633                        r_dcache_p0_valid = true;
    26322634                    } // end WRITE
    26332635 
    26342636                    // SC request:
     2637                    // The SC requests are taken only if the write pipe-line is empty.
    26352638                    // - if a valid LL reservation (with the same address) is registered,
    2636                     // we request a SC transaction to CMD FSM and go to the DCACHE_UNC_WAIT state
    2637                     // that will directly return the response to the processor, and invalidate
    2638                     // the LL reservation. We don't check a possible write hit in dcache,
    2639                     // as the cache update is done by the coherence transaction...
    2640                     // - if there is no registerd LL, we just stay in IDLE state, invalidate
    2641                     // the LL reservation, and return 1 (atomic access failed)
    2642                     else if ( dreq.type == iss_t::DATA_SC )
     2639                    // we request a SC transaction to CMD FSM and go to the DCACHE_SC_WAIT state
     2640                    // that will directly return the response to the processor, invalidate
     2641                    // the LL reservation, and set the Dirty bit if required.
     2642                    // We don't check a possible write hit in dcache, as the cache update
     2643                    // is done by the coherence transaction...
     2644                    // - if there is no valid registered LL, we just stay in IDLE state,
     2645                    // and return 1 (atomic access failed)
     2646                    else if ( ( m_dreq.type == iss_t::DATA_SC )
     2647                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
    26432648                    {
     2649
    26442650#ifdef INSTRUMENTATION
    26452651m_cpt_data_sc++;
    26462652#endif
    26472653                        // test if valid registered LL
    2648                         if ( r_dcache_ll_valid.read() and (r_dcache_ll_vaddr.read() == dreq.addr))
     2654                        if ( r_dcache_ll_valid.read() and (r_dcache_ll_vaddr.read() == m_dreq.addr))
    26492655                        {
    2650                             r_dcache_vci_paddr      = paddr;
    2651                             r_dcache_vci_sc_req     = true;
    2652                             r_dcache_vci_sc_old     = r_dcache_ll_data.read();
    2653                             r_dcache_vci_sc_new     = dreq.wdata;
    2654                             r_dcache_fsm            = DCACHE_UNC_WAIT;
     2656                            r_dcache_vci_paddr  = paddr;
     2657                            r_dcache_vci_sc_req = true;
     2658                            r_dcache_vci_sc_old = r_dcache_ll_data.read();
     2659                            r_dcache_vci_sc_new = m_dreq.wdata;
     2660                            r_dcache_fsm        = DCACHE_SC_WAIT;
    26552661                        }
    26562662                        else                                    // no registered LL
    26572663                        {
    2658                             drsp.valid        = true;
    2659                             drsp.rdata        = 1;
    2660                             r_dcache_ll_valid = false;
     2664                           
     2665                            m_drsp.valid        = true;
     2666                            m_drsp.rdata        = 1;
     2667                            r_dcache_ll_valid   = false;
    26612668                        }
     2669                        r_dcache_p0_valid = false;
    26622670                    } // end SC
     2671                    else
     2672                    {
     2673                        r_dcache_p0_valid = false;
     2674                    }
    26632675                } // end valid_req
    2664             }  // end if read/write request     
     2676                else
     2677                {
     2678                    r_dcache_p0_valid = false;
     2679                }
     2680            }  // end if read/write/ll/sc request       
     2681        } // end dreq.valid
     2682        else
     2683        {
     2684            r_dcache_p0_valid = false;
    26652685        } // end P0 pipe stage
    2666 
    2667         r_dcache_p0_valid = p0_valid;
    26682686        break;
    26692687    }
    26702688    /////////////////////
    26712689    case DCACHE_TLB_MISS: // This is the entry point for the sub-fsm handling all tlb miss.
    2672                           // - Input arguments are r_dcache_tlb_vaddr & r_dcache_tlb_ins
    2673                           // - The sub-fsm access the dcache to find the missing TLB entry,
    2674                           //   and activates the cache miss procedure in case of miss.
    2675                           // - It bypass the first level page table access if possible.
    2676                           // - It uses atomic access to update the R/L access bits
    2677                           //   in the page table if required.
    2678                           // - It directly updates the itlb or dtlb, and writes into the
    2679                           //   r_mmu_ins_* or r_mmu_data* error reporting registers.
     2690                          // Input arguments are:
     2691                          // - r_dcache_tlb_vaddr
     2692                          // - r_dcache_tlb_ins (true when itlb miss)
     2693                          // The sub-fsm access the dcache to find the missing TLB entry,
     2694                          // and activates the cache miss procedure in case of miss.
     2695                          // It bypass the first level page table access if possible.
     2696                          // It uses atomic access to update the R/L access bits
     2697                          // in the page table if required.
     2698                          // It directly updates the itlb or dtlb, and writes into the
     2699                          // r_mmu_ins_* or r_mmu_data* error reporting registers.
    26802700    {
    26812701        uint32_t        ptba = 0;
    26822702        bool            bypass;
    2683         paddr_t         paddr;
     2703        paddr_t         pte_paddr;
    26842704
    26852705        // evaluate bypass in order to skip first level page table access
     
    26932713        }
    26942714
    2695         if ( not bypass )     // Try to read the PTE1/PTD1 in dcache
    2696         {
    2697             paddr = (paddr_t)r_mmu_ptpr.read() << (INDEX1_NBITS+2) |
    2698                     (paddr_t)((r_dcache_tlb_vaddr.read() >> PAGE_M_NBITS) << 2);
    2699             r_dcache_tlb_paddr = paddr;
     2715        if ( not bypass )     // Try to read PTE1/PTD1 in dcache
     2716        {
     2717            pte_paddr = (paddr_t)r_mmu_ptpr.read() << (INDEX1_NBITS+2) |
     2718                        (paddr_t)((r_dcache_tlb_vaddr.read() >> PAGE_M_NBITS) << 2);
     2719            r_dcache_tlb_paddr = pte_paddr;
    27002720            r_dcache_fsm       = DCACHE_TLB_PTE1_GET;
    27012721        }
    2702         else                  // Try to read the PTE2 in dcache
    2703         {
    2704             paddr = (paddr_t)ptba << PAGE_K_NBITS |
    2705                     (paddr_t)(r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
    2706             r_dcache_tlb_paddr = paddr;
     2722        else                  // Try to read PTE2 in dcache
     2723        {
     2724            pte_paddr = (paddr_t)ptba << PAGE_K_NBITS |
     2725                        (paddr_t)(r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
     2726            r_dcache_tlb_paddr = pte_paddr;
    27072727            r_dcache_fsm       = DCACHE_TLB_PTE2_GET;
    27082728        }
     
    27122732{
    27132733    if ( r_dcache_tlb_ins.read() )
    2714         std::cout << "  <PROC.DCACHE_TLB_MISS> ITLB miss request:";
    2715     else                           
    2716         std::cout << "  <PROC.DCACHE_TLB_MISS> DTLB miss request:";
    2717     std::cout << " vaddr = " << std::hex << r_dcache_tlb_vaddr.read()
    2718               << " / bypass = " << bypass
    2719               << " / PTE address = " << paddr << std::endl;
     2734    {
     2735        std::cout << "  <PROC.DCACHE_TLB_MISS> ITLB miss";
     2736    }
     2737    else
     2738    {                           
     2739        std::cout << "  <PROC.DCACHE_TLB_MISS> DTLB miss";
     2740    }
     2741    std::cout << " / VADDR = " << std::hex << r_dcache_tlb_vaddr.read()
     2742              << " / BYPASS = " << bypass
     2743              << " / PTE_ADR = " << pte_paddr << std::endl;
    27202744}
    27212745#endif
     
    27552779                    r_mmu_detr             = MMU_READ_PT1_UNMAPPED;
    27562780                    r_mmu_dbvar            = r_dcache_tlb_vaddr.read();
    2757                     drsp.valid             = true;
    2758                     drsp.error             = true;
     2781                    m_drsp.valid             = true;
     2782                    m_drsp.error             = true;
    27592783                }
    27602784                r_dcache_fsm          = DCACHE_IDLE;
     
    28292853        else            // we must load the missing cache line in dcache
    28302854        {
     2855            r_dcache_vci_miss_req  = true;             
    28312856            r_dcache_vci_paddr     = r_dcache_tlb_paddr.read();
    28322857            r_dcache_miss_type     = PTE1_MISS;
    28332858            r_dcache_fsm           = DCACHE_MISS_VICTIM;         
    2834             r_dcache_vci_miss_req  = true;             
    28352859
    28362860#if DEBUG_DCACHE
     
    28952919        uint32_t  pte   = r_dcache_tlb_pte_flags.read();
    28962920        bool      updt  = false;
    2897 
    2898         //  test the access bits L/R, depending on the physical address locality
    2899         //  we must use the 10 MSB bits of the 19 bits PPN1 to obtain the target index
    2900         //  we must use the 10 MSB bits of the SRCID to obtain the local index
    2901         //  set the r_dcache_vci_sc_old and r_dcache_vci_sc_new registers if SC required
    2902 
    2903         uint32_t target = (pte >> 9) & 0x3FF;
    2904         uint32_t local  = m_srcid_d >> 4;
    2905 
    2906         if ( local == target )                                          // local_address
     2921        bool      local = true;
     2922
     2923        // We should compute the access locality:
     2924        // The PPN MSB bits define the destination cluster index.
     2925        // The m_srcid_d MSB bits define the source cluster index.
     2926        // The number of bits to compare depends on the number of clusters,
     2927        // and can be obtained in the mapping table.
     2928        // As long as this computation is not done, all access are local.
     2929
     2930        if ( local )                                            // local access
    29072931        {
    29082932            if ( not ((pte & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
    29092933            {
    2910                 updt            = true;
    2911                 r_dcache_vci_sc_old = r_dcache_tlb_pte_flags.read();
    2912                 r_dcache_vci_sc_new = r_dcache_tlb_pte_flags.read() | PTE_L_MASK;
    2913             }
    2914         }
    2915         else                                                            // remote address
     2934                updt                = true;
     2935                r_dcache_vci_sc_old = pte;
     2936                r_dcache_vci_sc_new = pte | PTE_L_MASK;
     2937                pte                 = pte | PTE_L_MASK;
     2938            }
     2939        }
     2940        else                                                    // remote access
    29162941        {
    29172942            if ( not ((pte & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
    29182943            {
    29192944                updt                = true;
    2920                 r_dcache_vci_sc_old = r_dcache_tlb_pte_flags.read();
    2921                 r_dcache_vci_sc_new = r_dcache_tlb_pte_flags.read() | PTE_R_MASK;
     2945                r_dcache_vci_sc_old = pte;
     2946                r_dcache_vci_sc_new = pte | PTE_R_MASK;
     2947                pte                 = pte | PTE_R_MASK;
    29222948            }
    29232949        }
     
    29512977        }
    29522978        // next state
    2953         if ( updt ) r_dcache_fsm = DCACHE_TLB_SC_UPDT;  // dcache and page table update
     2979        if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT;  // dcache and page table update
    29542980        else        r_dcache_fsm = DCACHE_TLB_RETURN;   // exit sub-fsm
    29552981
     
    29592985    if ( r_dcache_tlb_ins.read() )
    29602986    {
    2961         std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB:";
    2962         std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
    2963                   << " / set = " << r_dcache_tlb_set.read() << std::endl;
    2964         r_itlb.print();
     2987        std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB";
     2988        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     2989                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
     2990        r_itlb.printTrace();
    29652991    }
    29662992    else                           
    29672993    {
    2968         std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB:";
    2969         std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
    2970                   << " / set = " << r_dcache_tlb_set.read() << std::endl;
    2971         r_dtlb.print();
     2994        std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB";
     2995        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     2996                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
     2997        r_dtlb.printTrace();
    29722998    }
    29732999   
     
    30103036                    r_mmu_detr             = MMU_READ_PT2_UNMAPPED;
    30113037                    r_mmu_dbvar            = r_dcache_tlb_vaddr.read();
    3012                     drsp.valid             = true;
    3013                     drsp.error             = true;
     3038                    m_drsp.valid             = true;
     3039                    m_drsp.error             = true;
    30143040                }
    30153041                r_dcache_fsm          = DCACHE_IDLE;
     
    30473073        else            // we must load the missing cache line in dcache
    30483074        {
     3075            r_dcache_fsm          = DCACHE_MISS_VICTIM;
     3076            r_dcache_vci_miss_req = true;
    30493077            r_dcache_vci_paddr    = r_dcache_tlb_paddr.read();
    30503078            r_dcache_miss_type    = PTE2_MISS;
    3051             r_dcache_fsm          = DCACHE_MISS_VICTIM;
    3052             r_dcache_vci_miss_req = true;
    30533079
    30543080#if DEBUG_DCACHE
     
    30883114#endif
    30893115        }
     3116
     3117#if DEBUG_DCACHE
     3118if ( m_debug_dcache_fsm )
     3119{
     3120    if ( r_dcache_tlb_ins.read() )
     3121        std::cout << "  <PROC.DCACHE_TLB_PTE2_SELECT> Select a slot in ITLB:";
     3122    else                           
     3123        std::cout << "  <PROC.DCACHE_TLB_PTE2_SELECT> Select a slot in DTLB:";
     3124        std::cout << " way = " << std::dec << way
     3125                  << " / set = " << set << std::endl;
     3126}
     3127#endif
    30903128        r_dcache_tlb_way = way;
    30913129        r_dcache_tlb_set = set;
     
    30953133    //////////////////////////
    30963134    case DCACHE_TLB_PTE2_UPDT:          // write a new PTE2 in tlb after testing the L/R bit
    3097                                         // if L/R bit already set exit the sub-fsm
     3135                                        // if L/R bit already set, exit the sub-fsm
    30983136                                        // if not, the page table must be updated by an atomic access
    30993137    {
    3100         paddr_t         nline     = r_dcache_p0_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
     3138        paddr_t         nline     = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
    31013139        uint32_t        pte_flags = r_dcache_tlb_pte_flags.read();
    31023140        uint32_t        pte_ppn   = r_dcache_tlb_pte_ppn.read();
    3103         bool            updt      = false;                         // page table update required
    3104 
    3105         //  test the access bit L/R, depending on the physical address locality
    3106         //  we must use the 10 MSB bits of the 28 bits PPN2 to obtain the target cluster index
    3107         //  we must use the 10 MSB bits of the SRCID to obtain the local cluster index
    3108         //  set the r_dcache_vci_sc_old and r_dcache_vci_sc_new registers if SC required.
    3109 
    3110         uint32_t target = (pte_ppn >> 18) & 0x3FF;
    3111         uint32_t local  = m_srcid_d >> 4;
    3112 
    3113         if ( local == target )                                          // local address
     3141        bool            updt      = false;
     3142        bool            local     = true;
     3143
     3144        // We should compute the access locality:
     3145        // The PPN MSB bits define the destination cluster index.
     3146        // The m_srcid_d MSB bits define the source cluster index.
     3147        // The number of bits to compare depends on the number of clusters,
     3148        // and can be obtained in the mapping table.
     3149        // As long as this computation is not done, all access are local.
     3150
     3151        if ( local )                                            // local access
    31143152        {
    31153153            if ( not ((pte_flags & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
    31163154            {
     3155                updt                = true;
     3156                r_dcache_vci_sc_old = pte_flags;
     3157                r_dcache_vci_sc_new = pte_flags | PTE_L_MASK;
     3158                pte_flags           = pte_flags | PTE_L_MASK;
     3159            }
     3160        }
     3161        else                                                    // remote access
     3162        {
     3163            if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
     3164            {
    31173165                updt                   = true;
    3118                 r_dcache_vci_sc_old        = r_dcache_tlb_pte_flags.read();
    3119                 r_dcache_vci_sc_new        = r_dcache_tlb_pte_flags.read() | PTE_L_MASK;
    3120             }
    3121         }
    3122         else                                                             // remote address
    3123         {
    3124             if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
    3125             {
    3126                 updt                   = true;
    3127                 r_dcache_vci_sc_old        = r_dcache_tlb_pte_flags.read();
    3128                 r_dcache_vci_sc_new        = r_dcache_tlb_pte_flags.read() | PTE_R_MASK;
     3166                r_dcache_vci_sc_old = pte_flags;
     3167                r_dcache_vci_sc_new = pte_flags | PTE_R_MASK;
     3168                pte_flags           = pte_flags | PTE_R_MASK;
    31293169            }
    31303170        }
     
    31333173        if ( r_dcache_tlb_ins.read() ) 
    31343174        {
    3135             r_itlb.write( false,        // 2K page
     3175            r_itlb.write( false,        // 4K page
    31363176                          pte_flags,
    31373177                          pte_ppn,
     
    31463186        else
    31473187        {
    3148             r_dtlb.write( false,        // 2K page
     3188            r_dtlb.write( false,        // 4K page
    31493189                          pte_flags,
    31503190                          pte_ppn,
     
    31633203    if ( r_dcache_tlb_ins.read() )
    31643204    {
    3165         std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB:";
    3166         std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
    3167                   << " / set = " << r_dcache_tlb_set.read() << std::endl;
    3168         r_itlb.print();
     3205        std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB";
     3206        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     3207                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
     3208        r_itlb.printTrace();
    31693209    }
    31703210    else                           
    31713211    {
    3172         std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB:";
    3173         std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
    3174                   << " / set = " << r_dcache_tlb_set.read() << std::endl;
    3175         r_dtlb.print();
     3212        std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB";
     3213        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     3214                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
     3215        r_dtlb.printTrace();
    31763216    }
    31773217}
    31783218#endif
    31793219        // next state
    3180         if ( updt ) r_dcache_fsm = DCACHE_TLB_SC_UPDT;  // dcache and page table update
     3220        if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT;  // dcache and page table update
    31813221        else        r_dcache_fsm = DCACHE_TLB_RETURN;   // exit sub-fsm
    31823222        break;
    31833223    }
    31843224    ////////////////////////
    3185     case DCACHE_TLB_SC_UPDT:            // update the dcache after a tlb miss (L/R bit),
     3225    case DCACHE_TLB_LR_UPDT:            // update the dcache after a tlb miss (L/R bit),
    31863226                                        // request a SC transaction to CMD FSM
    31873227    {
     
    31893229if ( m_debug_dcache_fsm )
    31903230{
    3191     std::cout << "  <PROC.DCACHE_TLB_SC_UPDT> Update dcache: (L/R) bit" << std::endl;
     3231    std::cout << "  <PROC.DCACHE_TLB_LR_UPDT> Update dcache: (L/R) bit" << std::endl;
    31923232}
    31933233#endif
     
    32003240#endif
    32013241        // r_dcache_vci_sc_old & r_dcache_vci_sc_new registers are already set
     3242        r_dcache_vci_paddr   = r_dcache_tlb_paddr.read();
    32023243        r_dcache_vci_sc_req  = true;
    3203         r_dcache_fsm         = DCACHE_TLB_SC_WAIT;
     3244        r_dcache_fsm         = DCACHE_TLB_LR_WAIT;
    32043245        break;
    32053246    }
    32063247    ////////////////////////
    3207     case DCACHE_TLB_SC_WAIT:            // Waiting a response to SC transaction.
     3248    case DCACHE_TLB_LR_WAIT:            // Waiting a response to SC transaction.
    32083249                                        // We consume the response in rsp FIFO,
    32093250                                        // and exit the sub-fsm, but we don't
     
    32243265        if ( r_vci_rsp_data_error.read() )      // bus error
    32253266        {
    3226             std::cout << "BUS ERROR in DCACHE_TLB_SC_WAIT state" << std::endl;
     3267            std::cout << "BUS ERROR in DCACHE_TLB_LR_WAIT state" << std::endl;
    32273268            std::cout << "This should not happen in this state" << std::endl;
    32283269            exit(0);
     
    32333274if ( m_debug_dcache_fsm )
    32343275{
    3235     std::cout << "  <PROC.DCACHE_TLB_SC_WAIT> SC response received" << std::endl;
     3276    std::cout << "  <PROC.DCACHE_TLB_LR_WAIT> SC response received" << std::endl;
    32363277}
    32373278#endif
     
    32613302            r_dtlb.flush();
    32623303            r_dcache_fsm = DCACHE_IDLE;
    3263             drsp.valid = true;
     3304            m_drsp.valid = true;
    32643305        }
    32653306        break;
     
    32793320        if ( r_wbuf.empty() )
    32803321        {
    3281             drsp.valid   = true;
     3322            m_drsp.valid   = true;
    32823323            r_dcache_fsm = DCACHE_IDLE;
    32833324        }
     
    33113352        {
    33123353            r_dcache_fsm = DCACHE_IDLE;
    3313             drsp.valid = true;
     3354            m_drsp.valid = true;
    33143355        }
    33153356        break;
     
    33513392                }
    33523393                r_dcache_fsm = DCACHE_IDLE;
    3353                 drsp.valid = true;
     3394                m_drsp.valid = true;
    33543395            }
    33553396        }
     
    33613402        r_dtlb.inval(r_dcache_p0_wdata.read());
    33623403        r_dcache_fsm        = DCACHE_IDLE;
    3363         drsp.valid          = true;
     3404        m_drsp.valid          = true;
    33643405        break;
    33653406    }
     
    34293470        {
    34303471            r_dcache_fsm      = DCACHE_IDLE;
    3431             drsp.valid        = true;
     3472            m_drsp.valid        = true;
    34323473        }
    34333474        break;
     
    34803521            {
    34813522                r_dcache_fsm = DCACHE_IDLE;
    3482                 drsp.valid = true;
     3523                m_drsp.valid = true;
    34833524            }
    34843525        }
     
    34893530    {
    34903531        r_dcache_fsm = DCACHE_IDLE;
    3491         drsp.valid = true;
     3532        m_drsp.valid = true;
    34923533        break;
    34933534    }
     
    35933634                    r_mmu_detr            = MMU_READ_DATA_ILLEGAL_ACCESS;
    35943635                    r_mmu_dbvar           = r_dcache_p0_vaddr.read();
    3595                     drsp.valid            = true;
    3596                     drsp.error            = true;
     3636                    m_drsp.valid            = true;
     3637                    m_drsp.error            = true;
    35973638                    r_dcache_fsm          = DCACHE_IDLE;
    35983639                    break;
     
    36113652                        r_mmu_detr              = MMU_READ_PT1_ILLEGAL_ACCESS;
    36123653                        r_mmu_dbvar             = r_dcache_tlb_vaddr.read();
    3613                         drsp.valid              = true;
    3614                         drsp.error              = true;
     3654                        m_drsp.valid              = true;
     3655                        m_drsp.error              = true;
    36153656                    }
    36163657                    r_dcache_fsm                = DCACHE_IDLE;
     
    36303671                        r_mmu_detr              = MMU_READ_PT2_ILLEGAL_ACCESS;
    36313672                        r_mmu_dbvar             = r_dcache_tlb_vaddr.read();
    3632                         drsp.valid              = true;
    3633                         drsp.error              = true;
     3673                        m_drsp.valid              = true;
     3674                        m_drsp.error              = true;
    36343675                    }
    36353676                    r_dcache_fsm                = DCACHE_IDLE;
     
    37553796        {
    37563797            r_mmu_detr           = MMU_READ_DATA_ILLEGAL_ACCESS;
    3757             r_mmu_dbvar          = dreq.addr;
     3798            r_mmu_dbvar          = m_dreq.addr;
    37583799            r_vci_rsp_data_error = false;
    3759             drsp.error           = true;
    3760             drsp.valid           = true;
     3800            m_drsp.error           = true;
     3801            m_drsp.valid           = true;
    37613802            r_dcache_fsm         = DCACHE_IDLE;
    37623803            break;
     
    37673808            r_dcache_fsm            = DCACHE_IDLE;
    37683809            // we acknowledge the processor request if it has not been modified
    3769             if ( dreq.valid and (dreq.addr == r_dcache_p0_vaddr.read()) )
    3770             {
    3771                 drsp.valid          = true;
    3772                 drsp.rdata          = r_vci_rsp_fifo_dcache.read();
     3810            if ( m_dreq.valid and (m_dreq.addr == r_dcache_p0_vaddr.read()) )
     3811            {
     3812                m_drsp.valid          = true;
     3813                m_drsp.rdata          = r_vci_rsp_fifo_dcache.read();
    37733814            }
    37743815        }       
    37753816        break;
    37763817    }
    3777     ////////////////////////////
    3778     case DCACHE_WRITE_TLB_DIRTY:        // set PTE dirty bit in dtlb
     3818    ////////////////////
     3819    case DCACHE_SC_WAIT:        // waiting VCI response after a processor SC request
     3820                                // a long write is launched if dirty bit must be set
     3821    {
     3822        // external coherence request
     3823        if ( r_tgt_dcache_req.read() )
     3824        {
     3825            r_dcache_fsm = DCACHE_CC_CHECK;
     3826            r_dcache_fsm_save = r_dcache_fsm;
     3827            break;
     3828        }
     3829
     3830        if ( r_vci_rsp_data_error.read() )              // bus error
     3831        {
     3832            r_mmu_detr           = MMU_READ_DATA_ILLEGAL_ACCESS;
     3833            r_mmu_dbvar          = m_dreq.addr;
     3834            r_vci_rsp_data_error = false;
     3835            m_drsp.error         = true;
     3836            m_drsp.valid         = true;
     3837            r_dcache_fsm         = DCACHE_IDLE;
     3838            break;
     3839        }
     3840        else if ( r_vci_rsp_fifo_dcache.rok() )         // response available
     3841        {
     3842            bool sc_success = (r_vci_rsp_fifo_dcache.read() == 0);
     3843            vci_rsp_fifo_dcache_get = true;     
     3844
     3845            if ( sc_success and not r_dcache_p0_tlb_dirty.read() )      // Dirty bit must be set
     3846            {
     3847                // The PTE physical address is the concatenation of the nline value (from dtlb),
     3848                // with the word index (obtained from the proper bits of the virtual address)
     3849                if ( r_dcache_p0_tlb_big.read() )       // PTE1
     3850                {
     3851                    r_dcache_p2_pte_paddr = (paddr_t)(r_dcache_p0_tlb_nline.read()*(m_dcache_words<<2)) |
     3852                                            (paddr_t)((r_dcache_p0_vaddr.read()>>19) & 0x3c);
     3853                }
     3854                else                                    // PTE2
     3855                {
     3856                    r_dcache_p2_pte_paddr = (paddr_t)(r_dcache_p0_tlb_nline.read()*(m_dcache_words<<2)) |
     3857                                            (paddr_t)((r_dcache_p0_vaddr.read()>>9) & 0x38);
     3858                }
     3859                r_dcache_p2_sc_success = sc_success;
     3860                r_dcache_p2_way        = r_dcache_p0_tlb_way.read();
     3861                r_dcache_p2_set        = r_dcache_p0_tlb_set.read();
     3862                r_dcache_fsm           = DCACHE_DIRTY_TLB_SET;
     3863         
     3864            }
     3865            else
     3866            {
     3867                m_drsp.valid            = true;
     3868                m_drsp.rdata            = r_vci_rsp_fifo_dcache.read();
     3869                r_dcache_fsm            = DCACHE_IDLE;
     3870            }
     3871        }       
     3872        break;
     3873    }
     3874    //////////////////////////
     3875    case DCACHE_DIRTY_TLB_SET:          // Enter this sub_fsm in case of long write:
     3876                                        // - in case of WRITE request (r_dcache_p2_type_sc == false)
     3877                                        // - in case of SC request    (r_dcache_p2_type_sc == true)
     3878                                        // Inputs arguments are:
     3879                                        // - r_dcache_p2_way,
     3880                                        // - r_dcache_p2_set,
     3881                                        // - r_dcache_p2_pte_paddr,
     3882                                        // - r_dcache_p2_type_sc,
     3883                                        // - r_dcache_p2_sc_success,
     3884                                        // In this first state, we set PTE dirty bit in dtlb
    37793885                                        // and get PTE in dcache
    37803886    {
    37813887        // set dirty bit in dtlb
    3782         r_dtlb.set_dirty( r_dcache_p2_tlb_way.read(),
    3783                           r_dcache_p2_tlb_set.read() );
     3888        r_dtlb.set_dirty( r_dcache_p2_way.read(),
     3889                          r_dcache_p2_set.read() );
    37843890
    37853891        // get PTE in dcache
     
    38013907if ( m_debug_dcache_fsm )
    38023908{
    3803     std::cout << "  <PROC.DCACHE_WRITE_TLB_DIRTY> Set dirty bit in dtlb:" << std::dec
    3804               << " / tlb_way = " << r_dcache_p2_tlb_way.read()
    3805               << " / tlb_set = " << r_dcache_p2_tlb_set.read() << std::endl;
    3806     r_dtlb.print();
    3807     std::cout << "                                Get PTE in dcache:" << std::hex
    3808               << " paddr = " << r_dcache_p2_pte_paddr.read()
     3909    std::cout << "  <PROC.DCACHE_DIRTY_TLB_SET> Set dirty bit in dtlb:" << std::dec
     3910              << " / tlb_set = " << r_dcache_p2_set.read()
     3911              << " / tlb_way = " << r_dcache_p2_way.read() << std::endl;
     3912    r_dtlb.printTrace();
     3913    std::cout << "      and get PTE in dcache" << std::hex
     3914              << " / PADDR = " << r_dcache_p2_pte_paddr.read()
    38093915              << " / PTE = " << pte << std::dec
    3810               << " / dcache_way = " << way
    3811               << " / dcache_set = " << set << std::endl;
     3916              << " / set = " << set
     3917              << " / way = " << way << std::endl;
    38123918}
    38133919#endif
    3814         assert( hit and "error in DCACHE_WRITE_TLB_DIRTY: the PTE should be in dcache" );
    3815 
    3816         r_dcache_p2_pte_way   = way;                    // register pte way in dcache
    3817         r_dcache_p2_pte_set   = set;                    // register pte set in dcache;
    3818         r_dcache_p2_pte_word  = word;                   // register pte word in dcache;
    3819         r_dcache_p2_pte      = pte;                    // register pte value
    3820         r_dcache_fsm          = DCACHE_WRITE_CACHE_DIRTY;
    3821         break;
    3822     }
    3823     //////////////////////////////
    3824     case DCACHE_WRITE_CACHE_DIRTY:      // set PTE dirty bit in dcache
     3920        assert( hit and "error in DCACHE_DIRTY_TLB_SET: the PTE should be in dcache" );
     3921
     3922        r_dcache_p2_way       = way;                    // register pte way in dcache
     3923        r_dcache_p2_set       = set;                    // register pte set in dcache;
     3924        r_dcache_p2_word      = word;                   // register pte word in dcache;
     3925        r_dcache_p2_pte_value = pte;                    // register pte value
     3926        r_dcache_fsm          = DCACHE_DIRTY_CACHE_SET;
     3927        break;
     3928    }
     3929    ////////////////////////////
     3930    case DCACHE_DIRTY_CACHE_SET:        // set PTE dirty bit in dcache
    38253931                                        // request SC tranansaction to CMD FSM
    38263932    {
    38273933        // set PTE dirty bit in dcache
    3828         r_dcache.write( r_dcache_p2_pte_way.read(),
    3829                         r_dcache_p2_pte_set.read(),
    3830                         r_dcache_p2_pte_word.read(),
    3831                         r_dcache_p2_pte.read() | PTE_D_MASK,
     3934        r_dcache.write( r_dcache_p2_way.read(),
     3935                        r_dcache_p2_set.read(),
     3936                        r_dcache_p2_word.read(),
     3937                        r_dcache_p2_pte_value.read() | PTE_D_MASK,
    38323938                        0xF );
    38333939
     
    38353941m_cpt_dcache_data_write++;
    38363942#endif
    3837        
     3943        // request sc transaction to CMD_FSM
     3944        r_dcache_vci_sc_req = true;
     3945        r_dcache_vci_paddr  = r_dcache_p2_pte_paddr.read();
     3946        r_dcache_vci_sc_old = r_dcache_p2_pte_value.read();
     3947        r_dcache_vci_sc_new = r_dcache_p2_pte_value.read() | PTE_D_MASK;
     3948        r_dcache_fsm        = DCACHE_DIRTY_SC_WAIT;   
     3949
    38383950#if DEBUG_DCACHE
    38393951if ( m_debug_dcache_fsm )
    38403952{
    3841     std::cout << "  <PROC.DCACHE_WRITE_CACHE_DIRTY> Set PTE dirty bit in dcache"
    3842               << " / way = " << r_dcache_p2_pte_way.read()
    3843               << " / set = " << r_dcache_p2_pte_set.read()
    3844               << " / word = " << r_dcache_p2_pte_word.read() << std::endl;
    3845     std::cout << "                                  Request SC transaction"
    3846               << " / address = " << "bloup"
    3847               << " / old = " << r_dcache_p2_pte.read()
    3848               << " / new = " << (r_dcache_p2_pte.read() | PTE_D_MASK) << std::endl;
     3953    std::cout << "  <PROC.DCACHE_DIRTY_CACHE_SET> Set PTE dirty bit in dcache"
     3954              << " / way = " << r_dcache_p2_way.read()
     3955              << " / set = " << r_dcache_p2_set.read()
     3956              << " / word = " << r_dcache_p2_word.read() << std::endl;
     3957    std::cout << "   and request SC transaction for dirty bit update"
     3958              << " / address = " << r_dcache_p2_pte_paddr.read()
     3959              << " / old = " << r_dcache_p2_pte_value.read()
     3960              << " / new = " << (r_dcache_p2_pte_value.read() | PTE_D_MASK) << std::endl;
    38493961}
    38503962#endif
    3851         // request sc transaction to CMD_FSM
    3852         r_dcache_vci_sc_req = true;
    3853         r_dcache_vci_sc_old = r_dcache_p2_pte.read();
    3854         r_dcache_vci_sc_new = r_dcache_p2_pte.read() | PTE_D_MASK;
    3855         r_dcache_fsm        = DCACHE_WRITE_SC_WAIT;   
    38563963        break;
    38573964    }
    38583965    //////////////////////////
    3859     case DCACHE_WRITE_SC_WAIT:          // wait completion of SC
     3966    case DCACHE_DIRTY_SC_WAIT:          // wait completion of SC for PTE Dirty bit
    38603967                                        // if atomic, write completed : return to IDLE state
    3861                                         // else, makes an uncacheable read to retry the SC
     3968                                        // else, read the mofified PTE to retry the SC
    38623969    {
    38633970        // external coherence request
     
    38713978        if ( r_vci_rsp_data_error.read() )      // bus error
    38723979        {
    3873             r_mmu_detr   = MMU_WRITE_PT2_ILLEGAL_ACCESS;
    3874             r_mmu_dbvar  = r_dcache_p2_vaddr;
    3875             drsp.valid   = true;
    3876             drsp.error   = true;
    3877             r_dcache_fsm = DCACHE_IDLE;
    3878             break;
     3980            std::cout << "BUS ERROR in DCACHE_DIRTY_SC_WAIT state" << std::endl;
     3981            std::cout << "This should not happen in this state" << std::endl;
     3982            exit(0);
    38793983        }
    38803984        else if ( r_vci_rsp_fifo_dcache.rok() ) // response available
    38813985        {
    3882             if ( r_vci_rsp_fifo_dcache.read() == 0 )            // atomic
    3883             {
    3884                 drsp.valid   = true;            // acknowledge the initial write
    3885                 r_dcache_fsm = DCACHE_IDLE;
    3886             }
    3887             else                                               
     3986            vci_rsp_fifo_dcache_get = true;
     3987            if ( r_vci_rsp_fifo_dcache.read() == 0 )    // exit if dirty bit update atomic
     3988            {
     3989                if ( r_dcache_p2_type_sc.read() )       // long write for SC request
     3990                {
     3991                    m_drsp.valid = true;
     3992                    m_drsp.rdata = ( r_dcache_p2_sc_success.read() ? 0 : 1 );
     3993                    r_dcache_fsm = DCACHE_IDLE;
     3994                }
     3995                else                                    // long write for WRITE request
     3996                {
     3997                    r_dcache_fsm = DCACHE_IDLE;
     3998                }
     3999            }
     4000            else                                        // retry if dirty bit update failed
    38884001            {
    38894002                r_dcache_vci_paddr   = r_dcache_p2_pte_paddr;
    38904003                r_dcache_vci_unc_req = true;
    38914004                r_dcache_vci_unc_be  = 0xF;
    3892                 r_dcache_fsm         = DCACHE_WRITE_UNC_WAIT;
     4005                r_dcache_fsm         = DCACHE_DIRTY_UNC_WAIT;
    38934006            }
    38944007        }
     
    38964009    }
    38974010    ///////////////////////////
    3898     case DCACHE_WRITE_UNC_WAIT:         // wait completion of uncacheable read
    3899                                         // in case of success we retry a SC request to
     4011    case DCACHE_DIRTY_UNC_WAIT:         // wait completion of PTE read
     4012                                        // and retry a SC request to
    39004013                                        // set the dirty bit in the PTE
    39014014    {
     
    39104023        if ( r_vci_rsp_data_error.read() )      // bus error
    39114024        {
    3912             r_mmu_detr   = MMU_READ_PT2_ILLEGAL_ACCESS;
    3913             r_mmu_dbvar  = r_dcache_p2_vaddr;
    3914             drsp.valid   = true;
    3915             drsp.error   = true;
    3916             r_dcache_fsm = DCACHE_IDLE;
    3917             break;
     4025            std::cout << "BUS ERROR in DCACHE_DIRTY_UNC_WAIT state" << std::endl;
     4026            std::cout << "This should not happen in this state" << std::endl;
     4027            exit(0);
    39184028        }
    39194029        if ( r_vci_rsp_fifo_dcache.rok() )      // PTE available
     
    39224032            r_dcache_vci_sc_old = r_vci_rsp_fifo_dcache.read();
    39234033            r_dcache_vci_sc_new = r_vci_rsp_fifo_dcache.read() | PTE_D_MASK;
    3924             r_dcache_fsm        = DCACHE_WRITE_SC_WAIT;   
     4034            r_dcache_fsm        = DCACHE_DIRTY_SC_WAIT;   
    39254035        }
    39264036        break;
     
    41694279              << " / set = " << set
    41704280              << " / way = " << way << std::endl;
    4171     r_itlb.print();
     4281    r_itlb.printTrace();
    41724282}
    41734283#endif
     
    41864296              << " / set = " << set
    41874297              << " / way = " << way << std::endl;
    4188     r_dtlb.print();
     4298    r_dtlb.printTrace();
    41894299}
    41904300#endif
     
    42074317    } // end switch r_dcache_fsm
    42084318
    4209 
    4210     //////////////////// save DREQ and DRSP fields for print_trace() ////////////////
    4211     m_dreq_valid = dreq.valid;
    4212     m_dreq_addr  = dreq.addr;
    4213     m_dreq_mode  = dreq.mode;
    4214     m_dreq_type  = dreq.type;
    4215     m_dreq_wdata = dreq.wdata;
    4216     m_dreq_be    = dreq.be;
    4217    
    4218     m_drsp_valid = drsp.valid;
    4219     m_drsp_rdata = drsp.rdata;
    4220     m_drsp_error = drsp.error;
    4221 
    42224319    ///////////////// wbuf update //////////////////////////////////////////////////////
    42234320    r_wbuf.update();
    42244321
    4225     /////////// test processor frozen /////////////////////////////////////////////
     4322    //////////////// test processor frozen /////////////////////////////////////////////
    42264323    // The simulation exit if the number of consecutive frozen cycles
    42274324    // is larger than the m_max_frozen_cycles (constructor parameter)
    4228     if ( (ireq.valid and not irsp.valid) or (dreq.valid and not drsp.valid) )       
     4325    if ( (m_ireq.valid and not m_irsp.valid) or (m_dreq.valid and not m_drsp.valid) )       
    42294326    {
    42304327        m_cpt_frz_cycles++;             // used for instrumentation
     
    42484345    uint32_t it = 0;
    42494346    for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if(p_irq[i].read()) it |= (1<<i);
    4250     r_iss.executeNCycles(1, irsp, drsp, it);
     4347    r_iss.executeNCycles(1, m_irsp, m_drsp, it);
    42514348    }
    42524349
Note: See TracChangeset for help on using the changeset viewer.