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

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

Introducing support for read and write WTI transactions.
The WTI read transaction is used for IRQ reset.

File size: 102.1 KB
Line 
1/* -*- c++ -*-
2 * File : vci_io_bridge.cpp
3 * Copyright (c) UPMC, Lip6, SoC
4 * Authors: Cassio Fraga, Alain Greiner
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
32
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
37//    m_debug_activated = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)
38/////////////////////////////////////////////////////////////////////////////////
39
40#define DEBUG_DMA_CMD           1
41#define DEBUG_DMA_RSP           1
42#define DEBUG_TLB_MISS          1
43#define DEBUG_CONFIG_CMD                1
44#define DEBUG_CONFIG_RSP                1
45#define DEBUG_MISS_WTI_CMD              1
46
47namespace soclib { 
48namespace caba {
49
50namespace {
51
52const char *dma_cmd_fsm_state_str[] = 
53    {
54        "DMA_CMD_IDLE",
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",
61    };
62
63const char *dma_rsp_fsm_state_str[] = 
64    {
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",
71    };
72
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",
86    };
87
88const char *config_cmd_fsm_state_str[] = 
89    {
90        "CONFIG_CMD_IDLE",
91        "CONFIG_CMD_NEXT",
92        "CONFIG_CMD_PUT",
93        "CONFIG_CMD_RSP",
94    };
95
96const char *config_rsp_fsm_state_str[] = 
97    {
98        "CONFIG_RSP_IDLE_IOX",
99        "CONFIG_RSP_IDLE_LOC",
100        "CONFIG_RSP_PUT_LOW", 
101        "CONFIG_RSP_PUT_HI", 
102        "CONFIG_RSP_PUT_UNC", 
103        "CONFIG_RSP_PUT_LOC", 
104    };
105
106const char *miss_wti_rsp_state_str[] = 
107    { 
108        "MISS_WTI_RSP_IDLE",
109        "MISS_WTI_RSP_WTI_IOX",
110        "MISS_WTI_RSP_WTI_MMU",
111        "MISS_WTI_RSP_MISS",
112    };
113}
114
115#define tmpl(...)  template<typename vci_param_int,typename vci_param_ext> __VA_ARGS__ VciIoBridge<vci_param_int,vci_param_ext>
116
117////////////////////////
118tmpl(/**/)::VciIoBridge(
119    sc_module_name                                  name,
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)
131    : soclib::caba::BaseModule(name),
132
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"),
140
141      m_words( dcache_words ),
142
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
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
154      // addressable registers
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"),
160      r_iommu_wti_enable("r_iommu_wti_enable"),
161      r_iommu_wti_addr_lo("r_iommu_wti_addr_lo"),
162
163      // DMA_CMD FSM registers
164      r_dma_cmd_fsm("r_dma_cmd_fsm"),
165      r_dma_cmd_paddr("r_dma_cmd_paddr"),
166
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     
182      //DMA_RSP FSM registers
183      r_dma_rsp_fsm("r_dma_rsp_fsm"),
184
185      // CONFIG_CMD FSM registers
186      r_config_cmd_fsm("r_config_cmd_fsm"),
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
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"),
209
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"),
215      r_waiting_transaction("r_waiting_transaction"),
216      r_tlb_miss_type("r_tlb_miss_type"),
217      r_tlb_miss_error("r_tlb_miss_error"),
218
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"),
223      r_tlb_set("r_tlb_set"), 
224   
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"),
229
230      r_tlb_to_miss_wti_cmd_req("r_tlb_to_miss_wti_cmd_req"),
231
232      // MISS_WTI_RSP FSM registers
233      r_miss_wti_rsp_fsm("r_miss_wti_rsp_fsm"), 
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"),
237
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"),
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), 
262
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),
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)
310{
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()
322                  << " / size = " << int_seg->size() 
323                  << " / special = " << int_seg->special() << std::endl; 
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
344    assert( (vci_param_int::B == 4) and
345    "VCI_IO_BRIDGE ERROR: VCI DATA width must be 32 bits on internal network");   
346
347    assert( (vci_param_ext::B == 8) and
348    "VCI_IO_BRIDGE ERROR: VCI DATA width must be 64 bits on external network");   
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
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{
370    delete [] r_tlb_buf_data;
371}
372
373////////////////////////////////////
374tmpl(void)::print_trace(size_t mode)
375////////////////////////////////////
376{
377    // b0 : IOTLB trace
378
379    std::cout << std::dec << "IO_BRIDGE " << name() << std::endl;
380
381    std::cout << "  "  << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()]
382              << " | " << dma_rsp_fsm_state_str[r_dma_rsp_fsm.read()]
383              << " | " << tlb_fsm_state_str[r_tlb_fsm.read()]
384              << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()]
385              << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()]
386              << " | " << miss_wti_rsp_state_str[r_miss_wti_rsp_fsm.read()]
387              << std::endl;
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
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
428/////////////////////////
429tmpl(void)::transition()
430/////////////////////////
431{
432    if ( not p_resetn.read() ) 
433    {
434        r_dma_cmd_fsm      = DMA_CMD_IDLE;
435        r_dma_rsp_fsm      = DMA_RSP_IDLE_DMA;
436        r_tlb_fsm              = TLB_IDLE;
437        r_config_cmd_fsm   = CONFIG_CMD_IDLE;
438        r_config_rsp_fsm   = CONFIG_RSP_IDLE_IOX;
439        r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE;
440
441        r_tlb_buf_valid    = false; 
442                r_iommu_active     = false;
443                r_iommu_wti_enable = false;
444
445        r_xicu_size        = 0;
446        r_xicu_base        = 0;
447
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       
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       
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       
508        // SET/RESET Communication flip-flops
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;
516
517        // error flip_flops
518        r_miss_wti_rsp_error_miss      = false;
519        r_miss_wti_rsp_error_wti       = false;
520
521        // Debug variable
522                m_debug_activated                  = false;
523       
524            // activity counters
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;   
530       
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;
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;
538        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_tlb                [i]   = 0;
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;
541        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_rsp       [i]   = 0;
542
543        return;
544    }
545
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();
549   
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;
558
559    bool            config_cmd_fifo_put       = false;
560    bool            config_cmd_fifo_get       = p_vci_ini_iox.cmdack.read();
561
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
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() ] ++;
583    m_cpt_fsm_tlb                   [r_tlb_fsm.read() ] ++;
584    m_cpt_fsm_config_cmd            [r_config_cmd_fsm.read() ] ++;
585    m_cpt_fsm_config_rsp            [r_config_rsp_fsm.read() ] ++;
586    m_cpt_fsm_miss_wti_rsp      [r_miss_wti_rsp_fsm.read() ] ++;
587#endif
588
589    m_cpt_total_cycles++;
590
591    m_debug_activated  = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
592
593    //////////////////////////////////////////////////////////////////////////////
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)
607    ///////////////////////////////////////////////////////////////////////////////
608
609    switch( r_dma_cmd_fsm.read() ) 
610    {
611    //////////////////
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
615    {
616        if ( p_vci_tgt_iox.cmdval.read() ) 
617        { 
618            if ( not r_iommu_active.read() )    // tlb not activated
619            {
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
637#if DEBUG_DMA_CMD
638if( m_debug_activated )
639std::cout << "  <IOB DMA_CMD_IDLE> DMA command" << std::endl
640          << " : address = " << std::hex << p_vci_tgt_iox.address.read()
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;
645#endif
646            }
647            else if (r_tlb_fsm.read() == TLB_IDLE ||
648                     r_tlb_fsm.read() == TLB_WAIT )       // tlb access possible
649            {
650                vci_addr_t      iotlb_paddr;
651                pte_info_t  iotlb_flags; 
652                size_t      iotlb_way; 
653                size_t      iotlb_set;
654                vci_addr_t  iotlb_nline;
655                bool            iotlb_hit; 
656
657#ifdef INSTRUMENTATION
658m_cpt_iotlb_read++;
659#endif
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
666           
667                if ( iotlb_hit )                                     // tlb hit
668                { 
669                    if ( not iotlb_flags.w and    // access right violation
670                        (p_vci_tgt_iox.cmd.read() == vci_param_ext::CMD_WRITE) ) 
671                    {
672                        // register error
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();
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;
684#if DEBUG_DMA_CMD
685if( m_debug_activated )
686std::cout << "  <IOB DMA_CMD_IDLE> TLB HIT but writable violation" << std::endl;
687#endif
688                    }
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
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                        }
711                    }
712                }
713                else                                             // TLB miss
714                {
715
716#ifdef INSTRUMENTATION
717m_cpt_iotlb_miss++;
718#endif
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;
723#if DEBUG_DMA_CMD
724if( m_debug_activated )
725std::cout << "  <IOB DMA_CMD_IDLE> TLB MISS" << std::endl;
726#endif
727                } // end tlb miss
728            } // end if tlb_activated
729        } // end if cmdval
730        break;
731    }
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
737    {
738        if ( p_vci_tgt_iox.cmdval && m_dma_cmd_addr_fifo.wok() ) 
739        {
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;
744
745            if ( p_vci_tgt_iox.eop.read() )    r_dma_cmd_fsm   = DMA_CMD_IDLE;
746           
747#if DEBUG_DMA_CMD
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()
753          << " plen = " << std::dec << p_vci_tgt_iox.plen.read()
754          << " eop = " << std::dec << p_vci_tgt_iox.eop.read() << std::endl;
755#endif
756        }
757        break;
758    }
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
764    {
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        }
785        break;
786    }
787    //////////////////////////
788    case DMA_CMD_ERR_WAIT_EOP:   // wait EOP before requesting WTI & error response
789                                 // VCI flit is always consumed
790    {
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
807        {
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;
815
816            r_dma_cmd_fsm            = DMA_CMD_ERR_RSP_REQ;
817
818#if DEBUG_DMA_CMD
819if( m_debug_activated ) 
820std::cout << "  <IOB DMA_CMD_ERR_WTI_REQ> request an IOMMU WTI" << std::endl;
821#endif
822        }
823        break;
824    }
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
830    {
831        if ( not r_dma_cmd_to_dma_rsp_req.read() )  // no pending previous request
832        {
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        {
845            if ( r_tlb_miss_error.read() )   // Error reported by TLB FSM
846            {
847                r_iommu_etr     = MMU_READ_PT2_UNMAPPED; 
848                r_iommu_bvar    = r_dma_cmd_to_tlb_vaddr.read();
849                r_iommu_bad_id  = p_vci_tgt_iox.srcid.read();
850                r_dma_cmd_fsm   = DMA_CMD_ERR_WAIT_EOP;
851            }
852            else                            // No error
853            {
854                r_dma_cmd_fsm   = DMA_CMD_IDLE;
855            }
856        }
857        break;
858    }
859    } // end switch DMA_CMD FSM
860
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    ////////////////////////////////////////////////////////////////////////////////
870
871    // does nothing if FIFO is full
872    if ( m_dma_rsp_rerror_fifo.wok() )
873    {
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();
910
911                // update priority
912                if ( p_vci_ini_ram.reop.read() ) r_dma_rsp_fsm = DMA_RSP_IDLE_WTI;
913
914#if DEBUG_DMA_RSP
915if( m_debug_activated ) 
916std::cout << "  <IOB DMA_RSP_PUT_DMA> Push DMA response into DMA_RSP FIFO" 
917          << " : rsrcid = " << std::hex << p_vci_ini_ram.rsrcid.read()
918          << " / rtrdid = " << p_vci_ini_ram.rtrdid.read()
919          << " / rpktid = " << p_vci_ini_ram.rpktid.read()
920          << " / rdata = "  << p_vci_ini_ram.rdata.read()
921          << " / rerror = " << p_vci_ini_ram.rerror.read()
922          << " / reop = "   << p_vci_ini_ram.reop.read() << std::endl;
923#endif
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;
936
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
988    //////////////////////////////////////////////////////////////////////////////////
989    // The TLB FSM handles the TLB miss requests from DMA_CMD FSM,
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.
994    // It bypass the first level page table access if possible.
995    // It reset the r_dma_cmd_to_tlb_req flip-flop to signal TLB miss completion.
996    // An unexpected, but possible page fault is signaled in r_tlb_miss_error flip_flop.
997    ////////////////////////////////////////////////////////////////////////////////////
998
999    switch (r_tlb_fsm.read())
1000    {
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
1004    {
1005        if ( r_config_cmd_to_tlb_req.read() ) // Request for a PTE invalidation
1006        {
1007            r_config_cmd_to_tlb_req  = false;
1008            r_waiting_transaction    = false;
1009            r_tlb_fsm                = TLB_INVAL_CHECK;
1010        }
1011
1012        else if ( r_dma_cmd_to_tlb_req.read() )   // request for a TLB Miss
1013        {
1014            // Checking prefetch buffer
1015            if( not r_tlb_buf_big_page )     // small page => PTE2
1016            {
1017                if( r_tlb_buf_valid &&         // Hit on prefetch buffer
1018                    (r_tlb_buf_vaddr.read() == 
1019                    (r_dma_cmd_to_tlb_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK)))
1020                {
1021                    size_t   pte_offset = (r_dma_cmd_to_tlb_vaddr.read()& PTE2_LINE_OFFSET)>>12; 
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]; 
1024               
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;
1030                       
1031                        r_tlb_miss_error = true;
1032                        r_dma_cmd_to_tlb_req    = false;
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;
1039#endif
1040                        break; 
1041                    }
1042
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;
1052#endif
1053                    break;   
1054                }
1055            }
1056            else                             // big page => PTE1
1057            {
1058                if( r_tlb_buf_valid &&         // Hit on prefetch buffer
1059                    (r_tlb_buf_vaddr.read() == 
1060                    (r_dma_cmd_to_tlb_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 
1061                {
1062                    size_t   pte_offset = (r_dma_cmd_to_tlb_vaddr.read()& PTE1_LINE_OFFSET)>>21; 
1063                    uint32_t pte_flags  = r_tlb_buf_data[pte_offset];
1064                           
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;
1070                       
1071                        r_tlb_miss_error = true;
1072                        r_dma_cmd_to_tlb_req    = false;
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;
1078#endif
1079                        break; 
1080                    }
1081
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;
1090#endif
1091                    break;
1092                }
1093            }
1094       
1095            // prefetch buffer miss
1096            r_tlb_fsm = TLB_MISS; 
1097
1098#if DEBUG_TLB_MISS
1099if ( m_debug_activated )
1100std::cout << "  <IOB TLB_IDLE> Miss on prefetch buffer"
1101          << std::hex << " / vaddr = " << r_dma_cmd_to_tlb_vaddr.read() << std::endl;
1102#endif
1103        }
1104        break;
1105    }
1106    //////////////
1107    case TLB_MISS: // handling tlb miss
1108    {
1109        uint32_t        ptba = 0; 
1110        bool            bypass;
1111        vci_addr_t      pte_paddr;
1112
1113#ifdef INSTRUMENTATION
1114m_cpt_iotlbmiss_transaction++;
1115#endif
1116        // evaluate bypass in order to skip first level page table access
1117        bypass = r_iotlb.get_bypass(r_dma_cmd_to_tlb_vaddr.read(), &ptba);
1118       
1119        // Request MISS_WTI_FSM a transaction on INT Network
1120        if ( not bypass )     // Read PTE1/PTD1 in XRAM
1121        {
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)) |
1128                        (vci_addr_t)((r_dma_cmd_to_tlb_vaddr.read() >> PAGE_M_NBITS) << 2);
1129            r_tlb_paddr = pte_paddr;
1130           
1131            r_tlb_to_miss_wti_cmd_req = true;
1132            r_tlb_miss_type           = PTE1_MISS;
1133            r_tlb_fsm                 = TLB_WAIT;
1134        }
1135        else                  // Read PTE2 in XRAM
1136        {
1137
1138#if DEBUG_TLB_MISS
1139if ( m_debug_activated )
1140std::cout << "  <IOB TLB_MISS> Read PTE2 in memory" << std::endl;
1141#endif
1142            //&PTE2 = PTBA + IX2 * 8
1143            pte_paddr = (vci_addr_t)ptba << PAGE_K_NBITS |
1144                        (vci_addr_t)(r_dma_cmd_to_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
1145           
1146            r_tlb_paddr = pte_paddr;
1147           
1148            r_tlb_to_miss_wti_cmd_req = true;
1149            r_tlb_miss_type           = PTE2_MISS;
1150            r_tlb_fsm                 = TLB_WAIT;
1151        }
1152
1153        break;
1154    }
1155    ////////////////// 
1156    case TLB_PTE1_GET:  // Try to read a PT1 entry in the miss buffer
1157    {
1158       
1159        uint32_t  entry;
1160       
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 );
1163
1164        // Hit test. Just to verify.
1165        // Hit must happen, since we've just finished its' miss transaction
1166        bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 
1167        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
1168       
1169        entry = r_tlb_buf_data[word_position];
1170           
1171        // Bit valid checking
1172        if ( not ( entry & PTE_V_MASK) )        // unmapped
1173        {
1174            //must not occur!
1175            std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl
1176                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1177                       
1178            r_tlb_miss_error       = true;
1179            r_dma_cmd_to_tlb_req   = false;
1180            r_tlb_fsm              = TLB_IDLE;           
1181
1182#if DEBUG_TLB_MISS
1183if ( m_debug_activated )
1184{
1185    std::cout << "  <IOB DMA_PTE1_GET> First level entry Unmapped"
1186              << std::hex << " / paddr = " << r_tlb_paddr.read()
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
1196            r_iotlb.set_bypass( r_dma_cmd_to_tlb_vaddr.read(),
1197                                entry & ((1 << (vci_param_int::N-PAGE_K_NBITS)) - 1), 
1198                                0); //nline, unused
1199
1200            // &PTE2 = PTBA + IX2 * 8
1201            // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
1202            r_tlb_paddr = (vci_addr_t)(entry & ((1<<(vci_param_int::N-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
1203                                (vci_addr_t)(((r_dma_cmd_to_tlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
1204
1205            r_tlb_to_miss_wti_cmd_req = true;
1206            r_tlb_miss_type           = PTE2_MISS;
1207            r_tlb_fsm                 = TLB_WAIT;
1208
1209#ifdef INSTRUMENTATION
1210m_cpt_iotlbmiss_transaction++;
1211#endif
1212
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;
1218#endif
1219        }
1220        else                    //  PTE1 :  we must update the IOTLB
1221                        //  Should not occur if working only with small pages
1222        {
1223            r_tlb_pte_flags   = entry;
1224            r_tlb_fsm  = TLB_PTE1_SELECT;
1225
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;
1231#endif
1232        }
1233        break;
1234    }
1235    /////////////////////
1236    case TLB_PTE1_SELECT:       // select a slot for PTE1
1237    {
1238        size_t  way;
1239        size_t  set;
1240       
1241        r_iotlb.select(  r_dma_cmd_to_tlb_vaddr.read(),
1242                        true,  // PTE1
1243                        &way,
1244                        &set );
1245#ifdef INSTRUMENTATION
1246m_cpt_iotlb_read++;
1247#endif
1248
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;
1254#endif
1255        r_tlb_way = way;
1256        r_tlb_set = set;
1257        r_tlb_fsm     = TLB_PTE1_UPDT;
1258        break;
1259    }
1260    ///////////////////
1261    case TLB_PTE1_UPDT:     // write a new PTE1 in tlb
1262                            // not necessary to treat the L/R bit
1263    {
1264        uint32_t  pte   = r_tlb_pte_flags.read();
1265       
1266        r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_flags.read() & PPN1_MASK) << 21)
1267                        | (r_dma_cmd_to_tlb_vaddr.read()& M_PAGE_OFFSET_MASK) );
1268       
1269        // update TLB
1270        r_iotlb.write( true,            // 2M page
1271                      pte,
1272                      0,                // argument unused for a PTE1
1273                      r_dma_cmd_to_tlb_vaddr.read(),   
1274                      r_tlb_way.read(), 
1275                      r_tlb_set.read(),
1276                      0 );      //we set nline = 0
1277
1278#ifdef INSTRUMENTATION
1279m_cpt_iotlb_write++;
1280#endif
1281
1282#if DEBUG_TLB_MISS
1283if ( m_debug_activated )
1284{
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();
1289}
1290#endif
1291        // next state
1292        r_tlb_fsm = TLB_RETURN; // exit sub-fsm
1293        break;
1294    }
1295    //////////////////
1296    case TLB_PTE2_GET:  // Try to read a PTE2 (64 bits) in the miss buffer
1297    {   
1298        uint32_t        pte_flags;
1299        uint32_t        pte_ppn;
1300       
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 );
1303       
1304       
1305        // Hit test. Just to verify.
1306        bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 
1307        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
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
1310        // Bit valid checking
1311        if ( not ( pte_flags & PTE_V_MASK) )    // unmapped
1312        {
1313            //must not occur!
1314            std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl
1315                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1316                       
1317            r_tlb_miss_error       = true;
1318            r_dma_cmd_to_tlb_req         = false;
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;
1326#endif
1327            break; 
1328        }
1329           
1330        r_tlb_pte_flags       = pte_flags; 
1331        r_tlb_pte_ppn         = pte_ppn;
1332        r_tlb_fsm           = TLB_PTE2_SELECT;
1333               
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;
1339#endif
1340        break;
1341    }
1342    ////////////////////////////
1343    case TLB_PTE2_SELECT:    // select a slot for PTE2
1344    {
1345        size_t way;
1346        size_t set;
1347
1348        r_iotlb.select( r_dma_cmd_to_tlb_vaddr.read(),
1349                        false,  // PTE2
1350                        &way,
1351                        &set );
1352#ifdef INSTRUMENTATION
1353m_cpt_iotlb_read++;
1354#endif
1355
1356#if DEBUG_TLB_MISS
1357if ( m_debug_activated )
1358std::cout << "  <IOB TLB_PTE2_SELECT> Select a slot in IOTLB:"
1359          << " way = " << std::dec << way
1360          << " / set = " << set << std::endl;
1361#endif
1362        r_tlb_way = way;
1363        r_tlb_set = set;
1364        r_tlb_fsm     = TLB_PTE2_UPDT;
1365        break;
1366    }
1367    ///////////////////
1368    case TLB_PTE2_UPDT:         // write a new PTE2 in tlb
1369                                // not necessary to treat the L/R bit
1370    {
1371        uint32_t        pte_flags = r_tlb_pte_flags.read();
1372        uint32_t        pte_ppn   = r_tlb_pte_ppn.read();
1373       
1374        r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_ppn.read() & PPN2_MASK) << 12)
1375                        | (r_dma_cmd_to_tlb_vaddr.read()& K_PAGE_OFFSET_MASK) );
1376       
1377        // update TLB for a PTE2
1378        r_iotlb.write( false,   // 4K page
1379                       pte_flags,
1380                       pte_ppn,
1381                       r_dma_cmd_to_tlb_vaddr.read(),   
1382                       r_tlb_way.read(), 
1383                       r_tlb_set.read(),
1384                       0 );     // nline = 0
1385#ifdef INSTRUMENTATION
1386m_cpt_iotlb_write++;
1387#endif
1388
1389#if DEBUG_TLB_MISS
1390if ( m_debug_activated )
1391{
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();
1396}
1397#endif
1398        // next state
1399        r_tlb_fsm = TLB_RETURN; 
1400        break;
1401    }
1402    //////////////
1403    case TLB_WAIT:   // waiting completion of a miss transaction from MISS_WTI FSM
1404                     // PTE inval request are handled as unmaskable interrupts
1405    {
1406        if ( r_config_cmd_to_tlb_req.read() ) // Request for a PTE invalidation
1407        {
1408            r_config_cmd_to_tlb_req = false;
1409            r_waiting_transaction   = true;
1410            r_tlb_fsm               = TLB_INVAL_CHECK;
1411        }
1412
1413#ifdef INSTRUMENTATION
1414m_cost_iotlbmiss_transaction++;
1415#endif
1416        if ( not r_tlb_to_miss_wti_cmd_req.read() )     //  Miss transaction completed
1417        { 
1418                if ( r_miss_wti_rsp_error_miss.read() ) // bus error reported
1419                {
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;
1424            }
1425            else if(r_tlb_miss_type == PTE1_MISS)
1426            {
1427                r_tlb_fsm = TLB_PTE1_GET; 
1428            }
1429            else
1430            {
1431                r_tlb_fsm = TLB_PTE2_GET;
1432            }
1433        }
1434        break;
1435    }
1436    ////////////////
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
1439    {
1440#if DEBUG_TLB_MISS
1441if ( m_debug_activated )
1442std::cout << "  <IOB TLB_RETURN> IOTLB MISS completed" << std::endl;
1443#endif
1444        r_dma_cmd_to_tlb_req  = false;
1445        r_tlb_fsm = TLB_IDLE;
1446        break;
1447    }
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
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
1455        if(!r_waiting_transaction.read() && r_tlb_buf_valid)
1456        {
1457            if(!r_tlb_buf_big_page)
1458            {
1459               if( r_tlb_buf_vaddr.read() == 
1460                   (r_config_cmd_to_tlb_vaddr.read()& ~PTE2_LINE_OFFSET) ) 
1461                // The virtual address corresponds to one entry on the buffer line
1462                {
1463                    r_tlb_buf_valid = false;   //change here for individual invalidation
1464                }
1465            }
1466            else    // First level entries on buffer. Unused if only small pages
1467            {
1468               if( r_tlb_buf_vaddr.read() == 
1469                   (r_config_cmd_to_tlb_vaddr.read()& ~PTE1_LINE_OFFSET) ) 
1470                // The virtual address corresponds to one entry on the buffer line
1471                {
1472                    r_tlb_buf_valid = false;   //change here for individual invalidation
1473                }
1474            }
1475        }
1476       
1477        // Invalidation on IOTLB
1478        bool    ok;
1479        ok = r_iotlb.inval(r_config_cmd_to_tlb_vaddr.read());
1480         
1481        if(r_waiting_transaction.read()) r_tlb_fsm =TLB_WAIT; 
1482        else r_tlb_fsm = TLB_IDLE;
1483        break; 
1484    }
1485    } //end switch r_tlb_fsm
1486   
1487    ////////////////////////////////////////////////////////////////////////////////
1488    // The CONFIG_CMD_FSM handles the VCI commands from the INT network.
1489    // - it can be single flit config transactions
1490    // - it can be multi-flits data transactions to ROM (read) or FBF (write).
1491    // The write burst transactions must be serialised from 32 to 64 bits width.
1492    // The configuration requests can be local (IO_BRIDGE config registers)
1493    // or remote (config registers of peripherals on IOX network).
1494    // - The local configuration segment is identified by the "special" atribute
1495    //   in the mapping table.
1496    // - All configuration requests are checkeg against segmentation violation.
1497    // - In case of local config request, or in case of segmentation violation,
1498    //   the FSM send a response request to CONFIG_RSP FSM.
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.
1501    ///////////////////////////////////////////////////////////////////////////////
1502
1503    switch( r_config_cmd_fsm.read() ) 
1504    {
1505    /////////////////////
1506    case CONFIG_CMD_IDLE:   // A VCI INT command is always consumed in this state
1507    {
1508        if ( p_vci_tgt_int.cmdval.read() ) 
1509        {
1510
1511#if DEBUG_CONFIG_CMD
1512if( m_debug_activated )
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()
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;
1521#endif
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); 
1525            bool       eop   = p_vci_tgt_int.eop.read();
1526            bool       high  = (paddr & 0x4);
1527
1528            // chek segments
1529            std::list<soclib::common::Segment>::iterator seg;
1530            bool found   = false;
1531            bool special = false;
1532            for ( seg = m_int_seglist.begin() ; 
1533                  seg != m_int_seglist.end() and not found ; seg++ )
1534            {
1535                if ( seg->contains(paddr) ) 
1536                {
1537                   found   = true;
1538                   special = seg->special();
1539                }
1540            }
1541           
1542            if ( found and special )  // IO_BRIDGE itself
1543            {
1544                bool rerror = false;
1545
1546                assert( (p_vci_tgt_int.be.read() == 0xF) and
1547                "ERROR in vci_io_bridge : BE must be 0xF for a config access");
1548
1549                assert( ( eop ) and
1550                "ERROR in vci_io_bridge : local config access must be one flit");
1551
1552                if ( not read && (cell == IOB_IOMMU_PTPR) )       // WRITE PTPR
1553                {
1554                    r_iommu_ptpr = (uint32_t)p_vci_tgt_int.wdata.read();
1555                }
1556                else if ( read && (cell == IOB_IOMMU_PTPR) )      // READ PTPR
1557                {
1558                    r_config_cmd_to_config_rsp_rdata = r_iommu_ptpr.read();
1559                }
1560                else if( not read && (cell == IOB_WTI_ENABLE))  // WRITE WTI_ENABLE
1561                {
1562                    r_iommu_wti_enable = p_vci_tgt_int.wdata.read();
1563                }
1564                else if( read && (cell == IOB_WTI_ENABLE))       // READ WTI ENABLE
1565                {
1566                    r_config_cmd_to_config_rsp_rdata = r_iommu_wti_enable.read();
1567                }
1568                else if( read && (cell == IOB_IOMMU_BVAR))        // READ BVAR
1569                {
1570                    r_config_cmd_to_config_rsp_rdata = r_iommu_bvar.read();
1571                }
1572                else if( read && (cell == IOB_IOMMU_ETR))          // READ ETR
1573                {
1574                    r_config_cmd_to_config_rsp_rdata = r_iommu_etr.read();
1575                }
1576                else if( read && (cell == IOB_IOMMU_BAD_ID))      // READ BAD_ID
1577                {
1578                    r_config_cmd_to_config_rsp_rdata = r_iommu_bad_id.read();
1579                }
1580                else if( not read && (cell == IOB_INVAL_PTE))     // WRITE INVAL_PTE
1581                {
1582                    r_config_cmd_to_tlb_req   = true;
1583                    r_config_cmd_to_tlb_vaddr = (uint32_t)p_vci_tgt_int.wdata.read();
1584                }
1585                else if( not read && (cell == IOB_WTI_ADDR_LO)) // WRITE WTI_PADDR_LO
1586                {
1587                    r_iommu_wti_addr_lo = (vci_addr_t)p_vci_tgt_int.wdata.read();
1588                }
1589                else if( read && (cell == IOB_WTI_ADDR_LO))    // READ WTI_PADDR_LO
1590                {
1591                    r_config_cmd_to_config_rsp_rdata = r_iommu_wti_addr_lo.read();
1592                }
1593                else if( not read && (cell == IOB_WTI_ADDR_HI)) // WRITE WTI_PADDR_HI
1594                {
1595                    r_iommu_wti_addr_hi = (vci_addr_t)p_vci_tgt_int.wdata.read();
1596                }
1597                else if( read && (cell == IOB_WTI_ADDR_HI))    // READ WTI_PADDR_HI
1598                {
1599                    r_config_cmd_to_config_rsp_rdata = r_iommu_wti_addr_hi.read();
1600                }
1601                else if( not read && (cell == IOB_XICU_BASE)) // WRITE XICU_BASE   
1602                {
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   
1606                {
1607                    r_config_cmd_to_config_rsp_rdata = r_xicu_base.read();
1608                }
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                }
1617                else   // Error: Wrong address, or invalid operation.
1618                {
1619                    rerror = true;
1620                }
1621                r_config_cmd_to_config_rsp_rerror = rerror;
1622                r_config_cmd_fsm                 = CONFIG_CMD_RSP;
1623            }
1624            else if ( found )                            // remote peripheral
1625            {
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                }
1673            }
1674            else                                         // out of segment address
1675            {
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;
1679            }
1680        } // end if cmdval
1681        break;
1682    }
1683    /////////////////////
1684    case CONFIG_CMD_NEXT:  // Consume the second flit for a multi-flits write
1685    {
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    ////////////////////
1705    case CONFIG_CMD_PUT:   // post a command to CONFIG_CMD fifo (to IOX network)
1706    {
1707        config_cmd_fifo_put = true;
1708
1709        if ( m_config_cmd_addr_fifo.wok() )
1710        {
1711
1712#if DEBUG_CONFIG_CMD
1713if( m_debug_activated ) 
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()
1718          << std::endl;
1719#endif
1720            r_config_cmd_fsm = CONFIG_CMD_IDLE;
1721        }
1722        break;
1723    }
1724    ////////////////////
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.
1729    {
1730        if ( not r_config_cmd_to_config_rsp_req.read() )
1731        {
1732            r_config_cmd_to_config_rsp_req = true;
1733
1734#if DEBUG_CONFIG_CMD
1735if( m_debug_activated ) 
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;
1738#endif
1739            r_config_cmd_fsm = CONFIG_CMD_IDLE;
1740        }
1741        break;
1742    }
1743    } // end switch CONFIG_CMD FSM
1744
1745    //////////////////////////////////////////////////////////////////////////////
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).
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.
1756    //////////////////////////////////////////////////////////////////////////////
1757
1758    // does nothing if FIFO full
1759    if ( m_config_rsp_rerror_fifo.wok() )
1760    {
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;
1783            }
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
1808            {
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;
1816
1817                r_config_rsp_fsm   = CONFIG_RSP_PUT_HI;
1818
1819#if DEBUG_CONFIG_RSP
1820if( m_debug_activated ) 
1821std::cout << "  <IOB CONFIG_RSP_PUT_LOW> Push multi-flit response into CONFIG_RSP FIFO" 
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
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();
1842
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
1846#if DEBUG_CONFIG_RSP
1847if( m_debug_activated ) 
1848std::cout << "  <IOB CONFIG_RSP_PUT_HI> Push multi-flit response into CONFIG_RSP FIFO" 
1849          << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read()
1850          << " / rtrdid = " << p_vci_ini_iox.rtrdid.read()
1851          << " / rpktid = " << p_vci_ini_iox.rpktid.read()
1852          << " / rdata = " << (uint32_t)(p_vci_ini_iox.rdata.read() >> 32)
1853          << " / reop  = " << p_vci_ini_iox.reop.read()
1854          << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl;
1855#endif
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");
1864
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
1876#if DEBUG_CONFIG_RSP
1877if( m_debug_activated ) 
1878std::cout << "  <IOB CONFIG_RSP_PUT_UNC> Push single flit response into CONFIG_RSP FIFO" 
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
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;
1899
1900                // acknowledge request
1901                r_config_cmd_to_config_rsp_req = false;
1902
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
1921    ///////////////////////////////////////////////////////////////////////////////////
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.
1934    ////////////////////////////////////////////////////////////////////////////////////
1935 
1936    if ( r_tlb_to_miss_wti_cmd_req.read() and 
1937         m_miss_wti_cmd_addr_fifo.wok() )                   // put MISS READ
1938    {
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;
1946
1947#if DEBUG_MISS_WTI_CMD
1948if( m_debug_activated )
1949std::cout << "  <IOB MISS_WTI_CMD_WTI> push MISS TLB command into MISS_WTI FIFO"
1950          << " / PADDR = " << miss_wti_cmd_fifo_address << std::endl;
1951#endif
1952
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
1968if( m_debug_activated )
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;
1972#endif
1973
1974    }     
1975
1976    ///////////////////////////////////////////////////////////////////////////////////
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.
1987    ////////////////////////////////////////////////////////////////////////////////////
1988 
1989    switch ( r_miss_wti_rsp_fsm.read() ) 
1990    {
1991        ///////////////////////
1992        case MISS_WTI_RSP_IDLE:   // waiting a VCI response
1993                                  // no VCI flit is consumed
1994        {
1995            if ( p_vci_ini_int.rspval.read() ) 
1996            {
1997                if ( p_vci_ini_int.rpktid.read() == PKTID_WTI_IOX ) 
1998                {
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                {
2007                    r_miss_wti_rsp_fsm   = MISS_WTI_RSP_MISS;
2008                    r_miss_wti_rsp_count = 0;
2009                }
2010                else
2011                {
2012                    assert ( false and
2013                    "VCI_IO_BRIDGE ERROR : illegal response type on INT network");
2014                }
2015            }
2016            break;
2017        }
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.
2023        {
2024            assert( p_vci_ini_int.reop.read() and
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();
2034
2035                r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE;
2036
2037#if DEBUG_MISS_WTI_RSP
2038if( m_debug_activated )
2039std::cout << "  <IOB MISS_WTI_RSP_WTI_IOX> Transfer response to a WTI_IOX" << std::endl;
2040#endif
2041            }
2042            break;
2043        }
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        }
2065        ///////////////////////
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.
2070        {
2071            if ( p_vci_ini_int.rspval.read() ) 
2072            {
2073                if ( (p_vci_ini_int.rerror.read()&0x1) != 0 )  // error reported
2074                {
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
2080                }
2081                else                                           // no error
2082                {
2083
2084#if DEBUG_MISS_WTI_CMD
2085if( m_debug_activated ) 
2086std::cout << "  <IOB MISS_WTI_RSP_MISS> Receive response to a TLB MISS"
2087          << " / Count = " << r_miss_wti_rsp_count.read()
2088          << " / Data = " << std::hex << p_vci_ini_int.rdata.read() << std::endl; 
2089#endif
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();
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");
2098
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                {
2105                    r_miss_wti_rsp_count = r_miss_wti_rsp_count.read() + 1;
2106                }
2107            }
2108            break;
2109        }
2110    } // end  switch r_miss_wti_rsp_fsm
2111
2112
2113    ///////////////////////////////////////////////////////////
2114    // DMA_CMD fifo update
2115    // writer : DMA_CMD FSM
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
2163    // writer : DMA_RSP FSM
2164    //////////////////////////////////////////////////////////////
2165
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 );
2184
2185    ////////////////////////////////////////////////////////////////
2186    // CONFIG_CMD fifo update
2187    // writer : CONFIG_CMD FSM
2188    ////////////////////////////////////////////////////////////////
2189
2190    m_config_cmd_addr_fifo.update(   config_cmd_fifo_get,
2191                                     config_cmd_fifo_put,
2192                                     r_config_cmd_address.read() ); 
2193    m_config_cmd_cmd_fifo.update(    config_cmd_fifo_get,
2194                                     config_cmd_fifo_put,
2195                                     r_config_cmd_cmd.read() ); 
2196    m_config_cmd_contig_fifo.update( config_cmd_fifo_get,
2197                                     config_cmd_fifo_put,
2198                                     r_config_cmd_contig.read() ); 
2199    m_config_cmd_cons_fifo.update(   config_cmd_fifo_get,
2200                                     config_cmd_fifo_put,
2201                                     r_config_cmd_cons.read() ); 
2202    m_config_cmd_plen_fifo.update(   config_cmd_fifo_get,
2203                                     config_cmd_fifo_put,
2204                                     r_config_cmd_plen.read() ); 
2205    m_config_cmd_wrap_fifo.update(   config_cmd_fifo_get,
2206                                     config_cmd_fifo_put,
2207                                     r_config_cmd_wrap.read() ); 
2208    m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get,
2209                                     config_cmd_fifo_put,
2210                                     r_config_cmd_cfixed.read() ); 
2211    m_config_cmd_clen_fifo.update(   config_cmd_fifo_get,
2212                                     config_cmd_fifo_put,
2213                                     r_config_cmd_clen.read() ); 
2214    m_config_cmd_srcid_fifo.update(  config_cmd_fifo_get,
2215                                     config_cmd_fifo_put,
2216                                     r_config_cmd_srcid.read() );
2217    m_config_cmd_trdid_fifo.update(  config_cmd_fifo_get,
2218                                     config_cmd_fifo_put,
2219                                     r_config_cmd_trdid.read() );
2220    m_config_cmd_pktid_fifo.update(  config_cmd_fifo_get,
2221                                     config_cmd_fifo_put,
2222                                     r_config_cmd_pktid.read() );
2223    m_config_cmd_data_fifo.update(   config_cmd_fifo_get,
2224                                     config_cmd_fifo_put,
2225                                     r_config_cmd_wdata.read() );
2226    m_config_cmd_be_fifo.update(     config_cmd_fifo_get,
2227                                     config_cmd_fifo_put,
2228                                     r_config_cmd_be.read() );
2229    m_config_cmd_eop_fifo.update(    config_cmd_fifo_get,
2230                                     config_cmd_fifo_put,
2231                                     r_config_cmd_eop.read() );
2232   
2233    //////////////////////////////////////////////////////////////////////////
2234    // CONFIG_RSP fifo update
2235    // writer : CONFIG_RSP FSM
2236    //////////////////////////////////////////////////////////////////////////
2237
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    ////////////////////////////////////////////////////////////////
2261
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 );
2304   
2305} // end transition()
2306
2307//////////////////////////////////////////////////////////////////////////
2308tmpl(void)::genMoore()
2309//////////////////////////////////////////////////////////////////////////
2310{
2311    /////////////////  p_vci_ini_ram  /////////////////////////////
2312
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();
2330   
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); 
2335
2336    /////////////////  p_vci_tgt_iox  /////////////////////////////
2337
2338    // VCI target response on IOX network is
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();
2347
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    }
2374
2375    //////////////////  p_vci_ini_iox  /////////////////////////////
2376
2377    // VCI initiator command on IOX network is
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();
2384    p_vci_ini_iox.wdata   = m_config_cmd_data_fifo.read(); 
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();
2394   
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   
2413    // VCI target command ack on INT network
2414    // it depends on the CONFIG_CMD FSM state
2415    switch ( r_config_cmd_fsm.read() ) 
2416    {
2417    case CONFIG_CMD_IDLE:
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:         
2424        p_vci_tgt_int.cmdack  = false;
2425        break;
2426    case CONFIG_CMD_RSP:         
2427        p_vci_tgt_int.cmdack  = false;
2428        break;
2429    }
2430
2431    /////////////////  p_vci_ini_int  ////////////////////////////////
2432
2433    // VCI initiator command  on INT network
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();
2450
2451    // VCI initiator response on INT network
2452    // It depends on the MISS_WTI_RSP FSM state
2453
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    }
2466
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.