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

Last change on this file since 713 was 713, checked in by alain, 10 years ago

Cosmetic

File size: 102.1 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
[713]45#define DEBUG_MISS_WTI_CMD      1
[240]46
47namespace soclib { 
48namespace caba {
49
50namespace {
51
[434]52const char *dma_cmd_fsm_state_str[] = 
53    {
[240]54        "DMA_CMD_IDLE",
[712]55        "DMA_CMD_DMA_REQ",
56        "DMA_CMD_WTI_IOX_REQ",
57        "DMA_CMD_ERR_WAIT_EOP",
58        "DMA_CMD_ERR_WTI_REQ",
59        "DMA_CMD_ERR_RSP_REQ",
60        "DMA_CMD_TLB_MISS_WAIT",
[240]61    };
62
[434]63const char *dma_rsp_fsm_state_str[] = 
64    {
[712]65        "DMA_RSP_IDLE_DMA",
66        "DMA_RSP_IDLE_WTI",
67        "DMA_RSP_IDLE_ERR",
68        "DMA_RSP_PUT_DMA",
69        "DMA_RSP_PUT_WTI",
70        "DMA_RSP_PUT_ERR",
[240]71    };
72
[434]73const char *tlb_fsm_state_str[] = 
74    {
75        "TLB_IDLE",
76        "TLB_MISS",
77        "TLB_PTE1_GET",
78        "TLB_PTE1_SELECT",
79        "TLB_PTE1_UPDT",
80        "TLB_PTE2_GET",                                                 
81        "TLB_PTE2_SELECT",
82        "TLB_PTE2_UPDT",
83        "TLB_WAIT",
84        "TLB_RETURN",
85        "TLB_INVAL_CHECK",
[240]86    };
87
[434]88const char *config_cmd_fsm_state_str[] = 
89    {
[240]90        "CONFIG_CMD_IDLE",
[585]91        "CONFIG_CMD_NEXT",
92        "CONFIG_CMD_PUT",
93        "CONFIG_CMD_RSP",
[240]94    };
95
[434]96const char *config_rsp_fsm_state_str[] = 
97    {
[712]98        "CONFIG_RSP_IDLE_IOX",
99        "CONFIG_RSP_IDLE_LOC",
100        "CONFIG_RSP_PUT_LOW", 
[585]101        "CONFIG_RSP_PUT_HI", 
102        "CONFIG_RSP_PUT_UNC", 
[712]103        "CONFIG_RSP_PUT_LOC", 
[240]104    };
105
[549]106const char *miss_wti_rsp_state_str[] = 
107    { 
108        "MISS_WTI_RSP_IDLE",
[712]109        "MISS_WTI_RSP_WTI_IOX",
110        "MISS_WTI_RSP_WTI_MMU",
[434]111        "MISS_WTI_RSP_MISS",
[240]112    };
113}
114
[434]115#define tmpl(...)  template<typename vci_param_int,typename vci_param_ext> __VA_ARGS__ VciIoBridge<vci_param_int,vci_param_ext>
[240]116
[434]117////////////////////////
[240]118tmpl(/**/)::VciIoBridge(
119    sc_module_name                                  name,
[434]120    const soclib::common::MappingTable  &mt_ext,
121    const soclib::common::MappingTable  &mt_int,
122    const soclib::common::MappingTable  &mt_iox,
123    const soclib::common::IntTab            &int_tgtid,     // INT network TGTID
124    const soclib::common::IntTab            &int_srcid,     // INT network SRCID
125    const soclib::common::IntTab            &iox_tgtid,     // IOX network TGTID
126    const size_t                        dcache_words,
127    const size_t                                        iotlb_ways,
128    const size_t                                        iotlb_sets,
129    const uint32_t                                      debug_start_cycle,
130    const bool                                      debug_ok)
[240]131    : soclib::caba::BaseModule(name),
132
[434]133      p_clk("p_clk"),
134      p_resetn("p_resetn"),
135      p_vci_ini_ram("p_vci_ini_ram"),
136      p_vci_tgt_iox("p_vci_tgt_iox"),
137      p_vci_ini_iox("p_vci_ini_iox"),
138      p_vci_tgt_int("p_vci_tgt_int"),
139      p_vci_ini_int("p_vci_ini_int"),
[240]140
[434]141      m_words( dcache_words ),
[240]142
[434]143      // INT & IOX Network
144      m_int_seglist( mt_int.getSegmentList( int_tgtid )),
145      m_int_srcid( mt_int.indexForId( int_srcid )), 
146      m_iox_seglist( mt_iox.getSegmentList( iox_tgtid )),
147
[240]148      m_iotlb_ways(iotlb_ways),
149      m_iotlb_sets(iotlb_sets),
150
151      m_debug_start_cycle(debug_start_cycle),
152      m_debug_ok(debug_ok),
153
[434]154      // addressable registers
[240]155      r_iommu_ptpr("r_iommu_ptpr"),
156      r_iommu_active("r_iommu_active"),
157      r_iommu_bvar("r_iommu_bvar"),
158      r_iommu_etr("r_iommu_etr"),
159      r_iommu_bad_id("r_iommu_bad_id"),
[712]160      r_iommu_wti_enable("r_iommu_wti_enable"),
161      r_iommu_wti_addr_lo("r_iommu_wti_addr_lo"),
[240]162
[434]163      // DMA_CMD FSM registers
[240]164      r_dma_cmd_fsm("r_dma_cmd_fsm"),
[434]165      r_dma_cmd_paddr("r_dma_cmd_paddr"),
[240]166
[712]167      r_dma_cmd_to_miss_wti_cmd_req("r_dma_cmd_to_miss_wti_cmd_req"),
168      r_dma_cmd_to_miss_wti_cmd_addr("r_dma_cmd_to_miss_wti_cmd_addr"),
169      r_dma_cmd_to_miss_wti_cmd_srcid("r_dma_cmd_to_miss_wti_cmd_srcid"),
170      r_dma_cmd_to_miss_wti_cmd_trdid("r_dma_cmd_to_miss_wti_cmd_trdid"),
171      r_dma_cmd_to_miss_wti_cmd_pktid("r_dma_cmd_to_miss_wti_cmd_pktid"),
172      r_dma_cmd_to_miss_wti_cmd_wdata("r_dma_cmd_to_miss_wti_cmd_wdata"),
173
174      r_dma_cmd_to_dma_rsp_req("r_dma_cmd_to_dma_rsp_req"),
175      r_dma_cmd_to_dma_rsp_rsrcid("r_dma_cmd_to_dma_rsp_rsrcid"),
176      r_dma_cmd_to_dma_rsp_rtrdid("r_dma_cmd_to_dma_rsp_rtrdid"),
177      r_dma_cmd_to_dma_rsp_rpktid("r_dma_cmd_to_dma_rsp_rpktid"),
178     
179      r_dma_cmd_to_tlb_req("r_dma_cmd_to_tlb_req"),
180      r_dma_cmd_to_tlb_vaddr("r_dma_cmd_to_tlb_vaddr"),
181     
[434]182      //DMA_RSP FSM registers
183      r_dma_rsp_fsm("r_dma_rsp_fsm"),
[240]184
[434]185      // CONFIG_CMD FSM registers
186      r_config_cmd_fsm("r_config_cmd_fsm"),
[712]187
188      r_config_cmd_to_tlb_req("r_config_cmd_to_tlb_req"),
189      r_config_cmd_to_tlb_vaddr("r_config_cmd_to_tlb_vaddr"),
190
191      r_config_cmd_to_config_rsp_req("r_config_cmd_to_config_rsp_req"),
192      r_config_cmd_to_config_rsp_rerror("r_config_cmd_to_config_rsp_rerror"),
193      r_config_cmd_to_config_rsp_rdata("r_config_cmd_to_config_rsp_rdata"),
194
[585]195      r_config_cmd_wdata("r_config_cmd_wdata"),
196      r_config_cmd_be("r_config_cmd_be"),
197      r_config_cmd_cmd("r_config_cmd_wdata"),
198      r_config_cmd_address("r_config_cmd_address"),
199      r_config_cmd_srcid("r_config_cmd_srcid"),
200      r_config_cmd_pktid("r_config_cmd_pktid"),
201      r_config_cmd_trdid("r_config_cmd_trdid"),
202      r_config_cmd_plen("r_config_cmd_plen"),
203      r_config_cmd_clen("r_config_cmd_clen"),
204      r_config_cmd_cons("r_config_cmd_cons"),
205      r_config_cmd_contig("r_config_cmd_contig"),
206      r_config_cmd_cfixed("r_config_cmd_cfixed"),
207      r_config_cmd_wrap("r_config_cmd_wrap"),
208      r_config_cmd_eop("r_config_cmd_eop"),
[240]209
[434]210      // CONFIG_RSP FSM registers 
211      r_config_rsp_fsm("r_config_rsp_fsm"),
212
213      // TLB FSM registers
214      r_tlb_fsm("r_tlb_fsm"),
[240]215      r_waiting_transaction("r_waiting_transaction"),
216      r_tlb_miss_type("r_tlb_miss_type"),
[434]217      r_tlb_miss_error("r_tlb_miss_error"),
[712]218
[434]219      r_tlb_paddr("r_tlb_paddr"),               
220      r_tlb_pte_flags("r_tlb_pte_flags"),
221      r_tlb_pte_ppn("r_tlb_pte_ppn"),
222      r_tlb_way("r_tlb_way"),
[712]223      r_tlb_set("r_tlb_set"), 
224   
[434]225      r_tlb_buf_valid("r_tlb_buf_valid"),
226      r_tlb_buf_tag("r_tlb_buf_tag"),
227      r_tlb_buf_vaddr("r_tlb_buf_vaddr"),
228      r_tlb_buf_big_page("r_tlb_buf_big_page"),
[240]229
[712]230      r_tlb_to_miss_wti_cmd_req("r_tlb_to_miss_wti_cmd_req"),
[240]231
[712]232      // MISS_WTI_RSP FSM registers
[434]233      r_miss_wti_rsp_fsm("r_miss_wti_rsp_fsm"), 
[712]234      r_miss_wti_rsp_error_wti("r_miss_wti_rsp_error_wti"),
235      r_miss_wti_rsp_error_miss("r_miss_wti_rsp_error_miss"),
236      r_miss_wti_rsp_count("r_miss_wti_rsp_count"),
[434]237
[712]238      r_miss_wti_rsp_to_dma_rsp_req("r_miss_wti_rsp_to_dma_rsp_req"),
239      r_miss_wti_rsp_to_dma_rsp_rerror("r_miss_wti_rsp_to_dma_rsp_rerror"),
240      r_miss_wti_rsp_to_dma_rsp_rsrcid("r_miss_wti_rsp_to_dma_rsp_rsrcid"),
241      r_miss_wti_rsp_to_dma_rsp_rtrdid("r_miss_wti_rsp_to_dma_rsp_rtrdid"),
242      r_miss_wti_rsp_to_dma_rsp_rpktid("r_miss_wti_rsp_to_dma_rsp_rpktid"),
[434]243
244      // TLB for IOMMU
245      r_iotlb("iotlb", 0, iotlb_ways, iotlb_sets, vci_param_int::N),
246     
247      // DMA_CMD FIFOs
248      m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",2),
249      m_dma_cmd_srcid_fifo("m_dma_cmd_srcid_fifo",2), 
250      m_dma_cmd_trdid_fifo("m_dma_cmd_trdid_fifo",2), 
251      m_dma_cmd_pktid_fifo("m_dma_cmd_pktid_fifo",2), 
252      m_dma_cmd_be_fifo("m_dma_cmd_be_fifo",2), 
253      m_dma_cmd_cmd_fifo("m_dma_cmd_cmd_fifo",2), 
254      m_dma_cmd_contig_fifo("m_dma_cmd_contig_fifo",2), 
255      m_dma_cmd_data_fifo("m_dma_cmd_data_fifo",2), 
256      m_dma_cmd_eop_fifo("m_dma_cmd_eop_fifo",2),
257      m_dma_cmd_cons_fifo("m_dma_cmd_cons_fifo",2), 
258      m_dma_cmd_plen_fifo("m_dma_cmd_plen_fifo",2), 
259      m_dma_cmd_wrap_fifo("m_dma_cmd_wrap_fifo",2), 
260      m_dma_cmd_cfixed_fifo("m_dma_cmd_cfixed_fifo",2),
261      m_dma_cmd_clen_fifo("m_dma_cmd_clen_fifo",2), 
[240]262
[434]263      // DMA_RSP FIFOs
264      m_dma_rsp_data_fifo("m_dma_rsp_data_fifo",2),
265      m_dma_rsp_rsrcid_fifo("m_dma_rsp_rsrcid_fifo",2),
266      m_dma_rsp_rtrdid_fifo("m_dma_rsp_rtrdid_fifo",2),
267      m_dma_rsp_rpktid_fifo("m_dma_rsp_rpktid_fifo",2),
268      m_dma_rsp_reop_fifo("m_dma_rsp_reop_fifo",2),
269      m_dma_rsp_rerror_fifo("m_dma_rsp_rerror_fifo",2),
270 
271      // CONFIG_CMD FIFOs
272      m_config_cmd_addr_fifo("m_config_cmd_addr_fifo",2),
273      m_config_cmd_srcid_fifo("m_config_cmd_srcid_fifo",2),
274      m_config_cmd_trdid_fifo("m_config_cmd_trdid_fifo",2),
275      m_config_cmd_pktid_fifo("m_config_cmd_pktid_fifo",2),
276      m_config_cmd_be_fifo("m_config_cmd_be_fifo",2),
277      m_config_cmd_cmd_fifo("m_config_cmd_cmd_fifo",2),
278      m_config_cmd_contig_fifo("m_config_cmd_contig_fifo",2),
279      m_config_cmd_data_fifo("m_config_cmd_data_fifo",2),
280      m_config_cmd_eop_fifo("m_config_cmd_eop_fifo",2),
281      m_config_cmd_cons_fifo("m_config_cmd_cons_fifo",2),
282      m_config_cmd_plen_fifo("m_config_cmd_plen_fifo",2),
283      m_config_cmd_wrap_fifo("m_config_cmd_wrap_fifo",2),
284      m_config_cmd_cfixed_fifo("m_config_cmd_cfixed_fifo",2),
285      m_config_cmd_clen_fifo("m_config_cmd_clen_fifo",2),
286
287      // CONFIG_RSP FIFOs
288      m_config_rsp_data_fifo("m_config_rsp_data_fifo",2),     
289      m_config_rsp_rsrcid_fifo("m_config_rsp_rsrcid_fifo",2),
290      m_config_rsp_rtrdid_fifo("m_config_rsp_rtrdid_fifo",2),
291      m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",2),
292      m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",2),
[712]293      m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",2),
294
295      // MISS_WTI_CMD FIFOs
296      m_miss_wti_cmd_addr_fifo("m_miss_wti_cmd_addr_fifo",2),
297      m_miss_wti_cmd_srcid_fifo("m_miss_wti_cmd_srcid_fifo",2),
298      m_miss_wti_cmd_trdid_fifo("m_miss_wti_cmd_trdid_fifo",2),
299      m_miss_wti_cmd_pktid_fifo("m_miss_wti_cmd_pktid_fifo",2),
300      m_miss_wti_cmd_be_fifo("m_miss_wti_cmd_be_fifo",2),
301      m_miss_wti_cmd_cmd_fifo("m_miss_wti_cmd_cmd_fifo",2),
302      m_miss_wti_cmd_contig_fifo("m_miss_wti_cmd_contig_fifo",2),
303      m_miss_wti_cmd_data_fifo("m_miss_wti_cmd_data_fifo",2),
304      m_miss_wti_cmd_eop_fifo("m_miss_wti_cmd_eop_fifo",2),
305      m_miss_wti_cmd_cons_fifo("m_miss_wti_cmd_cons_fifo",2),
306      m_miss_wti_cmd_plen_fifo("m_miss_wti_cmd_plen_fifo",2),
307      m_miss_wti_cmd_wrap_fifo("m_miss_wti_cmd_wrap_fifo",2),
308      m_miss_wti_cmd_cfixed_fifo("m_miss_wti_cmd_cfixed_fifo",2),
309      m_miss_wti_cmd_clen_fifo("m_miss_wti_cmd_clen_fifo",2)
[240]310{
[434]311    std::cout << "  - Building VciIoBridge : " << name << std::endl;
312
313    // checking segments on INT network
314    assert ( ( not m_int_seglist.empty() ) and
315    "VCI_IO_BRIDGE ERROR : no segment allocated on INT network");
316
317    std::list<soclib::common::Segment>::iterator int_seg;
318    for ( int_seg = m_int_seglist.begin() ; int_seg != m_int_seglist.end() ; int_seg++ )
319    {
320        std::cout << "    => segment " << int_seg->name()
321                  << " / base = " << std::hex << int_seg->baseAddress()
[549]322                  << " / size = " << int_seg->size() 
323                  << " / special = " << int_seg->special() << std::endl; 
[434]324    }
325
326    // checking segments on IOX network
327    assert ( ( not m_iox_seglist.empty() ) and
328    "VCI_IO_BRIDGE ERROR : no segment allocated on IOX network");
329
330    std::list<soclib::common::Segment>::iterator iox_seg;
331    for ( iox_seg = m_iox_seglist.begin() ; iox_seg != m_iox_seglist.end() ; iox_seg++ )
332    {
333        std::cout << "    => segment " << iox_seg->name()
334                  << " / base = " << std::hex << iox_seg->baseAddress()
335                  << " / size = " << iox_seg->size() << std::endl; 
336    }
337
338    assert( (vci_param_int::N == vci_param_ext::N) and
339    "VCI_IO_BRIDGE ERROR: VCI ADDRESS widths must be equal on the 3 networks");
340
341    assert( (vci_param_int::N <=  64) and
342    "VCI_IO_BRIDGE ERROR: VCI ADDRESS width cannot be bigger than 64 bits");
343
[585]344    assert( (vci_param_int::B == 4) and
345    "VCI_IO_BRIDGE ERROR: VCI DATA width must be 32 bits on internal network");   
[434]346
[585]347    assert( (vci_param_ext::B == 8) and
348    "VCI_IO_BRIDGE ERROR: VCI DATA width must be 64 bits on external network");   
[434]349
350    assert( (vci_param_int::S == vci_param_ext::S) and
351            "VCI_IO_BRIDGE ERROR: SRCID widths must be equal on the 3 networks");
352
353    // Cache line buffer
354    r_tlb_buf_data = new uint32_t[dcache_words];
355
[240]356    SC_METHOD(transition);
357    dont_initialize();
358    sensitive << p_clk.pos();
359 
360    SC_METHOD(genMoore);
361    dont_initialize();
362    sensitive << p_clk.neg();
363
364 }
365
366/////////////////////////////////////
367tmpl(/**/)::~VciIoBridge()
368/////////////////////////////////////
369{
[434]370    delete [] r_tlb_buf_data;
[240]371}
372
373////////////////////////////////////
374tmpl(void)::print_trace(size_t mode)
375////////////////////////////////////
376{
[549]377    // b0 : IOTLB trace
[240]378
379    std::cout << std::dec << "IO_BRIDGE " << name() << std::endl;
380
[434]381    std::cout << "  "  << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()]
[240]382              << " | " << dma_rsp_fsm_state_str[r_dma_rsp_fsm.read()]
[434]383              << " | " << tlb_fsm_state_str[r_tlb_fsm.read()]
[240]384              << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()]
385              << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()]
[549]386              << " | " << miss_wti_rsp_state_str[r_miss_wti_rsp_fsm.read()]
[434]387              << std::endl;
[240]388
389    if(mode & 0x01)
390    {
391        std::cout << "  IOTLB" << std::endl;
392        r_iotlb.printTrace();
393    }
394}
395
396////////////////////////
397tmpl(void)::print_stats()
398////////////////////////
399{
400    std::cout << name() << std::endl
401        << "- IOTLB MISS RATE      = " << (float)m_cpt_iotlb_miss/m_cpt_iotlb_read << std::endl
402        << "- IOTLB MISS COST         = " << (float)m_cost_iotlb_miss/m_cpt_iotlb_miss << std::endl
403        << "- IOTLB MISS TRANSACTION COST  = " << (float)m_cost_iotlbmiss_transaction/m_cpt_iotlbmiss_transaction << std::endl
404        << "- IOTLB MISS TRANSACTION RATE (OVER ALL MISSES)  = " << (float)m_cpt_iotlbmiss_transaction/m_cpt_iotlb_miss << std::endl;
405}
406
407////////////////////////
408tmpl(void)::clear_stats()
409////////////////////////
410{
411    m_cpt_iotlb_read                = 0;             
412    m_cpt_iotlb_miss                = 0;             
413    m_cost_iotlb_miss               = 0;
414    m_cpt_iotlbmiss_transaction     = 0;   
415    m_cost_iotlbmiss_transaction    = 0;   
416}
417
[712]418////////////////////////////////////
419tmpl(bool)::is_wti(vci_addr_t paddr)
420////////////////////////////////////
421{
422    uint32_t addr32 = (uint32_t)paddr;
423    uint32_t base   = r_xicu_base.read();
424    uint32_t size   = r_xicu_size.read();
425    return ( (addr32 >= base) and (addr32 < (base + size)) ); 
426}
427
[240]428/////////////////////////
429tmpl(void)::transition()
430/////////////////////////
431{
432    if ( not p_resetn.read() ) 
433    {
[434]434        r_dma_cmd_fsm      = DMA_CMD_IDLE;
[712]435        r_dma_rsp_fsm      = DMA_RSP_IDLE_DMA;
[434]436        r_tlb_fsm              = TLB_IDLE;
437        r_config_cmd_fsm   = CONFIG_CMD_IDLE;
[712]438        r_config_rsp_fsm   = CONFIG_RSP_IDLE_IOX;
[434]439        r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE;
[240]440
[434]441        r_tlb_buf_valid    = false; 
442                r_iommu_active     = false;
443                r_iommu_wti_enable = false;
[712]444
445        r_xicu_size        = 0;
446        r_xicu_base        = 0;
447
[240]448        // initializing FIFOs
449        m_dma_cmd_addr_fifo.init();
450        m_dma_cmd_srcid_fifo.init();
451        m_dma_cmd_trdid_fifo.init();
452        m_dma_cmd_pktid_fifo.init();
453        m_dma_cmd_be_fifo.init();
454        m_dma_cmd_cmd_fifo.init();
455        m_dma_cmd_contig_fifo.init();
456        m_dma_cmd_data_fifo.init();
457        m_dma_cmd_eop_fifo.init();
458        m_dma_cmd_cons_fifo.init();
459        m_dma_cmd_plen_fifo.init();
460        m_dma_cmd_wrap_fifo.init();
461        m_dma_cmd_cfixed_fifo.init();
462        m_dma_cmd_clen_fifo.init();
463       
464        m_dma_rsp_rsrcid_fifo.init();
465        m_dma_rsp_rtrdid_fifo.init();
466        m_dma_rsp_rpktid_fifo.init();
467        m_dma_rsp_data_fifo.init();
468        m_dma_rsp_rerror_fifo.init();
469        m_dma_rsp_reop_fifo.init();
470       
471        m_config_cmd_addr_fifo.init();
472        m_config_cmd_srcid_fifo.init();
473        m_config_cmd_trdid_fifo.init();
474        m_config_cmd_pktid_fifo.init();
475        m_config_cmd_be_fifo.init();
476        m_config_cmd_cmd_fifo.init();
477        m_config_cmd_contig_fifo.init();
478        m_config_cmd_data_fifo.init();
479        m_config_cmd_eop_fifo.init();
480        m_config_cmd_cons_fifo.init();
481        m_config_cmd_plen_fifo.init();
482        m_config_cmd_wrap_fifo.init();
483        m_config_cmd_cfixed_fifo.init();
484        m_config_cmd_clen_fifo.init();
485       
[712]486        m_miss_wti_cmd_addr_fifo.init();
487        m_miss_wti_cmd_srcid_fifo.init();
488        m_miss_wti_cmd_trdid_fifo.init();
489        m_miss_wti_cmd_pktid_fifo.init();
490        m_miss_wti_cmd_be_fifo.init();
491        m_miss_wti_cmd_cmd_fifo.init();
492        m_miss_wti_cmd_contig_fifo.init();
493        m_miss_wti_cmd_data_fifo.init();
494        m_miss_wti_cmd_eop_fifo.init();
495        m_miss_wti_cmd_cons_fifo.init();
496        m_miss_wti_cmd_plen_fifo.init();
497        m_miss_wti_cmd_wrap_fifo.init();
498        m_miss_wti_cmd_cfixed_fifo.init();
499        m_miss_wti_cmd_clen_fifo.init();
500       
[240]501        m_config_rsp_rsrcid_fifo.init();
502        m_config_rsp_rtrdid_fifo.init();
503        m_config_rsp_rpktid_fifo.init();
504        m_config_rsp_data_fifo.init();
505        m_config_rsp_rerror_fifo.init();
506        m_config_rsp_reop_fifo.init();
507       
[434]508        // SET/RESET Communication flip-flops
[712]509        r_dma_cmd_to_miss_wti_cmd_req  = false;
510        r_dma_cmd_to_dma_rsp_req       = false;
511        r_dma_cmd_to_tlb_req               = false;
512        r_config_cmd_to_tlb_req            = false;
513        r_config_cmd_to_config_rsp_req = false;
514        r_tlb_to_miss_wti_cmd_req      = false;
515        r_miss_wti_rsp_to_dma_rsp_req  = false;
[240]516
[712]517        // error flip_flops
518        r_miss_wti_rsp_error_miss      = false;
519        r_miss_wti_rsp_error_wti       = false;
520
[434]521        // Debug variable
[712]522                m_debug_activated                  = false;
[240]523       
524            // activity counters
[712]525            m_cpt_total_cycles             = 0;
526        m_cpt_iotlb_read               = 0;             
527        m_cpt_iotlb_miss               = 0;             
528        m_cpt_iotlbmiss_transaction    = 0;   
529        m_cost_iotlbmiss_transaction   = 0;   
[240]530       
[712]531        m_cpt_trt_dma_full             = 0;
532        m_cpt_trt_dma_full_cost        = 0;
533        m_cpt_trt_config_full          = 0;
534        m_cpt_trt_config_full_cost     = 0;
[240]535
536        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_cmd            [i]   = 0;
537        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_rsp            [i]   = 0;
[434]538        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_tlb                [i]   = 0;
[240]539        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_cmd         [i]   = 0;
540        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_rsp         [i]   = 0;
[434]541        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_rsp       [i]   = 0;
542
[240]543        return;
544    }
545
[712]546    // default values for the 5 FIFOs
547    bool            dma_cmd_fifo_put          = false;
548    bool            dma_cmd_fifo_get          = p_vci_ini_ram.cmdack.read();
[240]549   
[712]550    bool            dma_rsp_fifo_put          = false; 
551    bool            dma_rsp_fifo_get          = p_vci_tgt_iox.rspack.read();
552    vci_rerror_t    dma_rsp_fifo_rerror       = 0;
553    vci_srcid_t     dma_rsp_fifo_rsrcid       = 0;
554    vci_trdid_t     dma_rsp_fifo_rtrdid       = 0;
555    vci_pktid_t     dma_rsp_fifo_rpktid       = 0;
556    ext_data_t      dma_rsp_fifo_rdata        = 0;
557    bool            dma_rsp_fifo_reop         = false;
[240]558
[712]559    bool            config_cmd_fifo_put       = false;
560    bool            config_cmd_fifo_get       = p_vci_ini_iox.cmdack.read();
[434]561
[712]562    bool            config_rsp_fifo_put       = false;
563    bool            config_rsp_fifo_get       = p_vci_tgt_int.rspack.read();
564    vci_rerror_t    config_rsp_fifo_rerror    = 0;
565    vci_srcid_t     config_rsp_fifo_rsrcid    = 0;
566    vci_trdid_t     config_rsp_fifo_rtrdid    = 0;
567    vci_pktid_t     config_rsp_fifo_rpktid    = 0;
568    ext_data_t      config_rsp_fifo_rdata     = 0;
569    bool            config_rsp_fifo_reop      = false;
570
571    bool            miss_wti_cmd_fifo_put     = false;
572    bool            miss_wti_cmd_fifo_get     = p_vci_ini_int.cmdack.read();
573    vci_addr_t      miss_wti_cmd_fifo_address = 0;
574    vci_cmd_t       miss_wti_cmd_fifo_cmd     = 0;
575    vci_srcid_t     miss_wti_cmd_fifo_srcid   = 0;
576    vci_trdid_t     miss_wti_cmd_fifo_trdid   = 0;
577    vci_pktid_t     miss_wti_cmd_fifo_pktid   = 0;
578    int_data_t      miss_wti_cmd_fifo_wdata   = 0;
579
[240]580#ifdef INSTRUMENTATION
581    m_cpt_fsm_dma_cmd           [r_dma_cmd_fsm.read()] ++;
582    m_cpt_fsm_dma_rsp           [r_dma_rsp_fsm.read() ] ++;
[434]583    m_cpt_fsm_tlb                   [r_tlb_fsm.read() ] ++;
[240]584    m_cpt_fsm_config_cmd            [r_config_cmd_fsm.read() ] ++;
585    m_cpt_fsm_config_rsp            [r_config_rsp_fsm.read() ] ++;
[434]586    m_cpt_fsm_miss_wti_rsp      [r_miss_wti_rsp_fsm.read() ] ++;
[240]587#endif
588
589    m_cpt_total_cycles++;
590
[434]591    m_debug_activated  = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
[240]592
[434]593    //////////////////////////////////////////////////////////////////////////////
[712]594    // The DMA_CMD_FSM handles transactions requested by peripherals.
595    // - it can be DMA transactions to RAM network (DMA_REQ state).
596    // - it can be WTI transactions to INT network (EXT_WTI_REQ state).
597    // It makes the address translation if IOMMU is activated, requesting
598    // the TLB_MISS FSM in case of TLB miss (TLB_MISS_WAIT state).
599    // When the IOMMU is activated, a DMA request can fail in two cases:
600    // - write to a read-only address : detected in IDLE state
601    // - virtual address unmapped     : detected in MISS_WAIT state
602    // In both cases of violation, the DMA_CMD FSM makes the following actions :
603    // 1. register the error in r_iommu_*** registers
604    // 2. wait the faulty command EOP (ERR_WAIT_EOP state)
605    // 3. request a IOMMU WTI to MISS_WTI FSM, (ERR_WTI_REQ state)
606    // 4. request a response error to DMA_RSP FSM (ERR_RSP_REQ state)
[240]607    ///////////////////////////////////////////////////////////////////////////////
608
609    switch( r_dma_cmd_fsm.read() ) 
610    {
[434]611    //////////////////
[712]612    case DMA_CMD_IDLE:  // wait a DMA or WTI VCI transaction and route it
613                        // after an IOMMU translation if IOMMU activated.
614                        // no VCI flit is consumed in this state
[240]615    {
[712]616        if ( p_vci_tgt_iox.cmdval.read() ) 
[240]617        { 
[434]618            if ( not r_iommu_active.read() )    // tlb not activated
[240]619            {
[712]620                // save paddr address
621                r_dma_cmd_paddr = p_vci_tgt_iox.address.read();
622
623                // analyse paddr for WTI/DMA routing
624                // WTI requests must be single flit (READ or WRITE)
625                if ( is_wti( p_vci_tgt_iox.address.read() ) )
626                {
627                    assert( p_vci_tgt_iox.eop.read() and
628                    "ERROR in VCI_IOB illegal VCI WTI command from IOX network");
629
630                    r_dma_cmd_fsm = DMA_CMD_WTI_IOX_REQ;
631                }
632                else
633                {
634                    r_dma_cmd_fsm = DMA_CMD_DMA_REQ;
635                }
636
[434]637#if DEBUG_DMA_CMD
638if( m_debug_activated )
[713]639std::cout << "  <IOB DMA_CMD_IDLE> DMA command"
[712]640          << " : address = " << std::hex << p_vci_tgt_iox.address.read()
[585]641          << " / srcid = " << p_vci_tgt_iox.srcid.read()
642          << " / wdata = " << std::hex << p_vci_tgt_iox.wdata.read()
643          << " / plen = " << std::dec << p_vci_tgt_iox.plen.read()
644          << " / eop = " << p_vci_tgt_iox.eop.read() << std::endl;
[434]645#endif
[240]646            }
[434]647            else if (r_tlb_fsm.read() == TLB_IDLE ||
648                     r_tlb_fsm.read() == TLB_WAIT )       // tlb access possible
[240]649            {
[434]650                vci_addr_t      iotlb_paddr;
[240]651                pte_info_t  iotlb_flags; 
652                size_t      iotlb_way; 
653                size_t      iotlb_set;
[434]654                vci_addr_t  iotlb_nline;
655                bool            iotlb_hit; 
[240]656
657#ifdef INSTRUMENTATION
658m_cpt_iotlb_read++;
659#endif
[434]660                iotlb_hit = r_iotlb.translate(p_vci_tgt_iox.address.read(),
661                                              &iotlb_paddr,
662                                              &iotlb_flags,
663                                              &iotlb_nline,  // unused
664                                              &iotlb_way,        // unused
665                                              &iotlb_set );  // unused
[240]666           
[434]667                if ( iotlb_hit )                                     // tlb hit
[240]668                { 
[434]669                    if ( not iotlb_flags.w and    // access right violation
670                        (p_vci_tgt_iox.cmd.read() == vci_param_ext::CMD_WRITE) ) 
[240]671                    {
[712]672                        // register error
[434]673                        r_iommu_etr      = MMU_WRITE_ACCES_VIOLATION; 
674                        r_iommu_bvar     = p_vci_tgt_iox.address.read();
675                        r_iommu_bad_id   = p_vci_tgt_iox.srcid.read();
[712]676                       
677                        // prepare response error request to DMA_RSP FSM
678                        r_dma_cmd_to_dma_rsp_rsrcid = p_vci_tgt_iox.srcid.read();
679                        r_dma_cmd_to_dma_rsp_rtrdid = p_vci_tgt_iox.trdid.read();
680                        r_dma_cmd_to_dma_rsp_rpktid = p_vci_tgt_iox.pktid.read();
681
682                        // jumps IOMMU error sequence
683                        r_dma_cmd_fsm = DMA_CMD_ERR_WAIT_EOP;
[240]684#if DEBUG_DMA_CMD
[434]685if( m_debug_activated )
686std::cout << "  <IOB DMA_CMD_IDLE> TLB HIT but writable violation" << std::endl;
[240]687#endif
688                    }
[434]689                    else                         // no access rights violation
690                    {
691#if DEBUG_DMA_CMD
692if( m_debug_activated )
693std::cout << "  <IOB DMA_CMD_IDLE> TLB HIT" << std::endl;
694#endif
[712]695                        // save paddr address
696                        r_dma_cmd_paddr = iotlb_paddr;
697
698                        // analyse address for WTI/DMA routing
699                        if ( is_wti( iotlb_paddr ) )
700                        {
701                            assert( p_vci_tgt_iox.eop.read() and
702                                   (p_vci_tgt_iox.cmd == vci_param_int::CMD_WRITE) and
703                            "ERROR in VCI_IOB illegal VCI WTI command from IOX network");
704
705                            r_dma_cmd_fsm   = DMA_CMD_WTI_IOX_REQ; 
706                        }
707                        else
708                        {
709                            r_dma_cmd_fsm = DMA_CMD_DMA_REQ;
710                        }
[434]711                    }
[240]712                }
[434]713                else                                             // TLB miss
[240]714                {
715
716#ifdef INSTRUMENTATION
717m_cpt_iotlb_miss++;
718#endif
[712]719                    // register virtual address, and send request to TLB FSM
720                            r_dma_cmd_to_tlb_vaddr = p_vci_tgt_iox.address.read();
721                    r_dma_cmd_to_tlb_req   = true;
722                    r_dma_cmd_fsm          = DMA_CMD_TLB_MISS_WAIT;
[240]723#if DEBUG_DMA_CMD
[434]724if( m_debug_activated )
725std::cout << "  <IOB DMA_CMD_IDLE> TLB MISS" << std::endl;
[240]726#endif
[712]727                } // end tlb miss
[240]728            } // end if tlb_activated
729        } // end if cmdval
730        break;
731    }
[712]732    /////////////////////
733    case DMA_CMD_DMA_REQ:    // put a flit in DMA_CMD FIFO
734                             // if contig, VCI address must be incremented
735                             // after initial translation by IOMMU.
736                             // flit is consumed if DMA_CMD FIFO not full
[240]737    {
[434]738        if ( p_vci_tgt_iox.cmdval && m_dma_cmd_addr_fifo.wok() ) 
[240]739        {
[434]740            dma_cmd_fifo_put = true;
741           
742            if ( p_vci_tgt_iox.contig.read() ) r_dma_cmd_paddr = r_dma_cmd_paddr.read() + 
743                                                          vci_param_ext::B;
[240]744
[434]745            if ( p_vci_tgt_iox.eop.read() )    r_dma_cmd_fsm   = DMA_CMD_IDLE;
746           
[240]747#if DEBUG_DMA_CMD
[434]748if( m_debug_activated ) 
749std::cout << "  <IOB DMA_CMD_FIFO_PUT_CMD> Push into DMA_CMD fifo:" 
750          << " address = " << std::hex << r_dma_cmd_paddr.read()
751          << " srcid = " << p_vci_tgt_iox.srcid.read()
752          << " wdata = " << p_vci_tgt_iox.wdata.read()
[712]753          << " plen = " << std::dec << p_vci_tgt_iox.plen.read()
754          << " eop = " << std::dec << p_vci_tgt_iox.eop.read() << std::endl;
[240]755#endif
756        }
757        break;
758    }
[712]759    /////////////////////////
760    case DMA_CMD_WTI_IOX_REQ:    // post a WTI_IOX request to MISS_WTI FSM
761                                 // if no prending previous request
762                                 // command arguments are stored in dedicated registers
763                                 // VCI flit is consumed if no previous request
[240]764    {
[712]765        if ( not r_dma_cmd_to_miss_wti_cmd_req.read() )  // no previous pending request
766        {
767            r_dma_cmd_to_miss_wti_cmd_req   = true;
768            r_dma_cmd_to_miss_wti_cmd_addr  = p_vci_tgt_iox.address.read();
769            r_dma_cmd_to_miss_wti_cmd_cmd   = p_vci_tgt_iox.cmd.read();
770            r_dma_cmd_to_miss_wti_cmd_wdata = (uint32_t)p_vci_tgt_iox.wdata.read();
771            r_dma_cmd_to_miss_wti_cmd_srcid = p_vci_tgt_iox.srcid.read();
772            r_dma_cmd_to_miss_wti_cmd_trdid = p_vci_tgt_iox.trdid.read();
773            r_dma_cmd_to_miss_wti_cmd_pktid = PKTID_WTI_IOX;
774
775            r_dma_cmd_fsm = DMA_CMD_IDLE;
776           
777#if DEBUG_DMA_CMD
778if( m_debug_activated ) 
779std::cout << "  <IOB DMA_CMD_WTI_IOX_REQ> request WTI transaction from ext peripheral"
780          << " : address = " << std::hex << r_dma_cmd_paddr.read()
781          << " / srcid = " << p_vci_tgt_iox.srcid.read()
782          << " / wdata = " << p_vci_tgt_iox.wdata.read() << std::endl;
783#endif
784        }
[240]785        break;
786    }
[434]787    //////////////////////////
[712]788    case DMA_CMD_ERR_WAIT_EOP:   // wait EOP before requesting WTI & error response
789                                 // VCI flit is always consumed
[240]790    {
[712]791        if ( p_vci_tgt_iox.eop.read() ) r_dma_cmd_fsm = DMA_CMD_ERR_WTI_REQ;
792
793#if DEBUG_DMA_CMD
794if( m_debug_activated ) 
795std::cout << "  <IOB DMA_CMD_WAIT_EOP> wait EOP for faulty DMA command" << std::endl;
796#endif
797        break;
798    }
799   
800    /////////////////////////
801    case DMA_CMD_ERR_WTI_REQ:    // post a WTI_MMU request to MISS_WTI_CMD FSM
802                                 // if no prending previous request
803                                 // response arguments are stored in dedicated registers
804                                 // no VCI flit is consumed
805    {
806        if ( not r_dma_cmd_to_miss_wti_cmd_req.read() )  // no pending previous request
[240]807        {
[712]808            r_dma_cmd_to_miss_wti_cmd_req   = true;
809            r_dma_cmd_to_miss_wti_cmd_addr  = (vci_addr_t)r_iommu_wti_addr_lo.read() |
810                                              (((vci_addr_t)r_iommu_wti_addr_hi.read())<<32);
811            r_dma_cmd_to_miss_wti_cmd_wdata = 0;
812            r_dma_cmd_to_miss_wti_cmd_srcid = m_int_srcid;
813            r_dma_cmd_to_miss_wti_cmd_trdid = 0;
814            r_dma_cmd_to_miss_wti_cmd_pktid = PKTID_WTI_MMU;
[434]815
[712]816            r_dma_cmd_fsm            = DMA_CMD_ERR_RSP_REQ;
[240]817
818#if DEBUG_DMA_CMD
[434]819if( m_debug_activated ) 
[712]820std::cout << "  <IOB DMA_CMD_ERR_WTI_REQ> request an IOMMU WTI" << std::endl;
[240]821#endif
822        }
823        break;
824    }
[712]825    /////////////////////////
826    case DMA_CMD_ERR_RSP_REQ:    // post an error response request to DMA_RSP FSM
827                                 // if no prending previous request
828                                 // response arguments are stored in dedicated registers
829                                 // no VCI flit is consumed
[240]830    {
[712]831        if ( not r_dma_cmd_to_dma_rsp_req.read() )  // no pending previous request
[240]832        {
[712]833            r_dma_cmd_to_dma_rsp_req    = true;
834            r_dma_cmd_to_dma_rsp_rerror = 0x1;
835            r_dma_cmd_to_dma_rsp_rdata  = 0;
836        }
837        break;
838    }
839    ///////////////////////////
840    case DMA_CMD_TLB_MISS_WAIT:  // waiting completion of a TLB miss
841                                 // we must test a possible page fault error...   
842    {
843        if ( not r_dma_cmd_to_tlb_req.read() ) // TLB miss completed
844        {
[434]845            if ( r_tlb_miss_error.read() )   // Error reported by TLB FSM
[240]846            {
[434]847                r_iommu_etr     = MMU_READ_PT2_UNMAPPED; 
[712]848                r_iommu_bvar    = r_dma_cmd_to_tlb_vaddr.read();
[434]849                r_iommu_bad_id  = p_vci_tgt_iox.srcid.read();
[712]850                r_dma_cmd_fsm   = DMA_CMD_ERR_WAIT_EOP;
[240]851            }
[434]852            else                            // No error
853            {
854                r_dma_cmd_fsm   = DMA_CMD_IDLE;
855            }
[240]856        }
857        break;
858    }
[434]859    } // end switch DMA_CMD FSM
[240]860
[712]861    ////////////////////////////////////////////////////////////////////////////////
862    // The DMA_RSP_FSM controls access to the DMA_RSP FIFO to the IOX network.
863    // There exist 3 "clients" to send VCI responses on the IOX network:
864    // - request from p_vci_ini_ram    : normal DMA response from RAM network,
865    // - request from MISS_WTI_RSP FSM : normal WTI response from INT network,
866    // - request from DMA_CMD FSM      : bad address error response
867    // This FSM implements a round robin priority, with a "dead cycle" between
868    // two transactions. It could be optimized if throughput is critical...
869    ////////////////////////////////////////////////////////////////////////////////
[434]870
[712]871    // does nothing if FIFO is full
872    if ( m_dma_rsp_rerror_fifo.wok() )
[240]873    {
[712]874        switch( r_dma_rsp_fsm.read() ) 
875        {
876            //////////////////////
877            case DMA_RSP_IDLE_DMA:  // normal DMA response has highest priority
878            {           
879                if     (p_vci_ini_ram.rspval.read())          r_dma_rsp_fsm = DMA_RSP_PUT_DMA;
880                else if(r_miss_wti_rsp_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_WTI;
881                else if(r_dma_cmd_to_dma_rsp_req.read())      r_dma_rsp_fsm = DMA_RSP_PUT_ERR;
882                break;
883            }
884            //////////////////////
885            case DMA_RSP_IDLE_WTI:  // normal WTI response has highest priority
886            {           
887                if     (r_miss_wti_rsp_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_WTI; 
888                else if(r_dma_cmd_to_dma_rsp_req.read())      r_dma_rsp_fsm = DMA_RSP_PUT_ERR;
889                else if(p_vci_ini_ram.rspval.read())          r_dma_rsp_fsm = DMA_RSP_PUT_DMA;
890                break;
891            }
892            //////////////////////
893            case DMA_RSP_IDLE_ERR:  // error  response has highest priority
894            {           
895                if     (r_dma_cmd_to_dma_rsp_req.read())      r_dma_rsp_fsm = DMA_RSP_PUT_ERR;
896                else if(p_vci_ini_ram.rspval.read())          r_dma_rsp_fsm = DMA_RSP_PUT_DMA;
897                else if(r_miss_wti_rsp_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_WTI; 
898                break;
899            }
900            ///////////////////////
901            case DMA_RSP_PUT_DMA:  // put one flit of the DMA response into FIFO
902            {           
903                dma_rsp_fifo_put    = true;
904                dma_rsp_fifo_rerror = p_vci_ini_ram.rerror.read();
905                dma_rsp_fifo_rdata  = p_vci_ini_ram.rdata.read();
906                dma_rsp_fifo_rsrcid = p_vci_ini_ram.rsrcid.read();
907                dma_rsp_fifo_rtrdid = p_vci_ini_ram.rtrdid.read();
908                dma_rsp_fifo_rpktid = p_vci_ini_ram.rpktid.read();
909                dma_rsp_fifo_reop   = p_vci_ini_ram.reop.read();
[240]910
[712]911                // update priority
912                if ( p_vci_ini_ram.reop.read() ) r_dma_rsp_fsm = DMA_RSP_IDLE_WTI;
[240]913
914#if DEBUG_DMA_RSP
[434]915if( m_debug_activated ) 
[712]916std::cout << "  <IOB DMA_RSP_PUT_DMA> Push DMA response into DMA_RSP FIFO" 
917          << " : rsrcid = " << std::hex << p_vci_ini_ram.rsrcid.read()
[434]918          << " / rtrdid = " << p_vci_ini_ram.rtrdid.read()
[712]919          << " / rpktid = " << p_vci_ini_ram.rpktid.read()
920          << " / rdata = "  << p_vci_ini_ram.rdata.read()
[434]921          << " / rerror = " << p_vci_ini_ram.rerror.read()
[712]922          << " / reop = "   << p_vci_ini_ram.reop.read() << std::endl;
[240]923#endif
[712]924                break;
925                    }
926            ///////////////////////
927            case DMA_RSP_PUT_WTI:  // put single flit WTI response into FIFO
928            {           
929                dma_rsp_fifo_put    = true;
930                dma_rsp_fifo_rerror = r_miss_wti_rsp_to_dma_rsp_rerror.read();
931                dma_rsp_fifo_rdata  = 0;
932                dma_rsp_fifo_rsrcid = r_miss_wti_rsp_to_dma_rsp_rsrcid.read();
933                dma_rsp_fifo_rtrdid = r_miss_wti_rsp_to_dma_rsp_rtrdid.read();
934                dma_rsp_fifo_rpktid = r_miss_wti_rsp_to_dma_rsp_rpktid.read();
935                dma_rsp_fifo_reop   = true;
[240]936
[712]937                // acknowledge request
938                r_miss_wti_rsp_to_dma_rsp_req = false;
939 
940                // update priority
941                r_dma_rsp_fsm = DMA_RSP_IDLE_ERR;
942
943#if DEBUG_DMA_RSP
944if( m_debug_activated ) 
945std::cout << "  <IOB DMA_RSP_PUT_WTI> Push WTI response into DMA_RSP FIFO" 
946          << " : rsrcid = " << std::hex << r_miss_wti_rsp_to_dma_rsp_rsrcid.read()
947          << " / rtrdid = " << r_miss_wti_rsp_to_dma_rsp_rtrdid.read()
948          << " / rpktid = " << r_miss_wti_rsp_to_dma_rsp_rpktid.read()
949          << " / rdata = "  << 0
950          << " / rerror = " << r_miss_wti_rsp_to_dma_rsp_rerror.read()
951          << " / reop = "   << true << std::endl;
952#endif
953                break;
954            }
955            ///////////////////////
956            case DMA_RSP_PUT_ERR:  // put sinfle flit error response into FIFO
957            {
958                dma_rsp_fifo_put    = true;
959                dma_rsp_fifo_rerror = 0x1;
960                dma_rsp_fifo_rdata  = 0;
961                dma_rsp_fifo_rsrcid = r_dma_cmd_to_dma_rsp_rsrcid.read();
962                dma_rsp_fifo_rtrdid = r_dma_cmd_to_dma_rsp_rtrdid.read();
963                dma_rsp_fifo_rpktid = r_dma_cmd_to_dma_rsp_rpktid.read();
964                dma_rsp_fifo_reop   = true;
965
966                // acknowledge request
967                r_dma_cmd_to_dma_rsp_req = false;
968 
969                // update priority
970                r_dma_rsp_fsm = DMA_RSP_PUT_DMA;
971
972#if DEBUG_DMA_RSP
973if( m_debug_activated ) 
974std::cout << "  <IOB DMA_RSP_PUT_DMA> Push IOMMU ERROR response into DMA_RSP FIFO" 
975          << " : rsrcid = " << std::hex << r_dma_cmd_to_dma_rsp_rsrcid.read()
976          << " / rtrdid = " << r_dma_cmd_to_dma_rsp_rtrdid.read()
977          << " / rpktid = " << r_dma_cmd_to_dma_rsp_rpktid.read()
978          << " / rdata = "  << 0
979          << " / rerror = " << r_dma_cmd_to_dma_rsp_rerror.read()
980          << " / reop = "   << true << std::endl;
981#endif
982                break;
983            }
984                } // end switch DMA_RSP FSM
985    }  // end if FIFO full
986
987
[434]988    //////////////////////////////////////////////////////////////////////////////////
[712]989    // The TLB FSM handles the TLB miss requests from DMA_CMD FSM,
[434]990    // and the PTE inval request (from CONFIG_CMD FSM).
991    // PTE inval request have highest priority. In case of TLB miss,
992    // this fsm searchs the requested PTE on the prefetch buffer.
993    // In case of buffer miss,  it request the MISS_WTI FSM to access the memory.
[240]994    // It bypass the first level page table access if possible.
[712]995    // It reset the r_dma_cmd_to_tlb_req flip-flop to signal TLB miss completion.
[434]996    // An unexpected, but possible page fault is signaled in r_tlb_miss_error flip_flop.
[240]997    ////////////////////////////////////////////////////////////////////////////////////
[434]998
999    switch (r_tlb_fsm.read())
[240]1000    {
[434]1001    //////////////
1002    case TLB_IDLE:   // In case of TLB miss request, chek the prefetch buffer first
1003                     // PTE inval request are handled as unmaskable interrupts
[240]1004    {
[712]1005        if ( r_config_cmd_to_tlb_req.read() ) // Request for a PTE invalidation
[240]1006        {
[712]1007            r_config_cmd_to_tlb_req  = false;
1008            r_waiting_transaction    = false;
1009            r_tlb_fsm                = TLB_INVAL_CHECK;
[240]1010        }
[434]1011
[712]1012        else if ( r_dma_cmd_to_tlb_req.read() )   // request for a TLB Miss
[240]1013        {
[434]1014            // Checking prefetch buffer
1015            if( not r_tlb_buf_big_page )     // small page => PTE2
[240]1016            {
[434]1017                if( r_tlb_buf_valid &&         // Hit on prefetch buffer
1018                    (r_tlb_buf_vaddr.read() == 
[712]1019                    (r_dma_cmd_to_tlb_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK)))
[434]1020                {
[712]1021                    size_t   pte_offset = (r_dma_cmd_to_tlb_vaddr.read()& PTE2_LINE_OFFSET)>>12; 
[434]1022                    uint32_t pte_flags  = r_tlb_buf_data[2*pte_offset];
1023                    uint32_t pte_ppn    = r_tlb_buf_data[2*pte_offset+1]; 
[240]1024               
[434]1025                    // Bit valid checking
1026                    if ( not ( pte_flags & PTE_V_MASK) )        // unmapped
1027                    {
1028                        std::cout << "VCI_IO_BRIDGE ERROR : " << name() 
1029                                  << " Page Table entry unmapped" << std::endl;
[240]1030                       
[434]1031                        r_tlb_miss_error = true;
[712]1032                        r_dma_cmd_to_tlb_req    = false;
[434]1033#if DEBUG_TLB_MISS
1034if ( m_debug_activated )
1035std::cout << "  <IOB TLB_IDLE> PTE2 Unmapped" << std::hex
1036          << " / paddr = " << r_tlb_paddr.read()
1037          << " / PTE_FLAGS = " << pte_flags
1038          << " / PTE_PPN = " << pte_ppn << std::endl;
[240]1039#endif
[434]1040                        break; 
1041                    }
[240]1042
[434]1043                    // valid PTE2 : we must update the TLB
1044                    r_tlb_pte_flags = pte_flags; 
1045                    r_tlb_pte_ppn   = pte_ppn;
1046                    r_tlb_fsm       = TLB_PTE2_SELECT;
1047#if DEBUG_TLB_MISS
1048if ( m_debug_activated )
1049std::cout << "  <IOB TLB_IDLE> Hit on prefetch buffer: PTE2" << std::hex
1050          << " / PTE_FLAGS = " << pte_flags
1051          << " / PTE_PPN = " << pte_ppn << std::endl;
[240]1052#endif
[434]1053                    break;   
1054                }
[240]1055            }
[434]1056            else                             // big page => PTE1
[240]1057            {
[434]1058                if( r_tlb_buf_valid &&         // Hit on prefetch buffer
1059                    (r_tlb_buf_vaddr.read() == 
[712]1060                    (r_dma_cmd_to_tlb_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 
[434]1061                {
[712]1062                    size_t   pte_offset = (r_dma_cmd_to_tlb_vaddr.read()& PTE1_LINE_OFFSET)>>21; 
[434]1063                    uint32_t pte_flags  = r_tlb_buf_data[pte_offset];
[240]1064                           
[434]1065                    // Bit valid checking
1066                    if ( not ( pte_flags & PTE_V_MASK) )        // unmapped
1067                    {
1068                        std::cout << "VCI_IO_BRIDGE ERROR : " << name() 
1069                                  << " Page Table entry unmapped" << std::endl;
[240]1070                       
[434]1071                        r_tlb_miss_error = true;
[712]1072                        r_dma_cmd_to_tlb_req    = false;
[434]1073#if DEBUG_TLB_MISS
1074if ( m_debug_activated )
1075std::cout << "  <IOB TLB_IDLE> PTE1 Unmapped" << std::hex
1076          << " / paddr = " << r_tlb_paddr.read()
1077          << " / PTE = " << pte_flags << std::endl;
[240]1078#endif
[434]1079                        break; 
1080                    }
[240]1081
[434]1082                    // valid PTE1 : we must update the TLB
1083                    r_tlb_pte_flags = pte_flags;
1084                    r_tlb_fsm       = TLB_PTE1_SELECT;
1085#if DEBUG_TLB_MISS
1086if ( m_debug_activated )
1087std::cout << "  <IOB TLB_PTE1_GET> Hit on prefetch buffer: PTE1" << std::hex
1088          << " / paddr = " << r_tlb_paddr.read()
1089          << std::hex << " / PTE1 = " << pte_flags << std::endl;
[240]1090#endif
[434]1091                    break;
[240]1092                }
1093            }
1094       
[434]1095            // prefetch buffer miss
1096            r_tlb_fsm = TLB_MISS; 
[240]1097
[434]1098#if DEBUG_TLB_MISS
1099if ( m_debug_activated )
1100std::cout << "  <IOB TLB_IDLE> Miss on prefetch buffer"
[712]1101          << std::hex << " / vaddr = " << r_dma_cmd_to_tlb_vaddr.read() << std::endl;
[240]1102#endif
1103        }
1104        break;
1105    }
[434]1106    //////////////
1107    case TLB_MISS: // handling tlb miss
[240]1108    {
[434]1109        uint32_t        ptba = 0; 
[240]1110        bool            bypass;
[434]1111        vci_addr_t      pte_paddr;
[240]1112
[434]1113#ifdef INSTRUMENTATION
1114m_cpt_iotlbmiss_transaction++;
1115#endif
[240]1116        // evaluate bypass in order to skip first level page table access
[712]1117        bypass = r_iotlb.get_bypass(r_dma_cmd_to_tlb_vaddr.read(), &ptba);
[240]1118       
[434]1119        // Request MISS_WTI_FSM a transaction on INT Network
[240]1120        if ( not bypass )     // Read PTE1/PTD1 in XRAM
1121        {
[434]1122
1123#if DEBUG_TLB_MISS
1124if ( m_debug_activated )
1125std::cout << "  <IOB TLB_MISS> Read PTE1/PTD1 in memory" << std::endl;
1126#endif
1127            pte_paddr = (vci_addr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) |
[712]1128                        (vci_addr_t)((r_dma_cmd_to_tlb_vaddr.read() >> PAGE_M_NBITS) << 2);
[434]1129            r_tlb_paddr = pte_paddr;
[240]1130           
[712]1131            r_tlb_to_miss_wti_cmd_req = true;
1132            r_tlb_miss_type           = PTE1_MISS;
1133            r_tlb_fsm                 = TLB_WAIT;
[240]1134        }
1135        else                  // Read PTE2 in XRAM
1136        {
[434]1137
1138#if DEBUG_TLB_MISS
1139if ( m_debug_activated )
1140std::cout << "  <IOB TLB_MISS> Read PTE2 in memory" << std::endl;
1141#endif
[240]1142            //&PTE2 = PTBA + IX2 * 8
[434]1143            pte_paddr = (vci_addr_t)ptba << PAGE_K_NBITS |
[712]1144                        (vci_addr_t)(r_dma_cmd_to_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
[240]1145           
[434]1146            r_tlb_paddr = pte_paddr;
[240]1147           
[712]1148            r_tlb_to_miss_wti_cmd_req = true;
1149            r_tlb_miss_type           = PTE2_MISS;
1150            r_tlb_fsm                 = TLB_WAIT;
[240]1151        }
1152
1153        break;
1154    }
[434]1155    ////////////////// 
1156    case TLB_PTE1_GET:  // Try to read a PT1 entry in the miss buffer
[240]1157    {
1158       
1159        uint32_t  entry;
1160       
[434]1161        vci_addr_t line_number  = (vci_addr_t)((r_tlb_paddr.read())&(CACHE_LINE_MASK));
1162        size_t word_position = (size_t)( ((r_tlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
[240]1163
1164        // Hit test. Just to verify.
1165        // Hit must happen, since we've just finished its' miss transaction
[434]1166        bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 
[240]1167        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
1168       
[434]1169        entry = r_tlb_buf_data[word_position];
[240]1170           
1171        // Bit valid checking
1172        if ( not ( entry & PTE_V_MASK) )        // unmapped
1173        {
1174            //must not occur!
[434]1175            std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl
[240]1176                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1177                       
[434]1178            r_tlb_miss_error       = true;
[712]1179            r_dma_cmd_to_tlb_req   = false;
1180            r_tlb_fsm              = TLB_IDLE;           
[434]1181
1182#if DEBUG_TLB_MISS
1183if ( m_debug_activated )
[240]1184{
[434]1185    std::cout << "  <IOB DMA_PTE1_GET> First level entry Unmapped"
1186              << std::hex << " / paddr = " << r_tlb_paddr.read()
[240]1187              << std::hex << " / PTE = " << entry << std::endl;
1188}
1189#endif
1190                    break; 
1191        }
1192   
1193        if( entry & PTE_T_MASK )        //  PTD : me must access PT2
1194        {
1195            // register bypass
[712]1196            r_iotlb.set_bypass( r_dma_cmd_to_tlb_vaddr.read(),
[434]1197                                entry & ((1 << (vci_param_int::N-PAGE_K_NBITS)) - 1), 
[240]1198                                0); //nline, unused
1199
[712]1200            // &PTE2 = PTBA + IX2 * 8
[240]1201            // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
[434]1202            r_tlb_paddr = (vci_addr_t)(entry & ((1<<(vci_param_int::N-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
[712]1203                                (vci_addr_t)(((r_dma_cmd_to_tlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
[434]1204
[712]1205            r_tlb_to_miss_wti_cmd_req = true;
1206            r_tlb_miss_type           = PTE2_MISS;
1207            r_tlb_fsm                 = TLB_WAIT;
1208
[240]1209#ifdef INSTRUMENTATION
1210m_cpt_iotlbmiss_transaction++;
1211#endif
1212
[434]1213#if DEBUG_TLB_MISS
1214if ( m_debug_activated )
1215std::cout << "  <IOB TLB_PTE1_GET> Success. Search PTE2" << std::hex
1216          << " / PADDR = " << r_tlb_paddr.read()
1217          << " / PTD = " << entry << std::endl;
[240]1218#endif
1219        }
1220        else                    //  PTE1 :  we must update the IOTLB
1221                        //  Should not occur if working only with small pages
1222        {
[434]1223            r_tlb_pte_flags   = entry;
1224            r_tlb_fsm  = TLB_PTE1_SELECT;
[240]1225
[434]1226#if DEBUG_TLB_MISS
1227if ( m_debug_activated )
1228std::cout << "  <IOB TLB_PTE1_GET> Success. Big page"
1229          << std::hex << " / paddr = " << r_tlb_paddr.read()
1230          << std::hex << " / PTE1 = " << entry << std::endl;
[240]1231#endif
1232        }
1233        break;
1234    }
[434]1235    /////////////////////
1236    case TLB_PTE1_SELECT:       // select a slot for PTE1
[240]1237    {
1238        size_t  way;
1239        size_t  set;
1240       
[712]1241        r_iotlb.select(  r_dma_cmd_to_tlb_vaddr.read(),
[240]1242                        true,  // PTE1
1243                        &way,
1244                        &set );
1245#ifdef INSTRUMENTATION
1246m_cpt_iotlb_read++;
1247#endif
1248
[434]1249#if DEBUG_TLB_MISS
1250if ( m_debug_activated )
1251std::cout << "  <IOB TLB_PTE1_SELECT> Select a slot in TLB"
1252          << " / way = " << std::dec << way
1253          << " / set = " << set << std::endl;
[240]1254#endif
[434]1255        r_tlb_way = way;
1256        r_tlb_set = set;
1257        r_tlb_fsm     = TLB_PTE1_UPDT;
[240]1258        break;
1259    }
[434]1260    ///////////////////
1261    case TLB_PTE1_UPDT:     // write a new PTE1 in tlb
1262                            // not necessary to treat the L/R bit
[240]1263    {
[434]1264        uint32_t  pte   = r_tlb_pte_flags.read();
[240]1265       
[434]1266        r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_flags.read() & PPN1_MASK) << 21)
[712]1267                        | (r_dma_cmd_to_tlb_vaddr.read()& M_PAGE_OFFSET_MASK) );
[240]1268       
1269        // update TLB
1270        r_iotlb.write( true,            // 2M page
1271                      pte,
1272                      0,                // argument unused for a PTE1
[712]1273                      r_dma_cmd_to_tlb_vaddr.read(),   
[434]1274                      r_tlb_way.read(), 
1275                      r_tlb_set.read(),
[240]1276                      0 );      //we set nline = 0
[712]1277
[240]1278#ifdef INSTRUMENTATION
1279m_cpt_iotlb_write++;
1280#endif
1281
[434]1282#if DEBUG_TLB_MISS
1283if ( m_debug_activated )
[240]1284{
[434]1285std::cout << "  <IOB TLB_PTE1_UPDT> write PTE1 in TLB"
1286          << " / set = " << std::dec << r_tlb_set.read()
1287          << " / way = " << r_tlb_way.read() << std::endl;
1288r_iotlb.printTrace();
[240]1289}
1290#endif
1291        // next state
[434]1292        r_tlb_fsm = TLB_RETURN; // exit sub-fsm
[240]1293        break;
1294    }
[434]1295    //////////////////
1296    case TLB_PTE2_GET:  // Try to read a PTE2 (64 bits) in the miss buffer
[240]1297    {   
1298        uint32_t        pte_flags;
1299        uint32_t        pte_ppn;
1300       
[434]1301        vci_addr_t line_number  = (vci_addr_t)((r_tlb_paddr.read())&(CACHE_LINE_MASK));
1302        size_t word_position = (size_t)( ((r_tlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
[240]1303       
1304       
1305        // Hit test. Just to verify.
[434]1306        bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 
[240]1307        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
[434]1308        pte_flags= r_tlb_buf_data[word_position];
1309        pte_ppn= r_tlb_buf_data[word_position+1]; //because PTE2 is 2 words long
[240]1310        // Bit valid checking
1311        if ( not ( pte_flags & PTE_V_MASK) )    // unmapped
1312        {
1313            //must not occur!
[434]1314            std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl
[240]1315                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1316                       
[434]1317            r_tlb_miss_error       = true;
[712]1318            r_dma_cmd_to_tlb_req         = false;
[434]1319            r_tlb_fsm             = TLB_IDLE;           
1320
1321#if DEBUG_TLB_MISS
1322if ( m_debug_activated )
1323std::cout << "  <IOB TLB_PTE2_GET> PTE2 Unmapped" << std::hex
1324          << " / PADDR = " << r_tlb_paddr.read()
1325          << " / PTE = " << pte_flags << std::endl;
[240]1326#endif
[434]1327            break; 
[240]1328        }
1329           
[434]1330        r_tlb_pte_flags       = pte_flags; 
1331        r_tlb_pte_ppn         = pte_ppn;
1332        r_tlb_fsm           = TLB_PTE2_SELECT;
[240]1333               
[434]1334#if DEBUG_TLB_MISS
1335if ( m_debug_activated )
1336std::cout << "  <IOB TLB_PTE2_GET> Mapped" << std::hex
1337          << " / PTE_FLAGS = " << pte_flags
1338          << " / PTE_PPN = " << pte_ppn << std::endl;
[240]1339#endif
1340        break;
1341    }
1342    ////////////////////////////
[434]1343    case TLB_PTE2_SELECT:    // select a slot for PTE2
[240]1344    {
1345        size_t way;
1346        size_t set;
1347
[712]1348        r_iotlb.select( r_dma_cmd_to_tlb_vaddr.read(),
[240]1349                        false,  // PTE2
1350                        &way,
1351                        &set );
1352#ifdef INSTRUMENTATION
1353m_cpt_iotlb_read++;
1354#endif
1355
[434]1356#if DEBUG_TLB_MISS
1357if ( m_debug_activated )
[712]1358std::cout << "  <IOB TLB_PTE2_SELECT> Select a slot in IOTLB:"
1359          << " way = " << std::dec << way
1360          << " / set = " << set << std::endl;
[240]1361#endif
[434]1362        r_tlb_way = way;
1363        r_tlb_set = set;
1364        r_tlb_fsm     = TLB_PTE2_UPDT;
[240]1365        break;
1366    }
[434]1367    ///////////////////
1368    case TLB_PTE2_UPDT:         // write a new PTE2 in tlb
1369                                // not necessary to treat the L/R bit
[240]1370    {
[434]1371        uint32_t        pte_flags = r_tlb_pte_flags.read();
1372        uint32_t        pte_ppn   = r_tlb_pte_ppn.read();
[240]1373       
[434]1374        r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_ppn.read() & PPN2_MASK) << 12)
[712]1375                        | (r_dma_cmd_to_tlb_vaddr.read()& K_PAGE_OFFSET_MASK) );
[240]1376       
1377        // update TLB for a PTE2
1378        r_iotlb.write( false,   // 4K page
1379                       pte_flags,
1380                       pte_ppn,
[712]1381                       r_dma_cmd_to_tlb_vaddr.read(),   
[434]1382                       r_tlb_way.read(), 
1383                       r_tlb_set.read(),
[240]1384                       0 );     // nline = 0
1385#ifdef INSTRUMENTATION
1386m_cpt_iotlb_write++;
1387#endif
1388
[434]1389#if DEBUG_TLB_MISS
1390if ( m_debug_activated )
[240]1391{
[712]1392std::cout << "  <IOB TLB_PTE2_UPDT> write PTE2 in IOTLB"
1393          << " / set = " << std::dec << r_tlb_set.read()
1394          << " / way = " << r_tlb_way.read() << std::endl;
1395r_iotlb.printTrace();
[240]1396}
1397#endif
1398        // next state
[434]1399        r_tlb_fsm = TLB_RETURN; 
[240]1400        break;
1401    }
[434]1402    //////////////
1403    case TLB_WAIT:   // waiting completion of a miss transaction from MISS_WTI FSM
1404                     // PTE inval request are handled as unmaskable interrupts
[240]1405    {
[712]1406        if ( r_config_cmd_to_tlb_req.read() ) // Request for a PTE invalidation
[240]1407        {
[712]1408            r_config_cmd_to_tlb_req = false;
1409            r_waiting_transaction   = true;
1410            r_tlb_fsm               = TLB_INVAL_CHECK;
[240]1411        }
1412
1413#ifdef INSTRUMENTATION
1414m_cost_iotlbmiss_transaction++;
1415#endif
[712]1416        if ( not r_tlb_to_miss_wti_cmd_req.read() )     //  Miss transaction completed
[240]1417        { 
[712]1418                if ( r_miss_wti_rsp_error_miss.read() ) // bus error reported
[240]1419                {
[712]1420                r_miss_wti_rsp_error_miss = false;
1421                r_tlb_miss_error          = true;
1422                r_dma_cmd_to_tlb_req      = false;
1423                r_tlb_fsm                 = TLB_IDLE;
[240]1424            }
1425            else if(r_tlb_miss_type == PTE1_MISS)
1426            {
[434]1427                r_tlb_fsm = TLB_PTE1_GET; 
[240]1428            }
1429            else
1430            {
[434]1431                r_tlb_fsm = TLB_PTE2_GET;
[240]1432            }
1433        }
1434        break;
1435    }
[434]1436    ////////////////
[712]1437    case TLB_RETURN:   // reset r_dma_cmd_to_tlb_req to signal TLB miss completion
1438                       // possible errors are signaled through r_tlb_miss_error
[240]1439    {
[434]1440#if DEBUG_TLB_MISS
1441if ( m_debug_activated )
1442std::cout << "  <IOB TLB_RETURN> IOTLB MISS completed" << std::endl;
[240]1443#endif
[712]1444        r_dma_cmd_to_tlb_req  = false;
[434]1445        r_tlb_fsm = TLB_IDLE;
[240]1446        break;
1447    }
[434]1448    /////////////////////
1449    case TLB_INVAL_CHECK:   // request from CONFIG_FSM to invalidate all PTE in a given line
1450                            // checks the necessity to invalidate prefetch buffer
[240]1451    {
1452        // If a transaction is pending, no need to invalidate the prefetch
1453        // We can ignore it, since we'll replace the line.
1454        // The new line is necessarily up-to-date
[434]1455        if(!r_waiting_transaction.read() && r_tlb_buf_valid)
[240]1456        {
[434]1457            if(!r_tlb_buf_big_page)
[240]1458            {
[434]1459               if( r_tlb_buf_vaddr.read() == 
[712]1460                   (r_config_cmd_to_tlb_vaddr.read()& ~PTE2_LINE_OFFSET) ) 
[240]1461                // The virtual address corresponds to one entry on the buffer line
1462                {
[434]1463                    r_tlb_buf_valid = false;   //change here for individual invalidation
[240]1464                }
1465            }
1466            else    // First level entries on buffer. Unused if only small pages
1467            {
[434]1468               if( r_tlb_buf_vaddr.read() == 
[712]1469                   (r_config_cmd_to_tlb_vaddr.read()& ~PTE1_LINE_OFFSET) ) 
[240]1470                // The virtual address corresponds to one entry on the buffer line
1471                {
[434]1472                    r_tlb_buf_valid = false;   //change here for individual invalidation
[240]1473                }
1474            }
1475        }
1476       
1477        // Invalidation on IOTLB
1478        bool    ok;
[712]1479        ok = r_iotlb.inval(r_config_cmd_to_tlb_vaddr.read());
[240]1480         
[434]1481        if(r_waiting_transaction.read()) r_tlb_fsm =TLB_WAIT; 
1482        else r_tlb_fsm = TLB_IDLE;
[240]1483        break; 
1484    }
[434]1485    } //end switch r_tlb_fsm
[240]1486   
[434]1487    ////////////////////////////////////////////////////////////////////////////////
1488    // The CONFIG_CMD_FSM handles the VCI commands from the INT network.
[712]1489    // - it can be single flit config transactions
1490    // - it can be multi-flits data transactions to ROM (read) or FBF (write).
[585]1491    // The write burst transactions must be serialised from 32 to 64 bits width.
[451]1492    // The configuration requests can be local (IO_BRIDGE config registers)
1493    // or remote (config registers of peripherals on IOX network).
[712]1494    // - The local configuration segment is identified by the "special" atribute
1495    //   in the mapping table.
[713]1496    // - All configuration requests are checked against segmentation violation.
[451]1497    // - In case of local config request, or in case of segmentation violation,
[712]1498    //   the FSM send a response request to CONFIG_RSP FSM.
[585]1499    // - In case of remote transaction, it put the VCI command in CONFIG_CMD fifo,
1500    //   and this require two cycles per IOX flit in case of write burst.
[434]1501    ///////////////////////////////////////////////////////////////////////////////
[240]1502
1503    switch( r_config_cmd_fsm.read() ) 
1504    {
[434]1505    /////////////////////
[585]1506    case CONFIG_CMD_IDLE:   // A VCI INT command is always consumed in this state
[240]1507    {
[434]1508        if ( p_vci_tgt_int.cmdval.read() ) 
[240]1509        {
[434]1510
[240]1511#if DEBUG_CONFIG_CMD
[434]1512if( m_debug_activated )
[585]1513std::cout << "  <IOB CONFIG_CMD_IDLE> ### Config Command received" << std::endl
1514          << "  address = " << std::hex << p_vci_tgt_int.address.read()
1515          << " / srcid = " << p_vci_tgt_int.srcid.read()
[434]1516          << " / trdid = " << p_vci_tgt_int.trdid.read()
1517          << " / wdata = " << std::hex << p_vci_tgt_int.wdata.read()
1518          << " / be = " << p_vci_tgt_int.be.read()
1519          << " / plen = " << std::dec << p_vci_tgt_int.plen.read()
1520          << " / eop = " << p_vci_tgt_int.eop.read() << std::endl;
[240]1521#endif
[434]1522            vci_addr_t paddr = p_vci_tgt_int.address.read();
1523            bool       read  = (p_vci_tgt_int.cmd.read() == vci_param_int::CMD_READ);
1524            uint32_t   cell  = (uint32_t)((paddr & 0x1FF)>>2); 
[585]1525            bool       eop   = p_vci_tgt_int.eop.read();
1526            bool       high  = (paddr & 0x4);
1527
[451]1528            // chek segments
1529            std::list<soclib::common::Segment>::iterator seg;
[549]1530            bool found   = false;
1531            bool special = false;
[451]1532            for ( seg = m_int_seglist.begin() ; 
1533                  seg != m_int_seglist.end() and not found ; seg++ )
1534            {
[549]1535                if ( seg->contains(paddr) ) 
1536                {
1537                   found   = true;
1538                   special = seg->special();
1539                }
[451]1540            }
[434]1541           
[549]1542            if ( found and special )  // IO_BRIDGE itself
[240]1543            {
[585]1544                bool rerror = false;
[434]1545
[585]1546                assert( (p_vci_tgt_int.be.read() == 0xF) and
[712]1547                "ERROR in vci_io_bridge : BE must be 0xF for a config access");
[585]1548
1549                assert( ( eop ) and
1550                "ERROR in vci_io_bridge : local config access must be one flit");
1551
[434]1552                if ( not read && (cell == IOB_IOMMU_PTPR) )       // WRITE PTPR
[240]1553                {
[434]1554                    r_iommu_ptpr = (uint32_t)p_vci_tgt_int.wdata.read();
1555                }
1556                else if ( read && (cell == IOB_IOMMU_PTPR) )      // READ PTPR
[240]1557                {
[712]1558                    r_config_cmd_to_config_rsp_rdata = r_iommu_ptpr.read();
[240]1559                }
[434]1560                else if( not read && (cell == IOB_WTI_ENABLE))  // WRITE WTI_ENABLE
[240]1561                {
[434]1562                    r_iommu_wti_enable = p_vci_tgt_int.wdata.read();
[240]1563                }
[434]1564                else if( read && (cell == IOB_WTI_ENABLE))       // READ WTI ENABLE
[240]1565                {
[712]1566                    r_config_cmd_to_config_rsp_rdata = r_iommu_wti_enable.read();
[240]1567                }
[434]1568                else if( read && (cell == IOB_IOMMU_BVAR))        // READ BVAR
[240]1569                {
[712]1570                    r_config_cmd_to_config_rsp_rdata = r_iommu_bvar.read();
[240]1571                }
[434]1572                else if( read && (cell == IOB_IOMMU_ETR))          // READ ETR
[240]1573                {
[712]1574                    r_config_cmd_to_config_rsp_rdata = r_iommu_etr.read();
[240]1575                }
[434]1576                else if( read && (cell == IOB_IOMMU_BAD_ID))      // READ BAD_ID
[240]1577                {
[712]1578                    r_config_cmd_to_config_rsp_rdata = r_iommu_bad_id.read();
[240]1579                }
[434]1580                else if( not read && (cell == IOB_INVAL_PTE))     // WRITE INVAL_PTE
[240]1581                {
[712]1582                    r_config_cmd_to_tlb_req   = true;
1583                    r_config_cmd_to_tlb_vaddr = (uint32_t)p_vci_tgt_int.wdata.read();
[240]1584                }
[434]1585                else if( not read && (cell == IOB_WTI_ADDR_LO)) // WRITE WTI_PADDR_LO
[240]1586                {
[712]1587                    r_iommu_wti_addr_lo = (vci_addr_t)p_vci_tgt_int.wdata.read();
[240]1588                }
[434]1589                else if( read && (cell == IOB_WTI_ADDR_LO))    // READ WTI_PADDR_LO
[240]1590                {
[712]1591                    r_config_cmd_to_config_rsp_rdata = r_iommu_wti_addr_lo.read();
[240]1592                }
[434]1593                else if( not read && (cell == IOB_WTI_ADDR_HI)) // WRITE WTI_PADDR_HI
[240]1594                {
[712]1595                    r_iommu_wti_addr_hi = (vci_addr_t)p_vci_tgt_int.wdata.read();
[240]1596                }
[434]1597                else if( read && (cell == IOB_WTI_ADDR_HI))    // READ WTI_PADDR_HI
[240]1598                {
[712]1599                    r_config_cmd_to_config_rsp_rdata = r_iommu_wti_addr_hi.read();
[240]1600                }
[712]1601                else if( not read && (cell == IOB_XICU_BASE)) // WRITE XICU_BASE   
[434]1602                {
[712]1603                    r_xicu_base = (vci_addr_t)p_vci_tgt_int.wdata.read();
1604                }
1605                else if( read && (cell == IOB_XICU_BASE))    // READ XICU_BASE   
[434]1606                {
[712]1607                    r_config_cmd_to_config_rsp_rdata = r_xicu_base.read();
[434]1608                }
[712]1609                else if( not read && (cell == IOB_XICU_SIZE)) // WRITE XICU_SIZE   
1610                {
1611                    r_xicu_size = (vci_addr_t)p_vci_tgt_int.wdata.read();
1612                }
1613                else if( read && (cell == IOB_XICU_SIZE))    // READ XICU_SIZE   
1614                {
1615                    r_config_cmd_to_config_rsp_rdata = r_xicu_size.read();
1616                }
[434]1617                else   // Error: Wrong address, or invalid operation.
1618                {
1619                    rerror = true;
1620                }
[712]1621                r_config_cmd_to_config_rsp_rerror = rerror;
1622                r_config_cmd_fsm                 = CONFIG_CMD_RSP;
[240]1623            }
[451]1624            else if ( found )                            // remote peripheral
[240]1625            {
[585]1626                r_config_cmd_address = p_vci_tgt_int.address.read();
1627                r_config_cmd_srcid   = p_vci_tgt_int.srcid.read();
1628                r_config_cmd_trdid   = p_vci_tgt_int.trdid.read();
1629                r_config_cmd_pktid   = p_vci_tgt_int.pktid.read();
1630                r_config_cmd_pktid   = p_vci_tgt_int.pktid.read();
1631                r_config_cmd_plen    = p_vci_tgt_int.plen.read();
1632                r_config_cmd_cmd     = p_vci_tgt_int.cmd.read();
1633                r_config_cmd_cons    = p_vci_tgt_int.cons.read();
1634                r_config_cmd_clen    = p_vci_tgt_int.clen.read();
1635                r_config_cmd_wrap    = p_vci_tgt_int.wrap.read();
1636                r_config_cmd_contig  = p_vci_tgt_int.contig.read();
1637                r_config_cmd_cfixed  = p_vci_tgt_int.cfixed.read();
1638
1639                if( eop )                                // single flit command
1640                {
1641                    if ( high )     // HI word
1642                    {
1643                        r_config_cmd_wdata = ((ext_data_t)p_vci_tgt_int.wdata.read())<<32;
1644                        r_config_cmd_be    = ((ext_be_t)p_vci_tgt_int.be.read())<<4;
1645                        r_config_cmd_eop   = true;
1646                        r_config_cmd_fsm   = CONFIG_CMD_PUT;
1647                    }
1648                    else            // LO word
1649                    {
1650                        r_config_cmd_wdata = ((ext_data_t)p_vci_tgt_int.wdata.read());
1651                        r_config_cmd_be    = ((ext_be_t)p_vci_tgt_int.be.read());
1652                        r_config_cmd_eop   = true;
1653                        r_config_cmd_fsm   = CONFIG_CMD_PUT;
1654                    }
1655                }
1656                else                                     // multi-flits write
1657                {
1658                    if ( high )     // MSB word
1659                    {
1660                        r_config_cmd_wdata = ((ext_data_t)p_vci_tgt_int.wdata.read())<<32;
1661                        r_config_cmd_be    = ((ext_be_t)p_vci_tgt_int.be.read())<<4;
1662                        r_config_cmd_eop   = false;
1663                        r_config_cmd_fsm   = CONFIG_CMD_PUT;
1664                    }
1665                    else            // LSB word
1666                    {
1667                        r_config_cmd_wdata = ((ext_data_t)p_vci_tgt_int.wdata.read());
1668                        r_config_cmd_be    = ((ext_be_t)p_vci_tgt_int.be.read());
1669                        r_config_cmd_eop   = false;
1670                        r_config_cmd_fsm   = CONFIG_CMD_NEXT;
1671                    }
1672                }
[240]1673            }
[585]1674            else                                         // out of segment address
[451]1675            {
[712]1676                r_config_cmd_to_config_rsp_rdata  = 0;
1677                r_config_cmd_to_config_rsp_rerror = true;
1678                if( eop ) r_config_cmd_fsm        = CONFIG_CMD_RSP;
[451]1679            }
[434]1680        } // end if cmdval
[240]1681        break;
1682    }
[585]1683    /////////////////////
1684    case CONFIG_CMD_NEXT:  // Consume the second flit for a multi-flits write
[240]1685    {
[585]1686        if ( p_vci_tgt_int.cmdval.read() ) 
1687        {
1688            vci_addr_t paddr = p_vci_tgt_int.address.read();
1689            bool       high  = (paddr & 0x4 == 0x4);
1690            bool       eop   = p_vci_tgt_int.eop.read();
1691
1692            assert( (paddr == r_config_cmd_address.read() + 4) and high and
1693            "ERROR in vci_io_bridge : addresses must be contiguous in write burst" );
1694
1695            r_config_cmd_wdata = r_config_cmd_wdata.read() |
1696                                 ((ext_data_t)p_vci_tgt_int.wdata.read()<<32);
1697            r_config_cmd_be    = r_config_cmd_be.read() |
1698                                 ((ext_be_t)p_vci_tgt_int.be.read()<<4);
1699            r_config_cmd_eop   = eop;
1700            r_config_cmd_fsm   = CONFIG_CMD_PUT;
1701        }
1702        break;
1703    }
1704    ////////////////////
[712]1705    case CONFIG_CMD_PUT:   // post a command to CONFIG_CMD fifo (to IOX network)
[585]1706    {
[434]1707        config_cmd_fifo_put = true;
1708
[585]1709        if ( m_config_cmd_addr_fifo.wok() )
[240]1710        {
[434]1711
1712#if DEBUG_CONFIG_CMD
1713if( m_debug_activated ) 
[585]1714std::cout << "  <IOB CONFIG_CMD_PUT> Transmit VCI command to IOX network"
1715          << " : address = " << std::hex << r_config_cmd_address.read()
1716          << " / srcid = " << r_config_cmd_srcid.read()
1717          << " / eop = " << r_config_cmd_eop.read()
[434]1718          << std::endl;
1719#endif
[585]1720            r_config_cmd_fsm = CONFIG_CMD_IDLE;
[434]1721        }
1722        break;
[240]1723    }
[585]1724    ////////////////////
[712]1725    case CONFIG_CMD_RSP:   // Post a request to CONFIG_RSP FSM,
1726                           // if no previous pending request.
1727                           // r_config_cmd_to_config_rsp_rerror
1728                           // has been set in IDLE state.
[240]1729    {
[712]1730        if ( not r_config_cmd_to_config_rsp_req.read() )
[240]1731        {
[712]1732            r_config_cmd_to_config_rsp_req = true;
[434]1733
1734#if DEBUG_CONFIG_CMD
1735if( m_debug_activated ) 
[712]1736std::cout << "  <IOB CONFIG_CMD_RSP> Request a response to CONFIG_RSP FSM"
1737          << " / error = " << r_config_cmd_to_config_rsp_rerror.read() << std::endl;
[434]1738#endif
[712]1739            r_config_cmd_fsm = CONFIG_CMD_IDLE;
[240]1740        }
1741        break;
1742    }
1743    } // end switch CONFIG_CMD FSM
1744
1745    //////////////////////////////////////////////////////////////////////////////
[712]1746    // The CONFIG_RSP_FSM controls access to the CONFIG_RSP FIFO to INT network.
1747    // It implements a round robin priority between 2 clients FSMs :
1748    // - CONFIG_CMD : response to a local config command.
1749    // - CONFIG_RSP : responses from peripherals on IOX network
1750    // Regarding the responses from IOX network it handles both single flit
1751    // config responses, and multi-flits read responses (ROM), where data must
1752    // be serialised (64 bits -> 32 bits).
[585]1753    // Note: We use the VCI RPKTID field to distinguish between read cached
1754    // (multi-flits response) and others (single flit response).
1755    // The VCI response flit is only consumed in the PUT_UNC or PUT_HI states.
[434]1756    //////////////////////////////////////////////////////////////////////////////
1757
[712]1758    // does nothing if FIFO full
1759    if ( m_config_rsp_rerror_fifo.wok() )
[240]1760    {
[712]1761        switch( r_config_rsp_fsm.read() ) 
1762        {
1763            /////////////////////////
1764            case CONFIG_RSP_IDLE_IOX:  // IOX requests have highest priority
1765                                       // no flit on IOX network is consumed
1766            {           
1767                if ( p_vci_ini_iox.rspval.read() )  // IOX request
1768                    {
1769                    if ( (p_vci_ini_iox.rpktid.read() & 0x5) == 0x1 )   // multi-flits
1770                    {
1771                        r_config_rsp_fsm   = CONFIG_RSP_PUT_LOW;
1772                    }
1773                    else                                                // single flit   
1774                    {
1775                        r_config_rsp_fsm   = CONFIG_RSP_PUT_UNC;
1776                    }
1777                    }
1778                else if ( r_config_cmd_to_config_rsp_req.read() ) // LOC request
1779                {
1780                    r_config_rsp_fsm = CONFIG_RSP_PUT_LOC;
1781                }
1782                    break;
[585]1783            }
[712]1784            /////////////////////////
1785            case CONFIG_RSP_IDLE_LOC:  // LOC requests have highest priority
1786                                       // no flit on IOX network is consumed
1787            {           
1788                if ( r_config_cmd_to_config_rsp_req.read() ) // LOC request
1789                {
1790                    r_config_rsp_fsm = CONFIG_RSP_PUT_LOC;
1791                }
1792                else if ( p_vci_ini_iox.rspval.read() ) // IOX request
1793                    {
1794                    if ( (p_vci_ini_iox.rpktid.read() & 0x5) == 0x1 )   // multi-flits
1795                    {
1796                        r_config_rsp_fsm   = CONFIG_RSP_PUT_LOW;
1797                    }
1798                    else                                                // single flit   
1799                    {
1800                        r_config_rsp_fsm   = CONFIG_RSP_PUT_UNC;
1801                    }
1802                    }
1803                break;
1804            }
1805            ////////////////////////
1806            case CONFIG_RSP_PUT_LOW:   // put 32 low bits into CONFIG_RSP fifo
1807                                       // no flit on IOX network is consumed
[585]1808            {
[712]1809                config_rsp_fifo_put    = true;
1810                config_rsp_fifo_rerror = p_vci_ini_iox.rerror.read();
1811                config_rsp_fifo_rdata  = (uint32_t)p_vci_ini_iox.rdata.read();
1812                config_rsp_fifo_rsrcid = p_vci_ini_iox.rsrcid.read();
1813                config_rsp_fifo_rtrdid = p_vci_ini_iox.rtrdid.read();
1814                config_rsp_fifo_rpktid = p_vci_ini_iox.rpktid.read();
1815                config_rsp_fifo_reop   = false;
[240]1816
[712]1817                r_config_rsp_fsm   = CONFIG_RSP_PUT_HI;
1818
[585]1819#if DEBUG_CONFIG_RSP
1820if( m_debug_activated ) 
[712]1821std::cout << "  <IOB CONFIG_RSP_PUT_LOW> Push multi-flit response into CONFIG_RSP FIFO" 
[585]1822          << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read()
1823          << " / rtrdid = " << p_vci_ini_iox.rtrdid.read()
1824          << " / rpktid = " << p_vci_ini_iox.rpktid.read()
1825          << " / rdata = " << (uint32_t)p_vci_ini_iox.rdata.read()
1826          << " / reop  = " << false
1827          << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl;
1828#endif
[712]1829                break;
1830            }
1831            ///////////////////////
1832            case CONFIG_RSP_PUT_HI:    // put 32 high bits into CONFIG_RSP fifo
1833                                   // flit on IOX network is consumed
1834            {
1835                config_rsp_fifo_put    = true;
1836                config_rsp_fifo_rerror = p_vci_ini_iox.rerror.read();
1837                config_rsp_fifo_rdata  = (uint32_t)(p_vci_ini_iox.rdata.read() >> 32);
1838                config_rsp_fifo_rsrcid = p_vci_ini_iox.rsrcid.read();
1839                config_rsp_fifo_rtrdid = p_vci_ini_iox.rtrdid.read();
1840                config_rsp_fifo_rpktid = p_vci_ini_iox.rpktid.read();
1841                config_rsp_fifo_reop   = p_vci_ini_iox.reop.read();
[434]1842
[712]1843                if( p_vci_ini_iox.reop.read() ) r_config_rsp_fsm = CONFIG_RSP_IDLE_LOC;
1844                else                            r_config_rsp_fsm = CONFIG_RSP_PUT_LOW;
1845
[240]1846#if DEBUG_CONFIG_RSP
[434]1847if( m_debug_activated ) 
[712]1848std::cout << "  <IOB CONFIG_RSP_PUT_HI> Push multi-flit response into CONFIG_RSP FIFO" 
[434]1849          << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read()
1850          << " / rtrdid = " << p_vci_ini_iox.rtrdid.read()
[585]1851          << " / rpktid = " << p_vci_ini_iox.rpktid.read()
[712]1852          << " / rdata = " << (uint32_t)(p_vci_ini_iox.rdata.read() >> 32)
[434]1853          << " / reop  = " << p_vci_ini_iox.reop.read()
1854          << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl;
[240]1855#endif
[712]1856                break;
1857            }
1858            ////////////////////////
1859            case CONFIG_RSP_PUT_UNC:   // put single flit into CONFIG_RSP fifo
1860                                       // flit on IOX network is consumed
1861            {
1862                assert(  p_vci_ini_iox.reop.read() and
1863                "ERROR in vci_io_bridge : a remote config response should be one flit");
[585]1864
[712]1865                config_rsp_fifo_put    = true;
1866                config_rsp_fifo_rerror = p_vci_ini_iox.rerror.read();
1867                config_rsp_fifo_rdata  = (uint32_t)p_vci_ini_iox.rdata.read();
1868                config_rsp_fifo_rsrcid = p_vci_ini_iox.rsrcid.read();
1869                config_rsp_fifo_rtrdid = p_vci_ini_iox.rtrdid.read();
1870                config_rsp_fifo_rpktid = p_vci_ini_iox.rpktid.read();
1871                config_rsp_fifo_reop   = true;
1872
1873                // update priority
1874                r_config_rsp_fsm   = CONFIG_RSP_IDLE_LOC;
1875
[585]1876#if DEBUG_CONFIG_RSP
1877if( m_debug_activated ) 
[712]1878std::cout << "  <IOB CONFIG_RSP_PUT_UNC> Push single flit response into CONFIG_RSP FIFO" 
[585]1879          << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read()
1880          << " / rtrdid = " << p_vci_ini_iox.rtrdid.read()
1881          << " / rpktid = " << p_vci_ini_iox.rpktid.read()
1882          << " / rdata = " << (uint32_t)p_vci_ini_iox.rdata.read()
1883          << " / reop  = " << true
1884          << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl;
1885#endif
[712]1886                break;
1887            }
1888            ////////////////////////
1889            case CONFIG_RSP_PUT_LOC:   // put single flit into CONFIG_RSP fifo
1890                                       // no flit on IOX network is consumed
1891            {
1892                config_rsp_fifo_put    = true;
1893                config_rsp_fifo_rerror = r_config_cmd_to_config_rsp_rerror.read();
1894                config_rsp_fifo_rdata  = r_config_cmd_to_config_rsp_rdata.read();
1895                config_rsp_fifo_rsrcid = r_config_cmd_srcid.read();
1896                config_rsp_fifo_rtrdid = r_config_cmd_trdid.read();
1897                config_rsp_fifo_rpktid = r_config_cmd_pktid.read();
1898                config_rsp_fifo_reop   = true;
[240]1899
[712]1900                // acknowledge request
1901                r_config_cmd_to_config_rsp_req = false;
[240]1902
[712]1903                // update priority
1904                r_config_rsp_fsm   = CONFIG_RSP_IDLE_IOX;
1905
1906#if DEBUG_CONFIG_RSP
1907if( m_debug_activated ) 
1908std::cout << "  <IOB CONFIG_RSP_PUT_UNC> Push single flit response into CONFIG_RSP FIFO" 
1909          << " / rsrcid = " << std::hex << r_config_cmd_srcid.read()
1910          << " / rtrdid = " << r_config_cmd_trdid.read()
1911          << " / rpktid = " << r_config_cmd_pktid.read()
1912          << " / rdata = "  << r_config_cmd_to_config_rsp_rdata.read()
1913          << " / reop  = "  << true
1914          << " / rerror = " << r_config_cmd_to_config_rsp_rerror.read() << std::endl;
1915#endif
1916                break;
1917            }
1918        } // end switch CONFIG_RSP FSM
1919    } // end if FIFO full
1920
[434]1921    ///////////////////////////////////////////////////////////////////////////////////
[712]1922    // The MISS_WTI_CMD component is a combinational switch that push one single flit
1923    // VCI command in the MISS_WTI FIFO to INT Network, depending on two clients :
1924    // 1. MISS requests from TLB_MISS FSM :
1925    //    These requests have highest priority because a TLB MISS is a blocking event
1926    //    for the DMA FSM. The r_tlb_to_miss_wti_cmd_req flip-flop is reset by the
1927    //    MISS_WTI_RSP FSM only when the response is received.
1928    // 2. WTI requests from DMA_CMD FSM :
1929    //    These requestsare non blocking events, and the r_dma_cmd_to_miss_wti_cmd_req
1930    //    flip-flop is reset as soon as the WTI command has been sent.
1931    //    There is two types of WTI requests:
1932    //    - external WTI from peripherals on IOX network.
1933    //    - internal WTI caused by illegal DMA requests.
[240]1934    ////////////////////////////////////////////////////////////////////////////////////
1935 
[712]1936    if ( r_tlb_to_miss_wti_cmd_req.read() and 
1937         m_miss_wti_cmd_addr_fifo.wok() )                   // put MISS READ
[240]1938    {
[712]1939        miss_wti_cmd_fifo_put     = true;
1940        miss_wti_cmd_fifo_address = r_tlb_paddr.read();     
1941        miss_wti_cmd_fifo_wdata   = 0;                 
1942        miss_wti_cmd_fifo_cmd     = vci_param_int::CMD_READ;
1943        miss_wti_cmd_fifo_pktid   = PKTID_MISS;
1944        miss_wti_cmd_fifo_srcid   = m_int_srcid;
1945        miss_wti_cmd_fifo_trdid   = 0;
[240]1946
[712]1947#if DEBUG_MISS_WTI_CMD
[434]1948if( m_debug_activated )
[712]1949std::cout << "  <IOB MISS_WTI_CMD_WTI> push MISS TLB command into MISS_WTI FIFO"
1950          << " / PADDR = " << miss_wti_cmd_fifo_address << std::endl;
[434]1951#endif
[240]1952
[712]1953    }
1954    else if ( r_dma_cmd_to_miss_wti_cmd_req.read() and 
1955              m_miss_wti_cmd_addr_fifo.wok() )               // put WTI READ / WRITE
1956    {
1957        r_dma_cmd_to_miss_wti_cmd_req = false;
1958
1959        miss_wti_cmd_fifo_put     = true;
1960        miss_wti_cmd_fifo_cmd     = r_dma_cmd_to_miss_wti_cmd_cmd.read();
1961        miss_wti_cmd_fifo_address = r_dma_cmd_to_miss_wti_cmd_addr.read();
1962        miss_wti_cmd_fifo_wdata   = r_dma_cmd_to_miss_wti_cmd_wdata.read();
1963        miss_wti_cmd_fifo_srcid   = r_dma_cmd_to_miss_wti_cmd_srcid.read();
1964        miss_wti_cmd_fifo_trdid   = r_dma_cmd_to_miss_wti_cmd_trdid.read();
1965        miss_wti_cmd_fifo_pktid   = r_dma_cmd_to_miss_wti_cmd_pktid.read();
1966
1967#if DEBUG_MISS_WTI_CMD
[434]1968if( m_debug_activated )
[712]1969std::cout << "  <IOB MISS_WTI_CMD_WTI> push WTI command into MISS_WTI FIFO"
1970          << " / CMD = " << miss_wti_cmd_fifo_cmd
1971          << " / PADDR = " << miss_wti_cmd_fifo_address << std::endl;
[240]1972#endif
[434]1973
[712]1974    }     
1975
[434]1976    ///////////////////////////////////////////////////////////////////////////////////
[712]1977    // The MISS_WTI_RSP FSM handles VCI responses from the INT network:
1978    // - for a TLB MISS (multi-flits read transaction), the cache line
1979    //   is written in r_tlb_buf_data[], and r_tlb_to_miss_wti_cmd_req flip-flop is reset. 
1980    // - for a WTI_IOX (single flit write transaction), the response must be
1981    //   forwarded to the source peripheral on the INT network
1982    // - for a WTI_MMU (single flit write transaction), there is nothing to do.
1983    //
1984    // TODO VCI addressing errors for TLB MISS or for WTI_MMU (i.e. kernel errors...)
1985    // are registered in the r_miss_wti_rsp_error_miss & r_miss_wti_rsp_error_wti
1986    // flip-flops, and simulation stops... They could be signaled to OS by a WTI.
[434]1987    ////////////////////////////////////////////////////////////////////////////////////
1988 
1989    switch ( r_miss_wti_rsp_fsm.read() ) 
1990    {
[712]1991        ///////////////////////
[434]1992        case MISS_WTI_RSP_IDLE:   // waiting a VCI response
[712]1993                                  // no VCI flit is consumed
[240]1994        {
[434]1995            if ( p_vci_ini_int.rspval.read() ) 
[240]1996            {
[712]1997                if ( p_vci_ini_int.rpktid.read() == PKTID_WTI_IOX ) 
[240]1998                {
[712]1999                    r_miss_wti_rsp_fsm   = MISS_WTI_RSP_WTI_IOX;
2000                }
2001                else if ( p_vci_ini_int.rpktid.read() == PKTID_WTI_MMU ) 
2002                {
2003                    r_miss_wti_rsp_fsm   = MISS_WTI_RSP_WTI_MMU;
2004                }
2005                else if ( p_vci_ini_int.rpktid.read() == PKTID_MISS )
2006                {
[434]2007                    r_miss_wti_rsp_fsm   = MISS_WTI_RSP_MISS;
2008                    r_miss_wti_rsp_count = 0;
[240]2009                }
[712]2010                else
[434]2011                {
[712]2012                    assert ( false and
2013                    "VCI_IO_BRIDGE ERROR : illegal response type on INT network");
[434]2014                }
[240]2015            }
2016            break;
2017        }
[712]2018        //////////////////////////
2019        case MISS_WTI_RSP_WTI_IOX:   // Handling response to a peripheral WTI
2020                                     // consume VCI flit and transfer response
2021                                     // to DMA_RSP FSM in dedicated registers
2022                                     // if no pending previous request.
[240]2023        {
[434]2024            assert( p_vci_ini_int.reop.read() and
[712]2025            "VCI_IO_BRIDGE ERROR: WTI_IOX response should have one single flit" ); 
2026                   
2027            if ( not r_miss_wti_rsp_to_dma_rsp_req.read() ) // no previous pending request
2028            {
2029                r_miss_wti_rsp_to_dma_rsp_req    = true;
2030                r_miss_wti_rsp_to_dma_rsp_rerror = p_vci_ini_int.rerror.read();
2031                r_miss_wti_rsp_to_dma_rsp_rsrcid = p_vci_ini_int.rsrcid.read();
2032                r_miss_wti_rsp_to_dma_rsp_rtrdid = p_vci_ini_int.rtrdid.read();
2033                r_miss_wti_rsp_to_dma_rsp_rpktid = p_vci_ini_int.rpktid.read();
[240]2034
[712]2035                r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE;
[434]2036
[712]2037#if DEBUG_MISS_WTI_RSP
[434]2038if( m_debug_activated )
[712]2039std::cout << "  <IOB MISS_WTI_RSP_WTI_IOX> Transfer response to a WTI_IOX" << std::endl;
[240]2040#endif
[712]2041            }
[240]2042            break;
2043        }
[712]2044        ////////////////////////// 
2045        case MISS_WTI_RSP_WTI_MMU:   // Handling response to an iommu WTI
2046                                     // consume VCI flit and test VCI error.
2047        {
2048            assert( p_vci_ini_int.reop.read() and
2049            "VCI_IO_BRIDGE ERROR: WTI_MMU response should have one single flit" ); 
2050                 
2051            if ( (p_vci_ini_int.rerror.read()&0x1) != 0 )  // error reported
2052            {
2053                // set the specific error flip-flop
2054                r_miss_wti_rsp_error_wti = true;
2055                assert( false and
2056                "VCI_IO_BRIDGE ERROR: VCI error response for a WTI_MMU transaction");
2057            }
2058
2059#if DEBUG_MISS_WTI_RSP
2060if( m_debug_activated ) 
2061std::cout << " <IOB MISS_WTI_RSP_WTI_MMU> Receive response to a WTI_MMU" << std::endl; 
2062#endif
2063            break;
2064        }
[434]2065        ///////////////////////
[712]2066        case MISS_WTI_RSP_MISS:   // Handling response to a TLB MISS
2067                                  // write cache line in r_tlb_buf buffer
2068                                  // and analyse possible VCI error
2069                                  // VCI flit is consumed.
[240]2070        {
[434]2071            if ( p_vci_ini_int.rspval.read() ) 
[240]2072            {
[434]2073                if ( (p_vci_ini_int.rerror.read()&0x1) != 0 )  // error reported
[240]2074                {
[712]2075                    // set the specific error flip-flop
2076                    r_miss_wti_rsp_error_miss = true;
2077                    assert( false and
2078                    "VCI_IO_BRIDGE ERROR: VCI error response for a TLB MISS transaction");
2079
[240]2080                }
[434]2081                else                                           // no error
[712]2082                {
[240]2083
[712]2084#if DEBUG_MISS_WTI_CMD
[434]2085if( m_debug_activated ) 
[712]2086std::cout << "  <IOB MISS_WTI_RSP_MISS> Receive response to a TLB MISS"
[434]2087          << " / Count = " << r_miss_wti_rsp_count.read()
2088          << " / Data = " << std::hex << p_vci_ini_int.rdata.read() << std::endl; 
[240]2089#endif
[712]2090                    r_tlb_buf_data[r_miss_wti_rsp_count.read()] = p_vci_ini_int.rdata.read();
2091                }
2092                   
2093                if ( p_vci_ini_int.reop.read() )               // last flit
2094                {   
2095                    bool eop = p_vci_ini_int.eop.read();
[434]2096                    assert(((eop == (r_miss_wti_rsp_count.read() == (m_words-1)))) and
2097                    "VCI_IO_BRIDGE ERROR: invalid length for a TLB MISS response");
[240]2098
[712]2099                    r_miss_wti_rsp_count      = 0;
2100                    r_miss_wti_rsp_fsm        = MISS_WTI_RSP_IDLE;
2101                    r_tlb_to_miss_wti_cmd_req = false; 
2102                }
2103                else                                           // not the last flit
2104                {
[434]2105                    r_miss_wti_rsp_count = r_miss_wti_rsp_count.read() + 1;
[240]2106                }
2107            }
2108            break;
2109        }
[434]2110    } // end  switch r_miss_wti_rsp_fsm
[240]2111
[434]2112
2113    ///////////////////////////////////////////////////////////
2114    // DMA_CMD fifo update
[712]2115    // writer : DMA_CMD FSM
[434]2116    ///////////////////////////////////////////////////////////
2117
2118    m_dma_cmd_addr_fifo.update(   dma_cmd_fifo_get,
2119                                  dma_cmd_fifo_put,
2120                                  r_dma_cmd_paddr.read() );   // address translation
2121    m_dma_cmd_cmd_fifo.update(    dma_cmd_fifo_get,
2122                                  dma_cmd_fifo_put,
2123                                  p_vci_tgt_iox.cmd.read() );
2124    m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
2125                                  dma_cmd_fifo_put,
2126                                  p_vci_tgt_iox.contig.read() );
2127    m_dma_cmd_cons_fifo.update(   dma_cmd_fifo_get,
2128                                  dma_cmd_fifo_put,
2129                                  p_vci_tgt_iox.cons.read() );
2130    m_dma_cmd_plen_fifo.update(   dma_cmd_fifo_get,
2131                                  dma_cmd_fifo_put,
2132                                  p_vci_tgt_iox.plen.read() );
2133    m_dma_cmd_wrap_fifo.update(   dma_cmd_fifo_get,
2134                                  dma_cmd_fifo_put,
2135                                  p_vci_tgt_iox.wrap.read() );
2136    m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
2137                                  dma_cmd_fifo_put,
2138                                  p_vci_tgt_iox.cfixed.read() );
2139    m_dma_cmd_clen_fifo.update(   dma_cmd_fifo_get,
2140                                  dma_cmd_fifo_put,
2141                                  p_vci_tgt_iox.clen.read() );
2142    m_dma_cmd_srcid_fifo.update(  dma_cmd_fifo_get,
2143                                  dma_cmd_fifo_put,
2144                                  p_vci_tgt_iox.srcid.read() );
2145    m_dma_cmd_trdid_fifo.update(  dma_cmd_fifo_get,
2146                                  dma_cmd_fifo_put,
2147                                  p_vci_tgt_iox.trdid.read() );
2148    m_dma_cmd_pktid_fifo.update(  dma_cmd_fifo_get,
2149                                  dma_cmd_fifo_put,
2150                                  p_vci_tgt_iox.pktid.read() );
2151    m_dma_cmd_data_fifo.update(   dma_cmd_fifo_get,
2152                                  dma_cmd_fifo_put,
2153                                  p_vci_tgt_iox.wdata.read() ); 
2154    m_dma_cmd_be_fifo.update(     dma_cmd_fifo_get,
2155                                  dma_cmd_fifo_put,
2156                                  p_vci_tgt_iox.be.read() ); 
2157    m_dma_cmd_eop_fifo.update(    dma_cmd_fifo_get,
2158                                  dma_cmd_fifo_put,
2159                                  p_vci_tgt_iox.eop.read() );
2160
2161    //////////////////////////////////////////////////////////////
2162    // DMA_RSP fifo update
[712]2163    // writer : DMA_RSP FSM
[434]2164    //////////////////////////////////////////////////////////////
2165
[712]2166    m_dma_rsp_data_fifo.update(   dma_rsp_fifo_get,
2167                                  dma_rsp_fifo_put,
2168                                  dma_rsp_fifo_rdata );
2169    m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
2170                                  dma_rsp_fifo_put,
2171                                  dma_rsp_fifo_rsrcid ); 
2172    m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
2173                                  dma_rsp_fifo_put,
2174                                  dma_rsp_fifo_rtrdid ); 
2175    m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
2176                                  dma_rsp_fifo_put,
2177                                  dma_rsp_fifo_rpktid ); 
2178    m_dma_rsp_reop_fifo.update(   dma_rsp_fifo_get,
2179                                  dma_rsp_fifo_put,
2180                                  dma_rsp_fifo_reop );     
2181    m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
2182                                  dma_rsp_fifo_put,
2183                                  dma_rsp_fifo_rerror );
[240]2184
[434]2185    ////////////////////////////////////////////////////////////////
2186    // CONFIG_CMD fifo update
[712]2187    // writer : CONFIG_CMD FSM
[434]2188    ////////////////////////////////////////////////////////////////
2189
2190    m_config_cmd_addr_fifo.update(   config_cmd_fifo_get,
2191                                     config_cmd_fifo_put,
[585]2192                                     r_config_cmd_address.read() ); 
[434]2193    m_config_cmd_cmd_fifo.update(    config_cmd_fifo_get,
2194                                     config_cmd_fifo_put,
[585]2195                                     r_config_cmd_cmd.read() ); 
[240]2196    m_config_cmd_contig_fifo.update( config_cmd_fifo_get,
[434]2197                                     config_cmd_fifo_put,
[585]2198                                     r_config_cmd_contig.read() ); 
[434]2199    m_config_cmd_cons_fifo.update(   config_cmd_fifo_get,
2200                                     config_cmd_fifo_put,
[585]2201                                     r_config_cmd_cons.read() ); 
[434]2202    m_config_cmd_plen_fifo.update(   config_cmd_fifo_get,
2203                                     config_cmd_fifo_put,
[585]2204                                     r_config_cmd_plen.read() ); 
[434]2205    m_config_cmd_wrap_fifo.update(   config_cmd_fifo_get,
2206                                     config_cmd_fifo_put,
[585]2207                                     r_config_cmd_wrap.read() ); 
[240]2208    m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get,
[434]2209                                     config_cmd_fifo_put,
[585]2210                                     r_config_cmd_cfixed.read() ); 
[434]2211    m_config_cmd_clen_fifo.update(   config_cmd_fifo_get,
2212                                     config_cmd_fifo_put,
[585]2213                                     r_config_cmd_clen.read() ); 
[434]2214    m_config_cmd_srcid_fifo.update(  config_cmd_fifo_get,
2215                                     config_cmd_fifo_put,
[585]2216                                     r_config_cmd_srcid.read() );
[434]2217    m_config_cmd_trdid_fifo.update(  config_cmd_fifo_get,
2218                                     config_cmd_fifo_put,
[585]2219                                     r_config_cmd_trdid.read() );
[434]2220    m_config_cmd_pktid_fifo.update(  config_cmd_fifo_get,
2221                                     config_cmd_fifo_put,
[585]2222                                     r_config_cmd_pktid.read() );
[434]2223    m_config_cmd_data_fifo.update(   config_cmd_fifo_get,
2224                                     config_cmd_fifo_put,
[585]2225                                     r_config_cmd_wdata.read() );
[434]2226    m_config_cmd_be_fifo.update(     config_cmd_fifo_get,
2227                                     config_cmd_fifo_put,
[585]2228                                     r_config_cmd_be.read() );
[434]2229    m_config_cmd_eop_fifo.update(    config_cmd_fifo_get,
2230                                     config_cmd_fifo_put,
[585]2231                                     r_config_cmd_eop.read() );
[240]2232   
[434]2233    //////////////////////////////////////////////////////////////////////////
2234    // CONFIG_RSP fifo update
[712]2235    // writer : CONFIG_RSP FSM
[434]2236    //////////////////////////////////////////////////////////////////////////
2237
[712]2238    m_config_rsp_data_fifo.update(   config_rsp_fifo_get,
2239                                     config_rsp_fifo_put,
2240                                     config_rsp_fifo_rdata ); 
2241    m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get,
2242                                     config_rsp_fifo_put,
2243                                     config_rsp_fifo_rsrcid );
2244    m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get,
2245                                     config_rsp_fifo_put,
2246                                     config_rsp_fifo_rtrdid );
2247    m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get,
2248                                     config_rsp_fifo_put,
2249                                     config_rsp_fifo_rpktid );
2250    m_config_rsp_reop_fifo.update(   config_rsp_fifo_get,
2251                                     config_rsp_fifo_put,
2252                                     config_rsp_fifo_reop );
2253    m_config_rsp_rerror_fifo.update( config_rsp_fifo_get,
2254                                     config_rsp_fifo_put,
2255                                     config_rsp_fifo_rerror );
2256     
2257    ////////////////////////////////////////////////////////////////
2258    // MISS_WTI_CMD fifo update
2259    // One writer : MISS_WTI switch
2260    ////////////////////////////////////////////////////////////////
[585]2261
[712]2262    m_miss_wti_cmd_addr_fifo.update(   miss_wti_cmd_fifo_get,
2263                                       miss_wti_cmd_fifo_put,
2264                                       miss_wti_cmd_fifo_address ); 
2265    m_miss_wti_cmd_cmd_fifo.update(    miss_wti_cmd_fifo_get,
2266                                       miss_wti_cmd_fifo_put,
2267                                       miss_wti_cmd_fifo_cmd ); 
2268    m_miss_wti_cmd_contig_fifo.update( config_cmd_fifo_get,
2269                                       miss_wti_cmd_fifo_put,
2270                                       true );
2271    m_miss_wti_cmd_cons_fifo.update(   miss_wti_cmd_fifo_get,
2272                                       miss_wti_cmd_fifo_put,
2273                                       false );
2274    m_miss_wti_cmd_plen_fifo.update(   miss_wti_cmd_fifo_get,
2275                                       miss_wti_cmd_fifo_put,
2276                                       4 );
2277    m_miss_wti_cmd_wrap_fifo.update(   miss_wti_cmd_fifo_get,
2278                                       miss_wti_cmd_fifo_put,
2279                                       false );
2280    m_miss_wti_cmd_cfixed_fifo.update( config_cmd_fifo_get,
2281                                       miss_wti_cmd_fifo_put,
2282                                       false );
2283    m_miss_wti_cmd_clen_fifo.update(   miss_wti_cmd_fifo_get,
2284                                       miss_wti_cmd_fifo_put,
2285                                       0 );
2286    m_miss_wti_cmd_srcid_fifo.update(  miss_wti_cmd_fifo_get,
2287                                       miss_wti_cmd_fifo_put,
2288                                       miss_wti_cmd_fifo_srcid );
2289    m_miss_wti_cmd_trdid_fifo.update(  miss_wti_cmd_fifo_get,
2290                                       miss_wti_cmd_fifo_put,
2291                                       miss_wti_cmd_fifo_trdid );
2292    m_miss_wti_cmd_pktid_fifo.update(  miss_wti_cmd_fifo_get,
2293                                       miss_wti_cmd_fifo_put,
2294                                       miss_wti_cmd_fifo_pktid );
2295    m_miss_wti_cmd_data_fifo.update(   miss_wti_cmd_fifo_get,
2296                                       miss_wti_cmd_fifo_put,
2297                                       miss_wti_cmd_fifo_wdata );
2298    m_miss_wti_cmd_be_fifo.update(     miss_wti_cmd_fifo_get,
2299                                       miss_wti_cmd_fifo_put,
2300                                       0xF );
2301    m_miss_wti_cmd_eop_fifo.update(    miss_wti_cmd_fifo_get,
2302                                       miss_wti_cmd_fifo_put,
2303                                       true );
[434]2304   
[240]2305} // end transition()
2306
[712]2307//////////////////////////////////////////////////////////////////////////
[240]2308tmpl(void)::genMoore()
[712]2309//////////////////////////////////////////////////////////////////////////
[240]2310{
[712]2311    /////////////////  p_vci_ini_ram  /////////////////////////////
2312
[434]2313    // VCI initiator command on RAM network
2314    // directly the content of the dma_cmd FIFO
2315    p_vci_ini_ram.cmdval  = m_dma_cmd_addr_fifo.rok(); 
2316    p_vci_ini_ram.address = m_dma_cmd_addr_fifo.read();
2317    p_vci_ini_ram.be      = m_dma_cmd_be_fifo.read();
2318    p_vci_ini_ram.cmd     = m_dma_cmd_cmd_fifo.read();
2319    p_vci_ini_ram.contig  = m_dma_cmd_contig_fifo.read();
2320    p_vci_ini_ram.wdata   = m_dma_cmd_data_fifo.read(); 
2321    p_vci_ini_ram.eop     = m_dma_cmd_eop_fifo.read();
2322    p_vci_ini_ram.cons    = m_dma_cmd_cons_fifo.read();
2323    p_vci_ini_ram.plen    = m_dma_cmd_plen_fifo.read();
2324    p_vci_ini_ram.wrap    = m_dma_cmd_wrap_fifo.read();
2325    p_vci_ini_ram.cfixed  = m_dma_cmd_cfixed_fifo.read();
2326    p_vci_ini_ram.clen    = m_dma_cmd_clen_fifo.read();
2327    p_vci_ini_ram.trdid   = m_dma_cmd_trdid_fifo.read();
2328    p_vci_ini_ram.pktid   = m_dma_cmd_pktid_fifo.read();
2329    p_vci_ini_ram.srcid   = m_dma_cmd_srcid_fifo.read();
[240]2330   
[712]2331    // VCI initiator response on the RAM Network
2332    // depends on the DMA_RSP FSM state
2333        p_vci_ini_ram.rspack = m_dma_rsp_data_fifo.wok() and
2334                           (r_dma_rsp_fsm.read() == DMA_RSP_PUT_DMA); 
[240]2335
[712]2336    /////////////////  p_vci_tgt_iox  /////////////////////////////
[240]2337
[712]2338    // VCI target response on IOX network is
[434]2339    // directly the content of the DMA_RSP FIFO
2340    p_vci_tgt_iox.rspval  = m_dma_rsp_data_fifo.rok();
2341    p_vci_tgt_iox.rsrcid  = m_dma_rsp_rsrcid_fifo.read();
2342    p_vci_tgt_iox.rtrdid  = m_dma_rsp_rtrdid_fifo.read();
2343    p_vci_tgt_iox.rpktid  = m_dma_rsp_rpktid_fifo.read();
2344    p_vci_tgt_iox.rdata   = m_dma_rsp_data_fifo.read(); 
2345    p_vci_tgt_iox.rerror  = m_dma_rsp_rerror_fifo.read();
2346    p_vci_tgt_iox.reop    = m_dma_rsp_reop_fifo.read();
[240]2347
[712]2348    // VCI target command ack on IOX network
2349    // depends on the DMA_CMD FSM state
2350    switch ( r_dma_cmd_fsm.read() ) 
2351    {
2352        case DMA_CMD_IDLE:             
2353             p_vci_tgt_iox.cmdack  = false; 
2354             break;
2355        case DMA_CMD_DMA_REQ:
2356             p_vci_tgt_iox.cmdack  = m_dma_cmd_addr_fifo.wok(); 
2357             break;
2358        case DMA_CMD_WTI_IOX_REQ:
2359             p_vci_tgt_iox.cmdack  = not r_dma_cmd_to_miss_wti_cmd_req.read(); 
2360             break;
2361        case DMA_CMD_ERR_WTI_REQ:
2362             p_vci_tgt_iox.cmdack  = false; 
2363             break;
2364        case DMA_CMD_ERR_WAIT_EOP: 
2365             p_vci_tgt_iox.cmdack  = true; 
2366             break;
2367        case DMA_CMD_ERR_RSP_REQ: 
2368             p_vci_tgt_iox.cmdack  = false; 
2369             break;
2370        case DMA_CMD_TLB_MISS_WAIT: 
2371             p_vci_tgt_iox.cmdack  = false; 
2372             break;
2373    }
[240]2374
[712]2375    //////////////////  p_vci_ini_iox  /////////////////////////////
[240]2376
[712]2377    // VCI initiator command on IOX network is
[434]2378    // directly the content of the CONFIG_CMD FIFO
2379    p_vci_ini_iox.cmdval  = m_config_cmd_addr_fifo.rok();
2380    p_vci_ini_iox.address = m_config_cmd_addr_fifo.read();
2381    p_vci_ini_iox.be      = m_config_cmd_be_fifo.read();
2382    p_vci_ini_iox.cmd     = m_config_cmd_cmd_fifo.read();
2383    p_vci_ini_iox.contig  = m_config_cmd_contig_fifo.read();
[585]2384    p_vci_ini_iox.wdata   = m_config_cmd_data_fifo.read(); 
[434]2385    p_vci_ini_iox.eop     = m_config_cmd_eop_fifo.read();
2386    p_vci_ini_iox.cons    = m_config_cmd_cons_fifo.read();
2387    p_vci_ini_iox.plen    = m_config_cmd_plen_fifo.read();
2388    p_vci_ini_iox.wrap    = m_config_cmd_wrap_fifo.read();
2389    p_vci_ini_iox.cfixed  = m_config_cmd_cfixed_fifo.read();
2390    p_vci_ini_iox.clen    = m_config_cmd_clen_fifo.read();
2391    p_vci_ini_iox.trdid   = m_config_cmd_trdid_fifo.read();
2392    p_vci_ini_iox.pktid   = m_config_cmd_pktid_fifo.read();
2393    p_vci_ini_iox.srcid   = m_config_cmd_srcid_fifo.read();
[240]2394   
[712]2395    // VCI initiator response on IOX Network
2396    // it depends on the CONFIG_RSP FSM state
2397        p_vci_ini_iox.rspack = m_config_rsp_data_fifo.wok() and
2398                           ( (r_config_rsp_fsm.read() == CONFIG_RSP_PUT_UNC) or
2399                             (r_config_rsp_fsm.read() == CONFIG_RSP_PUT_HI) );
2400
2401    /////////////////  p_vci_tgt_int  ////////////////////////////////
2402
2403    // VCI target response on INT network
2404    // directly the content of the CONFIG_RSP FIFO
2405    p_vci_tgt_int.rspval  = m_config_rsp_data_fifo.rok();
2406        p_vci_tgt_int.rsrcid  = m_config_rsp_rsrcid_fifo.read();
2407    p_vci_tgt_int.rtrdid  = m_config_rsp_rtrdid_fifo.read();
2408    p_vci_tgt_int.rpktid  = m_config_rsp_rpktid_fifo.read();
2409    p_vci_tgt_int.rdata   = m_config_rsp_data_fifo.read();
2410    p_vci_tgt_int.rerror  = m_config_rsp_rerror_fifo.read();
2411    p_vci_tgt_int.reop    = m_config_rsp_reop_fifo.read();
2412   
[434]2413    // VCI target command ack on INT network
[240]2414    // it depends on the CONFIG_CMD FSM state
2415    switch ( r_config_cmd_fsm.read() ) 
2416    {
2417    case CONFIG_CMD_IDLE:
[585]2418        p_vci_tgt_int.cmdack  = true;
2419        break;
2420    case CONFIG_CMD_NEXT: 
2421        p_vci_tgt_int.cmdack  = true;
2422        break;
2423    case CONFIG_CMD_PUT:         
[434]2424        p_vci_tgt_int.cmdack  = false;
[240]2425        break;
[585]2426    case CONFIG_CMD_RSP:         
2427        p_vci_tgt_int.cmdack  = false;
[240]2428        break;
[585]2429    }
[240]2430
[712]2431    /////////////////  p_vci_ini_int  ////////////////////////////////
[240]2432
[434]2433    // VCI initiator command  on INT network
[712]2434    // directly the content of the MISS_WTI_CMD FIFO 
2435    p_vci_ini_int.cmdval  = m_miss_wti_cmd_addr_fifo.rok();
2436    p_vci_ini_int.address = m_miss_wti_cmd_addr_fifo.read();
2437    p_vci_ini_int.be      = m_miss_wti_cmd_be_fifo.read();
2438    p_vci_ini_int.cmd     = m_miss_wti_cmd_cmd_fifo.read();
2439    p_vci_ini_int.contig  = m_miss_wti_cmd_contig_fifo.read();
2440    p_vci_ini_int.wdata   = m_miss_wti_cmd_data_fifo.read(); 
2441    p_vci_ini_int.eop     = m_miss_wti_cmd_eop_fifo.read();
2442    p_vci_ini_int.cons    = m_miss_wti_cmd_cons_fifo.read();
2443    p_vci_ini_int.plen    = m_miss_wti_cmd_plen_fifo.read();
2444    p_vci_ini_int.wrap    = m_miss_wti_cmd_wrap_fifo.read();
2445    p_vci_ini_int.cfixed  = m_miss_wti_cmd_cfixed_fifo.read();
2446    p_vci_ini_int.clen    = m_miss_wti_cmd_clen_fifo.read();
2447    p_vci_ini_int.trdid   = m_miss_wti_cmd_trdid_fifo.read();
2448    p_vci_ini_int.pktid   = m_miss_wti_cmd_pktid_fifo.read();
2449    p_vci_ini_int.srcid   = m_miss_wti_cmd_srcid_fifo.read();
[434]2450
2451    // VCI initiator response on INT network
2452    // It depends on the MISS_WTI_RSP FSM state
2453
[712]2454    if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_IDLE )
2455    {
2456        p_vci_ini_int.rspack = false;
2457    }
2458    else if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_WTI_IOX )
2459    {
2460        p_vci_ini_int.rspack = not r_miss_wti_rsp_to_dma_rsp_req.read();
2461    }
2462    else  //  MISS_WTI_RSP_MISS or MISS_WTI_RESP_WTI_MMU
2463    {
2464        p_vci_ini_int.rspack = true;
2465    }
[434]2466
[240]2467} // end genMoore
2468
2469}}
2470
2471// Local Variables:
2472// tab-width: 4
2473// c-basic-offset: 4
2474// c-file-offsets:((innamespace . 0)(inline-open . 0))
2475// indent-tabs-mode: nil
2476// End:
2477
2478// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.