source: trunk/modules/vci_io_bridge/caba/source/src/vci_io_bridge.cpp @ 451

Last change on this file since 451 was 451, checked in by alain, 11 years ago

Introducing the vci_iox_network modeling the external IO network.

File size: 79.4 KB
RevLine 
[434]1/* -*- c++ -*-
[240]2 * File : vci_io_bridge.cpp
3 * Copyright (c) UPMC, Lip6, SoC
[434]4 * Authors: Cassio Fraga, Alain Greiner
[240]5 *
6 * SOCLIB_LGPL_HEADER_BEGIN
7 *
8 * This file is part of SoCLib, GNU LGPLv2.1.
9 *
10 * SoCLib is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published
12 * by the Free Software Foundation; version 2.1 of the License.
13 *
14 * SoCLib is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with SoCLib; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 * SOCLIB_LGPL_HEADER_END
25 */
26
27#include <cassert>
28#include "arithmetics.h"
29#include "alloc_elems.h"
30#include "../include/vci_io_bridge.h"
31
[434]32
[240]33//////   debug services   ///////////////////////////////////////////////////////
34// All debug messages are conditionned by two variables:
35// - compile time : DEBUG_*** : defined below
36// - execution time : m_debug_***  : defined by constructor arguments
[434]37//    m_debug_activated = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)
[240]38/////////////////////////////////////////////////////////////////////////////////
39
40#define DEBUG_DMA_CMD           1
41#define DEBUG_DMA_RSP           1
[434]42#define DEBUG_TLB_MISS          1
[240]43#define DEBUG_CONFIG_CMD                1
44#define DEBUG_CONFIG_RSP                1
[434]45#define DEBUG_MISS_WTI                  1
[240]46
47namespace soclib { 
48namespace caba {
49
50namespace {
51
[434]52const char *dma_cmd_fsm_state_str[] = 
53    {
[240]54        "DMA_CMD_IDLE",
[434]55        "DMA_CMD_FIFO_PUT_CMD",
56        "DMA_CMD_FIFO_PUT_RSP",
57        "DMA_CMD_MISS_WAIT",
58        "DMA_CMD_WAIT_EOP",
[240]59    };
60
[434]61const char *dma_rsp_fsm_state_str[] = 
62    {
[240]63        "DMA_RSP_IDLE",
64        "DMA_RSP_FIFO_PUT",
65    };
66
[434]67const char *tlb_fsm_state_str[] = 
68    {
69        "TLB_IDLE",
70        "TLB_MISS",
71        "TLB_PTE1_GET",
72        "TLB_PTE1_SELECT",
73        "TLB_PTE1_UPDT",
74        "TLB_PTE2_GET",                                                 
75        "TLB_PTE2_SELECT",
76        "TLB_PTE2_UPDT",
77        "TLB_WAIT",
78        "TLB_RETURN",
79        "TLB_INVAL_CHECK",
[240]80    };
81
[434]82const char *config_cmd_fsm_state_str[] = 
83    {
[240]84        "CONFIG_CMD_IDLE",
[434]85        "CONFIG_CMD_FIFO_PUT_CMD",
86        "CONFIG_CMD_FIFO_PUT_RSP",
[240]87    };
88
[434]89const char *config_rsp_fsm_state_str[] = 
90    {
[240]91        "CONFIG_RSP_IDLE",
92        "CONFIG_RSP_FIFO_PUT", 
93    };
94
[434]95const char *miss_wti_fsm_state_str[] = { 
96        "MISS_WTI_IDLE_MISS",
97        "MISS_WTI_IDLE_WTI",
98        "MISS_WTI_CMD_WTI",
99        "MISS_WTI_RSP_WTI",
100        "MISS_WTI_CMD_MISS",
101        "MISS_WTI_RSP_MISS",
[240]102    };
103}
104
[434]105#define tmpl(...)  template<typename vci_param_int,typename vci_param_ext> __VA_ARGS__ VciIoBridge<vci_param_int,vci_param_ext>
[240]106
[434]107////////////////////////
[240]108tmpl(/**/)::VciIoBridge(
109    sc_module_name                                  name,
[434]110    const soclib::common::MappingTable  &mt_ext,
111    const soclib::common::MappingTable  &mt_int,
112    const soclib::common::MappingTable  &mt_iox,
113    const soclib::common::IntTab            &int_tgtid,     // INT network TGTID
114    const soclib::common::IntTab            &int_srcid,     // INT network SRCID
115    const soclib::common::IntTab            &iox_tgtid,     // IOX network TGTID
116    const bool                          has_irqs,
117    const size_t                        dcache_words,
118    const size_t                                        iotlb_ways,
119    const size_t                                        iotlb_sets,
120    const uint32_t                                      debug_start_cycle,
121    const bool                                      debug_ok)
[240]122    : soclib::caba::BaseModule(name),
123
[434]124      p_clk("p_clk"),
125      p_resetn("p_resetn"),
126      p_vci_ini_ram("p_vci_ini_ram"),
127      p_vci_tgt_iox("p_vci_tgt_iox"),
128      p_vci_ini_iox("p_vci_ini_iox"),
129      p_vci_tgt_int("p_vci_tgt_int"),
130      p_vci_ini_int("p_vci_ini_int"),
[240]131
[434]132      m_words( dcache_words ),
133      m_has_irqs( has_irqs ),
[240]134
[434]135      // INT & IOX Network
136      m_int_seglist( mt_int.getSegmentList( int_tgtid )),
137      m_int_srcid( mt_int.indexForId( int_srcid )), 
138      m_iox_seglist( mt_iox.getSegmentList( iox_tgtid )),
139
[240]140      m_iotlb_ways(iotlb_ways),
141      m_iotlb_sets(iotlb_sets),
142
143      m_debug_start_cycle(debug_start_cycle),
144      m_debug_ok(debug_ok),
145
[434]146      // addressable registers
[240]147      r_iommu_ptpr("r_iommu_ptpr"),
148      r_iommu_active("r_iommu_active"),
149      r_iommu_bvar("r_iommu_bvar"),
150      r_iommu_etr("r_iommu_etr"),
151      r_iommu_bad_id("r_iommu_bad_id"),
[434]152      r_iommu_wti_paddr("r_iommu_wti_paddr"),
153      r_iommu_peri_wti(alloc_elems<sc_signal<vci_addr_t> >("r_peri_wti_paddr", 32)),
[240]154
[434]155      // DMA_CMD FSM registers
[240]156      r_dma_cmd_fsm("r_dma_cmd_fsm"),
[434]157      r_dma_cmd_vaddr("r_dma_cmd_vaddr"),
158      r_dma_cmd_paddr("r_dma_cmd_paddr"),
[240]159
[434]160      //DMA_RSP FSM registers
161      r_dma_rsp_fsm("r_dma_rsp_fsm"),
[240]162
[434]163      // CONFIG_CMD FSM registers
164      r_config_cmd_fsm("r_config_cmd_fsm"),
165      r_config_cmd_rdata("r_config_cmd_rdata"),
166      r_config_cmd_error("r_config_cmd_error"),
167      r_config_cmd_inval_vaddr("r_config_cmd_inval_vaddr"),
[240]168
[434]169      // CONFIG_RSP FSM registers 
170      r_config_rsp_fsm("r_config_rsp_fsm"),
171
172      // TLB FSM registers
173      r_tlb_fsm("r_tlb_fsm"),
[240]174      r_waiting_transaction("r_waiting_transaction"),
175      r_tlb_miss_type("r_tlb_miss_type"),
[434]176      r_tlb_miss_error("r_tlb_miss_error"),
177      r_tlb_paddr("r_tlb_paddr"),               
178      r_tlb_pte_flags("r_tlb_pte_flags"),
179      r_tlb_pte_ppn("r_tlb_pte_ppn"),
180      r_tlb_way("r_tlb_way"),
181      r_tlb_set("r_tlb_set"),   
182      r_tlb_buf_valid("r_tlb_buf_valid"),
183      r_tlb_buf_tag("r_tlb_buf_tag"),
184      r_tlb_buf_vaddr("r_tlb_buf_vaddr"),
185      r_tlb_buf_big_page("r_tlb_buf_big_page"),
[240]186
[434]187      // MISS_WTI_CMD FSM registers
188      r_miss_wti_cmd_fsm("r_miss_wti_cmd_fsm"), 
189      r_miss_wti_cmd_index("r_miss_wti_cmd_index"),
[240]190
[434]191      // MISS_WTI_CMD FSM registers
192      r_miss_wti_rsp_fsm("r_miss_wti_rsp_fsm"), 
193      r_miss_wti_rsp_error("r_miss_wti_rsp_error"),
194
195      // allocator for CONFIG_RSP & DMA_RSP fifos
196      r_alloc_fifo_config_rsp_local("r_alloc_fifo_config_rsp_local"), 
197      r_alloc_fifo_dma_rsp_local("r_alloc_fifo_dma_rsp_local"), 
198
199      // IRQs registers
200      r_irq_pending(alloc_elems<sc_signal<bool> >("r_irq_pending", 32)),
201      r_irq_request(alloc_elems<sc_signal<bool> >("r_irq_request", 32)),
[240]202     
[434]203      // TLB for IOMMU
204      r_iotlb("iotlb", 0, iotlb_ways, iotlb_sets, vci_param_int::N),
205     
206      // Inter-FSM communications
[240]207      r_dma_tlb_req("r_dma_tlb_req"),
208      r_config_tlb_req("r_config_tlb_req"),
[434]209      r_tlb_miss_req("r_tlb_miss_req"),
[240]210     
[434]211      // DMA_CMD FIFOs
212      m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",2),
213      m_dma_cmd_srcid_fifo("m_dma_cmd_srcid_fifo",2), 
214      m_dma_cmd_trdid_fifo("m_dma_cmd_trdid_fifo",2), 
215      m_dma_cmd_pktid_fifo("m_dma_cmd_pktid_fifo",2), 
216      m_dma_cmd_be_fifo("m_dma_cmd_be_fifo",2), 
217      m_dma_cmd_cmd_fifo("m_dma_cmd_cmd_fifo",2), 
218      m_dma_cmd_contig_fifo("m_dma_cmd_contig_fifo",2), 
219      m_dma_cmd_data_fifo("m_dma_cmd_data_fifo",2), 
220      m_dma_cmd_eop_fifo("m_dma_cmd_eop_fifo",2),
221      m_dma_cmd_cons_fifo("m_dma_cmd_cons_fifo",2), 
222      m_dma_cmd_plen_fifo("m_dma_cmd_plen_fifo",2), 
223      m_dma_cmd_wrap_fifo("m_dma_cmd_wrap_fifo",2), 
224      m_dma_cmd_cfixed_fifo("m_dma_cmd_cfixed_fifo",2),
225      m_dma_cmd_clen_fifo("m_dma_cmd_clen_fifo",2), 
[240]226
[434]227      // DMA_RSP FIFOs
228      m_dma_rsp_data_fifo("m_dma_rsp_data_fifo",2),
229      m_dma_rsp_rsrcid_fifo("m_dma_rsp_rsrcid_fifo",2),
230      m_dma_rsp_rtrdid_fifo("m_dma_rsp_rtrdid_fifo",2),
231      m_dma_rsp_rpktid_fifo("m_dma_rsp_rpktid_fifo",2),
232      m_dma_rsp_reop_fifo("m_dma_rsp_reop_fifo",2),
233      m_dma_rsp_rerror_fifo("m_dma_rsp_rerror_fifo",2),
234 
235      // CONFIG_CMD FIFOs
236      m_config_cmd_addr_fifo("m_config_cmd_addr_fifo",2),
237      m_config_cmd_srcid_fifo("m_config_cmd_srcid_fifo",2),
238      m_config_cmd_trdid_fifo("m_config_cmd_trdid_fifo",2),
239      m_config_cmd_pktid_fifo("m_config_cmd_pktid_fifo",2),
240      m_config_cmd_be_fifo("m_config_cmd_be_fifo",2),
241      m_config_cmd_cmd_fifo("m_config_cmd_cmd_fifo",2),
242      m_config_cmd_contig_fifo("m_config_cmd_contig_fifo",2),
243      m_config_cmd_data_fifo("m_config_cmd_data_fifo",2),
244      m_config_cmd_eop_fifo("m_config_cmd_eop_fifo",2),
245      m_config_cmd_cons_fifo("m_config_cmd_cons_fifo",2),
246      m_config_cmd_plen_fifo("m_config_cmd_plen_fifo",2),
247      m_config_cmd_wrap_fifo("m_config_cmd_wrap_fifo",2),
248      m_config_cmd_cfixed_fifo("m_config_cmd_cfixed_fifo",2),
249      m_config_cmd_clen_fifo("m_config_cmd_clen_fifo",2),
250
251      // CONFIG_RSP FIFOs
252      m_config_rsp_data_fifo("m_config_rsp_data_fifo",2),     
253      m_config_rsp_rsrcid_fifo("m_config_rsp_rsrcid_fifo",2),
254      m_config_rsp_rtrdid_fifo("m_config_rsp_rtrdid_fifo",2),
255      m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",2),
256      m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",2),
257      m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",2)
[240]258{
[434]259    std::cout << "  - Building VciIoBridge : " << name << std::endl;
260
261    // checking segments on INT network
262    assert ( ( not m_int_seglist.empty() ) and
263    "VCI_IO_BRIDGE ERROR : no segment allocated on INT network");
264
265    std::list<soclib::common::Segment>::iterator int_seg;
266    for ( int_seg = m_int_seglist.begin() ; int_seg != m_int_seglist.end() ; int_seg++ )
267    {
268        std::cout << "    => segment " << int_seg->name()
269                  << " / base = " << std::hex << int_seg->baseAddress()
270                  << " / size = " << int_seg->size() << std::endl; 
271    }
272
273    // checking segments on IOX network
274    assert ( ( not m_iox_seglist.empty() ) and
275    "VCI_IO_BRIDGE ERROR : no segment allocated on IOX network");
276
277    std::list<soclib::common::Segment>::iterator iox_seg;
278    for ( iox_seg = m_iox_seglist.begin() ; iox_seg != m_iox_seglist.end() ; iox_seg++ )
279    {
280        std::cout << "    => segment " << iox_seg->name()
281                  << " / base = " << std::hex << iox_seg->baseAddress()
282                  << " / size = " << iox_seg->size() << std::endl; 
283    }
284
285    assert( (vci_param_int::N == vci_param_ext::N) and
286    "VCI_IO_BRIDGE ERROR: VCI ADDRESS widths must be equal on the 3 networks");
287
288    assert( (vci_param_int::N <=  64) and
289    "VCI_IO_BRIDGE ERROR: VCI ADDRESS width cannot be bigger than 64 bits");
290
291    assert( ((vci_param_int::B == 4) or (vci_param_int::B == 8)) and
292    "VCI_IO_BRIDGE ERROR: VCI DATA width must be 32 or 64 bits on internal network");   
293
294    assert( ((vci_param_ext::B == 4) or (vci_param_ext::B == 8)) and
295    "VCI_IO_BRIDGE ERROR: VCI DATA width must be 32 or 64 bits on external network");   
296
297    assert( (vci_param_int::S == vci_param_ext::S) and
298            "VCI_IO_BRIDGE ERROR: SRCID widths must be equal on the 3 networks");
299
300    // contruct 32 IRQ ports if required
301    if ( has_irqs )
302    {
303        for ( size_t n=0 ; n<32 ; n++ ) p_irq[n] = new sc_core::sc_in<bool>;
304    }
[240]305   
[434]306    // Cache line buffer
307    r_tlb_buf_data = new uint32_t[dcache_words];
308
[240]309    SC_METHOD(transition);
310    dont_initialize();
311    sensitive << p_clk.pos();
312 
313    SC_METHOD(genMoore);
314    dont_initialize();
315    sensitive << p_clk.neg();
316
317 }
318
319/////////////////////////////////////
320tmpl(/**/)::~VciIoBridge()
321/////////////////////////////////////
322{
[434]323    delete [] r_iommu_peri_wti;
324    delete [] r_tlb_buf_data;
325    soclib::common::dealloc_elems(p_irq, 32);
326    soclib::common::dealloc_elems(r_irq_request, 32);
327    soclib::common::dealloc_elems(r_irq_pending, 32);
[240]328}
329
330////////////////////////////////////
331tmpl(void)::print_trace(size_t mode)
332////////////////////////////////////
333{
334    // b0 : IOtlb trace
335
336    std::cout << std::dec << "IO_BRIDGE " << name() << std::endl;
337
[434]338    std::cout << "  "  << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()]
[240]339              << " | " << dma_rsp_fsm_state_str[r_dma_rsp_fsm.read()]
[434]340              << " | " << tlb_fsm_state_str[r_tlb_fsm.read()]
[240]341              << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()]
342              << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()]
[434]343              << " | " << miss_wti_fsm_state_str[r_miss_wti_cmd_fsm.read()]
344              << std::endl;
[240]345
346    if(mode & 0x01)
347    {
348        std::cout << "  IOTLB" << std::endl;
349        r_iotlb.printTrace();
350    }
351    if(mode & 0x02)
352    {
353       
354    }
355}
356
357////////////////////////
358tmpl(void)::print_stats()
359////////////////////////
360{
361    std::cout << name() << std::endl
362        << "- IOTLB MISS RATE      = " << (float)m_cpt_iotlb_miss/m_cpt_iotlb_read << std::endl
363        << "- IOTLB MISS COST         = " << (float)m_cost_iotlb_miss/m_cpt_iotlb_miss << std::endl
364        << "- IOTLB MISS TRANSACTION COST  = " << (float)m_cost_iotlbmiss_transaction/m_cpt_iotlbmiss_transaction << std::endl
365        << "- IOTLB MISS TRANSACTION RATE (OVER ALL MISSES)  = " << (float)m_cpt_iotlbmiss_transaction/m_cpt_iotlb_miss << std::endl;
366}
367
368////////////////////////
369tmpl(void)::clear_stats()
370////////////////////////
371{
372    m_cpt_iotlb_read                = 0;             
373    m_cpt_iotlb_miss                = 0;             
374    m_cost_iotlb_miss               = 0;
375    m_cpt_iotlbmiss_transaction     = 0;   
376    m_cost_iotlbmiss_transaction    = 0;   
377}
378
379/////////////////////////
380tmpl(void)::transition()
381/////////////////////////
382{
383    if ( not p_resetn.read() ) 
384    {
[434]385        r_dma_cmd_fsm      = DMA_CMD_IDLE;
386        r_dma_rsp_fsm      = DMA_RSP_IDLE;
387        r_tlb_fsm              = TLB_IDLE;
388        r_config_cmd_fsm   = CONFIG_CMD_IDLE;
389        r_config_rsp_fsm   = CONFIG_RSP_IDLE;
390        r_miss_wti_cmd_fsm = MISS_WTI_CMD_IDLE;
391        r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE;
[240]392
[434]393        r_alloc_fifo_config_rsp_local = true;
394        r_alloc_fifo_dma_rsp_local    = true;
[240]395
[434]396        r_tlb_buf_valid    = false; 
397                r_iommu_active     = false;
398                r_iommu_wti_enable = false;
[240]399       
400        // initializing FIFOs
401        m_dma_cmd_addr_fifo.init();
402        m_dma_cmd_srcid_fifo.init();
403        m_dma_cmd_trdid_fifo.init();
404        m_dma_cmd_pktid_fifo.init();
405        m_dma_cmd_be_fifo.init();
406        m_dma_cmd_cmd_fifo.init();
407        m_dma_cmd_contig_fifo.init();
408        m_dma_cmd_data_fifo.init();
409        m_dma_cmd_eop_fifo.init();
410        m_dma_cmd_cons_fifo.init();
411        m_dma_cmd_plen_fifo.init();
412        m_dma_cmd_wrap_fifo.init();
413        m_dma_cmd_cfixed_fifo.init();
414        m_dma_cmd_clen_fifo.init();
415       
416        m_dma_rsp_rsrcid_fifo.init();
417        m_dma_rsp_rtrdid_fifo.init();
418        m_dma_rsp_rpktid_fifo.init();
419        m_dma_rsp_data_fifo.init();
420        m_dma_rsp_rerror_fifo.init();
421        m_dma_rsp_reop_fifo.init();
422       
423        m_config_cmd_addr_fifo.init();
424        m_config_cmd_srcid_fifo.init();
425        m_config_cmd_trdid_fifo.init();
426        m_config_cmd_pktid_fifo.init();
427        m_config_cmd_be_fifo.init();
428        m_config_cmd_cmd_fifo.init();
429        m_config_cmd_contig_fifo.init();
430        m_config_cmd_data_fifo.init();
431        m_config_cmd_eop_fifo.init();
432        m_config_cmd_cons_fifo.init();
433        m_config_cmd_plen_fifo.init();
434        m_config_cmd_wrap_fifo.init();
435        m_config_cmd_cfixed_fifo.init();
436        m_config_cmd_clen_fifo.init();
437       
438        m_config_rsp_rsrcid_fifo.init();
439        m_config_rsp_rtrdid_fifo.init();
440        m_config_rsp_rpktid_fifo.init();
441        m_config_rsp_data_fifo.init();
442        m_config_rsp_rerror_fifo.init();
443        m_config_rsp_reop_fifo.init();
444       
[434]445        // SET/RESET Communication flip-flops
446        r_dma_tlb_req                   = false;
447        r_config_tlb_req                    = false;
448        r_tlb_miss_req              = false;
[240]449
[434]450        // Debug variable
451                m_debug_activated               = false;
[240]452       
[434]453        for ( size_t n=0 ; n<32 ; n++ )
454        {
455            r_irq_pending[n]        = false;
456            r_irq_request[n]        = false;
457        }
[240]458         
459            // activity counters
[434]460            m_cpt_total_cycles            = 0;
461        m_cpt_iotlb_read              = 0;             
462        m_cpt_iotlb_miss              = 0;             
463        m_cpt_iotlbmiss_transaction   = 0;   
464        m_cost_iotlbmiss_transaction  = 0;   
[240]465       
[434]466        m_cpt_trt_dma_full            = 0;
467        m_cpt_trt_dma_full_cost       = 0;
468        m_cpt_trt_config_full         = 0;
469        m_cpt_trt_config_full_cost    = 0;
[240]470
471        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_cmd            [i]   = 0;
472        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_rsp            [i]   = 0;
[434]473        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_tlb                [i]   = 0;
[240]474        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_cmd         [i]   = 0;
475        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_rsp         [i]   = 0;
[434]476        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_cmd       [i]   = 0;
477        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_rsp       [i]   = 0;
478
[240]479        return;
480    }
481
[434]482    // default values for FIFOs
483    bool        dma_cmd_fifo_put      = false;
484    bool        dma_cmd_fifo_get      = false;
485
486    bool        dma_rsp_fifo_put      = false; 
487    bool        dma_rsp_fifo_get      = false; 
[240]488   
[434]489    bool        config_cmd_fifo_put   = false;
490    bool        config_cmd_fifo_get   = false;
[240]491
[434]492    bool        config_rsp_fifo_put   = false;
493    bool        config_rsp_fifo_get   = false;
494
[240]495#ifdef INSTRUMENTATION
496    m_cpt_fsm_dma_cmd           [r_dma_cmd_fsm.read()] ++;
497    m_cpt_fsm_dma_rsp           [r_dma_rsp_fsm.read() ] ++;
[434]498    m_cpt_fsm_tlb                   [r_tlb_fsm.read() ] ++;
[240]499    m_cpt_fsm_config_cmd            [r_config_cmd_fsm.read() ] ++;
500    m_cpt_fsm_config_rsp            [r_config_rsp_fsm.read() ] ++;
[434]501    m_cpt_fsm_miss_wti_cmd      [r_miss_wti_cmd_fsm.read() ] ++;
502    m_cpt_fsm_miss_wti_rsp      [r_miss_wti_rsp_fsm.read() ] ++;
[240]503#endif
504
505    m_cpt_total_cycles++;
506
[434]507    m_debug_activated  = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
[240]508
[434]509    //////////////////////////////////////////////////////////////////////////////
510    // The DMA_CMD_FSM handles DMA transactions requested by peripherals
511    // It makes the address translation if IOMMU is activated.
[240]512    ///////////////////////////////////////////////////////////////////////////////
513
514    switch( r_dma_cmd_fsm.read() ) 
515    {
[434]516    //////////////////
517    case DMA_CMD_IDLE:  // waiting DMA VCI transaction
[240]518    {
[434]519        if ( p_vci_tgt_iox.cmdval.read() ) // compute physical address
[240]520        { 
[434]521            if ( not r_iommu_active.read() )    // tlb not activated
[240]522            {
[434]523#if DEBUG_DMA_CMD
524if( m_debug_activated )
525std::cout << "  <IOB DMA_CMD_IDLE> IOMMU not activated" << std::endl;
526#endif
527                // put DMA transaction into DMA_CMD fifo
528                r_dma_cmd_paddr = p_vci_tgt_iox.address.read();
529                r_dma_cmd_fsm   = DMA_CMD_FIFO_PUT_CMD;
[240]530            }
[434]531            else if (r_tlb_fsm.read() == TLB_IDLE ||
532                     r_tlb_fsm.read() == TLB_WAIT )       // tlb access possible
[240]533            {
[434]534                vci_addr_t      iotlb_paddr;
[240]535                pte_info_t  iotlb_flags; 
536                size_t      iotlb_way; 
537                size_t      iotlb_set;
[434]538                vci_addr_t  iotlb_nline;
539                bool            iotlb_hit; 
[240]540
541#ifdef INSTRUMENTATION
542m_cpt_iotlb_read++;
543#endif
[434]544                iotlb_hit = r_iotlb.translate(p_vci_tgt_iox.address.read(),
545                                              &iotlb_paddr,
546                                              &iotlb_flags,
547                                              &iotlb_nline,  // unused
548                                              &iotlb_way,        // unused
549                                              &iotlb_set );  // unused
[240]550           
[434]551                if ( iotlb_hit )                                     // tlb hit
[240]552                { 
[434]553                    if ( not iotlb_flags.w and    // access right violation
554                        (p_vci_tgt_iox.cmd.read() == vci_param_ext::CMD_WRITE) ) 
[240]555                    {
[434]556                        // put DMA response error into DMA_RSP fifo
557                        r_iommu_etr      = MMU_WRITE_ACCES_VIOLATION; 
558                        r_iommu_bvar     = p_vci_tgt_iox.address.read();
559                        r_iommu_bad_id   = p_vci_tgt_iox.srcid.read();
560                        r_dma_cmd_fsm    = DMA_CMD_FIFO_PUT_RSP;
[240]561#if DEBUG_DMA_CMD
[434]562if( m_debug_activated )
563std::cout << "  <IOB DMA_CMD_IDLE> TLB HIT but writable violation" << std::endl;
[240]564#endif
565                    }
[434]566                    else                         // no access rights violation
567                    {
568#if DEBUG_DMA_CMD
569if( m_debug_activated )
570std::cout << "  <IOB DMA_CMD_IDLE> TLB HIT" << std::endl;
571#endif
572                    // put DMA transaction into DMA_CMD fifo
573                    r_dma_cmd_paddr   = iotlb_paddr;                   
574                    r_dma_cmd_fsm     = DMA_CMD_FIFO_PUT_CMD;
575                    }
[240]576                }
[434]577                else                                             // TLB miss
[240]578                {
579
580#ifdef INSTRUMENTATION
581m_cpt_iotlb_miss++;
582#endif
[434]583                        // register virtual address, and send request to TLB FSM
584                                r_dma_cmd_vaddr = p_vci_tgt_iox.address.read();
[240]585                        r_dma_tlb_req   = true;
[434]586                        r_dma_cmd_fsm   = DMA_CMD_MISS_WAIT;
[240]587#if DEBUG_DMA_CMD
[434]588if( m_debug_activated )
589std::cout << "  <IOB DMA_CMD_IDLE> TLB MISS" << std::endl;
[240]590#endif
591                } // end !hit
592            } // end if tlb_activated
593        } // end if cmdval
594        break;
595    }
[434]596    //////////////////////////
597    case DMA_CMD_FIFO_PUT_CMD:    // put a DMA transaction in DMA_CMD fifo       
598                                  // if contig, VCI address must be incremented
[240]599    {
[434]600        if ( p_vci_tgt_iox.cmdval && m_dma_cmd_addr_fifo.wok() ) 
[240]601        {
[434]602            dma_cmd_fifo_put = true;
603           
604            if ( p_vci_tgt_iox.contig.read() ) r_dma_cmd_paddr = r_dma_cmd_paddr.read() + 
605                                                          vci_param_ext::B;
[240]606
[434]607            if ( p_vci_tgt_iox.eop.read() )    r_dma_cmd_fsm   = DMA_CMD_IDLE;
608           
[240]609#if DEBUG_DMA_CMD
[434]610if( m_debug_activated ) 
611std::cout << "  <IOB DMA_CMD_FIFO_PUT_CMD> Push into DMA_CMD fifo:" 
612          << " address = " << std::hex << r_dma_cmd_paddr.read()
613          << " srcid = " << p_vci_tgt_iox.srcid.read()
614          << " trdid = " << p_vci_tgt_iox.trdid.read()
615          << " wdata = " << p_vci_tgt_iox.wdata.read()
616          << " be = " << p_vci_tgt_iox.be.read()
617          << " contig = " << p_vci_tgt_iox.contig.read()
618          << " eop = " << std::dec << p_vci_tgt_iox.eop.read() 
619          << " plen = " << std::dec << p_vci_tgt_iox.plen.read() << std::endl;
[240]620#endif
621        }
622        break;
623    }
[434]624    //////////////////////
625    case DMA_CMD_WAIT_EOP:       // An error has been detected on the VCI DMA command
626                             // consume the VCI packet before sending the error response
[240]627    {
[434]628        if ( p_vci_tgt_iox.eop.read() )    r_dma_cmd_fsm   = DMA_CMD_FIFO_PUT_RSP;
[240]629        break;
630    }
[434]631    //////////////////////////
632    case DMA_CMD_FIFO_PUT_RSP:   // try to put a response error in DMA_RSP fifo
633                                 // The FIFO is shared with DMA_RSP FSM
634                                 // and we must we wait for allocation...
[240]635    {
[434]636        if ( r_alloc_fifo_dma_rsp_local.read() ) 
[240]637        {
[434]638            dma_rsp_fifo_put = true;
639
640            if( m_dma_rsp_data_fifo.wok() )
[240]641            {
642
643#if DEBUG_DMA_CMD
[434]644if( m_debug_activated ) 
645std::cout << "  <IOB DMA_CMD_FIFO_PUT_RSP> Put a response error to a DMA transaction." 
646          << std::endl;
[240]647#endif
[434]648                r_dma_cmd_fsm = DMA_CMD_IDLE;
649            }
[240]650        }
651        break;
652    }
[434]653    ///////////////////////
654    case DMA_CMD_MISS_WAIT:  // waiting completion of a TLB miss
655                             // we must test a possible page fault error...   
[240]656    {
[434]657        if ( not r_dma_tlb_req.read() ) // TLB miss completed
[240]658        {
[434]659            if ( r_tlb_miss_error.read() )   // Error reported by TLB FSM
[240]660            {
[434]661                r_iommu_etr     = MMU_READ_PT2_UNMAPPED; 
662                r_iommu_bvar    = r_dma_cmd_vaddr.read();
663                r_iommu_bad_id  = p_vci_tgt_iox.srcid.read();
664                r_dma_cmd_fsm   = DMA_CMD_FIFO_PUT_RSP;
[240]665            }
[434]666            else                            // No error
667            {
668                r_dma_cmd_fsm   = DMA_CMD_IDLE;
669            }
[240]670        }
671        break;
672    }
[434]673    } // end switch DMA_CMD FSM
[240]674
675    //////////////////////////////////////////////////////////////////////////////
[434]676    // The DMA_RSP_FSM handles the RAM responses to peripherals DMA transactions.
677    //////////////////////////////////////////////////////////////////////////////
678
[240]679    switch( r_dma_rsp_fsm.read() ) 
680    {
[434]681    //////////////////
682    case DMA_RSP_IDLE:  // waiting a response from RAM betwork
[240]683    {           
[434]684        if ( p_vci_ini_ram.rspval.read() ) 
[240]685                {
[434]686                        r_dma_rsp_fsm = DMA_RSP_FIFO_PUT;
[240]687                }
688                break;
689    }
[434]690    //////////////////////
[240]691    case DMA_RSP_FIFO_PUT:
692    {
[434]693        if(p_vci_ini_ram.rspval.read() and not r_alloc_fifo_dma_rsp_local.read() )
[240]694        {
695            dma_rsp_fifo_put = true;
696
[434]697            if(p_vci_ini_ram.reop.read())   r_dma_rsp_fsm = DMA_RSP_IDLE;       
[240]698
699#if DEBUG_DMA_RSP
[434]700if( m_debug_activated ) 
701std::cout << "  <IOB DMA_RSP_FIFO_PUT> Push response into DMA_RSP fifo:" 
702          << " / rsrcid = " << std::hex << p_vci_ini_ram.rsrcid.read()
703          << " / rtrdid = " << p_vci_ini_ram.rtrdid.read()
704          << " / rdata = " << std::hex << p_vci_ini_ram.rdata.read()
705          << " / rerror = " << p_vci_ini_ram.rerror.read()
706          << " / reop = " << p_vci_ini_ram.reop.read() << std::endl;
[240]707#endif
708        }
709        break;
710    }
711    } // end switch DMA_RSP_FSM
712
[434]713    //////////////////////////////////////////////////////////////////////////////////
714    // The TLB FSM handles TLB miss request (from DMA_CMD FSM),
715    // and the PTE inval request (from CONFIG_CMD FSM).
716    // PTE inval request have highest priority. In case of TLB miss,
717    // this fsm searchs the requested PTE on the prefetch buffer.
718    // In case of buffer miss,  it request the MISS_WTI FSM to access the memory.
[240]719    // It bypass the first level page table access if possible.
[434]720    // It reset the r_dma_tlb_req flip-flop to signal TLB miss completion.
721    // An unexpected, but possible page fault is signaled in r_tlb_miss_error flip_flop.
[240]722    ////////////////////////////////////////////////////////////////////////////////////
[434]723
724    switch (r_tlb_fsm.read())
[240]725    {
[434]726    //////////////
727    case TLB_IDLE:   // In case of TLB miss request, chek the prefetch buffer first
728                     // PTE inval request are handled as unmaskable interrupts
[240]729    {
[434]730        if ( r_config_tlb_req ) // Request from CONFIG FSM for a PTE invalidation
[240]731        {
[434]732            r_config_tlb_req      = false;
[240]733            r_waiting_transaction = false;
[434]734            r_tlb_fsm = TLB_INVAL_CHECK;
[240]735        }
[434]736
737        else if ( r_dma_tlb_req.read() )   // request from DMA_CMD for a TLB Miss
[240]738        {
[434]739            // Checking prefetch buffer
740            if( not r_tlb_buf_big_page )     // small page => PTE2
[240]741            {
[434]742                if( r_tlb_buf_valid &&         // Hit on prefetch buffer
743                    (r_tlb_buf_vaddr.read() == 
744                    (r_dma_cmd_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK)))
745                {
746                    size_t   pte_offset = (r_dma_cmd_vaddr.read()& PTE2_LINE_OFFSET)>>12; 
747                    uint32_t pte_flags  = r_tlb_buf_data[2*pte_offset];
748                    uint32_t pte_ppn    = r_tlb_buf_data[2*pte_offset+1]; 
[240]749               
[434]750                    // Bit valid checking
751                    if ( not ( pte_flags & PTE_V_MASK) )        // unmapped
752                    {
753                        std::cout << "VCI_IO_BRIDGE ERROR : " << name() 
754                                  << " Page Table entry unmapped" << std::endl;
[240]755                       
[434]756                        r_tlb_miss_error = true;
757                        r_dma_tlb_req    = false;
758#if DEBUG_TLB_MISS
759if ( m_debug_activated )
760std::cout << "  <IOB TLB_IDLE> PTE2 Unmapped" << std::hex
761          << " / paddr = " << r_tlb_paddr.read()
762          << " / PTE_FLAGS = " << pte_flags
763          << " / PTE_PPN = " << pte_ppn << std::endl;
[240]764#endif
[434]765                        break; 
766                    }
[240]767
[434]768                    // valid PTE2 : we must update the TLB
769                    r_tlb_pte_flags = pte_flags; 
770                    r_tlb_pte_ppn   = pte_ppn;
771                    r_tlb_fsm       = TLB_PTE2_SELECT;
772#if DEBUG_TLB_MISS
773if ( m_debug_activated )
774std::cout << "  <IOB TLB_IDLE> Hit on prefetch buffer: PTE2" << std::hex
775          << " / PTE_FLAGS = " << pte_flags
776          << " / PTE_PPN = " << pte_ppn << std::endl;
[240]777#endif
[434]778                    break;   
779                }
[240]780            }
[434]781            else                             // big page => PTE1
[240]782            {
[434]783                if( r_tlb_buf_valid &&         // Hit on prefetch buffer
784                    (r_tlb_buf_vaddr.read() == 
785                    (r_dma_cmd_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 
786                {
787                    size_t   pte_offset = (r_dma_cmd_vaddr.read()& PTE1_LINE_OFFSET)>>21; 
788                    uint32_t pte_flags  = r_tlb_buf_data[pte_offset];
[240]789                           
[434]790                    // Bit valid checking
791                    if ( not ( pte_flags & PTE_V_MASK) )        // unmapped
792                    {
793                        std::cout << "VCI_IO_BRIDGE ERROR : " << name() 
794                                  << " Page Table entry unmapped" << std::endl;
[240]795                       
[434]796                        r_tlb_miss_error = true;
797                        r_dma_tlb_req    = false;
798#if DEBUG_TLB_MISS
799if ( m_debug_activated )
800std::cout << "  <IOB TLB_IDLE> PTE1 Unmapped" << std::hex
801          << " / paddr = " << r_tlb_paddr.read()
802          << " / PTE = " << pte_flags << std::endl;
[240]803#endif
[434]804                        break; 
805                    }
[240]806
[434]807                    // valid PTE1 : we must update the TLB
808                    r_tlb_pte_flags = pte_flags;
809                    r_tlb_fsm       = TLB_PTE1_SELECT;
810#if DEBUG_TLB_MISS
811if ( m_debug_activated )
812std::cout << "  <IOB TLB_PTE1_GET> Hit on prefetch buffer: PTE1" << std::hex
813          << " / paddr = " << r_tlb_paddr.read()
814          << std::hex << " / PTE1 = " << pte_flags << std::endl;
[240]815#endif
[434]816                    break;
[240]817                }
818            }
819       
[434]820            // prefetch buffer miss
821            r_tlb_fsm = TLB_MISS; 
[240]822
[434]823#if DEBUG_TLB_MISS
824if ( m_debug_activated )
825std::cout << "  <IOB TLB_IDLE> Miss on prefetch buffer"
826          << std::hex << " / vaddr = " << r_dma_cmd_vaddr.read() << std::endl;
[240]827#endif
828        }
829        break;
830    }
[434]831    //////////////
832    case TLB_MISS: // handling tlb miss
[240]833    {
[434]834        uint32_t        ptba = 0; 
[240]835        bool            bypass;
[434]836        vci_addr_t      pte_paddr;
[240]837
[434]838#ifdef INSTRUMENTATION
839m_cpt_iotlbmiss_transaction++;
840#endif
[240]841        // evaluate bypass in order to skip first level page table access
[434]842        bypass = r_iotlb.get_bypass(r_dma_cmd_vaddr.read(), &ptba);
[240]843       
[434]844        // Request MISS_WTI_FSM a transaction on INT Network
[240]845        if ( not bypass )     // Read PTE1/PTD1 in XRAM
846        {
[434]847
848#if DEBUG_TLB_MISS
849if ( m_debug_activated )
850std::cout << "  <IOB TLB_MISS> Read PTE1/PTD1 in memory" << std::endl;
851#endif
852            pte_paddr = (vci_addr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) |
853                        (vci_addr_t)((r_dma_cmd_vaddr.read() >> PAGE_M_NBITS) << 2);
854            r_tlb_paddr = pte_paddr;
[240]855           
[434]856            r_tlb_miss_req     = true;
857            r_tlb_miss_type    = PTE1_MISS;
858            r_tlb_fsm          = TLB_WAIT;
[240]859        }
860        else                  // Read PTE2 in XRAM
861        {
[434]862
863#if DEBUG_TLB_MISS
864if ( m_debug_activated )
865std::cout << "  <IOB TLB_MISS> Read PTE2 in memory" << std::endl;
866#endif
[240]867            //&PTE2 = PTBA + IX2 * 8
[434]868            pte_paddr = (vci_addr_t)ptba << PAGE_K_NBITS |
869                        (vci_addr_t)(r_dma_cmd_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
[240]870           
[434]871            r_tlb_paddr = pte_paddr;
[240]872           
[434]873            r_tlb_miss_req     = true;
874            r_tlb_miss_type    = PTE2_MISS;
875            r_tlb_fsm          = TLB_WAIT;
[240]876        }
877
878        break;
879    }
[434]880    ////////////////// 
881    case TLB_PTE1_GET:  // Try to read a PT1 entry in the miss buffer
[240]882    {
883       
884        uint32_t  entry;
885       
[434]886        vci_addr_t line_number  = (vci_addr_t)((r_tlb_paddr.read())&(CACHE_LINE_MASK));
887        size_t word_position = (size_t)( ((r_tlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
[240]888
889        // Hit test. Just to verify.
890        // Hit must happen, since we've just finished its' miss transaction
[434]891        bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 
[240]892        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
893       
[434]894        entry = r_tlb_buf_data[word_position];
[240]895           
896        // Bit valid checking
897        if ( not ( entry & PTE_V_MASK) )        // unmapped
898        {
899            //must not occur!
[434]900            std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl
[240]901                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
902                       
[434]903            r_tlb_miss_error       = true;
904            r_dma_tlb_req         = false;
905            r_tlb_fsm             = TLB_IDLE;           
906
907#if DEBUG_TLB_MISS
908if ( m_debug_activated )
[240]909{
[434]910    std::cout << "  <IOB DMA_PTE1_GET> First level entry Unmapped"
911              << std::hex << " / paddr = " << r_tlb_paddr.read()
[240]912              << std::hex << " / PTE = " << entry << std::endl;
913}
914#endif
915                    break; 
916        }
917   
918        if( entry & PTE_T_MASK )        //  PTD : me must access PT2
919        {
920            // register bypass
[434]921            r_iotlb.set_bypass( r_dma_cmd_vaddr.read(),
922                                entry & ((1 << (vci_param_int::N-PAGE_K_NBITS)) - 1), 
[240]923                                0); //nline, unused
924
925            //&PTE2 = PTBA + IX2 * 8
926            // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
[434]927            r_tlb_paddr = (vci_addr_t)(entry & ((1<<(vci_param_int::N-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
928                                (vci_addr_t)(((r_dma_cmd_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
929            r_tlb_miss_req     = true;
930            r_tlb_miss_type    = PTE2_MISS;
931            r_tlb_fsm          = TLB_WAIT;
932
[240]933#ifdef INSTRUMENTATION
934m_cpt_iotlbmiss_transaction++;
935#endif
936
[434]937#if DEBUG_TLB_MISS
938if ( m_debug_activated )
939std::cout << "  <IOB TLB_PTE1_GET> Success. Search PTE2" << std::hex
940          << " / PADDR = " << r_tlb_paddr.read()
941          << " / PTD = " << entry << std::endl;
[240]942#endif
943        }
944        else                    //  PTE1 :  we must update the IOTLB
945                        //  Should not occur if working only with small pages
946        {
[434]947            r_tlb_pte_flags   = entry;
948            r_tlb_fsm  = TLB_PTE1_SELECT;
[240]949
[434]950#if DEBUG_TLB_MISS
951if ( m_debug_activated )
952std::cout << "  <IOB TLB_PTE1_GET> Success. Big page"
953          << std::hex << " / paddr = " << r_tlb_paddr.read()
954          << std::hex << " / PTE1 = " << entry << std::endl;
[240]955#endif
956        }
957        break;
958    }
[434]959    /////////////////////
960    case TLB_PTE1_SELECT:       // select a slot for PTE1
[240]961    {
962        size_t  way;
963        size_t  set;
964       
[434]965        r_iotlb.select(  r_dma_cmd_vaddr.read(),
[240]966                        true,  // PTE1
967                        &way,
968                        &set );
969#ifdef INSTRUMENTATION
970m_cpt_iotlb_read++;
971#endif
972
[434]973#if DEBUG_TLB_MISS
974if ( m_debug_activated )
975std::cout << "  <IOB TLB_PTE1_SELECT> Select a slot in TLB"
976          << " / way = " << std::dec << way
977          << " / set = " << set << std::endl;
[240]978#endif
[434]979        r_tlb_way = way;
980        r_tlb_set = set;
981        r_tlb_fsm     = TLB_PTE1_UPDT;
[240]982        break;
983    }
[434]984    ///////////////////
985    case TLB_PTE1_UPDT:     // write a new PTE1 in tlb
986                            // not necessary to treat the L/R bit
[240]987    {
[434]988        uint32_t  pte   = r_tlb_pte_flags.read();
[240]989       
[434]990        r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_flags.read() & PPN1_MASK) << 21)
991                        | (r_dma_cmd_vaddr.read()& M_PAGE_OFFSET_MASK) );
[240]992       
993        // update TLB
994        r_iotlb.write( true,            // 2M page
995                      pte,
996                      0,                // argument unused for a PTE1
[434]997                      r_dma_cmd_vaddr.read(),   
998                      r_tlb_way.read(), 
999                      r_tlb_set.read(),
[240]1000                      0 );      //we set nline = 0
1001#ifdef INSTRUMENTATION
1002m_cpt_iotlb_write++;
1003#endif
1004
[434]1005#if DEBUG_TLB_MISS
1006if ( m_debug_activated )
[240]1007{
[434]1008std::cout << "  <IOB TLB_PTE1_UPDT> write PTE1 in TLB"
1009          << " / set = " << std::dec << r_tlb_set.read()
1010          << " / way = " << r_tlb_way.read() << std::endl;
1011r_iotlb.printTrace();
[240]1012}
1013#endif
1014        // next state
[434]1015        r_tlb_fsm = TLB_RETURN; // exit sub-fsm
[240]1016        break;
1017    }
[434]1018    //////////////////
1019    case TLB_PTE2_GET:  // Try to read a PTE2 (64 bits) in the miss buffer
[240]1020    {   
1021        uint32_t        pte_flags;
1022        uint32_t        pte_ppn;
1023       
[434]1024        vci_addr_t line_number  = (vci_addr_t)((r_tlb_paddr.read())&(CACHE_LINE_MASK));
1025        size_t word_position = (size_t)( ((r_tlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
[240]1026       
1027       
1028        // Hit test. Just to verify.
[434]1029        bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 
[240]1030        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
[434]1031        pte_flags= r_tlb_buf_data[word_position];
1032        pte_ppn= r_tlb_buf_data[word_position+1]; //because PTE2 is 2 words long
[240]1033        // Bit valid checking
1034        if ( not ( pte_flags & PTE_V_MASK) )    // unmapped
1035        {
1036            //must not occur!
[434]1037            std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl
[240]1038                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1039                       
[434]1040            r_tlb_miss_error       = true;
1041            r_dma_tlb_req         = false;
1042            r_tlb_fsm             = TLB_IDLE;           
1043
1044#if DEBUG_TLB_MISS
1045if ( m_debug_activated )
1046std::cout << "  <IOB TLB_PTE2_GET> PTE2 Unmapped" << std::hex
1047          << " / PADDR = " << r_tlb_paddr.read()
1048          << " / PTE = " << pte_flags << std::endl;
[240]1049#endif
[434]1050            break; 
[240]1051        }
1052           
[434]1053        r_tlb_pte_flags       = pte_flags; 
1054        r_tlb_pte_ppn         = pte_ppn;
1055        r_tlb_fsm           = TLB_PTE2_SELECT;
[240]1056               
[434]1057#if DEBUG_TLB_MISS
1058if ( m_debug_activated )
1059std::cout << "  <IOB TLB_PTE2_GET> Mapped" << std::hex
1060          << " / PTE_FLAGS = " << pte_flags
1061          << " / PTE_PPN = " << pte_ppn << std::endl;
[240]1062#endif
1063        break;
1064    }
1065    ////////////////////////////
[434]1066    case TLB_PTE2_SELECT:    // select a slot for PTE2
[240]1067    {
1068        size_t way;
1069        size_t set;
1070
[434]1071        r_iotlb.select( r_dma_cmd_vaddr.read(),
[240]1072                        false,  // PTE2
1073                        &way,
1074                        &set );
1075#ifdef INSTRUMENTATION
1076m_cpt_iotlb_read++;
1077#endif
1078
[434]1079#if DEBUG_TLB_MISS
1080if ( m_debug_activated )
[240]1081{
[434]1082        std::cout << "  <IOB TLB_PTE2_SELECT> Select a slot in IOTLB:";
[240]1083        std::cout << " way = " << std::dec << way
1084                  << " / set = " << set << std::endl;
1085}
1086#endif
[434]1087        r_tlb_way = way;
1088        r_tlb_set = set;
1089        r_tlb_fsm     = TLB_PTE2_UPDT;
[240]1090        break;
1091    }
[434]1092    ///////////////////
1093    case TLB_PTE2_UPDT:         // write a new PTE2 in tlb
1094                                // not necessary to treat the L/R bit
[240]1095    {
[434]1096        uint32_t        pte_flags = r_tlb_pte_flags.read();
1097        uint32_t        pte_ppn   = r_tlb_pte_ppn.read();
[240]1098       
[434]1099        r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_ppn.read() & PPN2_MASK) << 12)
1100                        | (r_dma_cmd_vaddr.read()& K_PAGE_OFFSET_MASK) );
[240]1101       
1102        // update TLB for a PTE2
1103        r_iotlb.write( false,   // 4K page
1104                       pte_flags,
1105                       pte_ppn,
[434]1106                       r_dma_cmd_vaddr.read(),   
1107                       r_tlb_way.read(), 
1108                       r_tlb_set.read(),
[240]1109                       0 );     // nline = 0
1110#ifdef INSTRUMENTATION
1111m_cpt_iotlb_write++;
1112#endif
1113
[434]1114#if DEBUG_TLB_MISS
1115if ( m_debug_activated )
[240]1116{
[434]1117        std::cout << "  <IOB TLB_PTE2_UPDT> write PTE2 in IOTLB";
1118        std::cout << " / set = " << std::dec << r_tlb_set.read()
1119                  << " / way = " << r_tlb_way.read() << std::endl;
[240]1120        r_iotlb.printTrace();
1121}
1122#endif
1123        // next state
[434]1124        r_tlb_fsm = TLB_RETURN; 
[240]1125        break;
1126    }
[434]1127    //////////////
1128    case TLB_WAIT:   // waiting completion of a miss transaction from MISS_WTI FSM
1129                     // PTE inval request are handled as unmaskable interrupts
[240]1130    {
[434]1131        if ( r_config_tlb_req ) // Request from CONFIG FSM for a PTE invalidation
[240]1132        {
1133            r_config_tlb_req = false;
1134            r_waiting_transaction = true;
[434]1135            r_tlb_fsm = TLB_INVAL_CHECK;
[240]1136        }
1137
1138#ifdef INSTRUMENTATION
1139m_cost_iotlbmiss_transaction++;
1140#endif
[434]1141        if ( not r_tlb_miss_req )       //  Miss transaction is done
[240]1142        { 
[434]1143                if ( r_miss_wti_rsp_error.read() ) // bus error
[240]1144                {
[434]1145                r_miss_wti_rsp_error = false;
1146                r_tlb_miss_error     = true;
1147                r_dma_tlb_req        = false;
1148                r_tlb_fsm            = TLB_IDLE;
[240]1149            }
1150            else if(r_tlb_miss_type == PTE1_MISS)
1151            {
[434]1152                r_tlb_fsm = TLB_PTE1_GET; 
[240]1153            }
1154            else
1155            {
[434]1156                r_tlb_fsm = TLB_PTE2_GET;
[240]1157            }
1158        }
1159        break;
1160    }
[434]1161    ////////////////
1162    case TLB_RETURN:            // reset r_dma_tlb_req flip-flop to signal TLB miss completion
1163                            // possible errors are signaled through r_tlb_miss_error
[240]1164    {
[434]1165#if DEBUG_TLB_MISS
1166if ( m_debug_activated )
1167std::cout << "  <IOB TLB_RETURN> IOTLB MISS completed" << std::endl;
[240]1168#endif
[434]1169        r_dma_tlb_req  = false;
1170        r_tlb_fsm = TLB_IDLE;
[240]1171        break;
1172    }
[434]1173    /////////////////////
1174    case TLB_INVAL_CHECK:   // request from CONFIG_FSM to invalidate all PTE in a given line
1175                            // checks the necessity to invalidate prefetch buffer
[240]1176    {
1177        // If a transaction is pending, no need to invalidate the prefetch
1178        // We can ignore it, since we'll replace the line.
1179        // The new line is necessarily up-to-date
[434]1180        if(!r_waiting_transaction.read() && r_tlb_buf_valid)
[240]1181        {
[434]1182            if(!r_tlb_buf_big_page)
[240]1183            {
[434]1184               if( r_tlb_buf_vaddr.read() == 
1185                   (r_config_cmd_inval_vaddr.read()& ~PTE2_LINE_OFFSET) ) 
[240]1186                // The virtual address corresponds to one entry on the buffer line
1187                {
[434]1188                    r_tlb_buf_valid = false;   //change here for individual invalidation
[240]1189                }
1190            }
1191            else    // First level entries on buffer. Unused if only small pages
1192            {
[434]1193               if( r_tlb_buf_vaddr.read() == 
1194                   (r_config_cmd_inval_vaddr.read()& ~PTE1_LINE_OFFSET) ) 
[240]1195                // The virtual address corresponds to one entry on the buffer line
1196                {
[434]1197                    r_tlb_buf_valid = false;   //change here for individual invalidation
[240]1198                }
1199            }
1200        }
1201       
1202        // Invalidation on IOTLB
1203        bool    ok;
[434]1204        ok = r_iotlb.inval(r_config_cmd_inval_vaddr.read());
[240]1205         
[434]1206        if(r_waiting_transaction.read()) r_tlb_fsm =TLB_WAIT; 
1207        else r_tlb_fsm = TLB_IDLE;
[240]1208        break; 
1209    }
[434]1210    } //end switch r_tlb_fsm
[240]1211   
[434]1212    ////////////////////////////////////////////////////////////////////////////////
1213    // The CONFIG_CMD_FSM handles the VCI commands from the INT network.
1214    // This FSM is mainly intended to handle single flit config transactions,
1215    // but it can also handle software driven, multi-flits data transactions.
[451]1216    // The configuration requests can be local (IO_BRIDGE config registers)
1217    // or remote (config registers of peripherals on IOX network).
1218    // - The local configuration segment is identified by the "special" atribute.
1219    // - All configuration requests are checkeg against segmentation violation.
1220    // - In case of local config request, or in case of segmentation violation,
1221    //   the FSM put a VCI response request in CONFIG_RSP fifo.
1222    // - In case of remote transaction, it put the VCI command in CONFIG_CMD fifo.
[434]1223    ///////////////////////////////////////////////////////////////////////////////
[240]1224
1225    switch( r_config_cmd_fsm.read() ) 
1226    {
[434]1227    /////////////////////
1228    case CONFIG_CMD_IDLE:   // waiting VCI command
[240]1229    {
[434]1230        if ( p_vci_tgt_int.cmdval.read() ) 
[240]1231        {
[434]1232
[240]1233#if DEBUG_CONFIG_CMD
[434]1234if( m_debug_activated )
1235std::cout << "  <IOB CONFIG_CMD_IDLE> Command received" 
1236          << " / address = " << std::hex << p_vci_tgt_int.address.read()
1237          << " / srcid = " << std::dec << p_vci_tgt_int.srcid.read()
1238          << " / trdid = " << p_vci_tgt_int.trdid.read()
1239          << " / wdata = " << std::hex << p_vci_tgt_int.wdata.read()
1240          << " / be = " << p_vci_tgt_int.be.read()
1241          << " / plen = " << std::dec << p_vci_tgt_int.plen.read()
1242          << " / eop = " << p_vci_tgt_int.eop.read() << std::endl;
[240]1243#endif
[434]1244            vci_addr_t paddr = p_vci_tgt_int.address.read();
1245            bool       read  = (p_vci_tgt_int.cmd.read() == vci_param_int::CMD_READ);
1246            uint32_t   cell  = (uint32_t)((paddr & 0x1FF)>>2); 
[240]1247 
[451]1248            // chek segments
1249            std::list<soclib::common::Segment>::iterator seg;
1250            bool found = false;
1251            for ( seg = m_int_seglist.begin() ; 
1252                  seg != m_int_seglist.end() and not found ; seg++ )
1253            {
1254                if ( seg->contains(paddr) )  found = true;
1255            }
[434]1256           
[451]1257            if ( found and seg->special() )  // IO_BRIDGE itself
[240]1258            {
[434]1259                uint32_t      rdata  = 0;
1260                bool          rerror = false;
1261
1262                if ( not read && (cell == IOB_IOMMU_PTPR) )       // WRITE PTPR
[240]1263                {
[434]1264                    r_iommu_ptpr = (uint32_t)p_vci_tgt_int.wdata.read();
1265                }
1266                else if ( read && (cell == IOB_IOMMU_PTPR) )      // READ PTPR
[240]1267                {
[434]1268                    rdata = r_iommu_ptpr.read();
[240]1269                }
[434]1270                else if( not read && (cell == IOB_WTI_ENABLE))  // WRITE WTI_ENABLE
[240]1271                {
[434]1272                    r_iommu_wti_enable = p_vci_tgt_int.wdata.read();
[240]1273                }
[434]1274                else if( read && (cell == IOB_WTI_ENABLE))       // READ WTI ENABLE
[240]1275                {
[434]1276                    rdata = r_iommu_wti_enable.read();
[240]1277                }
[434]1278                else if( read && (cell == IOB_IOMMU_BVAR))        // READ BVAR
[240]1279                {
[434]1280                    rdata = r_iommu_bvar.read();
[240]1281                }
[434]1282                else if( read && (cell == IOB_IOMMU_ETR))          // READ ETR
[240]1283                {
[434]1284                    rdata = r_iommu_etr.read();
[240]1285                }
[434]1286                else if( read && (cell == IOB_IOMMU_BAD_ID))      // READ BAD_ID
[240]1287                {
[434]1288                    rdata = r_iommu_bad_id.read();
[240]1289                }
[434]1290                else if( not read && (cell == IOB_INVAL_PTE))     // WRITE INVAL_PTE
[240]1291                {
[434]1292                    r_config_tlb_req         = true;
1293                    r_config_cmd_inval_vaddr = (uint32_t)p_vci_tgt_int.wdata.read();
[240]1294                }
[434]1295                else if( not read && (cell == IOB_WTI_ADDR_LO)) // WRITE WTI_PADDR_LO
[240]1296                {
[434]1297                    r_iommu_wti_paddr = (vci_addr_t)p_vci_tgt_int.wdata.read();
[240]1298                }
[434]1299                else if( read && (cell == IOB_WTI_ADDR_LO))    // READ WTI_PADDR_LO
[240]1300                {
[434]1301                    rdata = (uint32_t)r_iommu_wti_paddr.read();
[240]1302                }
[434]1303                else if( not read && (cell == IOB_WTI_ADDR_HI)) // WRITE WTI_PADDR_HI
[240]1304                {
[434]1305                    r_iommu_wti_paddr = (r_iommu_wti_paddr.read() & 0x00000000FFFFFFFFLL) |
1306                                        ((vci_addr_t)p_vci_tgt_int.wdata.read())<<32;
[240]1307                }
[434]1308                else if( read && (cell == IOB_WTI_ADDR_HI))    // READ WTI_PADDR_HI
[240]1309                {
[434]1310                    rdata = (uint32_t)(r_iommu_wti_paddr.read()>>32);
[240]1311                }
[434]1312                else if( not read && ((cell >= IOB_PERI_WTI_BEGIN)  // WRITE PERI WTI
1313                          && (cell< (IOB_PERI_WTI_BEGIN + 64))) )
1314                {
1315                    size_t  index = (cell - IOB_PERI_WTI_BEGIN)/2;
1316                    bool    high  = (cell - IOB_PERI_WTI_BEGIN)%2;
1317                    if ( high ) r_iommu_peri_wti[index] =          // set 32 MSB bits
1318                        (r_iommu_peri_wti[index].read() & 0x00000000FFFFFFFFLL) |
1319                        ((vci_addr_t)p_vci_tgt_int.wdata.read())<<32;
1320                    else        r_iommu_peri_wti[index] =          // set 32 LSB bits
1321                         (vci_addr_t)p_vci_tgt_int.wdata.read();
1322                } 
1323                else if( read && ((cell >= IOB_PERI_WTI_BEGIN)      // READ PERI WTI   
1324                         && (cell< (IOB_PERI_WTI_BEGIN + 64))) ) 
1325                {
1326                    size_t  index = (cell - IOB_PERI_WTI_BEGIN)/2;
1327                    bool    high  = (cell - IOB_PERI_WTI_BEGIN)%2;
1328                    if ( high ) rdata = (uint32_t)(r_iommu_peri_wti[index].read()>>32);
1329                    else        rdata = (uint32_t)(r_iommu_peri_wti[index].read());
1330                }
1331                else   // Error: Wrong address, or invalid operation.
1332                {
1333                    rerror = true;
1334                }
[451]1335                r_config_cmd_rdata = rdata;
[434]1336                r_config_cmd_error = rerror;
[451]1337                r_config_cmd_fsm   = CONFIG_CMD_FIFO_PUT_RSP;
[240]1338            }
[451]1339            else if ( found )                            // remote peripheral
[240]1340            {
[434]1341                r_config_cmd_fsm  = CONFIG_CMD_FIFO_PUT_CMD;
[240]1342            }
[451]1343            else                                         // out of segment
1344            {
1345                r_config_cmd_rdata = 0;
1346                r_config_cmd_error = true;
1347                r_config_cmd_fsm   = CONFIG_CMD_FIFO_PUT_RSP;
1348            }
[434]1349        } // end if cmdval
[240]1350        break;
1351    }
[434]1352    /////////////////////////////
1353    case CONFIG_CMD_FIFO_PUT_CMD:       // transmit VCI command from the INT network
1354                                    // to the CONFIG_CMD fifo to IOX network
[240]1355    {
[434]1356        config_cmd_fifo_put = true;
1357
1358        if ( p_vci_tgt_int.cmdval.read()  and m_config_cmd_addr_fifo.wok() )
[240]1359        {
[434]1360
1361#if DEBUG_CONFIG_CMD
1362if( m_debug_activated ) 
1363std::cout << "  <IOB CONFIG_CMD_FIFO_PUT_CMD> Transmit VCI command to IOX network"
1364          << " : address = " << std::hex << p_vci_tgt_int.address.read()
1365          << " / srcid = " << p_vci_tgt_int.srcid.read()
1366          << std::endl;
1367#endif
1368            if(  p_vci_tgt_int.eop.read() ) r_config_cmd_fsm = CONFIG_CMD_IDLE;
1369        }
1370        break;
[240]1371    }
[434]1372    /////////////////////////////
1373    case CONFIG_CMD_FIFO_PUT_RSP:   // Try to put a response in CONFIG_RSP fifo,
1374                                    // for a local configuration transaction.
1375                                    // The FIFO is shared with CONFIG_RSP FSM
1376                                    // and must we wait for allocation...
[240]1377    {
[434]1378        if ( p_vci_tgt_int.cmdval.read() and r_alloc_fifo_config_rsp_local.read() )
[240]1379        {
[434]1380            config_rsp_fifo_put = true;
1381
1382            if ( m_config_rsp_data_fifo.wok() ) 
1383            {
1384
1385#if DEBUG_CONFIG_CMD
1386if( m_debug_activated ) 
1387std::cout << "  <IOB CONFIG_CMD_FIFO_PUT_RSP> Response to a local configuration request" 
1388          << std::endl;
1389#endif
1390                if(  p_vci_tgt_int.eop.read() ) r_config_cmd_fsm = CONFIG_CMD_IDLE;
1391            }
[240]1392        }
1393        break;
1394    }
1395    } // end switch CONFIG_CMD FSM
1396
1397    //////////////////////////////////////////////////////////////////////////////
[434]1398    // The CONFIG_RSP_FSM handles the VCI responses from the periherals
1399    // on the IOX network and  writes the responses in the CONFIG_RSP fifo.
1400    // The VCI response flit is only consumed in the FIFO_PUT state.
1401    // This FSM is mainly intended to handle single flit config transactions,
1402    // but it can also handle software driven, multi-flits data transactions.
1403    //////////////////////////////////////////////////////////////////////////////
1404
[240]1405    switch( r_config_rsp_fsm.read() ) 
1406    {
1407    /////////////////////
[434]1408    case CONFIG_RSP_IDLE:  // waiting a VCI response from IOX network
[240]1409    {           
[434]1410        if ( p_vci_ini_iox.rspval.read() ) 
[240]1411                {
[434]1412            r_config_rsp_fsm = CONFIG_RSP_FIFO_PUT;
[240]1413                }
1414                break;
1415    }
[434]1416    /////////////////////////
1417    case CONFIG_RSP_FIFO_PUT:  // try to write into CONFIG_RSP fifo
1418                               // as soon as it is allocated
[240]1419    {
[434]1420        if ( p_vci_ini_iox.rspval.read() and not r_alloc_fifo_config_rsp_local.read() )
[240]1421        {
1422            config_rsp_fifo_put = true;
1423
[434]1424            if ( m_config_rsp_data_fifo.wok() ) 
1425            {
1426                if ( p_vci_ini_iox.reop.read() ) r_config_rsp_fsm = CONFIG_RSP_IDLE;   
1427
[240]1428#if DEBUG_CONFIG_RSP
[434]1429if( m_debug_activated ) 
1430std::cout << "  <IOB CONFIG_RSP_FIFO_PUT> Push response into CONFIG_RSP fifo:" 
1431          << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read()
1432          << " / rtrdid = " << p_vci_ini_iox.rtrdid.read()
1433          << " / rdata = " << p_vci_ini_iox.rdata.read()
1434          << " / reop  = " << p_vci_ini_iox.reop.read()
1435          << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl;
[240]1436#endif
[434]1437            }
[240]1438                       
1439        }
1440        break;
1441    }
1442    } // end switch CONFIG_RSP FSM
1443
[434]1444    /////////////////////////////////////////////////////////////////////////////////
1445    // If the IOB component has IRQ ports, the IRQ FSM detects all changes
1446    // on the 32 p_irq[i] ports and request a VCI write transaction to the
1447    // MISS_INIT FSM, using the 64 r_irq_request[i] and r_irq_pending[i] flip-flops.
1448    /////////////////////////////////////////////////////////////////////////////////
[240]1449
[434]1450    if ( m_has_irqs )
[240]1451    {
[434]1452        for ( size_t i = 0; i<32; ++i )
[240]1453        {
[434]1454            r_irq_request[i] = ( p_irq[i]->read() == not r_irq_pending[i].read() );
1455            r_irq_pending[i] = p_irq[i]->read();
[240]1456        }
1457    }
[434]1458       
1459    ///////////////////////////////////////////////////////////////////////////////////
1460    // The MISS_WTI_CMD FSM send VCI commands on the Internal Network.
1461    // It handles PTE MISS requests from TLB_MISS FSM and software IRQs.
1462    // It supports several simultaneous VCI transactions.
[240]1463    ////////////////////////////////////////////////////////////////////////////////////
1464 
[434]1465    switch ( r_miss_wti_cmd_fsm.read() ) 
[240]1466    {
[434]1467        ///////////////////////
1468        case MISS_WTI_CMD_IDLE:   // TLB MISS have highest priority
[240]1469        {
[434]1470            if ( r_tlb_miss_req.read() )
[240]1471            {
[434]1472                r_miss_wti_cmd_fsm = MISS_WTI_CMD_MISS;
[240]1473            }
[434]1474            else if ( r_iommu_wti_enable.read() )
1475            {
1476                // checking if there is a new pending interrupt
[240]1477                bool found = false;
[434]1478                size_t n;
1479                for ( n = 0 ; (n < 32) and not found ; n++ )
[240]1480                {
[434]1481                    if ( r_irq_request[n] ) found = true;
[240]1482                }
[434]1483                if ( found )
1484                {
1485                    r_miss_wti_cmd_index = n;
1486                    r_miss_wti_cmd_fsm   = MISS_WTI_CMD_WTI;
1487                }
[240]1488            }
1489                        break;
1490        }
[434]1491        //////////////////////     
1492        case MISS_WTI_CMD_WTI:   // send a single flit IRQ WRITE on INT Network
1493                                 // address is defined by IRQ_VECTOR[r_miss_wti_index]
1494                                 // data is defined by r_irq_pending[r_miss_wti_index]
[240]1495        {
[434]1496            if ( p_vci_ini_int.cmdack ) 
1497            {
1498                // reset the request
1499                r_irq_request[r_miss_wti_cmd_index.read()] = false;
1500                r_miss_wti_cmd_fsm = MISS_WTI_RSP_WTI;         
[240]1501
[434]1502#if DEBUG_MISS_WTI
1503if( m_debug_activated )
1504std::cout << "  <IOB MISS_WTI_CMD_WTI> Send WTI write command on Internal Network"
1505          << " / IRQID = " << std::dec << r_miss_wti_cmd_index.read() << std::endl;
1506#endif
[240]1507            }
[434]1508            break;
[240]1509        }
[434]1510        ///////////////////////
1511        case MISS_WTI_CMD_MISS:   // send a TLB MISS request on INT Network
[240]1512        {
[434]1513            if ( p_vci_ini_int.cmdack ) 
1514            {
1515                r_tlb_buf_tag     = ( (r_tlb_paddr.read()) & CACHE_LINE_MASK ); 
1516                r_tlb_buf_valid   = true;
1517           
1518                if( r_tlb_miss_type.read() == PTE1_MISS )
1519                    r_tlb_buf_vaddr = (r_dma_cmd_vaddr.read() & 
1520                                        ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET);
1521                else
1522                    r_tlb_buf_vaddr = (r_dma_cmd_vaddr.read() & 
1523                                        ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET);
1524               
1525                r_miss_wti_cmd_fsm = MISS_WTI_RSP_MISS;         
[240]1526
[434]1527#if DEBUG_MISS_WTI
1528if( m_debug_activated )
1529std::cout << "  <IOB MISS_WTI_CMD_MISS> Send TLB MISS command on Internal Network" << std::hex
1530          << " / address = " <<(vci_addr_t)((r_tlb_paddr.read())& CACHE_LINE_MASK) << std::endl;
[240]1531#endif
[434]1532            }
[240]1533            break;
1534        }
[434]1535    } // end switch r_miss_wti_cmd_fsm
1536
1537    ///////////////////////////////////////////////////////////////////////////////////
1538    // The MISS_WTI_RSP FSM handles VCI responses on the Internal Network.
1539    // it can be response to TLB MISS (read transaction) or WTI (write transaction).
1540    // It supports several simultaneous VCI transactions.
1541    ////////////////////////////////////////////////////////////////////////////////////
1542 
1543    switch ( r_miss_wti_rsp_fsm.read() ) 
1544    {
1545        case MISS_WTI_RSP_IDLE:   // waiting a VCI response
[240]1546        {
[434]1547            if ( p_vci_ini_int.rspval.read() ) 
[240]1548            {
[434]1549                if ( p_vci_ini_int.rpktid.read() == PKTID_READ )  // it's a TLB MISS response
[240]1550                {
[434]1551                    r_miss_wti_rsp_fsm   = MISS_WTI_RSP_MISS;
1552                    r_miss_wti_rsp_count = 0;
[240]1553                }
[434]1554                else                                       // it's a WTI WRITE response
1555                {
1556                    r_miss_wti_rsp_fsm   = MISS_WTI_RSP_WTI;
1557
1558                }
[240]1559            }
1560            break;
1561        }
[434]1562        //////////////////////
1563        case MISS_WTI_RSP_WTI:   // Handling response to a WTI transaction
[240]1564        {
[434]1565            assert( p_vci_ini_int.reop.read() and
1566            "VCI_IO_BRIDGE ERROR: IRQ Write response should have one single flit" ); 
[240]1567
[434]1568            assert( ( (p_vci_ini_int.rerror.read()&0x1) == 0 ) and
1569            "VCI_IO_BRIDGE ERROR: IRQ Write response error !!!" ); 
1570             // TODO traiter error using the IOMMU IRQ
1571
1572#if DEBUG_MISS_WTI
1573if( m_debug_activated )
1574std::cout << "  <IOB MISS_WTI_RSP_WTI> Response to WTI write" << std::endl;
[240]1575#endif
[434]1576            r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE;
[240]1577            break;
1578        }
[434]1579        ///////////////////////
1580        case MISS_WTI_RSP_MISS:   // Handling response to a TLB MISS transaction
[240]1581        {
[434]1582            if ( p_vci_ini_int.rspval.read() ) 
[240]1583            {
[434]1584                if ( (p_vci_ini_int.rerror.read()&0x1) != 0 )  // error reported
[240]1585                {
[434]1586                    r_miss_wti_rsp_error = true;
1587                    if ( p_vci_ini_int.reop.read() ) 
[240]1588                    {   
[434]1589                        r_miss_wti_cmd_fsm = MISS_WTI_RSP_IDLE;
1590                        r_tlb_miss_req = false; 
[240]1591                    }
[434]1592#if DEBUG_MISS_WTI
1593if( m_debug_activated ) 
1594std::cout << " <IOB MISS_WTI_RSP_MISS> ERROR " << std::endl; 
[240]1595#endif
1596                }
[434]1597                else                                           // no error
[240]1598                { 
[434]1599                    bool   eop          = p_vci_ini_int.reop.read();
[240]1600
[434]1601#if DEBUG_MISS_WTI
1602if( m_debug_activated ) 
1603std::cout << "  <IOB MISS_WTI_RSP_MISS> Response to a tlb miss transaction"
1604          << " / Count = " << r_miss_wti_rsp_count.read()
1605          << " / Data = " << std::hex << p_vci_ini_int.rdata.read() << std::endl; 
[240]1606#endif
[434]1607                    assert(((eop == (r_miss_wti_rsp_count.read() == (m_words-1)))) and
1608                    "VCI_IO_BRIDGE ERROR: invalid length for a TLB MISS response");
[240]1609
[434]1610                    r_tlb_buf_data[r_miss_wti_rsp_count.read()] = p_vci_ini_int.rdata.read();
1611                    r_miss_wti_rsp_count = r_miss_wti_rsp_count.read() + 1;
[240]1612                   
1613                    if ( eop ) 
1614                    {
[434]1615                        r_tlb_miss_req = false;     //reset the request flip-flop
1616                        r_miss_wti_cmd_fsm = MISS_WTI_RSP_IDLE;         
[240]1617                    }
1618                }
1619            }
1620            break;
1621        }
[434]1622    } // end  switch r_miss_wti_rsp_fsm
[240]1623
[434]1624    /////////////////////////////////////////////////////////////////////////
1625    // This flip-flop allocates the access to the CONFIG_RSP fifo
1626    // with a round robin priority between 2 clients FSMs :
1627    // - CONFIG_CMD : to put a response to a local config command.
1628    // - CONFIG_RSP : to put a response to a peripheral config command.
1629    // The ressource is always allocated.
1630    // A new allocation occurs when the owner FSM is not using it,
1631    // and the other FSM is requiring it.
1632    /////////////////////////////////////////////////////////////////////////
[240]1633   
[434]1634    if ( r_alloc_fifo_config_rsp_local.read() )
[240]1635    {
[434]1636        if ( (r_config_rsp_fsm.read() == CONFIG_RSP_FIFO_PUT) and
1637             (r_config_cmd_fsm.read() != CONFIG_CMD_FIFO_PUT_RSP) )
1638        r_alloc_fifo_config_rsp_local = false;
[240]1639    }
[434]1640    else 
[240]1641    {
[434]1642        if ( (r_config_cmd_fsm.read() == CONFIG_CMD_FIFO_PUT_RSP) and
1643             (r_config_rsp_fsm.read() != CONFIG_RSP_FIFO_PUT) )
1644        r_alloc_fifo_config_rsp_local = true;
[240]1645    }
[434]1646
1647    /////////////////////////////////////////////////////////////////////////
1648    // This flip-flop allocates the access to the DMA_RSP fifo
1649    // with a round robin priority between 2 clients FSMs :
1650    // - DMA_CMD : to put a error response in case of bad address translation
1651    // - DMA_RSP : to put a normal response to a DMA transaction.
1652    // The ressource is always allocated.
1653    // A new allocation occurs when the owner FSM is not using it,
1654    // and the other FSM is requiring it.
1655    /////////////////////////////////////////////////////////////////////////
1656   
1657    if ( r_alloc_fifo_dma_rsp_local.read() )
[240]1658    {
[434]1659        if ( (r_dma_rsp_fsm.read() == DMA_RSP_FIFO_PUT) and
1660             (r_dma_cmd_fsm.read() != DMA_CMD_FIFO_PUT_RSP) )
1661        r_alloc_fifo_dma_rsp_local = false;
[240]1662    }
1663    else 
1664    {
[434]1665        if ( (r_dma_cmd_fsm.read() == DMA_CMD_FIFO_PUT_RSP) and
1666             (r_dma_rsp_fsm.read() != DMA_RSP_FIFO_PUT) )
1667        r_alloc_fifo_dma_rsp_local = true;
[240]1668    }
1669
[434]1670    // Define GET signals for all output FIFOs
1671    dma_cmd_fifo_get    = p_vci_ini_ram.cmdack.read();
1672    dma_rsp_fifo_get    = p_vci_tgt_iox.rspack.read();
1673    config_cmd_fifo_get = p_vci_ini_iox.cmdack.read();
1674    config_rsp_fifo_get = p_vci_tgt_int.rspack.read();
1675
1676    ///////////////////////////////////////////////////////////
1677    // DMA_CMD fifo update
1678    // One writer : DMA_CMD FSM
1679    ///////////////////////////////////////////////////////////
1680
1681    m_dma_cmd_addr_fifo.update(   dma_cmd_fifo_get,
1682                                  dma_cmd_fifo_put,
1683                                  r_dma_cmd_paddr.read() );   // address translation
1684    m_dma_cmd_cmd_fifo.update(    dma_cmd_fifo_get,
1685                                  dma_cmd_fifo_put,
1686                                  p_vci_tgt_iox.cmd.read() );
1687    m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
1688                                  dma_cmd_fifo_put,
1689                                  p_vci_tgt_iox.contig.read() );
1690    m_dma_cmd_cons_fifo.update(   dma_cmd_fifo_get,
1691                                  dma_cmd_fifo_put,
1692                                  p_vci_tgt_iox.cons.read() );
1693    m_dma_cmd_plen_fifo.update(   dma_cmd_fifo_get,
1694                                  dma_cmd_fifo_put,
1695                                  p_vci_tgt_iox.plen.read() );
1696    m_dma_cmd_wrap_fifo.update(   dma_cmd_fifo_get,
1697                                  dma_cmd_fifo_put,
1698                                  p_vci_tgt_iox.wrap.read() );
1699    m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
1700                                  dma_cmd_fifo_put,
1701                                  p_vci_tgt_iox.cfixed.read() );
1702    m_dma_cmd_clen_fifo.update(   dma_cmd_fifo_get,
1703                                  dma_cmd_fifo_put,
1704                                  p_vci_tgt_iox.clen.read() );
1705    m_dma_cmd_srcid_fifo.update(  dma_cmd_fifo_get,
1706                                  dma_cmd_fifo_put,
1707                                  p_vci_tgt_iox.srcid.read() );
1708    m_dma_cmd_trdid_fifo.update(  dma_cmd_fifo_get,
1709                                  dma_cmd_fifo_put,
1710                                  p_vci_tgt_iox.trdid.read() );
1711    m_dma_cmd_pktid_fifo.update(  dma_cmd_fifo_get,
1712                                  dma_cmd_fifo_put,
1713                                  p_vci_tgt_iox.pktid.read() );
1714    m_dma_cmd_data_fifo.update(   dma_cmd_fifo_get,
1715                                  dma_cmd_fifo_put,
1716                                  p_vci_tgt_iox.wdata.read() ); 
1717    m_dma_cmd_be_fifo.update(     dma_cmd_fifo_get,
1718                                  dma_cmd_fifo_put,
1719                                  p_vci_tgt_iox.be.read() ); 
1720    m_dma_cmd_eop_fifo.update(    dma_cmd_fifo_get,
1721                                  dma_cmd_fifo_put,
1722                                  p_vci_tgt_iox.eop.read() );
1723
1724    //////////////////////////////////////////////////////////////
1725    // DMA_RSP fifo update
1726    // Two writers : DMA_CMD FSM & DMA_RSP FSM
1727    //////////////////////////////////////////////////////////////
1728
1729    if (r_alloc_fifo_dma_rsp_local.read() )  // owner is DMA_CMD FSM
1730                                             // local response for a translation error
[240]1731    {
[434]1732        m_dma_rsp_data_fifo.update(   dma_rsp_fifo_get,
1733                                      dma_rsp_fifo_put,
1734                                      0 );                      // no data if error
[240]1735        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
[434]1736                                      dma_rsp_fifo_put,
1737                                      p_vci_tgt_iox.rsrcid.read() ); 
[240]1738        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
[434]1739                                      dma_rsp_fifo_put,
1740                                      p_vci_tgt_iox.rtrdid.read() ); 
[240]1741        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
[434]1742                                      dma_rsp_fifo_put,
1743                                      p_vci_tgt_iox.rpktid.read() ); 
1744        m_dma_rsp_reop_fifo.update(   dma_rsp_fifo_get,
1745                                      dma_rsp_fifo_put,
1746                                      true );                    // single flit response
[240]1747        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
1748                                      dma_rsp_fifo_put,
[434]1749                                      1 );                        // error
[240]1750    }
[434]1751    else                                   // owner is DMA_RSP FSM
1752                                           // normal response to a DMA transaction
[240]1753    {
[434]1754        m_dma_rsp_data_fifo.update(   dma_rsp_fifo_get,
1755                                      dma_rsp_fifo_put,
1756                                      p_vci_ini_ram.rdata.read() );
[240]1757        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
[434]1758                                      dma_rsp_fifo_put,
1759                                      p_vci_ini_ram.rsrcid.read() );
[240]1760        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
[434]1761                                      dma_rsp_fifo_put,
1762                                      p_vci_ini_ram.rtrdid.read() );
[240]1763        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
[434]1764                                      dma_rsp_fifo_put,
1765                                      p_vci_ini_ram.rpktid.read() );
1766        m_dma_rsp_reop_fifo.update(   dma_rsp_fifo_get,
1767                                      dma_rsp_fifo_put,
1768                                      p_vci_ini_ram.reop.read() );
[240]1769        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
1770                                      dma_rsp_fifo_put,
[434]1771                                      p_vci_ini_ram.rerror.read() );
[240]1772    }
1773
[434]1774    ////////////////////////////////////////////////////////////////
1775    // CONFIG_CMD fifo update
1776    // One writer : CONFIG_CMD FSM
1777    ////////////////////////////////////////////////////////////////
1778
1779    m_config_cmd_addr_fifo.update(   config_cmd_fifo_get,
1780                                     config_cmd_fifo_put,
1781                                     p_vci_tgt_int.address.read() ); 
1782    m_config_cmd_cmd_fifo.update(    config_cmd_fifo_get,
1783                                     config_cmd_fifo_put,
1784                                     p_vci_tgt_int.cmd.read() );
[240]1785    m_config_cmd_contig_fifo.update( config_cmd_fifo_get,
[434]1786                                     config_cmd_fifo_put,
1787                                     p_vci_tgt_int.contig.read() );
1788    m_config_cmd_cons_fifo.update(   config_cmd_fifo_get,
1789                                     config_cmd_fifo_put,
1790                                     p_vci_tgt_int.cons.read() );
1791    m_config_cmd_plen_fifo.update(   config_cmd_fifo_get,
1792                                     config_cmd_fifo_put,
1793                                     p_vci_tgt_int.plen.read() );
1794    m_config_cmd_wrap_fifo.update(   config_cmd_fifo_get,
1795                                     config_cmd_fifo_put,
1796                                     p_vci_tgt_int.wrap.read() );
[240]1797    m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get,
[434]1798                                     config_cmd_fifo_put,
1799                                     p_vci_tgt_int.cfixed.read() );
1800    m_config_cmd_clen_fifo.update(   config_cmd_fifo_get,
1801                                     config_cmd_fifo_put,
1802                                     p_vci_tgt_int.clen.read() );
1803    m_config_cmd_srcid_fifo.update(  config_cmd_fifo_get,
1804                                     config_cmd_fifo_put,
1805                                     p_vci_tgt_int.srcid.read() );
1806    m_config_cmd_trdid_fifo.update(  config_cmd_fifo_get,
1807                                     config_cmd_fifo_put,
1808                                     p_vci_tgt_int.trdid.read() ); 
1809    m_config_cmd_pktid_fifo.update(  config_cmd_fifo_get,
1810                                     config_cmd_fifo_put,
1811                                     p_vci_tgt_int.pktid.read() );
1812    m_config_cmd_data_fifo.update(   config_cmd_fifo_get,
1813                                     config_cmd_fifo_put,
1814                                     (ext_data_t)p_vci_tgt_int.wdata.read() );
1815    m_config_cmd_be_fifo.update(     config_cmd_fifo_get,
1816                                     config_cmd_fifo_put,
1817                                     p_vci_tgt_int.be.read() );
1818    m_config_cmd_eop_fifo.update(    config_cmd_fifo_get,
1819                                     config_cmd_fifo_put,
1820                                     p_vci_tgt_int.eop.read() );
[240]1821   
[434]1822    //////////////////////////////////////////////////////////////////////////
1823    // CONFIG_RSP fifo update
1824    // There is two writers : CONFIG_CMD FSM & CONFIG_RSP FSM
1825    //////////////////////////////////////////////////////////////////////////
1826
1827    if ( r_alloc_fifo_config_rsp_local.read() )  // owner is CONFIG_CMD FSM
1828                                                 // response for a local config transaction
[240]1829    {
[434]1830        m_config_rsp_data_fifo.update(   config_rsp_fifo_get,
1831                                         config_rsp_fifo_put,
1832                                         (int_data_t)r_config_cmd_rdata.read() ); 
1833        m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get,
1834                                         config_rsp_fifo_put,
1835                                         p_vci_tgt_int.srcid.read() );
1836        m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get,
1837                                         config_rsp_fifo_put,
1838                                         p_vci_tgt_int.trdid.read() );
1839        m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get,
1840                                         config_rsp_fifo_put,
1841                                         p_vci_tgt_int.pktid.read() );
1842        m_config_rsp_reop_fifo.update(   config_rsp_fifo_get,
1843                                         config_rsp_fifo_put,
1844                                         true );                // local config are one flit
1845        m_config_rsp_rerror_fifo.update( config_rsp_fifo_get,
1846                                         config_rsp_fifo_put,
1847                                         r_config_cmd_error.read() );
[240]1848    }
[434]1849    else                                         // owner is CONFIG_RSP FSM
1850                                                 // response for a remote transaction
1851    {
1852        m_config_rsp_data_fifo.update(   config_rsp_fifo_get,
1853                                         config_rsp_fifo_put,
1854                                         (int_data_t)p_vci_ini_iox.rdata.read() );
1855        m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get,
1856                                         config_rsp_fifo_put,
1857                                         p_vci_ini_iox.rsrcid.read() );
1858        m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get,
1859                                         config_rsp_fifo_put,
1860                                         p_vci_ini_iox.rtrdid.read() );
1861        m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get,
1862                                         config_rsp_fifo_put,
1863                                         p_vci_ini_iox.rpktid.read() );
1864        m_config_rsp_reop_fifo.update(   config_rsp_fifo_get,
1865                                         config_rsp_fifo_put,
1866                                         p_vci_ini_iox.reop.read() );
1867        m_config_rsp_rerror_fifo.update( config_rsp_fifo_get,
1868                                         config_rsp_fifo_put,
1869                                         p_vci_ini_iox.rerror.read() );
1870    }
1871   
[240]1872} // end transition()
1873
1874///////////////////////
1875tmpl(void)::genMoore()
1876///////////////////////
1877{
[434]1878    // VCI initiator command on RAM network
1879    // directly the content of the dma_cmd FIFO
1880
1881    p_vci_ini_ram.cmdval  = m_dma_cmd_addr_fifo.rok(); 
1882    p_vci_ini_ram.address = m_dma_cmd_addr_fifo.read();
1883    p_vci_ini_ram.be      = m_dma_cmd_be_fifo.read();
1884    p_vci_ini_ram.cmd     = m_dma_cmd_cmd_fifo.read();
1885    p_vci_ini_ram.contig  = m_dma_cmd_contig_fifo.read();
1886    p_vci_ini_ram.wdata   = m_dma_cmd_data_fifo.read(); 
1887    p_vci_ini_ram.eop     = m_dma_cmd_eop_fifo.read();
1888    p_vci_ini_ram.cons    = m_dma_cmd_cons_fifo.read();
1889    p_vci_ini_ram.plen    = m_dma_cmd_plen_fifo.read();
1890    p_vci_ini_ram.wrap    = m_dma_cmd_wrap_fifo.read();
1891    p_vci_ini_ram.cfixed  = m_dma_cmd_cfixed_fifo.read();
1892    p_vci_ini_ram.clen    = m_dma_cmd_clen_fifo.read();
1893    p_vci_ini_ram.trdid   = m_dma_cmd_trdid_fifo.read();
1894    p_vci_ini_ram.pktid   = m_dma_cmd_pktid_fifo.read();
1895    p_vci_ini_ram.srcid   = m_dma_cmd_srcid_fifo.read();
[240]1896   
[434]1897    // VCI target command ack on IOX network
1898    // depends on the DMA_CMD FSM state
[240]1899
1900    switch ( r_dma_cmd_fsm.read() ) 
1901    {
1902    case DMA_CMD_IDLE:
[434]1903    case DMA_CMD_MISS_WAIT:
1904        p_vci_tgt_iox.cmdack  = false;
[240]1905        break;
[434]1906    case DMA_CMD_WAIT_EOP:
1907        p_vci_tgt_iox.cmdack  = true;
[240]1908        break;
[434]1909    case DMA_CMD_FIFO_PUT_CMD:
1910        p_vci_tgt_iox.cmdack  = m_dma_cmd_addr_fifo.wok();
[240]1911        break;
[434]1912    case DMA_CMD_FIFO_PUT_RSP:
1913        p_vci_tgt_iox.cmdack  = m_dma_rsp_data_fifo.wok();
[240]1914        break; 
1915    }// end switch r_dma_cmd_fsm
1916
[434]1917    // VCI target response on IOX network
1918    // directly the content of the DMA_RSP FIFO
[240]1919
[434]1920    p_vci_tgt_iox.rspval  = m_dma_rsp_data_fifo.rok();
1921    p_vci_tgt_iox.rsrcid  = m_dma_rsp_rsrcid_fifo.read();
1922    p_vci_tgt_iox.rtrdid  = m_dma_rsp_rtrdid_fifo.read();
1923    p_vci_tgt_iox.rpktid  = m_dma_rsp_rpktid_fifo.read();
1924    p_vci_tgt_iox.rdata   = m_dma_rsp_data_fifo.read(); 
1925    p_vci_tgt_iox.rerror  = m_dma_rsp_rerror_fifo.read();
1926    p_vci_tgt_iox.reop    = m_dma_rsp_reop_fifo.read();
[240]1927
[434]1928    // VCI initiator response on the RAM Network
1929    // depends on the DMA_RSP FSM state
[240]1930
[434]1931        p_vci_ini_ram.rspack = m_dma_rsp_data_fifo.wok() and
1932                           (r_dma_rsp_fsm.read() == DMA_RSP_FIFO_PUT) and
1933                           not r_alloc_fifo_dma_rsp_local.read();
[240]1934
[434]1935    // VCI initiator command on IOX network
1936    // directly the content of the CONFIG_CMD FIFO
1937
1938    p_vci_ini_iox.cmdval  = m_config_cmd_addr_fifo.rok();
1939    p_vci_ini_iox.address = m_config_cmd_addr_fifo.read();
1940    p_vci_ini_iox.be      = m_config_cmd_be_fifo.read();
1941    p_vci_ini_iox.cmd     = m_config_cmd_cmd_fifo.read();
1942    p_vci_ini_iox.contig  = m_config_cmd_contig_fifo.read();
1943    p_vci_ini_iox.wdata   = (ext_data_t)m_config_cmd_data_fifo.read(); 
1944    p_vci_ini_iox.eop     = m_config_cmd_eop_fifo.read();
1945    p_vci_ini_iox.cons    = m_config_cmd_cons_fifo.read();
1946    p_vci_ini_iox.plen    = m_config_cmd_plen_fifo.read();
1947    p_vci_ini_iox.wrap    = m_config_cmd_wrap_fifo.read();
1948    p_vci_ini_iox.cfixed  = m_config_cmd_cfixed_fifo.read();
1949    p_vci_ini_iox.clen    = m_config_cmd_clen_fifo.read();
1950    p_vci_ini_iox.trdid   = m_config_cmd_trdid_fifo.read();
1951    p_vci_ini_iox.pktid   = m_config_cmd_pktid_fifo.read();
1952    p_vci_ini_iox.srcid   = m_config_cmd_srcid_fifo.read();
[240]1953   
[434]1954    // VCI target command ack on INT network
[240]1955    // it depends on the CONFIG_CMD FSM state
1956
1957    switch ( r_config_cmd_fsm.read() ) 
1958    {
1959    case CONFIG_CMD_IDLE:
[434]1960        p_vci_tgt_int.cmdack  = false;
[240]1961        break;
[434]1962    case CONFIG_CMD_FIFO_PUT_CMD:         
1963        p_vci_tgt_int.cmdack  = m_config_cmd_addr_fifo.wok();
[240]1964        break;
[434]1965    case CONFIG_CMD_FIFO_PUT_RSP:         
1966        p_vci_tgt_int.cmdack  = m_config_rsp_data_fifo.wok() and
1967                                r_alloc_fifo_config_rsp_local.read();
[240]1968        break;
1969    }// end switch r_config_cmd_fsm
1970
[434]1971    // VCI target response on INT network
1972    // directly the content of the CONFIG_RSP FIFO
[240]1973
[434]1974    p_vci_tgt_int.rspval  = m_config_rsp_data_fifo.rok();
1975        p_vci_tgt_int.rsrcid  = m_config_rsp_rsrcid_fifo.read();
1976    p_vci_tgt_int.rtrdid  = m_config_rsp_rtrdid_fifo.read();
1977    p_vci_tgt_int.rpktid  = m_config_rsp_rpktid_fifo.read();
1978    p_vci_tgt_int.rdata   = m_config_rsp_data_fifo.read();
1979    p_vci_tgt_int.rerror  = m_config_rsp_rerror_fifo.read();
1980    p_vci_tgt_int.reop    = m_config_rsp_reop_fifo.read();
[240]1981   
[434]1982    // VCI initiator response on IOX Network
[240]1983    // it depends on the CONFIG_RSP FSM state
1984
[434]1985        p_vci_ini_iox.rspack = m_config_rsp_data_fifo.wok() and
1986                           (r_config_rsp_fsm.read() == CONFIG_RSP_FIFO_PUT) and
1987                           not r_alloc_fifo_config_rsp_local.read();
1988
1989    // VCI initiator command  on INT network
1990    // it depends on the MISS_WTI_CMD FSM state
1991
1992    // default values
1993    p_vci_ini_int.srcid   = m_int_srcid;
1994    p_vci_ini_int.trdid   = 0;
1995    p_vci_ini_int.cfixed  = false;
1996    p_vci_ini_int.eop     = true;
1997    p_vci_ini_int.wrap    = false;
1998    p_vci_ini_int.clen    = 0;
1999    p_vci_ini_int.contig  = false;
2000    p_vci_ini_int.cons    = true;
2001    p_vci_ini_int.be      = 0xFF;
[240]2002   
[434]2003    switch ( r_miss_wti_cmd_fsm.read() ) 
[240]2004    {   
[434]2005    case MISS_WTI_CMD_IDLE:
2006                p_vci_ini_int.cmdval  = false;
2007        p_vci_ini_int.address = 0;
2008        p_vci_ini_int.cmd     = vci_param_int::CMD_NOP;
2009        p_vci_ini_int.pktid   = PKTID_READ;
2010        p_vci_ini_int.wdata   = 0;
2011        p_vci_ini_int.plen    = 0;
[240]2012        break;
2013   
[434]2014    case MISS_WTI_CMD_WTI:
2015        p_vci_ini_int.cmdval  = true;
2016        p_vci_ini_int.address = r_iommu_peri_wti[r_miss_wti_cmd_index.read()].read(); 
2017        p_vci_ini_int.cmd     = vci_param_int::CMD_WRITE;
2018        p_vci_ini_int.pktid   = PKTID_WRITE;
2019        p_vci_ini_int.wdata   = (int_data_t)r_irq_pending[r_miss_wti_cmd_index.read()].read();
2020        p_vci_ini_int.plen    = vci_param_int::B;
[240]2021        break;
2022   
[434]2023    case MISS_WTI_CMD_MISS:
2024        p_vci_ini_int.cmdval  = true;
2025        p_vci_ini_int.address = r_tlb_paddr.read() & CACHE_LINE_MASK;
2026        p_vci_ini_int.cmd     = vci_param_int::CMD_READ;
2027        p_vci_ini_int.pktid   = PKTID_READ;
2028        p_vci_ini_int.wdata   = 0;
2029        p_vci_ini_int.plen    = m_words*(vci_param_int::B);
[240]2030        break;
[434]2031    }
[240]2032
[434]2033    // VCI initiator response on INT network
2034    // It depends on the MISS_WTI_RSP FSM state
2035
2036    if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_IDLE ) p_vci_ini_int.rspack  = false;
2037    else                                                  p_vci_ini_int.rspack  = true;
2038
[240]2039} // end genMoore
2040
2041}}
2042
2043// Local Variables:
2044// tab-width: 4
2045// c-basic-offset: 4
2046// c-file-offsets:((innamespace . 0)(inline-open . 0))
2047// indent-tabs-mode: nil
2048// End:
2049
2050// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.