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

Last change on this file since 405 was 405, checked in by fraga, 11 years ago

VCI_IO_BRIDGE: Adding some casts to handle the different VCI fields sizes on
each network.

File size: 123.4 KB
Line 
1/* i*- c++ -*-C
2 * File : vci_io_bridge.cpp
3 * Copyright (c) UPMC, Lip6, SoC
4 *
5 * SOCLIB_LGPL_HEADER_BEGIN
6 *
7 * This file is part of SoCLib, GNU LGPLv2.1.
8 *
9 * SoCLib is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; version 2.1 of the License.
12 *
13 * SoCLib is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with SoCLib; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 * SOCLIB_LGPL_HEADER_END
24 */
25
26#include <cassert>
27#include "arithmetics.h"
28#include "alloc_elems.h"
29#include "../include/vci_io_bridge.h"
30
31//////   debug services   ///////////////////////////////////////////////////////
32// All debug messages are conditionned by two variables:
33// - compile time : DEBUG_*** : defined below
34// - execution time : m_debug_***  : defined by constructor arguments
35//    m_debug_* = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)
36/////////////////////////////////////////////////////////////////////////////////
37
38#define DEBUG_DMA_CMD           1
39#define DEBUG_DMA_RSP           1
40#define DEBUG_DMA_TLB           1
41#define DEBUG_CONFIG_CMD                1
42#define DEBUG_CONFIG_RSP                1
43#define DEBUG_MISS_INIT                 1
44
45#define NEW_XRAM_VCI            0
46   
47#define IOMMU_ID                4097
48
49namespace soclib { 
50namespace caba {
51
52namespace {
53
54//DMA
55const char *dma_cmd_fsm_state_str[] = {
56        "DMA_CMD_IDLE",
57        "DMA_CMD_TRT_LOCK",
58        "DMA_CMD_TRT_WAIT",
59        "DMA_CMD_TRT_SET",
60        "DMA_CMD_FIFO_PUT",
61        "DMA_CMD_FIFO_MISS_PUT",
62        "DMA_CMD_TLB_MISS_WAIT",
63        "DMA_CMD_TLB_MISS_STORE",
64        "DMA_CMD_ERROR",
65    };
66
67const char *dma_rsp_fsm_state_str[] = {
68        "DMA_RSP_IDLE",
69        "DMA_RSP_TRT_LOCK",
70        "DMA_RSP_FIFO_PUT",
71        "DMA_RSP_FIFO_ERROR_PUT",
72 };
73
74const char *alloc_trt_dma_fsm_state_str[] = {
75        "ALLOC_TRT_DMA_CMD",
76        "ALLOC_TRT_DMA_RSP",
77    };
78
79const char *dma_tlb_fsm_state_str[] = {
80        "DMA_TLB_IDLE",
81        "DMA_TLB_MISS",
82        "DMA_TLB_PTE1_GET",
83        "DMA_TLB_PTE1_SELECT",
84        "DMA_TLB_PTE1_UPDT",
85        "DMA_TLB_PTE2_GET",                                                 
86        "DMA_TLB_PTE2_SELECT",
87        "DMA_TLB_PTE2_UPDT",
88        "DMA_TLB_WAIT_TRANSACTION",
89        "DMA_TLB_RETURN",
90        "DMA_TLB_INVAL_CHECK",
91        "DMA_TLB_INVAL_SCAN",
92    };
93
94//CONFIG
95const char *config_cmd_fsm_state_str[] = {
96        "CONFIG_CMD_IDLE",
97        "CONFIG_CMD_TRT_LOCK",
98        "CONFIG_CMD_TRT_WAIT",
99        "CONFIG_CMD_TRT_SET",
100        "CONFIG_CMD_FIFO_PUT",
101         
102        // IOB private configuration segment
103        "CONFIG_CMD_PTPR_WRITE",
104        "CONFIG_CMD_PTPR_READ",
105        "CONFIG_CMD_ACTIVE_WRITE",
106        "CONFIG_CMD_ACTIVE_READ",
107        "CONFIG_CMD_BVAR_READ",
108        "CONFIG_CMD_ETR_READ",
109        "CONFIG_CMD_BAD_ID_READ",
110        "CONFIG_CMD_INVAL_REQ",
111        "CONFIG_CMD_INVAL",
112        "CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1",
113        "CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2",
114        "CONFIG_CMD_IT_ADDR_IOMMU_READ_1",
115        "CONFIG_CMD_IT_ADDR_IOMMU_READ_2",
116        "CONFIG_CMD_IT_ADDR_WRITE_1",
117        "CONFIG_CMD_IT_ADDR_WRITE_2",
118        "CONFIG_CMD_IT_ADDR_READ_1",
119        "CONFIG_CMD_IT_ADDR_READ_2",
120        "CONFIG_CMD_ERROR_WAIT",
121        "CONFIG_CMD_ERROR_RSP",
122    };
123
124const char *config_rsp_fsm_state_str[] = {
125        "CONFIG_RSP_IDLE",
126        "CONFIG_RSP_TRT_LOCK",
127        "CONFIG_RSP_FIFO_PUT", 
128    };
129
130const char *alloc_trt_config_fsm_state_str[] = {
131        "ALLOC_TRT_CONFIG_CMD",
132        "ALLOC_TRT_CONFIG_RSP",
133    };
134
135//MISS TRANSACTIONS (to Direct Network)
136const char *miss_init_fsm_state_str[] = { 
137        "MISS_INIT_IDLE_MISS",
138        "MISS_INIT_IDLE_IRQ",
139        "MISS_INIT_IRQ_CMD",
140        "MISS_INIT_IRQ_RSP",
141        "MISS_INIT_TLB_MISS_CMD",
142        "MISS_INIT_TLB_MISS_RSP",
143    };
144}
145
146#define tmpl(...)  template<typename vci_param_d,typename vci_param_x, typename vci_param_io> __VA_ARGS__ VciIoBridge<vci_param_d,vci_param_x,vci_param_io>
147
148/////////////////////////////////
149tmpl(/**/)::VciIoBridge(
150    sc_module_name                                  name,
151    size_t                              nb_periph,
152    const soclib::common::MappingTable  &mtx,
153    const soclib::common::MappingTable  &mtd,
154    const soclib::common::MappingTable  &mtio,
155    const soclib::common::Segment       &seg_config_iob,
156    const soclib::common::IntTab            &tgt_index_iocluster,
157//    const soclib::common::IntTab          &tgt_index_config,
158    const soclib::common::IntTab            &init_index_direct,
159    const soclib::common::IntTab            &tgt_index_iospace,
160    const soclib::common::IntTab            &init_index_iospace,
161    const soclib::common::IntTab            &init_index_dma,
162    size_t                              dcache_words,
163    size_t                                              iotlb_ways,
164    size_t                                              iotlb_sets,
165    uint32_t                                        debug_start_cycle,
166    bool                                                debug_ok)
167    : soclib::caba::BaseModule(name),
168
169      p_clk("clk"),
170      p_resetn("resetn"),
171      p_irq_in(soclib::common::alloc_elems<sc_core::sc_in<bool> >("irq_in", nb_periph)),
172      p_vci_ini_dma("vci_ini_dma"),
173      p_vci_tgt_dma("vci_tgt_dma"),
174      p_vci_ini_config("vci_ini_config"),
175      p_vci_tgt_config("vci_tgt_config"),
176      p_vci_ini_miss("vci_ini_miss"),
177
178      m_words(dcache_words),
179      m_nb_periph(nb_periph),
180     
181      // m_locality_table_config(mtd.getLocalityTable<unsigned long>(tgt_index_iocluster)),
182      // These structures simulate what in hardware will be a correspondence table
183      // Between segments' base address on the direct space and on the IO space
184      // m_routing_table_config(mtd.getRoutingTable<unsigned long>(tgt_index_iocluster)),
185      //m_mtio(mtio),
186     
187      m_transaction_tab_dma(2),
188      m_transaction_tab_config(1),
189      //Direct Network
190//      m_segment_config(mtd.getSegment(tgt_index_config)),
191      m_segment_config(seg_config_iob),
192      m_srcid_miss(mtx.indexForId(init_index_direct)), 
193      //XRAM Network
194      m_srcid_dma(mtx.indexForId(init_index_dma)),
195      //IO Network
196      m_segment_io(mtio.getSegment(tgt_index_iospace)),
197      m_srcid_config(mtio.indexForId(init_index_iospace)),
198
199      m_iotlb_ways(iotlb_ways),
200      m_iotlb_sets(iotlb_sets),
201      m_paddr_nbits(vci_param_d::N),
202
203      m_debug_start_cycle(debug_start_cycle),
204      m_debug_ok(debug_ok),
205
206      r_iommu_ptpr("r_iommu_ptpr"),
207      r_iommu_active("r_iommu_active"),
208      r_iommu_bvar("r_iommu_bvar"),
209      r_iommu_etr("r_iommu_etr"),
210      r_iommu_bad_id("r_iommu_bad_id"),
211      r_it_addr_iommu("r_it_addr_iommu"),
212
213      // DMA_CMD
214      r_dma_cmd_fsm("r_dma_cmd_fsm"),
215      r_dma_cmd_fsm_save("r_dma_cmd_fsm_save"),     
216      r_miss_interrupt("r_miss_interrupt"),
217      r_dma_cmd_count("r_dma_cmd_count"),
218      r_dma_cmd_trt_index("r_dma_cmd_trt_index"),
219      r_dma_paddr("r_dma_paddr"),
220      // FIFOs
221      m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",4),
222      //m_dma_cmd_length_fifo("m_dma_cmd_length_fifo",4),
223      m_dma_cmd_srcid_fifo("m_dma_cmd_srcid_fifo",4), 
224      m_dma_cmd_trdid_fifo("m_dma_cmd_trdid_fifo",4), 
225      m_dma_cmd_pktid_fifo("m_dma_cmd_pktid_fifo",4), 
226      m_dma_cmd_be_fifo("m_dma_cmd_be_fifo",4), 
227      m_dma_cmd_cmd_fifo("m_dma_cmd_cmd_fifo",4), 
228      m_dma_cmd_contig_fifo("m_dma_cmd_contig_fifo",4), 
229      m_dma_cmd_data_fifo("m_dma_cmd_data_fifo",4), 
230      m_dma_cmd_eop_fifo("m_dma_cmd_eop_fifo",4),
231      m_dma_cmd_cons_fifo("m_dma_cmd_cons_fifo",4), 
232      m_dma_cmd_plen_fifo("m_dma_cmd_plen_fifo",4), 
233      m_dma_cmd_wrap_fifo("m_dma_cmd_wrap_fifo",4), 
234      m_dma_cmd_cfixed_fifo("m_dma_cmd_cfixed_fifo",4),
235      m_dma_cmd_clen_fifo("m_dma_cmd_clen_fifo",4), 
236
237      r_miss_paddr       ("r_miss_paddr"), 
238      r_miss_cmd         ("r_miss_cmd"), 
239      r_miss_contig      ("r_miss_contig"),
240      r_miss_cons        ("r_miss_cons"),
241      r_miss_plen        ("r_miss_plen"),
242      r_miss_wrap        ("r_miss_wrap"),
243      r_miss_cfixed      ("r_miss_cfixed"),   
244      r_miss_clen        ("r_miss_clen"),
245      r_miss_srcid       ("r_miss_srcid"),
246      r_miss_trdid       ("r_miss_trdid"),
247      r_miss_pktid       ("r_miss_pktid"),
248
249      r_dma_error_type("r_dma_error_type"),     
250      r_dma_error_trdid("r_dma_error_trdid"), 
251      r_dma_error_pktid("r_dma_error_pktid"), 
252
253 
254      r_dma_tlb_fsm("r_dma_tlb_fsm"),
255      r_waiting_transaction("r_waiting_transaction"),
256      r_tlb_miss_type("r_tlb_miss_type"),
257
258                     
259      r_iotlb_vaddr("r_iotlb_vaddr"),            // virtual address for a tlb miss
260      r_iotlb_paddr("r_iotlb_paddr"),            // physical address of pte
261      r_iotlb_pte_flags("r_iotlb_pte_flags"),// pte1 or first word of pte2
262      r_iotlb_pte_ppn("r_iotlb_pte_ppn"),        // second word of pte2
263      r_iotlb_way("r_iotlb_way"),                    // selected way in tlb   
264      r_iotlb_set("r_iotlb_set"),                    // selected set in tlb   
265
266      r_iotlb("iotlb", IOMMU_ID, iotlb_ways,iotlb_sets,vci_param_d::N),
267     
268      //DMA_RSP
269      r_dma_rsp_fsm("r_dma_rsp_fsm"),
270      r_dma_rtrdid("r_dma_rtrdid"),
271      r_dma_rsrcid("r_dma_rsrcid"),
272      //Fifo's
273      m_dma_rsp_data_fifo("m_dma_rsp_data_fifo",4),
274      m_dma_rsp_rsrcid_fifo("m_dma_rsp_rsrcid_fifo",4),
275      m_dma_rsp_rtrdid_fifo("m_dma_rsp_rtrdid_fifo",4),
276      m_dma_rsp_rpktid_fifo("m_dma_rsp_rpktid_fifo",4),
277      m_dma_rsp_reop_fifo("m_dma_rsp_reop_fifo",4),
278      m_dma_rsp_rerror_fifo("m_dma_rsp_rerror_fifo",4),
279     
280      r_dma_cmd_rsp_erase_req("r_dma_cmd_rsp_erase_req"),
281      r_dma_cmd_error_req("r_dma_cmd_error_req"),
282      r_dma_tlb_req("r_dma_tlb_req"),
283      r_tlb_dma_untreated("r_tlb_dma_untreated"), 
284      r_dma_tlb_error_req("r_dma_tlb_error_req"),
285      r_config_tlb_req("r_config_tlb_req"),
286      r_config_tlb_inval_vaddr("r_config_tlb_inval_vaddr"), 
287     
288      // ALLOC TRT DMA
289      r_alloc_trt_dma_fsm("r_alloc_trt_dma_fsm"),
290     
291      // CONFIG CMD
292      r_config_cmd_fsm("r_config_cmd_fsm"),
293      r_config_cmd_trt_index("r_config_cmd_trt_index"),
294     
295      m_config_cmd_addr_fifo("m_config_cmd_addr_fifo",4),
296      //m_config_cmd_length_fifo("m_config_cmd_length_fifo",4),
297      m_config_cmd_srcid_fifo("m_config_cmd_srcid_fifo",4),
298      m_config_cmd_trdid_fifo("m_config_cmd_trdid_fifo",4),
299      m_config_cmd_pktid_fifo("m_config_cmd_pktid_fifo",4),
300      m_config_cmd_be_fifo("m_config_cmd_be_fifo",4),
301      m_config_cmd_cmd_fifo("m_config_cmd_cmd_fifo",4),
302      m_config_cmd_contig_fifo("m_config_cmd_contig_fifo",4),
303      m_config_cmd_data_fifo("m_config_cmd_data_fifo",4),
304      m_config_cmd_eop_fifo("m_config_cmd_eop_fifo",4),
305      m_config_cmd_cons_fifo("m_config_cmd_cons_fifo",4),
306      m_config_cmd_plen_fifo("m_config_cmd_plen_fifo",4),
307      m_config_cmd_wrap_fifo("m_config_cmd_wrap_fifo",4),
308      m_config_cmd_cfixed_fifo("m_config_cmd_cfixed_fifo",4),
309      m_config_cmd_clen_fifo("m_config_cmd_clen_fifo",4),
310      // Private configuration registers
311      r_config_error_type("r_config_error_type"),
312      r_config_first_word("r_config_first_word"),
313      r_it_index("r_it_index"),
314      //Fifo's
315      m_config_local_data_fifo("m_config_local_data_fifo",4),     
316      m_config_local_rsrcid_fifo("m_config_local_rsrcid_fifo",4),
317      m_config_local_rtrdid_fifo("m_config_local_rtrdid_fifo",4),
318      m_config_local_rpktid_fifo("m_config_local_rpktid_fifo",4),
319      m_config_local_reop_fifo("m_config_local_reop_fifo",4),
320      m_config_local_rerror_fifo("m_config_local_rerror_fifo",4),   
321      r_config_vaddr("r_config_vaddr"),
322   
323      // CONFIG RSP 
324      r_config_rsp_fsm("r_config_rsp_fsm"),
325      r_config_rtrdid("r_config_rtrdid"),
326      r_config_rsrcid("r_config_rsrcid"),
327      //Fifo's
328      m_config_rsp_data_fifo("m_config_rsp_data_fifo",4),     
329      m_config_rsp_rsrcid_fifo("m_config_rsp_rsrcid_fifo",4),
330      m_config_rsp_rtrdid_fifo("m_config_rsp_rtrdid_fifo",4),
331      m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",4),
332      m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",4),
333      m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",4),   
334
335      // Communication between CONFIG CMD and CONFIG RSP
336      r_config_cmd_rsp_erase_req("r_config_cmd_rsp_erase_req"),     
337   
338      // ALLOC TRT CONFIG
339      r_alloc_trt_config_fsm("r_alloc_trt_config_fsm"), 
340      // MISS INIT
341      r_miss_init_fsm("r_miss_init_fsm"), 
342      r_miss_rdata("r_miss_rdata"),
343      r_miss_rpktid("r_miss_rpktid"),
344      r_miss_rtrdid("r_miss_rtrdid"),
345      r_miss_rerror("r_miss_rerror"),
346      r_miss_reop("r_miss_reop"),
347      //r_miss_rsrcid("r_miss_rsrcid"),
348      r_miss_rsp_cpt("r_miss_rsp_cpt"),
349      //IRQ
350      r_irq_pending("r_irq_pending"),
351      r_irq_mask("r_irq_mask"),
352      r_irq_chosen("r_irq_chosen"),
353     
354      r_tlb_miss_init_req("r_tlb_miss_init_req"),
355      r_miss_init_error("r_miss_init_error"),
356     
357      r_miss_buf_valid("r_miss_buf_valid"),
358      r_miss_buf_tag("r_miss_buf_tag")
359{
360    assert( (vci_param_d::N <=  64) and
361            "ADDRESS cannot be bigger than 64 bits");
362    assert( (vci_param_x::B)*8 == 64 and (vci_param_io::B)*8 == 64 and
363            "DATA field must be 64 bits in Extern and IO Network");
364    assert ( (vci_param_d::B)*8 == 32 
365        and "Error: data field in Direct Noc must be 32 bits" );
366                   
367   
368    // Interruption Address vector, one entry for each IO
369    r_it_addr           = new paddr_t[nb_periph];
370    // One cache line buffer
371    r_miss_buf_data     = new vci_data_t[dcache_words];
372    // Command storage in case of miss TLB
373    // (dcache_words/2) => Maximal size of a write command
374    r_miss_data     = new vci_data_t[dcache_words]; 
375    r_miss_be     = new vci_be_t[dcache_words];
376   
377    SC_METHOD(transition);
378    dont_initialize();
379    sensitive << p_clk.pos();
380 
381    SC_METHOD(genMoore);
382    dont_initialize();
383    sensitive << p_clk.neg();
384
385 }
386
387/////////////////////////////////////
388tmpl(/**/)::~VciIoBridge()
389/////////////////////////////////////
390{
391    delete [] r_it_addr;
392    delete [] r_miss_buf_data;
393    delete [] r_miss_data;
394    delete [] r_miss_be;
395    soclib::common::dealloc_elems(p_irq_in, m_nb_periph);
396}
397
398////////////////////////////////////
399tmpl(void)::print_trace(size_t mode)
400////////////////////////////////////
401{
402    // b0 : IOtlb trace
403
404    std::cout << std::dec << "IO_BRIDGE " << name() << std::endl;
405
406    std::cout << "  " << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()]
407              << " | " << dma_rsp_fsm_state_str[r_dma_rsp_fsm.read()]
408              << " | " << dma_tlb_fsm_state_str[r_dma_tlb_fsm.read()]
409              << " | " << alloc_trt_dma_fsm_state_str[r_alloc_trt_dma_fsm.read()]
410              << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()]
411              << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()]
412              << " | " << alloc_trt_config_fsm_state_str[r_alloc_trt_config_fsm.read()]
413              << " | " << miss_init_fsm_state_str[r_miss_init_fsm.read()];
414    std::cout << std::endl;
415
416    if(mode & 0x01)
417    {
418        std::cout << "  IOTLB" << std::endl;
419        r_iotlb.printTrace();
420    }
421    if(mode & 0x02)
422    {
423       
424    }
425}
426
427
428
429////////////////////////
430tmpl(void)::print_stats()
431////////////////////////
432{
433    std::cout << name() << std::endl
434        << "- IOTLB MISS RATE      = " << (float)m_cpt_iotlb_miss/m_cpt_iotlb_read << std::endl
435        << "- IOTLB MISS COST         = " << (float)m_cost_iotlb_miss/m_cpt_iotlb_miss << std::endl
436        << "- IOTLB MISS TRANSACTION COST  = " << (float)m_cost_iotlbmiss_transaction/m_cpt_iotlbmiss_transaction << std::endl
437        << "- IOTLB MISS TRANSACTION RATE (OVER ALL MISSES)  = " << (float)m_cpt_iotlbmiss_transaction/m_cpt_iotlb_miss << std::endl;
438}
439
440////////////////////////
441tmpl(void)::clear_stats()
442////////////////////////
443{
444    m_cpt_iotlb_read                = 0;             
445    m_cpt_iotlb_miss                = 0;             
446    m_cost_iotlb_miss               = 0;
447    m_cpt_iotlbmiss_transaction     = 0;   
448    m_cost_iotlbmiss_transaction    = 0;   
449       
450    m_cpt_trt_dma_full          = 0;
451    m_cpt_trt_dma_full_cost     = 0;
452    m_cpt_trt_config_full          = 0;
453    m_cpt_trt_config_full_cost     = 0;
454}
455
456/////////////////////////
457tmpl(void)::transition()
458/////////////////////////
459{
460    if ( not p_resetn.read() ) 
461    {
462
463        r_dma_cmd_fsm               = DMA_CMD_IDLE;
464        r_dma_rsp_fsm               = DMA_RSP_IDLE;
465        r_alloc_trt_dma_fsm     = ALLOC_TRT_DMA_CMD;
466        r_dma_tlb_fsm           = DMA_TLB_IDLE;
467        r_config_cmd_fsm            = CONFIG_CMD_IDLE;
468        r_config_rsp_fsm            = CONFIG_RSP_IDLE;
469        r_alloc_trt_config_fsm  = ALLOC_TRT_CONFIG_CMD;
470        r_miss_init_fsm             = MISS_INIT_IDLE_MISS;
471
472        //miss buffer invalidation
473        r_miss_buf_valid = false; 
474       
475                r_iommu_active = false;
476
477        r_dma_cmd_count = 0;
478       
479        // initializing FIFOs
480        m_dma_cmd_addr_fifo.init();
481        m_dma_cmd_srcid_fifo.init();
482        m_dma_cmd_trdid_fifo.init();
483        m_dma_cmd_pktid_fifo.init();
484        m_dma_cmd_be_fifo.init();
485        m_dma_cmd_cmd_fifo.init();
486        m_dma_cmd_contig_fifo.init();
487        m_dma_cmd_data_fifo.init();
488        m_dma_cmd_eop_fifo.init();
489        m_dma_cmd_cons_fifo.init();
490        m_dma_cmd_plen_fifo.init();
491        m_dma_cmd_wrap_fifo.init();
492        m_dma_cmd_cfixed_fifo.init();
493        m_dma_cmd_clen_fifo.init();
494       
495        m_dma_rsp_rsrcid_fifo.init();
496        m_dma_rsp_rtrdid_fifo.init();
497        m_dma_rsp_rpktid_fifo.init();
498        m_dma_rsp_data_fifo.init();
499        m_dma_rsp_rerror_fifo.init();
500        m_dma_rsp_reop_fifo.init();
501       
502        m_config_cmd_addr_fifo.init();
503        m_config_cmd_srcid_fifo.init();
504        m_config_cmd_trdid_fifo.init();
505        m_config_cmd_pktid_fifo.init();
506        m_config_cmd_be_fifo.init();
507        m_config_cmd_cmd_fifo.init();
508        m_config_cmd_contig_fifo.init();
509        m_config_cmd_data_fifo.init();
510        m_config_cmd_eop_fifo.init();
511        m_config_cmd_cons_fifo.init();
512        m_config_cmd_plen_fifo.init();
513        m_config_cmd_wrap_fifo.init();
514        m_config_cmd_cfixed_fifo.init();
515        m_config_cmd_clen_fifo.init();
516       
517        m_config_rsp_rsrcid_fifo.init();
518        m_config_rsp_rtrdid_fifo.init();
519        m_config_rsp_rpktid_fifo.init();
520        m_config_rsp_data_fifo.init();
521        m_config_rsp_rerror_fifo.init();
522        m_config_rsp_reop_fifo.init();
523       
524        m_config_local_rsrcid_fifo.init();
525        m_config_local_rtrdid_fifo.init();
526        m_config_local_rpktid_fifo.init();
527        m_config_local_data_fifo.init();
528        m_config_local_rerror_fifo.init();
529        m_config_local_reop_fifo.init();
530
531        //Communication between DMA_CMD and DMA_RSP
532        r_dma_cmd_rsp_erase_req         =false;
533        r_dma_cmd_error_req         =false;
534        //Communication between DMA_CMD and TLB
535        r_dma_tlb_req                   =false;
536        r_tlb_dma_untreated                 =false; 
537        //Communication betweeen TLB and CONFIG_CMD
538        r_config_tlb_req                    =false;
539        r_config_tlb_inval_vaddr        =false;
540            r_dma_tlb_error_req         =false; 
541        r_tlb_error_type            =false;   
542        //Communication between CONFIG_CMD and CONFIG_RSP
543        r_config_cmd_rsp_erase_req  =false;
544        //Communication between TLB_MISS and MISS_INIT
545        r_tlb_miss_init_req         =false;
546        r_miss_init_error           =false;
547        // Debug variables
548                m_debug_dma_rsp_fsm             = false;
549                m_debug_dma_cmd_fsm         = false;
550        m_debug_dma_tlb_fsm         = false;
551        m_debug_config_cmd_fsm      = false;
552        m_debug_config_rsp_fsm      = false;
553        m_debug_miss_init_fsm       = false;
554       
555        r_irq_mask              = 0xFFFFFFFF;
556        r_irq_chosen            = 0;
557         
558            // activity counters
559            m_cpt_total_cycles      = 0;
560        m_cpt_iotlb_read       = 0;             
561        m_cpt_iotlb_miss       = 0;             
562        m_cpt_iotlbmiss_transaction      = 0;   
563        m_cost_iotlbmiss_transaction      = 0;   
564       
565        m_cpt_trt_dma_full          = 0;
566        m_cpt_trt_dma_full_cost     = 0;
567        m_cpt_trt_config_full          = 0;
568        m_cpt_trt_config_full_cost     = 0;
569
570        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_cmd            [i]   = 0;
571        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_rsp            [i]   = 0;
572        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_tlb            [i]   = 0;
573        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_alloc_trt_dma      [i]   = 0;
574        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_cmd         [i]   = 0;
575        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_rsp         [i]   = 0;
576        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_alloc_trt_config   [i]   = 0;
577        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_init          [i]   = 0;
578        return;
579    }
580
581   
582    //bool        miss_unposted      = false;
583    bool        dma_cmd_fifo_put    = false;
584    bool        dma_cmd_fifo_get    = false;
585    bool        dma_rsp_fifo_put    = false; 
586    bool        dma_rsp_fifo_get    = false; 
587   
588    bool        config_cmd_fifo_put = false;
589    bool        config_cmd_fifo_get = false;
590    bool        config_rsp_fifo_put = false;
591    bool        config_rsp_fifo_get = false;
592    bool        config_local_fifo_put = false;
593    bool        config_local_fifo_get = false;
594
595#ifdef INSTRUMENTATION
596    m_cpt_fsm_dma_cmd           [r_dma_cmd_fsm.read()] ++;
597    m_cpt_fsm_dma_rsp           [r_dma_rsp_fsm.read() ] ++;
598    m_cpt_fsm_dma_tlb               [r_dma_tlb_fsm.read() ] ++;
599    m_cpt_fsm_alloc_trt_dma     [r_alloc_trt_dma_fsm.read() ] ++;
600    m_cpt_fsm_config_cmd            [r_config_cmd_fsm.read() ] ++;
601    m_cpt_fsm_config_rsp            [r_config_rsp_fsm.read() ] ++;
602    m_cpt_fsm_alloc_trt_config  [r_alloc_trt_config_fsm.read() ] ++;
603    m_cpt_fsm_miss_init         [r_miss_init_fsm.read() ] ++;
604#endif
605
606    m_cpt_total_cycles++;
607
608    m_debug_dma_cmd_fsm        = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
609    m_debug_dma_rsp_fsm         = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
610    m_debug_dma_tlb_fsm    = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
611    m_debug_config_cmd_fsm      = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
612    m_debug_config_rsp_fsm     = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
613    m_debug_miss_init_fsm       = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
614
615    /////////////////////////////////////////////////////////////////////
616    // The DMA_CMD_FSM controls the following ressources:
617    // - r_dma_cmd_fsm
618    // - r_dma_srcid
619    // - r_dma_tlb_req (set)
620    // - r_tlb_dma_untreated (reset)
621    // - r_dma_cmd_rsp_erase_req (set)
622    ///////////////////////////////////////////////////////////////////////////////
623
624    switch( r_dma_cmd_fsm.read() ) 
625    {
626    //////////////
627    case DMA_CMD_IDLE:
628    {
629        // Treats an eventual request from TLB_MISS fsm
630        // to send a command whose miss treatment is now finished
631        if ( r_tlb_dma_untreated.read() )
632        {
633            r_dma_cmd_fsm    = DMA_CMD_TRT_LOCK;//before posting we must update TRT
634            r_dma_cmd_fsm_save = DMA_CMD_IDLE;
635            r_miss_interrupt = true;
636            break;
637        }
638        // Error during miss treatment
639        else if (r_dma_tlb_error_req.read())
640        {
641            r_iommu_etr     = r_tlb_error_type.read(); 
642            r_iommu_bvar    = r_iotlb_vaddr.read();
643            r_iommu_bad_id  = r_miss_srcid.read();
644            // For DMA_RSP FSM
645            if(r_miss_cmd.read() == vci_param_io::CMD_WRITE) r_dma_error_type = WRITE_ERROR;
646            else r_dma_error_type = READ_ERROR;
647            r_dma_error_trdid   = r_miss_trdid.read(); 
648            r_dma_error_pktid   = r_miss_pktid.read(); 
649 
650            r_dma_tlb_error_req = false; 
651            r_dma_cmd_fsm   = DMA_CMD_ERROR;
652        }
653
654        if ( p_vci_tgt_dma.cmdval.read() )
655        { 
656            if ( not r_iommu_active.read())     // iotlb not activated
657            {
658                // physical address
659                r_dma_paddr = (paddr_t)p_vci_tgt_dma.address.read();
660                r_dma_cmd_fsm   = DMA_CMD_TRT_LOCK;
661            }
662            else if (r_dma_tlb_fsm.read() == DMA_TLB_IDLE ||
663                     r_dma_tlb_fsm.read() == DMA_TLB_WAIT_TRANSACTION )   // iotlb activated
664            {
665                paddr_t paddr;
666
667               
668                // We compute physical address and check access rights :
669                // - If MMU not activated :the physical address is equal to the virtual
670                //address (identity mapping) and there is no access rights checking
671                // - If MMU activated : cacheability is defined by the C bit in the PTE,
672                //   the physical address is obtained from the TLB, and the access rights are
673                //   defined by the W bit in the PTE.
674
675                paddr_t         iotlb_paddr;
676                pte_info_t  iotlb_flags; 
677                size_t      iotlb_way; 
678                size_t      iotlb_set;
679                paddr_t     iotlb_nline;
680                bool            iotlb_hit   = false;; 
681
682
683#ifdef INSTRUMENTATION
684m_cpt_iotlb_read++;
685#endif
686
687                iotlb_hit = r_iotlb.translate(p_vci_tgt_dma.address.read(),
688                                            &iotlb_paddr,
689                                            &iotlb_flags,
690                                            &iotlb_nline,// unused
691                                            &iotlb_way,  // unused
692                                            &iotlb_set );// unused
693           
694           
695                if ( iotlb_hit )        // tlb hit
696                { 
697                    paddr       = iotlb_paddr;
698                                       
699                    // access rights checking
700                    if ( not iotlb_flags.w and
701                        (p_vci_tgt_dma.cmd.read() == vci_param_io::CMD_WRITE) ) 
702                    {
703                        r_iommu_etr     = MMU_WRITE_ACCES_VIOLATION; 
704                        r_iommu_bvar    = p_vci_tgt_dma.address.read();
705                        r_iommu_bad_id  = p_vci_tgt_dma.srcid.read();
706                        r_dma_cmd_fsm   = DMA_CMD_ERROR;
707                        // For DMA_RSP
708                        r_dma_error_type    = WRITE_ERROR; 
709                        r_dma_error_trdid   = p_vci_tgt_dma.trdid.read(); 
710                        r_dma_error_pktid   = p_vci_tgt_dma.pktid.read(); 
711#if DEBUG_DMA_CMD
712if( m_debug_dma_cmd_fsm )
713{
714    std::cout << "  <IOB.DMA_CMD_IDLE> HIT in iotlb, but writable violation" << std::endl;
715}
716#endif
717                    break;
718                    }
719
720                    // Physical address registration
721                    r_dma_paddr   = paddr;                     
722                    r_dma_cmd_fsm       = DMA_CMD_TRT_LOCK;
723                }
724                // TLB miss: we enter TLB_MISS treatment sub-fsm
725                else 
726                {
727
728#ifdef INSTRUMENTATION
729m_cpt_iotlb_miss++;
730#endif
731                    if( r_dma_tlb_req.read() || r_tlb_dma_untreated.read() || r_dma_tlb_error_req.read() )
732                    {
733                        // There's already a ongoing request
734                        // or a completed request but not yet put on FIFO.
735                        // We stay blocked
736                        r_dma_cmd_fsm = DMA_CMD_TLB_MISS_WAIT;
737#if DEBUG_DMA_CMD
738if( m_debug_dma_cmd_fsm )
739{
740    std::cout << "  <IOB.DMA_CMD_IDLE> MISS in iotlb. There is a pending request." << std::endl;
741}
742#endif
743                    }
744                    else
745                    {
746                        // We register request virtual address, to be used by DMA_TLB_MISS FSM
747                                r_iotlb_vaddr = p_vci_tgt_dma.address.read();
748                        assert((r_dma_cmd_count.read() == 0)
749                                and "ERROR: TRT counter should be 0");
750                        r_dma_tlb_req   = true;
751                        r_dma_cmd_fsm   = DMA_CMD_TLB_MISS_STORE;
752#if DEBUG_DMA_CMD
753if( m_debug_dma_cmd_fsm )
754{
755    std::cout << "  <IOB.DMA_CMD_IDLE> MISS in iotlb. No pending request." << std::endl;
756}
757#endif
758                    }
759                } // end !hit
760            } // end if tlb_activated
761        } // end if cmdval
762        break;
763    }
764    /////////////////////////
765    case DMA_CMD_TRT_LOCK:      // Waiting for the lock to modify Transaction Table
766    {
767        if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_CMD ) 
768        {
769
770#if DEBUG_DMA_CMD
771if( m_debug_dma_cmd_fsm )
772{
773    std::cout << "  <IOB.DMA_CMD_TRT_LOCK> Check the TRT" << std::endl;
774}
775#endif
776            size_t              wok_index = 0;
777            bool                wok       = !m_transaction_tab_dma.full(wok_index);
778
779            if ( wok )  // TRT isn't full. Write the new transaction.
780            {
781                r_dma_cmd_trt_index = (vci_trdid_t)wok_index;
782                r_dma_cmd_fsm       = DMA_CMD_TRT_SET;
783            } 
784            else                // wait an empty entry in TRT
785            {
786                r_dma_cmd_rsp_erase_req = true;
787                r_dma_cmd_fsm       = DMA_CMD_TRT_WAIT;
788#if DEBUG_DMA_CMD
789if( m_debug_dma_cmd_fsm )
790{
791    std::cout << "  <IOB.DMA_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl;
792}
793#endif
794           
795#ifdef INSTRUMENTATION       
796m_cpt_trt_dma_full++;
797#endif
798            }
799        }
800        break;
801    }
802    ////////////////
803    case DMA_CMD_TRT_WAIT:      // release the lock protecting the transaction tab
804                            // waits that RSP erases an entry
805    { 
806#ifdef INSTRUMENTATION       
807m_cpt_trt_dma_full_cost++;
808#endif
809        // DMA_RSP will notify an erase action by reseting this register
810        if(!r_dma_cmd_rsp_erase_req.read())
811        {
812            r_dma_cmd_fsm = DMA_CMD_TRT_LOCK; // take the lock again
813        }
814        break;
815    }
816    ////////////////////////
817    case DMA_CMD_TRT_SET:       // register a new transaction in TRT
818    { 
819        if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_CMD ) 
820        {
821            if(r_miss_interrupt.read())
822            {
823                m_transaction_tab_dma.set(r_dma_cmd_trt_index.read(),
824                                      r_miss_srcid.read(), 
825                                      r_miss_trdid.read() );
826                r_dma_cmd_fsm = DMA_CMD_FIFO_MISS_PUT;
827            }
828            else
829            {
830                m_transaction_tab_dma.set(r_dma_cmd_trt_index.read(),
831                                          p_vci_tgt_dma.srcid.read(), 
832                                          p_vci_tgt_dma.trdid.read() );
833                r_dma_cmd_fsm = DMA_CMD_FIFO_PUT;
834            }
835#if DEBUG_DMA_CMD
836if( m_debug_dma_cmd_fsm )
837{
838    std::cout << "  <IOB.DMA_CMD_TRT_SET> Set a new entry in TRT" << std::endl;
839    if(r_miss_interrupt.read()) std::cout << " From the Network " << std::endl;
840    else std::cout << " From miss interruption" << std::endl;
841}
842#endif
843        }
844        break;
845    } 
846    ///////////////////////
847    case DMA_CMD_FIFO_PUT:       
848    {
849        if ( p_vci_tgt_dma.cmdval && m_dma_cmd_addr_fifo.wok() ) 
850        {
851            dma_cmd_fifo_put = true;
852            //miss_unposted = false;
853            if(  p_vci_tgt_dma.contig )    r_dma_paddr = r_dma_paddr.read() + 4;
854            if(  p_vci_tgt_dma.eop )    r_dma_cmd_fsm = DMA_CMD_IDLE;
855           
856#if DEBUG_DMA_CMD
857if( m_debug_dma_cmd_fsm ) 
858{
859    std::cout << "  <IOB.DMA_CMD_FIFO_PUT> Push into cmd_fifo:" 
860              << " address = " << std::hex << r_dma_paddr.read()
861              << " srcid = " << std::dec << m_srcid_dma
862              << " trdid = " << r_dma_cmd_trt_index.read()
863              << " wdata = " << std::hex << p_vci_tgt_dma.wdata.read()
864              << " be = " << p_vci_tgt_dma.be.read()
865              << " contig = " << p_vci_tgt_dma.contig.read()
866              << " eop = " << std::dec << p_vci_tgt_dma.eop.read() 
867              << " plen = " << std::dec << p_vci_tgt_dma.plen.read() << std::endl;
868}
869#endif
870        }
871        break;
872    }
873    ///////////////////////
874    case DMA_CMD_FIFO_MISS_PUT: 
875    {
876        if ( m_dma_cmd_addr_fifo.wok() ) 
877        {
878            dma_cmd_fifo_put    = true;
879            //miss_unposted       = true;
880            if( r_miss_contig.read() )    r_miss_paddr = r_miss_paddr.read() + 4;
881           
882            if( r_dma_cmd_count.read() == 1 ) 
883            {
884                r_tlb_dma_untreated = false;
885                r_miss_interrupt = false;
886                r_dma_cmd_fsm = r_dma_cmd_fsm_save.read();
887            }
888            r_dma_cmd_count = r_dma_cmd_count.read() - 1;
889
890#if DEBUG_DMA_CMD
891if( m_debug_dma_cmd_fsm ) 
892{
893    std::cout << "  <IOB.DMA_CMD_FIFO_MISS_PUT> Push into cmd_fifo:" 
894              << " counter = " << std::hex << r_dma_cmd_count.read()
895              << " address = " << std::hex << r_miss_paddr.read()
896              << " srcid = " << std::dec << r_miss_srcid.read()
897              << " trdid = " << r_miss_trdid.read()
898              << " wdata = " << std::hex << r_miss_data
899              << " be = " << r_miss_be
900              << " plen = " << std::dec << r_miss_plen.read() << std::endl;
901}
902#endif
903        }
904        break;
905    }
906    ///////////////////
907    case DMA_CMD_TLB_MISS_WAIT: // to store the miss request there must be
908                                // neither an ongoing request, nor a unposted finished request
909    {
910        // Treats an eventual request from TLB_MISS fsm
911        // to send a command whose miss treatment is now finished
912        if ( r_tlb_dma_untreated.read() )
913        {
914            r_dma_cmd_fsm    = DMA_CMD_TRT_LOCK; //before posting we must update TRT
915            r_dma_cmd_fsm_save = DMA_CMD_TLB_MISS_WAIT;
916            r_miss_interrupt = true;
917            break;
918        }
919        // Error during miss treatment
920        else if (r_dma_tlb_error_req.read())
921        {
922            r_iommu_etr     = r_tlb_error_type.read(); 
923            r_iommu_bvar    = r_iotlb_vaddr.read();
924            r_iommu_bad_id  = r_miss_srcid.read();
925            // For DMA_RSP FSM
926            if(r_miss_cmd.read() == vci_param_io::CMD_WRITE) r_dma_error_type = WRITE_ERROR;
927            else r_dma_error_type = READ_ERROR;
928            r_dma_error_trdid   = r_miss_trdid.read(); 
929            r_dma_error_pktid   = r_miss_pktid.read(); 
930 
931            r_dma_tlb_error_req = false; 
932            r_dma_cmd_fsm   = DMA_CMD_ERROR;
933        }
934
935#ifdef INSTRUMENTATION       
936m_cost_iotlb_miss++;  // Now it represents misses' total blocking cost (not the treatment cost itself)
937#endif
938        else if (not r_dma_tlb_req.read())
939        {
940            r_dma_cmd_fsm   = DMA_CMD_TLB_MISS_STORE;
941            assert((r_dma_cmd_count.read() == 0) and "ERROR: TRT counter should be 0");
942        }
943        break;
944    }
945    ///////////////////
946    case DMA_CMD_TLB_MISS_STORE:
947    {
948        if ( p_vci_tgt_dma.cmdval.read()) 
949        {
950            if(r_dma_cmd_count.read() == 0)
951            {
952                r_miss_cmd = p_vci_tgt_dma.cmd.read();
953                r_miss_contig = p_vci_tgt_dma.contig.read();
954                r_miss_cons = p_vci_tgt_dma.cons.read();
955                r_miss_plen = p_vci_tgt_dma.plen.read();
956                r_miss_wrap = p_vci_tgt_dma.wrap.read();
957                r_miss_cfixed = p_vci_tgt_dma.cfixed.read();
958                r_miss_clen = p_vci_tgt_dma.clen.read();
959                r_miss_srcid = p_vci_tgt_dma.srcid.read();
960                r_miss_trdid = p_vci_tgt_dma.trdid.read();
961                r_miss_pktid = p_vci_tgt_dma.pktid.read();
962               
963//                r_dma_tlb_req   = true;
964            }
965           
966            r_miss_data[r_dma_cmd_count.read()] = p_vci_tgt_dma.wdata.read();
967            r_miss_be[r_dma_cmd_count.read()] = p_vci_tgt_dma.be.read();
968           
969            r_dma_cmd_count = r_dma_cmd_count.read() + 1;
970           
971            if(  p_vci_tgt_dma.eop )  r_dma_cmd_fsm = DMA_CMD_IDLE;
972           
973#if DEBUG_DMA_CMD
974if( m_debug_dma_cmd_fsm ) 
975{
976    std::cout << "  <IOB.DMA_CMD_TLB_MISS_STORE> Storing VCI fields of command that originate the Miss:" 
977              << " counter = " << std::hex << r_dma_cmd_count.read()
978              << " address = " << std::hex << p_vci_tgt_dma.address.read()
979              << " srcid = " << std::dec << p_vci_tgt_dma.srcid.read()
980              << " trdid = " << p_vci_tgt_dma.trdid.read()
981              << " wdata = " << std::hex << p_vci_tgt_dma.wdata.read()
982              << " be = " << p_vci_tgt_dma.be.read()
983              << " plen = " << std::dec << p_vci_tgt_dma.plen.read() << std::endl;
984}
985#endif
986        }
987        break;
988    }
989    ///////////////////
990    case DMA_CMD_ERROR:
991    {
992        // Wait in case of pending request
993        // it isn't the case, generally
994        if(!r_dma_cmd_error_req.read())
995        { 
996            r_dma_cmd_error_req = true; 
997            r_dma_cmd_fsm       = DMA_CMD_IDLE;
998        }
999        break;
1000    }
1001    } // end switch DMA_CMD_FSM
1002
1003    /////////////////////////////////////////////////////////////////////
1004    // The DMA_RSP_FSM controls the following ressources:
1005    // - r_dma_rsp_fsm
1006    // - r_dma_cmd_rsp_erase_req (reset)
1007    // - r_fma_error_req (reset)
1008    // -
1009    //////////////////////////////////////////////////////////////////////////////
1010    switch( r_dma_rsp_fsm.read() ) 
1011    {
1012    /////////////////////
1013    case DMA_RSP_IDLE:
1014    {           
1015        // Interruption from DMA_CMD following an error
1016        if(r_dma_cmd_error_req.read()) r_dma_rsp_fsm = DMA_RSP_FIFO_ERROR_PUT;
1017       
1018        if(p_vci_ini_dma.rspval.read()) 
1019                {
1020                        r_dma_rsp_fsm = DMA_RSP_TRT_LOCK;
1021                }
1022                break;
1023    }
1024    /////////////////////
1025    case DMA_RSP_TRT_LOCK:
1026    {           
1027        if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_RSP ) 
1028        {
1029           
1030#if DEBUG_DMA_RSP
1031if( m_debug_dma_rsp_fsm )
1032{
1033    std::cout << "  <IOB.DMA_RSP_TRT_LOCK> Erase entry" << std::endl;
1034}
1035#endif
1036            uint32_t trdid_xram = p_vci_ini_dma.rtrdid.read(); 
1037           
1038            r_dma_rsrcid = (vci_srcid_t)m_transaction_tab_dma.readSrcid(trdid_xram);
1039            r_dma_rtrdid = (vci_trdid_t)m_transaction_tab_dma.readTrdid(trdid_xram);
1040            m_transaction_tab_dma.erase(trdid_xram);
1041            if (r_dma_cmd_rsp_erase_req.read()) r_dma_cmd_rsp_erase_req = false;
1042            r_dma_rsp_fsm       = DMA_RSP_FIFO_PUT;
1043        }       
1044                break;
1045    }
1046    //////////////////
1047    case DMA_RSP_FIFO_PUT:
1048    {
1049        if(p_vci_ini_dma.rspval.read() && m_dma_rsp_data_fifo.wok())
1050        {
1051            dma_rsp_fifo_put = true;
1052            if(p_vci_ini_dma.reop.read())   r_dma_rsp_fsm = DMA_RSP_IDLE;       
1053
1054#if DEBUG_DMA_RSP
1055if( m_debug_dma_rsp_fsm ) 
1056{
1057    std::cout << "  <IOB.DMA_RSP_FIFO_PUT> Push into rsp_fifo:" 
1058              << " rsrcid = " << std::dec << r_dma_rsrcid.read()
1059              << " rtrdid = " << r_dma_rtrdid.read()
1060              << " rdata = " << std::hex << p_vci_ini_dma.rdata.read()
1061    << std::endl;
1062}
1063#endif
1064                       
1065        }
1066        break;
1067    }
1068    //////////////////
1069    case DMA_RSP_FIFO_ERROR_PUT:
1070    {
1071        if(m_dma_rsp_data_fifo.wok())
1072        {
1073            dma_rsp_fifo_put = true;
1074            r_dma_rsp_fsm = DMA_RSP_IDLE;       
1075
1076#if DEBUG_DMA_RSP
1077if( m_debug_dma_rsp_fsm ) 
1078{
1079    std::cout << "  <IOB.DMA_RSP_FIFO_ERROR_PUT> Push into rsp_fifo:" 
1080              << " rsrcid = " << std::dec << r_iommu_bad_id.read()
1081              << " rtrdid = " << r_dma_error_trdid.read()
1082              << " rerror = " << r_dma_error_type.read()
1083              << " rdata = " << std::hex << 0
1084    << std::endl;
1085}
1086#endif
1087                       
1088        }
1089        break;
1090    }
1091    } // end switch DMA_RSP_FSM
1092
1093    ////////////////////////////////////////////////////////////////////////////
1094    // The ALLOC_TRT_DMA fsm allocates the access to the Transaction Table (m_transaction_tab_dma)
1095    // with a round robin priority between 2 user FSMs :
1096    // - DMA_CMD : to set a new entry
1097    // - DMA_RSP : to read and erase an entry
1098    // The ressource is always allocated.
1099    ////////////////////////////////////////////////////////////////////////////
1100   
1101    switch ( r_alloc_trt_dma_fsm.read() ) 
1102    {
1103    ///////////////////
1104    case ALLOC_TRT_DMA_CMD:
1105    {
1106        if ( r_dma_cmd_fsm.read() != DMA_CMD_TRT_LOCK ) 
1107        {
1108          if (r_dma_rsp_fsm.read() == DMA_RSP_TRT_LOCK) r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_RSP;
1109        }
1110        break;
1111    }
1112    ///////////////////
1113    case ALLOC_TRT_DMA_RSP:
1114    {
1115        if (r_dma_rsp_fsm.read() != DMA_RSP_TRT_LOCK) 
1116        {
1117            if (r_dma_cmd_fsm.read() == DMA_CMD_TRT_LOCK) r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_CMD;
1118        }
1119        break;
1120    }
1121    } // end switch r_alloc_trt_dma_fsm
1122   
1123
1124    ////////////////////////////////////////////////////////////////////////////
1125    // The DMA_TLB_MISS FSM handles an IOTLB miss. It blocks the TGT_FSM.
1126    // Input argument is:
1127    // - r_iotlb_vaddr
1128    // - r_dma_tlb_req (reset)
1129    // - r_tlb_miss_init_req (set)
1130    // - r_config_tlb_req (reset)
1131    // - r_tlb_dma_untreated (set)
1132    //
1133    // This fsm searchs the requested PTE on the  prefetch buffer.
1134    // In case of miss,  it accesses the XRAM to find the missing TLB entry,
1135    // It bypass the first level page table access if possible.
1136    // It directly updates the iotlb, and writes into the
1137    // r_mmu_ins_* or r_mmu_data* error reporting registers.
1138    ////////////////////////////////////////////////////////////////////////////////////
1139    switch (r_dma_tlb_fsm.read())
1140    {
1141    case DMA_TLB_IDLE:
1142    {
1143        if(r_config_tlb_req)
1144        {
1145            r_config_tlb_req = false;
1146            r_waiting_transaction = false;
1147            r_dma_tlb_fsm = DMA_TLB_INVAL_CHECK;
1148        // Request from CONFIG FSM following an PTE invalidation signal by OS
1149        }
1150        // Miss in IOTLB
1151        else if(r_dma_tlb_req.read())   
1152        {
1153        // Checking prefetch buffer, by the virtual address
1154        if(!r_miss_buf_first_level)
1155        {
1156            if( r_miss_buf_valid &&
1157                (r_miss_buf_vaddr_begin.read() == 
1158                (r_iotlb_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK)))
1159            {
1160              // Hit
1161                size_t pte_offset = (r_iotlb_vaddr.read()& PTE2_LINE_OFFSET)>>12; 
1162             
1163
1164                uint32_t pte_flags = r_miss_buf_data[2*pte_offset];
1165                uint32_t pte_ppn = r_miss_buf_data[2*pte_offset+1]; //because PTE2 is 2 words long
1166               
1167                // Bit valid checking
1168                if ( not ( pte_flags & PTE_V_MASK) )    // unmapped
1169                {
1170                    //must not occur!
1171                    std::cout << "IOMMU ERROR : " << name() << " DMA_TLB_IDLE state" << std::endl
1172                                  << "The Page Table entry ins't valid (unmapped)" << std::endl;
1173                       
1174                    r_tlb_error_type          = MMU_READ_PT2_UNMAPPED;
1175                    r_dma_tlb_error_req       = true;
1176                    r_dma_tlb_req             = false;
1177                       
1178#if DEBUG_DMA_TLB
1179if ( m_debug_dma_tlb_fsm )
1180{
1181    std::cout << "  <IOB.DMA_TLB_IDLE> PTE2 Unmapped"
1182              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1183              << std::hex << " / PTE (first word) = " << pte_flags << std::endl;
1184}
1185#endif
1186                    break; 
1187                }
1188
1189                r_iotlb_pte_flags       = pte_flags; 
1190                r_iotlb_pte_ppn         = pte_ppn;
1191                r_dma_tlb_fsm           = DMA_TLB_PTE2_SELECT;
1192               
1193#if DEBUG_DMA_TLB
1194if ( m_debug_dma_tlb_fsm )
1195{
1196    std::cout << "  <IOB.DMA_TLB_IDLE> Hit on the prefetch buffer for PTE2:"
1197              << " PTE_FLAGS = " << std::hex << pte_flags
1198              << " PTE_PPN = " << std::hex << pte_ppn << std::endl;
1199}
1200#endif
1201                break;   
1202            }
1203        }
1204        else    // First level entries on buffer. Unused if only small pages
1205        {
1206           if( r_miss_buf_valid &&
1207              (r_miss_buf_vaddr_begin.read() == 
1208               (r_iotlb_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 
1209            // The virtual address corresponds to one entry on the buffer line
1210            {
1211              // Hit
1212                size_t pte_offset = (r_iotlb_vaddr.read()& PTE1_LINE_OFFSET)>>21; 
1213             
1214                uint32_t pte_flags = r_miss_buf_data[pte_offset];
1215                           
1216                // Bit valid checking
1217                if ( not ( pte_flags & PTE_V_MASK) )    // unmapped
1218                {
1219                    //must not occur!
1220                    std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl
1221                                  << "The Page Table entry ins't valid (unmapped)" << std::endl;
1222                       
1223                    r_tlb_error_type          = MMU_READ_PT1_UNMAPPED;
1224                    r_dma_tlb_error_req       = true;
1225                    r_dma_tlb_req             = false;
1226                       
1227#if DEBUG_DMA_TLB
1228if ( m_debug_dma_tlb_fsm )
1229{
1230    std::cout << "  <IOB.DMA_TLB_IDLE> First level entry Unmapped"
1231              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1232              << std::hex << " / PTE = " << pte_flags << std::endl;
1233}
1234#endif
1235                    break; 
1236                }
1237               
1238                if( pte_flags & PTE_T_MASK )    //  PTD : me must access PT2
1239                {
1240                    // register bypass
1241                    r_iotlb.set_bypass( r_iotlb_vaddr.read(),
1242                                      pte_flags & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 
1243                                     0); //nline, unused
1244
1245                    //&PTE2 = PTBA + IX2 * 8
1246                    // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
1247                    r_iotlb_paddr = (paddr_t)(pte_flags & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
1248                                  (paddr_t)(((r_iotlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
1249                    r_tlb_miss_init_req     = true;
1250                    r_tlb_miss_type         = PTE2_MISS;
1251                    r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
1252#ifdef INSTRUMENTATION
1253m_cpt_iotlbmiss_transaction++;
1254#endif
1255
1256#if DEBUG_DMA_TLB
1257if ( m_debug_dma_tlb_fsm )
1258{
1259    std::cout << "  <IOB.DMA_TLB_IDLE> Hit on prefetch, but it is a PTD.Search PTE2"
1260              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1261              << std::hex << " / PTD = " << pte_flags << std::endl;
1262}
1263#endif
1264                }
1265                else                    //  PTE1 :  we must update the TLB
1266                            //  Should not occur if working only with small pages
1267                {
1268                    r_iotlb_pte_flags   = pte_flags;
1269                    r_dma_tlb_fsm  = DMA_TLB_PTE1_SELECT;
1270
1271#if DEBUG_DMA_TLB
1272if ( m_debug_dma_tlb_fsm )
1273{
1274    std::cout << "  <IOB.DMA_TLB_PTE1_GET> Success. Big page"
1275              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1276              << std::hex << " / PTE1 = " << pte_flags << std::endl;
1277}
1278#endif
1279                }
1280                break;
1281            }
1282        }
1283       
1284        r_dma_tlb_fsm = DMA_TLB_MISS; 
1285
1286#if DEBUG_DMA_TLB
1287if ( m_debug_dma_tlb_fsm )
1288{
1289    std::cout << "  <IOB.DMA_TLB_IDLE> Miss on prefetch."
1290              << std::hex << " / vaddr = " << r_iotlb_vaddr.read() << std::endl;
1291}
1292#endif
1293        }
1294        break;
1295    }
1296    /////////////////////
1297    case DMA_TLB_MISS: // handling all tlb miss
1298    {
1299        uint32_t        ptba = 0; //28 bits en TSAR
1300        bool            bypass;
1301        paddr_t         pte_paddr;
1302
1303        // evaluate bypass in order to skip first level page table access
1304        bypass = r_iotlb.get_bypass(r_iotlb_vaddr.read(), &ptba);
1305       
1306        //Request to MISS_INIT_FSM to start transaction on Direct Network       
1307        if ( not bypass )     // Read PTE1/PTD1 in XRAM
1308        {
1309        // VOIR CONVENTION >> 13
1310            pte_paddr = (paddr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) |
1311                        (paddr_t)((r_iotlb_vaddr.read() >> PAGE_M_NBITS) << 2);
1312            r_iotlb_paddr = pte_paddr;
1313           
1314            r_tlb_miss_init_req     = true;
1315            r_tlb_miss_type         = PTE1_MISS;
1316            r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
1317#ifdef INSTRUMENTATION
1318m_cpt_iotlbmiss_transaction++;
1319#endif
1320        }
1321        else                  // Read PTE2 in XRAM
1322        {
1323            //&PTE2 = PTBA + IX2 * 8
1324            pte_paddr = (paddr_t)ptba << PAGE_K_NBITS |
1325                        (paddr_t)(r_iotlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
1326           
1327            r_iotlb_paddr = pte_paddr;
1328           
1329            r_tlb_miss_init_req     = true;
1330            r_tlb_miss_type         = PTE2_MISS;
1331            r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
1332#ifdef INSTRUMENTATION
1333m_cpt_iotlbmiss_transaction++;
1334#endif
1335        }
1336
1337#if DEBUG_DMA_TLB
1338if ( m_debug_dma_tlb_fsm )
1339{
1340    std::cout << "  <IOB.DMA_TLB_MISS> IOTLB miss";
1341    std::cout << " / VADDR = " << std::hex << r_iotlb_vaddr.read()
1342              << " / BYPASS = " << bypass
1343              << " / PTE_ADR = " << pte_paddr << std::endl;
1344}
1345#endif
1346 
1347        break;
1348    }
1349    ///////////////////////// 
1350    case DMA_TLB_PTE1_GET:      // Try to read a PT1 entry in the miss buffer
1351    {
1352       
1353        uint32_t  entry;
1354       
1355        paddr_t line_number  = (paddr_t)((r_iotlb_paddr.read())&(CACHE_LINE_MASK));
1356        size_t word_position = (size_t)( ((r_iotlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
1357
1358        // Hit test. Just to verify.
1359        // Hit must happen, since we've just finished its' miss transaction
1360        bool hit = (r_miss_buf_valid && (r_miss_buf_tag.read()== line_number) ); 
1361        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
1362       
1363        entry = r_miss_buf_data[word_position];
1364           
1365        // Bit valid checking
1366        if ( not ( entry & PTE_V_MASK) )        // unmapped
1367        {
1368            //must not occur!
1369            std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl
1370                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1371                       
1372            r_tlb_error_type          = MMU_READ_PT1_UNMAPPED;
1373            r_dma_tlb_error_req       = true;
1374            r_dma_tlb_req             = false;
1375            r_dma_tlb_fsm             = DMA_TLB_IDLE;           
1376#if DEBUG_DMA_TLB
1377if ( m_debug_dma_tlb_fsm )
1378{
1379    std::cout << "  <IOB.DMA_PTE1_GET> First level entry Unmapped"
1380              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1381              << std::hex << " / PTE = " << entry << std::endl;
1382}
1383#endif
1384                    break; 
1385        }
1386   
1387        if( entry & PTE_T_MASK )        //  PTD : me must access PT2
1388        {
1389            // register bypass
1390            r_iotlb.set_bypass( r_iotlb_vaddr.read(),
1391                                entry & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 
1392                                0); //nline, unused
1393
1394            //&PTE2 = PTBA + IX2 * 8
1395            // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
1396            r_iotlb_paddr = (paddr_t)(entry & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
1397                                (paddr_t)(((r_iotlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
1398            r_tlb_miss_init_req     = true;
1399            r_tlb_miss_type         = PTE2_MISS;
1400            r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
1401#ifdef INSTRUMENTATION
1402m_cpt_iotlbmiss_transaction++;
1403#endif
1404
1405#if DEBUG_DMA_TLB
1406if ( m_debug_dma_tlb_fsm )
1407{
1408    std::cout << "  <IOB.DMA_TLB_PTE1_GET> Success. Search PTE2"
1409              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1410              << std::hex << " / PTD = " << entry << std::endl;
1411}
1412#endif
1413        }
1414        else                    //  PTE1 :  we must update the IOTLB
1415                        //  Should not occur if working only with small pages
1416        {
1417            r_iotlb_pte_flags   = entry;
1418            r_dma_tlb_fsm  = DMA_TLB_PTE1_SELECT;
1419
1420#if DEBUG_DMA_TLB
1421if ( m_debug_dma_tlb_fsm )
1422{
1423    std::cout << "  <IOB.DMA_TLB_PTE1_GET> Success. Big page"
1424              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1425              << std::hex << " / PTE1 = " << entry << std::endl;
1426}
1427#endif
1428        }
1429       
1430        break;
1431    }
1432    ////////////////////////////
1433    case DMA_TLB_PTE1_SELECT:   // select a slot for PTE1
1434    {
1435        size_t  way;
1436        size_t  set;
1437       
1438        r_iotlb.select(  r_iotlb_vaddr.read(),
1439                        true,  // PTE1
1440                        &way,
1441                        &set );
1442#ifdef INSTRUMENTATION
1443m_cpt_iotlb_read++;
1444#endif
1445
1446#if DEBUG_DMA_TLB
1447if ( m_debug_dma_tlb_fsm )
1448{
1449    std::cout << "  <IOB.DMA_TLB_PTE1_SELECT> Select a slot in IOTLB:";
1450    std::cout << " way = " << std::dec << way
1451                  << " / set = " << set << std::endl;
1452}
1453#endif
1454        r_iotlb_way = way;
1455        r_iotlb_set = set;
1456        r_dma_tlb_fsm     = DMA_TLB_PTE1_UPDT;
1457        break;
1458    }
1459    //////////////////////////
1460    case DMA_TLB_PTE1_UPDT:     // write a new PTE1 in tlb
1461                                // not necessary to treat the L/R bit
1462    {
1463        //(OLD) paddr_t   nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
1464        uint32_t  pte   = r_iotlb_pte_flags.read();
1465       
1466        r_miss_paddr = (paddr_t)( ((r_iotlb_pte_flags.read() & PPN1_MASK) << 21)
1467                        | (r_iotlb_vaddr.read()& M_PAGE_OFFSET_MASK) );
1468       
1469        // update TLB
1470        r_iotlb.write( true,            // 2M page
1471                      pte,
1472                      0,                // argument unused for a PTE1
1473                      r_iotlb_vaddr.read(),   
1474                      r_iotlb_way.read(), 
1475                      r_iotlb_set.read(),
1476                      0 );      //we set nline = 0
1477#ifdef INSTRUMENTATION
1478m_cpt_iotlb_write++;
1479#endif
1480
1481#if DEBUG_DMA_TLB
1482if ( m_debug_dma_tlb_fsm )
1483{
1484    std::cout   << "  <IOB.DMA_TLB_PTE1_UPDT> write PTE1 in IOTLB";
1485    std::cout   << " / set = " << std::dec << r_iotlb_set.read()
1486                << " / way = " << r_iotlb_way.read() << std::endl;
1487    r_iotlb.printTrace();
1488}
1489#endif
1490        // next state
1491        r_dma_tlb_fsm = DMA_TLB_RETURN; // exit sub-fsm
1492        break;
1493    }
1494    /////////////////////////
1495    case DMA_TLB_PTE2_GET:      // Try to read a PTE2 (64 bits) in the miss buffer
1496    {   
1497        uint32_t        pte_flags;
1498        uint32_t        pte_ppn;
1499       
1500        paddr_t line_number  = (paddr_t)((r_iotlb_paddr.read())&(CACHE_LINE_MASK));
1501        size_t word_position = (size_t)( ((r_iotlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
1502       
1503       
1504        // Hit test. Just to verify.
1505        bool hit = (r_miss_buf_valid && (r_miss_buf_tag.read()== line_number) ); 
1506        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
1507        pte_flags= r_miss_buf_data[word_position];
1508        pte_ppn= r_miss_buf_data[word_position+1]; //because PTE2 is 2 words long
1509        // Bit valid checking
1510        if ( not ( pte_flags & PTE_V_MASK) )    // unmapped
1511        {
1512            //must not occur!
1513            std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl
1514                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
1515                       
1516            r_tlb_error_type          = MMU_READ_PT2_UNMAPPED;
1517            r_dma_tlb_error_req       = true;
1518            r_dma_tlb_req             = false;
1519            r_dma_tlb_fsm             = DMA_TLB_IDLE;           
1520#if DEBUG_DMA_TLB
1521if ( m_debug_dma_tlb_fsm )
1522{
1523    std::cout << "  <IOB.DMA_TLB_PTE2_GET> PTE2 Unmapped"
1524              << std::hex << " / paddr = " << r_iotlb_paddr.read()
1525              << std::hex << " / PTE = " << pte_flags << std::endl;
1526}
1527#endif
1528                    break; 
1529        }
1530           
1531        r_iotlb_pte_flags       = pte_flags; 
1532        r_iotlb_pte_ppn         = pte_ppn;
1533        r_dma_tlb_fsm           = DMA_TLB_PTE2_SELECT;
1534               
1535#if DEBUG_DMA_TLB
1536if ( m_debug_dma_tlb_fsm )
1537{
1538    std::cout << "  <IOB.DMA_TLB_PTE2_GET> Mapped:"
1539              << " PTE_FLAGS = " << std::hex << pte_flags
1540              << " PTE_PPN = " << std::hex << pte_ppn << std::endl;
1541}
1542#endif
1543        break;
1544    }
1545    ////////////////////////////
1546    case DMA_TLB_PTE2_SELECT:    // select a slot for PTE2
1547    {
1548        size_t way;
1549        size_t set;
1550
1551        r_iotlb.select( r_iotlb_vaddr.read(),
1552                        false,  // PTE2
1553                        &way,
1554                        &set );
1555#ifdef INSTRUMENTATION
1556m_cpt_iotlb_read++;
1557#endif
1558
1559#if DEBUG_DMA_TLB
1560if ( m_debug_dma_tlb_fsm )
1561{
1562        std::cout << "  <IOB.DMA_TLB_PTE2_SELECT> Select a slot in IOTLB:";
1563        std::cout << " way = " << std::dec << way
1564                  << " / set = " << set << std::endl;
1565}
1566#endif
1567        r_iotlb_way = way;
1568        r_iotlb_set = set;
1569        r_dma_tlb_fsm     = DMA_TLB_PTE2_UPDT;
1570        break;
1571    }
1572    //////////////////////////
1573    case DMA_TLB_PTE2_UPDT:             // write a new PTE2 in tlb
1574                                    // not necessary to treat the L/R bit
1575    {
1576        //(OLD) paddr_t         nline     = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
1577        uint32_t        pte_flags = r_iotlb_pte_flags.read();
1578        uint32_t        pte_ppn   = r_iotlb_pte_ppn.read();
1579       
1580        r_miss_paddr = (paddr_t)( ((r_iotlb_pte_ppn.read() & PPN2_MASK) << 12)
1581                        | (r_iotlb_vaddr.read()& K_PAGE_OFFSET_MASK) );
1582       
1583        // update TLB for a PTE2
1584        r_iotlb.write( false,   // 4K page
1585                       pte_flags,
1586                       pte_ppn,
1587                       r_iotlb_vaddr.read(),   
1588                       r_iotlb_way.read(), 
1589                       r_iotlb_set.read(),
1590                       0 );     // nline = 0
1591#ifdef INSTRUMENTATION
1592m_cpt_iotlb_write++;
1593#endif
1594
1595#if DEBUG_DMA_TLB
1596if ( m_debug_dma_tlb_fsm )
1597{
1598        std::cout << "  <IOB.DMA_TLB_PTE2_UPDT> write PTE2 in IOTLB";
1599        std::cout << " / set = " << std::dec << r_iotlb_set.read()
1600                  << " / way = " << r_iotlb_way.read() << std::endl;
1601        r_iotlb.printTrace();
1602}
1603#endif
1604        // next state
1605        r_dma_tlb_fsm = DMA_TLB_RETURN; // exit sub-fsm
1606        break;
1607    }
1608    ///////////////////////
1609    case DMA_TLB_WAIT_TRANSACTION:
1610    {
1611        // CONFIG FSM request following a invalidation signal sent by OS.
1612        if(r_config_tlb_req)
1613        {
1614            r_config_tlb_req = false;
1615            r_waiting_transaction = true;
1616            r_dma_tlb_fsm = DMA_TLB_INVAL_CHECK;
1617        }
1618
1619#ifdef INSTRUMENTATION
1620m_cost_iotlbmiss_transaction++;
1621#endif
1622        if ( not r_tlb_miss_init_req )  //  Miss transaction is done
1623        { 
1624                if ( r_miss_init_error.read() ) // bus error
1625                {
1626                r_miss_init_error  = false;
1627                r_tlb_error_type    = MMU_READ_DATA_ILLEGAL_ACCESS;
1628                r_dma_tlb_error_req     = true;
1629                r_dma_tlb_req           = false;
1630                r_dma_tlb_fsm = DMA_TLB_IDLE;
1631            }
1632            else if(r_tlb_miss_type == PTE1_MISS)
1633            {
1634                r_dma_tlb_fsm = DMA_TLB_PTE1_GET; 
1635       
1636            }
1637            else
1638            {
1639                r_dma_tlb_fsm = DMA_TLB_PTE2_GET;
1640            }
1641        }
1642        break;
1643    }
1644    ///////////////////////
1645    case DMA_TLB_RETURN:                // return to caller depending on tlb miss type
1646    {
1647#if DEBUG_DMA_TLB
1648if ( m_debug_dma_tlb_fsm )
1649{
1650    std::cout << "  <IOB.DMA_TLB_RETURN> IOTLB MISS completed" << std::endl;
1651}
1652#endif
1653        r_dma_tlb_req = false;
1654        r_tlb_dma_untreated = true;
1655        r_dma_tlb_fsm = DMA_TLB_IDLE;
1656        break;
1657    }
1658    //////////////////////
1659    case DMA_TLB_INVAL_CHECK:   // request from CONFIG FSM to invalidate all PTE on a given line
1660                                // This state checks the necessity to invalidate prefetch buffer
1661    {
1662        // If a transaction is pending, no need to invalidate the prefetch
1663        // We can ignore it, since we'll replace the line.
1664        // The new line is necessarily up-to-date
1665        if(!r_waiting_transaction.read() && r_miss_buf_valid)
1666        {
1667            if(!r_miss_buf_first_level)
1668            {
1669               if( r_miss_buf_vaddr_begin.read() == 
1670                   (r_config_tlb_inval_vaddr.read()& ~PTE2_LINE_OFFSET) ) 
1671                // The virtual address corresponds to one entry on the buffer line
1672                {
1673                    r_miss_buf_valid = false;   //change here for individual invalidation
1674                }
1675            }
1676            else    // First level entries on buffer. Unused if only small pages
1677            {
1678               if( r_miss_buf_vaddr_begin.read() == 
1679                   (r_config_tlb_inval_vaddr.read()& ~PTE1_LINE_OFFSET) ) 
1680                // The virtual address corresponds to one entry on the buffer line
1681                {
1682                    r_miss_buf_valid = false;   //change here for individual invalidation
1683                }
1684            }
1685        }
1686       
1687        // Invalidation on IOTLB
1688        bool    ok;
1689        ok = r_iotlb.inval(r_config_tlb_inval_vaddr.read());
1690         
1691        if(r_waiting_transaction.read()) r_dma_tlb_fsm =DMA_TLB_WAIT_TRANSACTION; 
1692        else r_dma_tlb_fsm = DMA_TLB_IDLE;
1693        break; 
1694    }
1695    } //end switch r_dma_tlb_fsm
1696   
1697   
1698    /////////////////////////////////////////////////////////////////////
1699    // The CONFIG_CMD_FSM is similar to the DMA_CMD_FSM, but without miss TLB treatment.
1700    // It controls the following ressources:
1701    // - r_config_cmd_fsm
1702    //
1703    // - r_config_cmd_rsp_erase_req (set)
1704    // - r_config_tlb_req (set)
1705    /////////////////////////////////////////////////////////////////////
1706
1707    switch( r_config_cmd_fsm.read() ) 
1708    {
1709    //////////////
1710    case CONFIG_CMD_IDLE:
1711    {
1712        if ( p_vci_tgt_config.cmdval.read() ) 
1713        {
1714#if DEBUG_CONFIG_CMD
1715if( m_debug_config_cmd_fsm )
1716{
1717    std::cout << "  <IOB.CONFIG_CMD_IDLE> Configuration command received!" <<std::endl;
1718    std::cout << " address = " << std::hex << p_vci_tgt_config.address.read()
1719              << " srcid = " << std::dec << p_vci_tgt_config.srcid.read()
1720              << " trdid = " << p_vci_tgt_config.trdid.read()
1721              << " wdata = " << std::hex << p_vci_tgt_config.wdata.read()
1722              << " be = " << p_vci_tgt_config.be.read()
1723              << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl;
1724}
1725#endif
1726            paddr_t config_paddr = p_vci_tgt_config.address.read();
1727   
1728//           // Just to verify
1729//           if(! m_locality_table_config[config_paddr] ) //cannot receive remote packets
1730//           {
1731//           std::cout << "IOB ERROR " << name() << " CONFIG_CMD_IDLE state" << std::endl
1732//                         << "Received a remote packet" << std::endl;
1733//               exit(0);
1734//           }
1735
1736            bool read = (p_vci_tgt_config.cmd.read() == vci_param_d::CMD_READ);
1737           
1738            uint32_t              cell    = (uint32_t)((config_paddr & 0x1FF)>>2); 
1739           
1740            // Treatement of received command
1741            // Verifies error, tests if the the command is for IOB itself
1742 
1743            // To IOB itself
1744            if(m_segment_config.contains(config_paddr))
1745            {
1746                if(!read && (cell == IOB_IOMMU_PTPR)) 
1747                    r_config_cmd_fsm = CONFIG_CMD_PTPR_WRITE;
1748                else if(read && (cell == IOB_IOMMU_PTPR)) 
1749                    r_config_cmd_fsm = CONFIG_CMD_PTPR_READ;
1750                else if(!read && (cell == IOB_IOMMU_ACTIVE)) 
1751                    r_config_cmd_fsm = CONFIG_CMD_ACTIVE_WRITE;
1752                else if(read && (cell == IOB_IOMMU_ACTIVE)) 
1753                    r_config_cmd_fsm = CONFIG_CMD_ACTIVE_READ;
1754                else if(read && (cell == IOB_IOMMU_BVAR)) 
1755                    r_config_cmd_fsm = CONFIG_CMD_BVAR_READ;
1756                else if(read && (cell == IOB_IOMMU_ETR)) 
1757                    r_config_cmd_fsm = CONFIG_CMD_ETR_READ;
1758                else if(read && (cell == IOB_IOMMU_BAD_ID)) 
1759                    r_config_cmd_fsm = CONFIG_CMD_BAD_ID_READ;
1760                // PTE invalidation signaled by the OS
1761                else if(!read && (cell == IOB_INVAL_PTE))
1762                    r_config_cmd_fsm = CONFIG_CMD_INVAL_REQ;
1763                else if(!read && (cell == IOB_IT_ADDR_IOMMU_LO)) 
1764                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1;
1765                else if(read && (cell == IOB_IT_ADDR_IOMMU_LO)) 
1766                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_1;
1767                else if( !read && ((cell >= IOB_IT_ADDR_BEGIN)&&
1768                        ( cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1) ) ) )
1769                {
1770                    // a factor two shows up because the registres come in couples
1771                    r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2;
1772                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_1;
1773                } 
1774                else if( read && ((cell >= IOB_IT_ADDR_BEGIN)&&
1775                        (cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1))) ) 
1776                {
1777                    r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2;
1778                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_1;
1779                }
1780                else
1781                //Error. Wrong address, or invalid operation.
1782                {
1783                    if(read)    r_config_error_type = READ_ERROR;
1784                    else        r_config_error_type = WRITE_ERROR;
1785                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1786                }
1787            }
1788            // Must route the command to the correct IO
1789            else
1790            {
1791                if(!p_vci_tgt_config.eop.read())
1792                {
1793                    //Error
1794                    if(read)    r_config_error_type = READ_ERROR;
1795                    else        r_config_error_type = WRITE_ERROR;
1796                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1797                }
1798               
1799                // Find the corresponding address on IO Space
1800//                int tgt_index = m_routing_table_config[config_paddr];
1801//#if DEBUG_CONFIG_CMD
1802//if( m_debug_config_cmd_fsm )
1803//{
1804//    std::cout << "  <IOB.CONFIG_CMD_IDLE> Routing a configuration packet" <<std::endl
1805//            << "Target Index on Direct NoC: " << tgt_index << std::endl;
1806//}
1807//#endif
1808//                soclib::common::Segment io_segment = m_mtio.getSegment(IntTab(tgt_index));
1809//               #define L2 soclib::common::uint32_log2
1810//               paddr_t offset_mask = ( (1 << L2(io_segment.size())) - 1);
1811//               #undef L2
1812//               r_config_vaddr = (vaddr_t)( io_segment.baseAddress() |
1813//                               (vaddr_t)(config_paddr & offset_mask) );
1814               
1815                // TODO So far, it is in identity mapping
1816                r_config_vaddr = (vaddr_t) config_paddr ; 
1817                r_config_cmd_fsm        = CONFIG_CMD_TRT_LOCK;
1818
1819            }
1820
1821
1822        } // end if cmdval
1823        break;
1824    }
1825    /////////////////////////
1826    case CONFIG_CMD_TRT_LOCK: // Waiting for the lock to modify Transaction Table
1827    {
1828        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 
1829        {
1830
1831#if DEBUG_CONFIG_CMD
1832if( m_debug_config_cmd_fsm )
1833{
1834    std::cout << "  <IOB.CONFIG_CMD_TRT_LOCK> Check the TRT" << std::endl;
1835}
1836#endif
1837            size_t              wok_index = 0;
1838            bool                wok       = !m_transaction_tab_config.full(wok_index);
1839
1840            if ( wok )  // TRT isn't full. Write the new transaction.
1841            {
1842                r_config_cmd_trt_index = (vci_trdid_t)wok_index;
1843                r_config_cmd_fsm       = CONFIG_CMD_TRT_SET;
1844            } 
1845            else                // wait an empty entry in TRT
1846            {
1847                r_config_cmd_fsm       = CONFIG_CMD_TRT_WAIT;
1848                r_config_cmd_rsp_erase_req = true;
1849#if DEBUG_CONFIG_CMD
1850if( m_debug_config_cmd_fsm )
1851{
1852    std::cout << "  <IOB.CONFIG_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl;
1853}
1854#endif
1855           
1856#ifdef INSTRUMENTATION       
1857m_cpt_trt_config_full++;
1858#endif
1859            }
1860        }
1861        break;
1862    }
1863    ////////////////
1864    case CONFIG_CMD_TRT_WAIT:   // release the lock protecting the transaction tab
1865                                // waits that RSP erases an entry
1866    { 
1867#ifdef INSTRUMENTATION       
1868m_cpt_trt_config_full_cost++;
1869#endif
1870        // CONFIG_RSP will notify an erase action by reseting this register
1871        if(!r_config_cmd_rsp_erase_req.read())
1872        {
1873            r_config_cmd_fsm = CONFIG_CMD_TRT_LOCK; // take the lock again
1874        }
1875        break;
1876    }
1877    ////////////////////////
1878    case CONFIG_CMD_TRT_SET:    // register a new transaction in TRT
1879    { 
1880        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 
1881        {
1882            m_transaction_tab_config.set(   r_config_cmd_trt_index.read(),
1883                                            p_vci_tgt_config.srcid.read(), 
1884                                            p_vci_tgt_config.trdid.read() );
1885           
1886            r_config_cmd_fsm = CONFIG_CMD_FIFO_PUT;
1887#if DEBUG_CONFIG_CMD
1888if( m_debug_config_cmd_fsm )
1889{
1890    std::cout << "  <IOB.CONFIG_CMD_TRT_SET> Set a new entry in TRT" << std::endl;
1891}
1892#endif
1893        }
1894        break;
1895    } 
1896    ///////////////////////
1897    case CONFIG_CMD_FIFO_PUT:   
1898    {
1899        if ( p_vci_tgt_config.cmdval && m_config_cmd_addr_fifo.wok() ) 
1900        {
1901            config_cmd_fifo_put = true;
1902            if(  p_vci_tgt_config.eop )    r_config_cmd_fsm = CONFIG_CMD_IDLE;
1903           
1904#if DEBUG_CONFIG_CMD
1905if( m_debug_config_cmd_fsm ) 
1906{
1907    std::cout << "  <IOB.CONFIG_CMD_FIFO_PUT> Push into config_cmd_fifo:" 
1908              << " address = " << std::hex << r_config_vaddr.read()
1909              << " srcid = " << std::dec << m_srcid_config
1910              << " trdid = " << r_config_cmd_trt_index.read()
1911              << " wdata = " << std::hex << p_vci_tgt_config.wdata.read()
1912              << " be = " << p_vci_tgt_config.be.read()
1913              << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl;
1914}
1915#endif
1916        }
1917        break;
1918    }
1919   
1920    ///////////////////////////////
1921    // Private Configuration States
1922    ///////////////////////////////
1923
1924    //////////////////
1925    case CONFIG_CMD_PTPR_WRITE: // Convention- The word received is in the format:
1926                                // 00000 BASE_ADDRESS[39:13]
1927                                // Same pattern as in iommu_ptpr register
1928    {
1929        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok()
1930            && r_dma_tlb_fsm == DMA_TLB_IDLE )
1931        {
1932            // This verification could have been done on IDLE state
1933            // It would save us one cycle
1934            if ( !p_vci_tgt_config.eop.read() )
1935            {
1936                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_PTPR_WRITE state" << std::endl;
1937                std::cout << " PTPR write command must contain one single flit" << std::endl;
1938                r_config_error_type = WRITE_ERROR;
1939                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1940                break;
1941            }
1942           
1943            // Depends on the convention
1944            r_iommu_ptpr = (uint32_t)(p_vci_tgt_config.wdata.read()); 
1945           
1946            config_local_fifo_put = true;
1947            r_config_cmd_fsm = CONFIG_CMD_IDLE;
1948
1949#if DEBUG_CONFIG_CMD
1950if( m_debug_config_cmd_fsm ) 
1951{
1952    std::cout << "  <IOB.CONFIG_CMD_PTPR_WRITE> PTPR received:" 
1953              << "r_iommu_ptpr = " << std::hex << (p_vci_tgt_config.wdata.read())
1954              <<std::endl;
1955}
1956#endif
1957        } 
1958        break;
1959    }
1960    /////////////////////
1961    case CONFIG_CMD_ACTIVE_WRITE: 
1962    {
1963        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() 
1964            && r_dma_tlb_fsm == DMA_TLB_IDLE )
1965        {
1966            // This verification could have been done on IDLE state
1967            // It would save us one cycle
1968            if ( !p_vci_tgt_config.eop.read() )
1969            {
1970                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_ACTIVE_WRITE state" << std::endl;
1971                std::cout << " ACTIVE write command must contain one single flit" << std::endl;
1972                r_config_error_type = WRITE_ERROR;
1973                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1974                break;
1975            }
1976           
1977            r_iommu_active = (p_vci_tgt_config.wdata.read() != 0);
1978           
1979            config_local_fifo_put = true;
1980            r_config_cmd_fsm = CONFIG_CMD_IDLE;
1981        } 
1982        break;
1983    }
1984    ///////////////////
1985    case CONFIG_CMD_INVAL_REQ: // Blocks in case of untreated request
1986    {   
1987        if ( !r_config_tlb_req.read() )
1988        {
1989            r_config_tlb_req = true;     
1990            r_config_cmd_fsm = CONFIG_CMD_INVAL;
1991        } 
1992        break;
1993    }
1994    ///////////////////
1995    case CONFIG_CMD_INVAL: // Consuming the 32bit Virtual Address of the invalidated page
1996    {
1997        if ( p_vci_tgt_config.cmdval.read() && 
1998                m_config_local_data_fifo.wok() ) 
1999        {
2000           
2001            if ( !p_vci_tgt_config.eop.read() )
2002            {
2003                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_INVAL state" << std::endl;
2004                std::cout << " PTE invalidation commands must contain one single flit" << std::endl;
2005                r_config_error_type = WRITE_ERROR;
2006                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2007                break;
2008            }
2009           
2010            assert( (p_vci_tgt_config.wdata.read()& K_PAGE_OFFSET_MASK) == 0 
2011                    and " Error : Invalid format for Page Virtual Address. At least the 12 LSB bits must be zero");
2012
2013            r_config_tlb_inval_vaddr = (vaddr_t)(p_vci_tgt_config.wdata.read());
2014             
2015            config_local_fifo_put = true;
2016            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2017        } 
2018        break;
2019    }
2020    //////////////////
2021    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1: 
2022    {
2023        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok())
2024        {
2025            if(vci_param_d::N <= 32)
2026            {
2027            // address holds in one single flit
2028                if (!p_vci_tgt_config.eop.read() )
2029                {
2030                   
2031                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl;
2032                    std::cout << " PTE invalidation command should contain just one flit" << std::endl;
2033                    r_config_error_type = WRITE_ERROR;
2034                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT;
2035                }
2036                else
2037                {
2038                    // If physical address holds on a single word
2039                    r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 
2040                 
2041                    config_local_fifo_put = true; 
2042                    r_config_cmd_fsm = CONFIG_CMD_IDLE;
2043                }
2044       
2045            }
2046            else
2047            {
2048            // two flits are required to send address
2049                if ( p_vci_tgt_config.eop.read() )
2050                {
2051                   
2052                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl;
2053                    std::cout << " PTE invalidation commands should contain two flits" << std::endl;
2054                    r_config_error_type = WRITE_ERROR;
2055                    r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP;
2056                }
2057                else
2058                {
2059                    r_config_first_word = p_vci_tgt_config.wdata.read(); 
2060                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2;
2061                }
2062            }
2063        } 
2064        break;
2065    }
2066    /////////////////
2067    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2: 
2068    {
2069        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2070        {
2071            if ( !p_vci_tgt_config.eop.read() )
2072            {
2073                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_IOMMU_WRITE_2 state" << std::endl;
2074                std::cout << " PTE invalidation commands must contain two flits" << std::endl;
2075                r_config_error_type = WRITE_ERROR;
2076                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2077                break;
2078            }
2079           
2080            // Depends on the convention
2081            size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ;
2082            r_it_addr_iommu = (paddr_t)(r_config_first_word.read() |
2083                                   ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 
2084             
2085            config_local_fifo_put = true;
2086            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2087        } 
2088    }
2089    //////////////////
2090    case CONFIG_CMD_IT_ADDR_WRITE_1: 
2091    {
2092        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok())
2093        {
2094            if(vci_param_d::N <= 32)
2095            {
2096            // address holds in one single flit
2097                if (!p_vci_tgt_config.eop.read() )
2098                {
2099                   
2100                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl;
2101                    std::cout << " PTE invalidation command should contain just one flit" << std::endl;
2102                    r_config_error_type = WRITE_ERROR;
2103                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT;
2104                   
2105                   
2106                }
2107                else
2108                {
2109                    // If physical address holds on a single word
2110                    r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 
2111                 
2112                    config_local_fifo_put = true; 
2113                    r_config_cmd_fsm = CONFIG_CMD_IDLE;
2114                }
2115       
2116            }
2117            else
2118            {
2119            // two flits are required to send address
2120                if ( p_vci_tgt_config.eop.read() )
2121                {
2122                   
2123                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl;
2124                    std::cout << " PTE invalidation commands should contain two flits" << std::endl;
2125                    r_config_error_type = WRITE_ERROR;
2126                    r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP;
2127                }
2128                else
2129                {
2130                    r_config_first_word = p_vci_tgt_config.wdata.read();
2131                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_2;
2132                }
2133            } 
2134        } 
2135        break;
2136    }
2137    /////////////////
2138    case CONFIG_CMD_IT_ADDR_WRITE_2: 
2139    {
2140        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2141        {
2142            if ( !p_vci_tgt_config.eop.read() )
2143            {
2144                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_2 state" << std::endl;
2145                std::cout << " PTE invalidation commands must contain two flits" << std::endl;
2146                r_config_error_type = WRITE_ERROR;
2147                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2148                break;
2149            }
2150           
2151            // Depends on the convention
2152            size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ;
2153            r_it_addr[r_it_index.read()] = (paddr_t)(r_config_first_word.read() |
2154                                ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 
2155             
2156            config_local_fifo_put = true;
2157            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2158        } 
2159    }
2160    //////////////////
2161    case CONFIG_CMD_PTPR_READ: 
2162    case CONFIG_CMD_ACTIVE_READ:
2163    case CONFIG_CMD_BVAR_READ:
2164    case CONFIG_CMD_ETR_READ:
2165    case CONFIG_CMD_BAD_ID_READ:
2166    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
2167    case CONFIG_CMD_IT_ADDR_READ_1:
2168    {
2169        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2170        {
2171            // This verification could have been done on IDLE state
2172            // It would save us one cycle
2173            if ( !p_vci_tgt_config.eop.read() )
2174            {
2175                std::cout << "CONFIG_CMD ERROR " << name() << config_cmd_fsm_state_str[r_config_cmd_fsm.read()] << std::endl;
2176                std::cout << " Read commands must contain one single flit" << std::endl;
2177                r_config_error_type = READ_ERROR;
2178                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2179                break;
2180            }
2181           
2182            // fifo data receives the content of the corresponding register
2183            // (depending on the current state)
2184            config_local_fifo_put = true;
2185            if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_READ_1)
2186            r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_2;
2187            else if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_IOMMU_READ_1)
2188            r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_2;
2189            else
2190            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2191        } 
2192        break;
2193    }
2194    //////////////////
2195    case CONFIG_CMD_IT_ADDR_READ_2:
2196    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
2197    {
2198        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2199        {
2200            config_local_fifo_put = true;
2201            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2202        } 
2203    }
2204    //////////////////
2205    case CONFIG_CMD_ERROR_WAIT: //receives the other flits of the same transaction
2206    {
2207        if ( p_vci_tgt_config.cmdval.read() && p_vci_tgt_config.eop.read() ) 
2208        r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP; 
2209    }
2210    ///////////////////
2211    case CONFIG_CMD_ERROR_RSP:
2212    {
2213        if ( m_config_local_data_fifo.wok() )
2214        {
2215            config_local_fifo_put = true;
2216            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2217        }
2218        break;
2219    }
2220
2221    } // end switch CONFIG_CMD FSM
2222
2223    /////////////////////////////////////////////////////////////////////
2224    // The CONFIG_RSP_FSM controls the following ressources:
2225    // - r_config_rsp_fsm
2226    // - r_config_cmd_rsp_erase_req (reset)
2227    // -
2228    // -
2229    //////////////////////////////////////////////////////////////////////////////
2230    switch( r_config_rsp_fsm.read() ) 
2231    {
2232    /////////////////////
2233    case CONFIG_RSP_IDLE:
2234    {           
2235        if(p_vci_ini_config.rspval.read()) 
2236                {
2237            r_config_rsp_fsm = CONFIG_RSP_TRT_LOCK;
2238                }
2239                break;
2240    }
2241    /////////////////////
2242    case CONFIG_RSP_TRT_LOCK:
2243    {           
2244        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_RSP ) 
2245        {
2246           
2247#if DEBUG_CONFIG_RSP
2248if( m_debug_config_rsp_fsm )
2249{
2250    std::cout << "  <IOB.CONFIG_RSP_TRT_LOCK> Read and erase entry" << std::endl;
2251}
2252#endif
2253            uint32_t trdid_iospace = p_vci_ini_config.rtrdid.read(); 
2254           
2255            r_config_rsrcid = (vci_srcid_t)m_transaction_tab_config.readSrcid(trdid_iospace);
2256            r_config_rtrdid = (vci_trdid_t)m_transaction_tab_config.readTrdid(trdid_iospace);
2257            m_transaction_tab_config.erase(trdid_iospace);
2258            if (r_config_cmd_rsp_erase_req.read()) r_config_cmd_rsp_erase_req = false;
2259            r_config_rsp_fsm       = CONFIG_RSP_FIFO_PUT;
2260        }       
2261                break;
2262    }
2263    //////////////////
2264    case CONFIG_RSP_FIFO_PUT:
2265    {
2266        if(p_vci_ini_config.rspval.read() && m_config_rsp_data_fifo.wok())
2267        {
2268            config_rsp_fifo_put = true;
2269            if(p_vci_ini_config.reop.read())   r_config_rsp_fsm = CONFIG_RSP_IDLE;     
2270
2271#if DEBUG_CONFIG_RSP
2272if( m_debug_config_rsp_fsm ) 
2273{
2274    std::cout << "  <IOB.CONFIG_RSP_FIFO_PUT> Push into rsp_fifo:" 
2275              << " rsrcid = " << std::dec << r_config_rsrcid.read()
2276              << " rtrdid = " << r_config_rtrdid.read()
2277              << " rdata = " << std::hex << p_vci_ini_config.rdata.read()
2278    << std::endl;
2279}
2280#endif
2281                       
2282        }
2283        break;
2284    }
2285    } // end switch CONFIG_RSP FSM
2286
2287
2288    ////////////////////////////////////////////////////////////////////////////
2289    // The ALLOC_TRT_CONFIG fsm allocates the access to the Transaction Table (m_transaction_tab_config)
2290    // with a round robin priority between 2 user FSMs :
2291    // - CONFIG_CMD : to set a new entry
2292    // - CONFIG_RSP : to read and erase an entry
2293    // The ressource is always allocated.
2294    ////////////////////////////////////////////////////////////////////////////////////
2295   
2296    switch ( r_alloc_trt_config_fsm.read() ) 
2297    {
2298    ///////////////////
2299    case ALLOC_TRT_CONFIG_CMD:
2300    {
2301        if ( r_config_cmd_fsm.read() != CONFIG_CMD_TRT_LOCK ) 
2302        {
2303          if (r_config_rsp_fsm.read() == CONFIG_RSP_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_RSP;
2304        }
2305    }
2306    ///////////////////
2307    case ALLOC_TRT_CONFIG_RSP:
2308    {
2309        if (r_config_rsp_fsm.read() != CONFIG_RSP_TRT_LOCK) 
2310        {
2311            if (r_config_cmd_fsm.read() == CONFIG_CMD_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_CMD;
2312        }
2313    }
2314    } // end switch r_alloc_trt_config_fsm
2315
2316    ////////////////////////////////////////////////////////////////////////////
2317    // The MISS_INIT FSM sends a page table entry miss request into Direct Noc
2318    // It controls the following ressources:
2319    // - r_miss_init_fsm
2320    // - r_tlb_miss_init_req (reset)
2321    // - r_miss_buf_data
2322    // - r_miss_buf_valid
2323    // - r_miss_buf_tag
2324    ////////////////////////////////////////////////////////////////////////////////////
2325
2326    // Building the interruption vector (systematically)
2327    uint32_t irq_demands = 0;
2328    for ( size_t i = 0; i<m_nb_periph; ++i )
2329        irq_demands |= (p_irq_in[i].read() ? 1 : 0) << i;
2330   
2331    // For next cycle:
2332        // Afectation of the new pending vector.
2333        // Not useful, unless Irq choice is postponed to next cycle
2334    r_irq_pending = irq_demands & r_irq_mask.read();
2335        // Updating Mask
2336    r_irq_mask = r_irq_mask.read()| ~irq_demands; 
2337   
2338 
2339    switch ( r_miss_init_fsm.read() ) 
2340    {
2341        //////////////
2342        case MISS_INIT_IDLE_MISS:
2343        {
2344            if(r_tlb_miss_init_req.read())
2345            {
2346                r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD;
2347            }
2348            else if (irq_demands & r_irq_mask.read()){
2349                // Choosing one interruption to send           
2350                // Find the first bit 1
2351                // starting by the bit just after the last chosen
2352                size_t i = (r_irq_chosen.read() + 1)% m_nb_periph;
2353                bool found = false;
2354                do
2355                {
2356                    if(irq_demands & r_irq_mask.read() & (1<<i)) 
2357                    {
2358                        r_irq_chosen = i;
2359                        found = true;
2360                    }
2361                    i = (i+1) % m_nb_periph;
2362                }
2363                while(i != r_irq_chosen.read()+1 && !found); 
2364
2365                r_miss_init_fsm = MISS_INIT_IRQ_CMD;
2366            }
2367                        break;
2368        }
2369        //////////////
2370        case MISS_INIT_IDLE_IRQ:
2371        {
2372            if (irq_demands & r_irq_mask.read()){
2373                // Choosing one interruption to send           
2374                // Find the first bit 1
2375                // starting by the bit just after the last chosen
2376                size_t i = (r_irq_chosen.read() + 1)% m_nb_periph;
2377                bool found = false;
2378                do
2379                {
2380                    if(irq_demands & r_irq_mask.read() & (1<<i)) 
2381                    {
2382                        r_irq_chosen = i;
2383                        found = true;
2384                    }
2385                    i = (i+1) % m_nb_periph;
2386                }
2387                while(i != r_irq_chosen.read()+1 && !found); 
2388
2389                r_miss_init_fsm = MISS_INIT_IRQ_CMD;
2390            }
2391            else if(r_tlb_miss_init_req.read())
2392            {
2393                r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD;
2394            }
2395                        break;
2396        }
2397        /////////////////////////       // send a read request to Direct Network
2398        case MISS_INIT_IRQ_CMD: 
2399        {
2400        if ( p_vci_ini_miss.cmdack ) 
2401        {
2402            // Masking chosen interruption, until it is resolved
2403            r_irq_mask = r_irq_mask.read() & ~(1<<r_irq_chosen.read());
2404            r_miss_init_fsm = MISS_INIT_IRQ_RSP;               
2405
2406#if DEBUG_MISS_INIT
2407if( m_debug_miss_init_fsm )
2408{
2409    std::cout << "  <IOB.MISS_INIT_IRQ_CMD> Send write (irq) command to XICU"
2410              << " irq ID = " << std::dec << r_irq_chosen.read()
2411              << " new mask = " << std::hex << (r_irq_mask.read() & ~(1<<r_irq_chosen.read()))
2412     << std::endl;
2413}
2414#endif
2415        }
2416            break;
2417        }
2418        //////////////////
2419        case MISS_INIT_IRQ_RSP: 
2420        {
2421            if ( p_vci_ini_miss.rspval.read() ) 
2422            {
2423                // It is a WRITE command, response in one single flit long
2424                assert( p_vci_ini_miss.reop.read() and "Write answer should have one single flit" ); 
2425                bool error;
2426               
2427                if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 )  // error reported
2428                {
2429                    // TODO traiter error
2430                    error = true;
2431                }
2432                r_miss_init_fsm = MISS_INIT_IDLE_MISS;
2433            }
2434            break;
2435        }
2436        /////////////////////////       // send a read request to Direct Network
2437        case MISS_INIT_TLB_MISS_CMD: 
2438        {
2439        if ( p_vci_ini_miss.cmdack ) 
2440        {
2441            r_miss_rsp_cpt  = 0;    //counter for the response flits
2442            r_miss_buf_tag  = ( (r_iotlb_paddr.read()) & CACHE_LINE_MASK ); 
2443            r_miss_buf_valid = true;
2444           
2445            if(r_tlb_miss_type.read()== PTE1_MISS)
2446                r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET);
2447            else
2448                r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET);
2449               
2450            r_miss_init_fsm = MISS_INIT_TLB_MISS_RSP;           
2451
2452#if DEBUG_MISS_INIT
2453if( m_debug_miss_init_fsm )
2454{
2455    std::cout << "  <IOB.MISS_INIT_TLB_MISS_CMD> Send read (tlb entry) request to MEM CACHE: "
2456    << " | address :  "<< std::hex <<(paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK)
2457    << std::endl;
2458}
2459#endif
2460        }
2461            break;
2462        }
2463        //////////////////
2464        case MISS_INIT_TLB_MISS_RSP:   
2465        {
2466            if ( p_vci_ini_miss.rspval.read() ) 
2467            {
2468                if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 )  // error reported
2469                {
2470                    r_miss_init_error = true;
2471                    if ( p_vci_ini_miss.reop.read() ) 
2472                    {   
2473                        r_miss_init_fsm = MISS_INIT_IDLE_IRQ;
2474                        r_tlb_miss_init_req = false; 
2475                    }
2476#if DEBUG_MISS_INIT
2477if( m_debug_miss_init_fsm ) 
2478{
2479    std::cout << " <IOB.MISS_INIT_TLB_MISS_RSP> ERROR " << std::endl; 
2480}
2481#endif
2482                }
2483                else
2484                { 
2485                    bool   eop          = p_vci_ini_miss.reop.read();
2486
2487
2488#if DEBUG_MISS_INIT
2489if( m_debug_miss_init_fsm ) 
2490{
2491    std::cout << "  <IOB.MISS_INIT_TLB_MISS_RSP> Response from Mem Cache to a read (tlb entry) transaction. Count = " << r_miss_rsp_cpt.read()
2492    <<" | Data = " << std::hex << p_vci_ini_miss.rdata.read() << std::endl; 
2493}
2494#endif
2495
2496                    assert(((eop == (r_miss_rsp_cpt.read() == (m_words-1))) ) 
2497                        and "Error : invalid length for a response from MEM CACHE");
2498                    r_miss_buf_data[r_miss_rsp_cpt] =  (uint32_t)p_vci_ini_miss.rdata.read();
2499                   
2500                    r_miss_rsp_cpt = r_miss_rsp_cpt.read() + 1;
2501                   
2502                    if ( eop ) 
2503                    {
2504                        r_tlb_miss_init_req = false;     //reset the request flip-flop
2505                        r_miss_init_fsm = MISS_INIT_IDLE_IRQ;           
2506                    }
2507
2508                }
2509            }
2510            break;
2511        }
2512
2513    } // end  switch r_miss_init_fsm
2514   
2515    //////////////////////////////////
2516    // Fifo consumption arbitration //
2517    //////////////////////////////////
2518   
2519    // Round Robin priority for CONFIG_RSP FIFO consumption
2520    r_config_rsp_fifo_local_priority = ! r_config_rsp_fifo_local_priority.read(); 
2521   
2522    //DMA CMD
2523    dma_cmd_fifo_get = (p_vci_ini_dma.cmdack.read() && m_dma_cmd_addr_fifo.rok());
2524    // DMA RSP
2525    dma_rsp_fifo_get = (p_vci_tgt_dma.rspack.read() && m_dma_rsp_data_fifo.rok());
2526    // CONFIG CMD
2527    config_cmd_fifo_get = (p_vci_ini_config.cmdack.read() && m_config_cmd_addr_fifo.rok() );
2528    // CONFIG RSP, detemines wich fifo to consume
2529    if(r_config_rsp_fifo_local_priority)
2530    {
2531        if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read();
2532        else if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read();
2533           
2534    }
2535    else
2536    {
2537        if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read();
2538        else if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read();
2539    }
2540    ///////////////
2541    //DMA_CMD Fifo
2542    ///////////////
2543    if(r_miss_interrupt)
2544    {
2545        m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get,
2546                                    dma_cmd_fifo_put,
2547                                    r_miss_paddr.read() );
2548        m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get,
2549                                    dma_cmd_fifo_put,
2550                                    r_miss_cmd.read() );
2551        m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
2552                                    dma_cmd_fifo_put,
2553                                    r_miss_contig.read() );
2554        m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get,
2555                                    dma_cmd_fifo_put,
2556                                    r_miss_cons.read() );
2557        m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get,
2558                                    dma_cmd_fifo_put,
2559                                    r_miss_plen.read() );
2560        m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get,
2561                                    dma_cmd_fifo_put,
2562                                    r_miss_wrap.read() );
2563        m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
2564                                    dma_cmd_fifo_put,
2565                                    r_miss_cfixed.read() );
2566        m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get,
2567                                    dma_cmd_fifo_put,
2568                                    r_miss_clen.read() );
2569        m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get,
2570                                    dma_cmd_fifo_put,
2571                                    m_srcid_dma ); //r_miss_srcid.read()
2572        m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get,
2573                                    dma_cmd_fifo_put,
2574                                    r_miss_trdid.read() );
2575        m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get,
2576                                    dma_cmd_fifo_put,
2577                                    r_miss_pktid.read() );
2578        m_dma_cmd_data_fifo.update( dma_cmd_fifo_get,
2579                                    dma_cmd_fifo_put,
2580                                    r_miss_data[r_dma_cmd_count.read()-1] );
2581        m_dma_cmd_be_fifo.update( dma_cmd_fifo_get,
2582                                    dma_cmd_fifo_put,
2583                                    r_miss_be[r_dma_cmd_count.read()-1] );
2584        m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get,
2585                                    dma_cmd_fifo_put,
2586                                    (r_dma_cmd_count.read() == 1) );
2587    }
2588    else 
2589    {
2590        m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get,
2591                                    dma_cmd_fifo_put,
2592                                    r_dma_paddr.read() ); 
2593        m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get,
2594                                    dma_cmd_fifo_put,
2595                                    p_vci_tgt_dma.cmd.read() );
2596        m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
2597                                    dma_cmd_fifo_put,
2598                                    p_vci_tgt_dma.contig.read() );
2599        m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get,
2600                                    dma_cmd_fifo_put,
2601                                    p_vci_tgt_dma.cons.read() );
2602        m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get,
2603                                    dma_cmd_fifo_put,
2604                                    p_vci_tgt_dma.plen.read() );
2605        m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get,
2606                                    dma_cmd_fifo_put,
2607                                    p_vci_tgt_dma.wrap.read() );
2608        m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
2609                                    dma_cmd_fifo_put,
2610                                    p_vci_tgt_dma.cfixed.read() );
2611        m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get,
2612                                    dma_cmd_fifo_put,
2613                                    p_vci_tgt_dma.clen.read() );
2614        m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get,
2615                                    dma_cmd_fifo_put,
2616                                    m_srcid_dma );
2617        m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get,
2618                                    dma_cmd_fifo_put,
2619                                    r_dma_cmd_trt_index.read() );
2620        m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get,
2621                                    dma_cmd_fifo_put,
2622                                    p_vci_tgt_dma.pktid.read() );
2623        m_dma_cmd_data_fifo.update( dma_cmd_fifo_get,
2624                                    dma_cmd_fifo_put,
2625                                    p_vci_tgt_dma.wdata.read() ); // TODO change
2626                                                            // For 64bits XRAM
2627        m_dma_cmd_be_fifo.update( dma_cmd_fifo_get,
2628                                    dma_cmd_fifo_put,
2629                                    p_vci_tgt_dma.be.read() ); 
2630        m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get,
2631                                    dma_cmd_fifo_put,
2632                                     p_vci_tgt_dma.eop.read() );
2633    }
2634
2635    ///////////////
2636    //DMA_RSP Fifo
2637    ///////////////
2638    if(r_dma_rsp_fsm.read() == DMA_RSP_FIFO_ERROR_PUT)
2639    {
2640        m_dma_rsp_data_fifo.update( dma_rsp_fifo_get,
2641                                    dma_rsp_fifo_put,
2642                                    0 );
2643        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
2644                                    dma_rsp_fifo_put,
2645                                    r_iommu_bad_id.read() ); 
2646        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
2647                                    dma_rsp_fifo_put,
2648                                    r_dma_error_trdid.read() ); 
2649        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
2650                                    dma_rsp_fifo_put,
2651                                    r_dma_error_pktid.read() );
2652        m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,
2653                                   dma_rsp_fifo_put,
2654                                   true );
2655        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
2656                                      dma_rsp_fifo_put,
2657                                      r_dma_error_type.read() );
2658    }
2659    else
2660    {
2661        m_dma_rsp_data_fifo.update( dma_rsp_fifo_get,
2662                                    dma_rsp_fifo_put,
2663                                    p_vci_ini_dma.rdata.read() );
2664        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
2665                                    dma_rsp_fifo_put,
2666                                    r_dma_rsrcid.read() ); 
2667        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
2668                                    dma_rsp_fifo_put,
2669                                    r_dma_rtrdid.read() ); 
2670        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
2671                                    dma_rsp_fifo_put,
2672                                    p_vci_ini_dma.rpktid.read() );
2673        m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,
2674                                   dma_rsp_fifo_put,
2675                                   p_vci_ini_dma.reop.read() );
2676        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
2677                                      dma_rsp_fifo_put,
2678                                      p_vci_ini_dma.rerror.read() );
2679    }
2680
2681    //////////////////
2682    //CONFIG_CMD Fifo
2683    //////////////////
2684    m_config_cmd_addr_fifo.update( config_cmd_fifo_get,
2685                                config_cmd_fifo_put,
2686                                r_config_vaddr.read() ); 
2687    m_config_cmd_cmd_fifo.update( config_cmd_fifo_get,
2688                                config_cmd_fifo_put,
2689                                p_vci_tgt_config.cmd.read() );
2690    m_config_cmd_contig_fifo.update( config_cmd_fifo_get,
2691                                config_cmd_fifo_put,
2692                                p_vci_tgt_config.contig.read() );
2693    m_config_cmd_cons_fifo.update( config_cmd_fifo_get,
2694                                config_cmd_fifo_put,
2695                                p_vci_tgt_config.cons.read() );
2696    m_config_cmd_plen_fifo.update( config_cmd_fifo_get,
2697                                config_cmd_fifo_put,
2698                                p_vci_tgt_config.plen.read() );
2699    m_config_cmd_wrap_fifo.update( config_cmd_fifo_get,
2700                                config_cmd_fifo_put,
2701                                p_vci_tgt_config.wrap.read() );
2702    m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get,
2703                                config_cmd_fifo_put,
2704                                p_vci_tgt_config.cfixed.read() );
2705    m_config_cmd_clen_fifo.update( config_cmd_fifo_get,
2706                                config_cmd_fifo_put,
2707                                p_vci_tgt_config.clen.read() );
2708    m_config_cmd_srcid_fifo.update( config_cmd_fifo_get,
2709                                config_cmd_fifo_put,
2710                                m_srcid_config );
2711    m_config_cmd_trdid_fifo.update( config_cmd_fifo_get,
2712                                config_cmd_fifo_put,
2713                                r_config_cmd_trt_index.read() ); 
2714    m_config_cmd_pktid_fifo.update( config_cmd_fifo_get,
2715                                config_cmd_fifo_put,
2716                                p_vci_tgt_config.pktid.read() );
2717    m_config_cmd_data_fifo.update( config_cmd_fifo_get,
2718                                config_cmd_fifo_put,
2719                                p_vci_tgt_config.wdata.read() );
2720    m_config_cmd_be_fifo.update( config_cmd_fifo_get,
2721                                config_cmd_fifo_put,
2722                                p_vci_tgt_config.be.read() );
2723    m_config_cmd_eop_fifo.update( config_cmd_fifo_get,
2724                                    config_cmd_fifo_put,
2725                                     p_vci_tgt_config.eop.read() );
2726   
2727    //////////////////
2728    //CONFIG_RSP Fifo
2729    //////////////////
2730    m_config_rsp_data_fifo.update( config_rsp_fifo_get,
2731                                config_rsp_fifo_put,
2732                                p_vci_ini_config.rdata.read() );
2733    m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get,
2734                                config_rsp_fifo_put,
2735                                r_config_rsrcid.read() );
2736    m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get,
2737                                config_rsp_fifo_put,
2738                                r_config_rtrdid.read() );
2739    m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get,
2740                                config_rsp_fifo_put,
2741                                p_vci_ini_config.rpktid.read() );
2742    m_config_rsp_reop_fifo.update( config_rsp_fifo_get,
2743                               config_rsp_fifo_put,
2744                               p_vci_ini_config.reop.read() );
2745    m_config_rsp_rerror_fifo.update( config_rsp_fifo_get,
2746                                  config_rsp_fifo_put,
2747                                  p_vci_ini_config.rerror.read() );
2748   
2749    ///////////////////////
2750    //CONFIG Local RSP Fifo
2751    ///////////////////////
2752    m_config_local_rsrcid_fifo.update( config_local_fifo_get,
2753                                config_local_fifo_put,
2754                                p_vci_tgt_config.srcid.read() );
2755    m_config_local_rtrdid_fifo.update( config_local_fifo_get,
2756                                config_local_fifo_put,
2757                                p_vci_tgt_config.trdid.read() );
2758    m_config_local_rpktid_fifo.update( config_local_fifo_get,
2759                                config_local_fifo_put,
2760                                p_vci_tgt_config.pktid.read() );
2761   
2762    switch( r_config_cmd_fsm.read() ) 
2763    {
2764    case CONFIG_CMD_PTPR_WRITE:
2765    case CONFIG_CMD_ACTIVE_WRITE:
2766    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:
2767    case CONFIG_CMD_IT_ADDR_WRITE_2:
2768    case CONFIG_CMD_INVAL:
2769        m_config_local_data_fifo.update( config_local_fifo_get,
2770                                config_local_fifo_put,
2771                                0); 
2772        m_config_local_rerror_fifo.update( config_local_fifo_get,
2773                                        config_local_fifo_put,
2774                                        WRITE_OK );
2775        m_config_local_reop_fifo.update( config_local_fifo_get,
2776                                        config_local_fifo_put,
2777                                        true );
2778        break;
2779    case CONFIG_CMD_PTPR_READ:
2780        m_config_local_data_fifo.update( config_local_fifo_get,
2781                                config_local_fifo_put,
2782                                r_iommu_ptpr.read()); 
2783        m_config_local_rerror_fifo.update( config_local_fifo_get,
2784                                        config_local_fifo_put,
2785                                        READ_OK );
2786        m_config_local_reop_fifo.update( config_local_fifo_get,
2787                                        config_local_fifo_put,
2788                                        true );
2789        break;
2790    case CONFIG_CMD_ACTIVE_READ:
2791        m_config_local_data_fifo.update( config_local_fifo_get,
2792                                config_local_fifo_put,
2793                                r_iommu_active.read()); 
2794        m_config_local_rerror_fifo.update( config_local_fifo_get,
2795                                        config_local_fifo_put,
2796                                        READ_OK );
2797        m_config_local_reop_fifo.update( config_local_fifo_get,
2798                                        config_local_fifo_put,
2799                                        true );
2800        break;
2801    case CONFIG_CMD_BVAR_READ:
2802        m_config_local_data_fifo.update( config_local_fifo_get,
2803                                config_local_fifo_put,
2804                                r_iommu_bvar.read()); 
2805        m_config_local_rerror_fifo.update( config_local_fifo_get,
2806                                        config_local_fifo_put,
2807                                        READ_OK );
2808        m_config_local_reop_fifo.update( config_local_fifo_get,
2809                                        config_local_fifo_put,
2810                                        true );
2811        break;
2812    case CONFIG_CMD_ETR_READ:
2813        m_config_local_data_fifo.update( config_local_fifo_get,
2814                                config_local_fifo_put,
2815                                r_iommu_etr.read()); 
2816        m_config_local_rerror_fifo.update( config_local_fifo_get,
2817                                        config_local_fifo_put,
2818                                        READ_OK );
2819        m_config_local_reop_fifo.update( config_local_fifo_get,
2820                                        config_local_fifo_put,
2821                                        true );
2822        break;
2823    case CONFIG_CMD_BAD_ID_READ:
2824        m_config_local_data_fifo.update( config_local_fifo_get,
2825                                config_local_fifo_put,
2826                                r_iommu_bad_id.read()); 
2827        m_config_local_rerror_fifo.update( config_local_fifo_get,
2828                                        config_local_fifo_put,
2829                                        READ_OK );
2830        m_config_local_reop_fifo.update( config_local_fifo_get,
2831                                        config_local_fifo_put,
2832                                        true );
2833        break;
2834    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
2835        m_config_local_data_fifo.update( config_local_fifo_get,
2836                                config_local_fifo_put,
2837                                (uint32_t)(r_it_addr_iommu.read() & 0xFFFFFFFF) ); 
2838        m_config_local_rerror_fifo.update( config_local_fifo_get,
2839                                        config_local_fifo_put,
2840                                        READ_OK );
2841        m_config_local_reop_fifo.update( config_local_fifo_get,
2842                                        config_local_fifo_put,
2843                                        false );
2844        break;
2845    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
2846        m_config_local_data_fifo.update( config_local_fifo_get,
2847                                config_local_fifo_put,
2848                               (uint32_t)((r_it_addr_iommu.read()>>32)&0xFF) ); 
2849        m_config_local_rerror_fifo.update( config_local_fifo_get,
2850                                        config_local_fifo_put,
2851                                        READ_OK );
2852        m_config_local_reop_fifo.update( config_local_fifo_get,
2853                                        config_local_fifo_put,
2854                                        true );
2855        break;
2856    case CONFIG_CMD_IT_ADDR_READ_1:
2857        m_config_local_data_fifo.update( config_local_fifo_get,
2858                                config_local_fifo_put,
2859                               (uint32_t)(r_it_addr[r_it_index.read()] & 0xFFFFFFFF) ); 
2860        m_config_local_rerror_fifo.update( config_local_fifo_get,
2861                                        config_local_fifo_put,
2862                                        READ_OK );
2863        m_config_local_reop_fifo.update( config_local_fifo_get,
2864                                        config_local_fifo_put,
2865                                        false );
2866        break;
2867    case CONFIG_CMD_IT_ADDR_READ_2:
2868        m_config_local_data_fifo.update( config_local_fifo_get,
2869                                config_local_fifo_put,
2870                                (uint32_t)((r_it_addr[r_it_index.read()]>>32)&0xFF) ); 
2871        m_config_local_rerror_fifo.update( config_local_fifo_get,
2872                                        config_local_fifo_put,
2873                                        READ_OK );
2874        m_config_local_reop_fifo.update( config_local_fifo_get,
2875                                        config_local_fifo_put,
2876                                        true );
2877        break;
2878    case CONFIG_CMD_ERROR_RSP:
2879        m_config_local_data_fifo.update( config_local_fifo_get,
2880                                        config_local_fifo_put,
2881                                        0); 
2882        m_config_local_rerror_fifo.update( config_local_fifo_get,
2883                                        config_local_fifo_put,
2884                                        r_config_error_type.read() );
2885        m_config_local_reop_fifo.update( config_local_fifo_get,
2886                                        config_local_fifo_put,
2887                                        true );
2888        break;
2889    default:
2890        m_config_local_data_fifo.update( config_local_fifo_get,
2891                                config_local_fifo_put,
2892                                0); 
2893        m_config_local_rerror_fifo.update( config_local_fifo_get,
2894                                        config_local_fifo_put,
2895                                        0 );
2896        m_config_local_reop_fifo.update( config_local_fifo_get,
2897                               config_local_fifo_put,
2898                               false );
2899        break;
2900    }
2901
2902} // end transition()
2903
2904///////////////////////
2905tmpl(void)::genMoore()
2906///////////////////////
2907{
2908    //////////////////
2909    // DMA Commands //
2910    //////////////////
2911   
2912    // VCI initiator command on the xram network
2913    if(m_dma_cmd_addr_fifo.rok()) 
2914    //&& p_vci_ini_dma.cmdack.read())
2915    {
2916        p_vci_ini_dma.cmdval  = true;
2917        #if NEW_XRAM_VCI
2918        p_vci_ini_dma.address = (paddr_t_x)(m_dma_cmd_addr_fifo.read() >> 6 )
2919        #else
2920        p_vci_ini_dma.address = m_dma_cmd_addr_fifo.read();
2921        #endif
2922       
2923        p_vci_ini_dma.be      = m_dma_cmd_be_fifo.read();
2924        p_vci_ini_dma.cmd     = m_dma_cmd_cmd_fifo.read();
2925        p_vci_ini_dma.contig  = m_dma_cmd_contig_fifo.read();
2926        #if NEW_XRAM_VCI
2927        //TODO for 64 bits field
2928        #else
2929        p_vci_ini_dma.wdata   = m_dma_cmd_data_fifo.read(); // The first is in param_x
2930                                                    // the second in param_io
2931        #endif
2932        p_vci_ini_dma.eop     = m_dma_cmd_eop_fifo.read();
2933        p_vci_ini_dma.cons    = m_dma_cmd_cons_fifo.read();
2934        p_vci_ini_dma.plen    = m_dma_cmd_plen_fifo.read();
2935        p_vci_ini_dma.wrap    = m_dma_cmd_wrap_fifo.read();
2936        p_vci_ini_dma.cfixed  = m_dma_cmd_cfixed_fifo.read();
2937        p_vci_ini_dma.clen    = m_dma_cmd_clen_fifo.read();
2938        p_vci_ini_dma.trdid   = m_dma_cmd_trdid_fifo.read();
2939        p_vci_ini_dma.pktid   = m_dma_cmd_pktid_fifo.read();
2940        p_vci_ini_dma.srcid   = m_dma_cmd_srcid_fifo.read();
2941    }
2942    else
2943    {
2944        p_vci_ini_dma.cmdval  = false;
2945        p_vci_ini_dma.address = 0;
2946        p_vci_ini_dma.be      = 0;
2947        p_vci_ini_dma.cmd     = vci_param_x::CMD_NOP;
2948        p_vci_ini_dma.contig  = false;
2949        p_vci_ini_dma.wdata   = 0;
2950        p_vci_ini_dma.eop     = false;
2951        p_vci_ini_dma.cons    = true;
2952        p_vci_ini_dma.plen    = 0;
2953        p_vci_ini_dma.wrap    = false;
2954        p_vci_ini_dma.cfixed  = false;
2955        p_vci_ini_dma.clen    = 0;
2956        p_vci_ini_dma.trdid   = 0;
2957        p_vci_ini_dma.pktid   = 0; 
2958    }
2959   
2960    // VCI target command on the IO network
2961    // it depends on the DMA_CMD FSM state
2962
2963    switch ( r_dma_cmd_fsm.read() ) 
2964    {
2965    case DMA_CMD_IDLE:
2966    case DMA_CMD_TRT_LOCK:     
2967    case DMA_CMD_TRT_WAIT:     
2968    case DMA_CMD_TRT_SET:       
2969        p_vci_tgt_dma.cmdack  = false;
2970        break;
2971    case DMA_CMD_FIFO_PUT:
2972    case DMA_CMD_FIFO_MISS_PUT:
2973        p_vci_tgt_dma.cmdack  = m_dma_cmd_addr_fifo.wok();
2974        break;
2975    case DMA_CMD_TLB_MISS_WAIT:
2976        p_vci_tgt_dma.cmdack  = false;
2977        break;
2978    case DMA_CMD_TLB_MISS_STORE:
2979        p_vci_tgt_dma.cmdack  = true;
2980        break;
2981    case DMA_CMD_ERROR:
2982        p_vci_tgt_dma.cmdack  = !r_dma_cmd_error_req.read();
2983        break; 
2984    }// end switch r_dma_cmd_fsm
2985
2986    //////////////////
2987    // DMA Responses//
2988    //////////////////
2989   
2990    // VCI target response on the IO network
2991    if(m_dma_rsp_data_fifo.rok())
2992    {
2993        p_vci_tgt_dma.rspval  = true;
2994                p_vci_tgt_dma.rsrcid  = m_dma_rsp_rsrcid_fifo.read();
2995        p_vci_tgt_dma.rtrdid  = m_dma_rsp_rtrdid_fifo.read();
2996       
2997        p_vci_tgt_dma.rpktid  = m_dma_rsp_rpktid_fifo.read();
2998   
2999        #if NEW_XRAM_VCI
3000        //TODO for 64 bit data field
3001        #else
3002        p_vci_tgt_dma.rdata   = m_dma_rsp_data_fifo.read(); // The first is in param_io
3003                                                    // the second in param_x
3004        #endif
3005       
3006        p_vci_tgt_dma.rerror  = m_dma_rsp_rerror_fifo.read();
3007        p_vci_tgt_dma.reop    = m_dma_rsp_reop_fifo.read();
3008    }
3009    else
3010    {
3011        p_vci_tgt_dma.rspval  = false;
3012       
3013                p_vci_tgt_dma.rsrcid  = 0;
3014                p_vci_tgt_dma.rdata   = 0;
3015                p_vci_tgt_dma.rpktid  = 0;
3016                p_vci_tgt_dma.rtrdid  = 0;
3017                p_vci_tgt_dma.rerror  = 0;
3018                p_vci_tgt_dma.reop    = false;
3019
3020    }
3021
3022    // VCI initiator response on the Xram Network
3023    // it depends on the DMA_RSP FSM state
3024    switch ( r_dma_rsp_fsm.read() ) 
3025    {
3026    case DMA_RSP_IDLE:
3027    case DMA_RSP_TRT_LOCK:
3028    case DMA_RSP_FIFO_ERROR_PUT:
3029    {
3030                p_vci_ini_dma.rspack = false;
3031        break;
3032    }
3033    case DMA_RSP_FIFO_PUT:
3034        {
3035        p_vci_ini_dma.rspack = m_dma_rsp_data_fifo.wok();
3036        break;
3037    }
3038    }// end switch r_dma_rsp_fsm
3039
3040    /////////////////////
3041    // CONFIG Commands //
3042    /////////////////////
3043
3044    // VCI initiator command on the IO network
3045    if(m_config_cmd_addr_fifo.rok())
3046    {
3047        p_vci_ini_config.cmdval  = true;
3048        #if NEW_XRAM_VCI
3049        p_vci_ini_config.address = (paddr_t_x)(m_config_cmd_addr_fifo.read() >> 6 )
3050        #else
3051        p_vci_ini_config.address = m_config_cmd_addr_fifo.read();
3052        #endif
3053       
3054        p_vci_ini_config.be      = (vci_be_t_x)m_config_cmd_be_fifo.read();
3055        p_vci_ini_config.cmd     = m_config_cmd_cmd_fifo.read();
3056        p_vci_ini_config.contig  = m_config_cmd_contig_fifo.read();
3057        #if NEW_XRAM_VCI
3058        //TODO
3059        #else
3060        p_vci_ini_config.wdata   = (vci_data_t_x)m_config_cmd_data_fifo.read(); // The first is in param_io
3061                                                    // the second in param_d
3062        #endif
3063        p_vci_ini_config.eop     = m_config_cmd_eop_fifo.read();
3064        p_vci_ini_config.cons    = m_config_cmd_cons_fifo.read();
3065        p_vci_ini_config.plen    = m_config_cmd_plen_fifo.read();
3066        p_vci_ini_config.wrap    = m_config_cmd_wrap_fifo.read();
3067        p_vci_ini_config.cfixed  = m_config_cmd_cfixed_fifo.read();
3068        p_vci_ini_config.clen    = m_config_cmd_clen_fifo.read();
3069        p_vci_ini_config.trdid   = m_config_cmd_trdid_fifo.read();
3070        p_vci_ini_config.pktid   = m_config_cmd_pktid_fifo.read();
3071    }
3072    else
3073    {
3074        p_vci_ini_config.cmdval  = false;
3075        p_vci_ini_config.address = 0;
3076        p_vci_ini_config.be      = 0;
3077        p_vci_ini_config.cmd     = vci_param_io::CMD_NOP;
3078        p_vci_ini_config.contig  = false;
3079        p_vci_ini_config.wdata   = 0;
3080        p_vci_ini_config.eop     = false;
3081        p_vci_ini_config.cons    = true;
3082        p_vci_ini_config.plen    = 0;
3083        p_vci_ini_config.wrap    = false;
3084        p_vci_ini_config.cfixed  = false;
3085        p_vci_ini_config.clen    = 0;
3086        p_vci_ini_config.trdid   = 0;
3087        p_vci_ini_config.pktid   = 0; 
3088    }
3089   
3090    // VCI target command on the Direct network
3091    // it depends on the CONFIG_CMD FSM state
3092
3093    switch ( r_config_cmd_fsm.read() ) 
3094    {
3095    case CONFIG_CMD_IDLE:
3096    case CONFIG_CMD_TRT_LOCK:   
3097    case CONFIG_CMD_TRT_WAIT: 
3098    case CONFIG_CMD_TRT_SET: 
3099    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
3100    case CONFIG_CMD_IT_ADDR_READ_1:
3101    case CONFIG_CMD_ERROR_RSP: 
3102    case CONFIG_CMD_INVAL_REQ:
3103        p_vci_tgt_config.cmdack  = false;
3104        break;
3105    case CONFIG_CMD_FIFO_PUT:     
3106    case CONFIG_CMD_PTPR_WRITE:
3107    case CONFIG_CMD_PTPR_READ:
3108    case CONFIG_CMD_ACTIVE_WRITE:
3109    case CONFIG_CMD_ACTIVE_READ:
3110    case CONFIG_CMD_BVAR_READ:
3111    case CONFIG_CMD_ETR_READ:
3112    case CONFIG_CMD_BAD_ID_READ:
3113    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:
3114    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
3115    case CONFIG_CMD_IT_ADDR_WRITE_2:
3116    case CONFIG_CMD_IT_ADDR_READ_2:
3117    case CONFIG_CMD_INVAL: 
3118        p_vci_tgt_config.cmdack  = m_config_cmd_addr_fifo.wok();
3119        break;
3120    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1:
3121    case CONFIG_CMD_IT_ADDR_WRITE_1:
3122    case CONFIG_CMD_ERROR_WAIT: 
3123        p_vci_tgt_config.cmdack = true; 
3124        break;
3125    default: 
3126        p_vci_tgt_config.cmdack  = false;
3127        break;
3128    }// end switch r_config_cmd_fsm
3129
3130    /////////////////////
3131    // CONFIG Responses//
3132    /////////////////////
3133   
3134    // VCI target response on the Direct network
3135    if(r_config_rsp_fifo_local_priority)
3136    {
3137    if( m_config_local_data_fifo.rok() )
3138    {
3139        p_vci_tgt_config.rspval  = true;
3140                p_vci_tgt_config.rsrcid  = m_config_local_rsrcid_fifo.read();
3141        p_vci_tgt_config.rtrdid  = m_config_local_rtrdid_fifo.read();
3142        p_vci_tgt_config.rpktid  = m_config_local_rpktid_fifo.read();
3143        p_vci_tgt_config.rdata   = (vci_data_t)m_config_local_data_fifo.read();
3144        p_vci_tgt_config.rerror  = m_config_local_rerror_fifo.read();
3145        p_vci_tgt_config.reop    = m_config_local_reop_fifo.read();
3146    }
3147    else if(m_config_rsp_data_fifo.rok() )
3148    {
3149        p_vci_tgt_config.rspval  = true;
3150                p_vci_tgt_config.rsrcid  = m_config_rsp_rsrcid_fifo.read();
3151        p_vci_tgt_config.rtrdid  = m_config_rsp_rtrdid_fifo.read();
3152       
3153        p_vci_tgt_config.rpktid  = m_config_rsp_rpktid_fifo.read();
3154   
3155        p_vci_tgt_config.rdata   = (vci_data_t)m_config_rsp_data_fifo.read(); // The first is in param_d
3156                                                    // the second in param_io
3157        p_vci_tgt_config.rerror  = m_config_rsp_rerror_fifo.read();
3158        p_vci_tgt_config.reop    = m_config_rsp_reop_fifo.read();
3159    }
3160    else
3161    {
3162        p_vci_tgt_config.rspval  = false;
3163       
3164                p_vci_tgt_config.rsrcid  = 0;
3165                p_vci_tgt_config.rdata   = 0;
3166                p_vci_tgt_config.rpktid  = 0;
3167                p_vci_tgt_config.rtrdid  = 0;
3168                p_vci_tgt_config.rerror  = 0;
3169                p_vci_tgt_config.reop    = false;
3170
3171    }
3172    }
3173    else
3174    {
3175    if(m_config_rsp_data_fifo.rok() )
3176    {
3177        p_vci_tgt_config.rspval  = true;
3178                p_vci_tgt_config.rsrcid  = m_config_rsp_rsrcid_fifo.read();
3179        p_vci_tgt_config.rtrdid  = m_config_rsp_rtrdid_fifo.read();
3180       
3181        p_vci_tgt_config.rpktid  = m_config_rsp_rpktid_fifo.read();
3182   
3183        p_vci_tgt_config.rdata   = (vci_data_t)m_config_rsp_data_fifo.read(); // The first is in param_d
3184                                                    // the second in param_io
3185        p_vci_tgt_config.rerror  = m_config_rsp_rerror_fifo.read();
3186        p_vci_tgt_config.reop    = m_config_rsp_reop_fifo.read();
3187    }
3188    else if( m_config_local_data_fifo.rok() )
3189    {
3190        p_vci_tgt_config.rspval  = true;
3191                p_vci_tgt_config.rsrcid  = m_config_local_rsrcid_fifo.read();
3192        p_vci_tgt_config.rtrdid  = m_config_local_rtrdid_fifo.read();
3193        p_vci_tgt_config.rpktid  = m_config_local_rpktid_fifo.read();
3194        p_vci_tgt_config.rdata   = (vci_data_t)m_config_local_data_fifo.read();
3195        p_vci_tgt_config.rerror  = m_config_local_rerror_fifo.read();
3196        p_vci_tgt_config.reop    = m_config_local_reop_fifo.read();
3197    }
3198    else
3199    {
3200        p_vci_tgt_config.rspval  = false;
3201       
3202                p_vci_tgt_config.rsrcid  = 0;
3203                p_vci_tgt_config.rdata   = 0;
3204                p_vci_tgt_config.rpktid  = 0;
3205                p_vci_tgt_config.rtrdid  = 0;
3206                p_vci_tgt_config.rerror  = 0;
3207                p_vci_tgt_config.reop    = false;
3208
3209    }
3210    }
3211   
3212    // VCI initiator response on the IO Network
3213    // it depends on the CONFIG_RSP FSM state
3214    switch ( r_config_rsp_fsm.read() ) 
3215    {
3216    case CONFIG_RSP_IDLE:
3217    case CONFIG_RSP_TRT_LOCK:
3218        p_vci_ini_config.rspack = false;
3219        break;
3220    case CONFIG_RSP_FIFO_PUT:
3221                p_vci_ini_config.rspack = m_config_rsp_data_fifo.wok();
3222        break;
3223    }// end switch r_config_rsp_fsm
3224
3225    ////////////////////////////////////////////////////////////////
3226    // VCI initiator command and response on from the Direct network
3227    // for Miss Transactions
3228    p_vci_ini_miss.srcid   = m_srcid_miss;
3229   
3230    switch ( r_miss_init_fsm.read() ) 
3231    {   
3232    case MISS_INIT_IDLE_MISS:
3233    case MISS_INIT_IDLE_IRQ:
3234                p_vci_ini_miss.cmdval  = false;
3235        p_vci_ini_miss.address = 0;
3236        p_vci_ini_miss.be      = 0;
3237        p_vci_ini_miss.cmd     = vci_param_d::CMD_NOP;
3238        p_vci_ini_miss.contig  = false;
3239        p_vci_ini_miss.wdata   = 0;
3240        p_vci_ini_miss.eop     = false;
3241        p_vci_ini_miss.cons    = true;
3242        p_vci_ini_miss.plen    = 0;
3243        p_vci_ini_miss.wrap    = false;
3244        p_vci_ini_miss.cfixed  = false;
3245        p_vci_ini_miss.clen    = 0;
3246        p_vci_ini_miss.trdid   = 0;
3247        p_vci_ini_miss.pktid   = 0;
3248
3249                p_vci_ini_miss.rspack = false;
3250        break;
3251   
3252    case MISS_INIT_IRQ_CMD:
3253        p_vci_ini_miss.cmdval  = true;
3254        p_vci_ini_miss.address = (paddr_t)r_it_addr[r_irq_chosen.read()]; 
3255        p_vci_ini_miss.wdata   = 0;
3256        p_vci_ini_miss.plen    = vci_param_d::B;
3257        p_vci_ini_miss.trdid   = 0; 
3258        p_vci_ini_miss.cmd     = vci_param_d::CMD_READ;
3259        p_vci_ini_miss.eop     = true;
3260       
3261        p_vci_ini_miss.be      = 0xF;
3262        p_vci_ini_miss.pktid   = 0;
3263        p_vci_ini_miss.cons    = false;
3264        p_vci_ini_miss.wrap    = false;
3265        p_vci_ini_miss.contig  = true;
3266        p_vci_ini_miss.clen    = 0;
3267        p_vci_ini_miss.cfixed  = false;
3268        break;
3269   
3270    case MISS_INIT_IRQ_RSP:
3271    case MISS_INIT_TLB_MISS_RSP:
3272        p_vci_ini_miss.cmdval  = false;
3273        p_vci_ini_miss.address = 0;
3274        p_vci_ini_miss.be      = 0;
3275        p_vci_ini_miss.cmd     = vci_param_d::CMD_NOP;
3276        p_vci_ini_miss.contig  = false;
3277        p_vci_ini_miss.wdata   = 0;
3278        p_vci_ini_miss.eop     = false;
3279        p_vci_ini_miss.cons    = true;
3280        p_vci_ini_miss.plen    = 0;
3281        p_vci_ini_miss.wrap    = false;
3282        p_vci_ini_miss.cfixed  = false;
3283        p_vci_ini_miss.clen    = 0;
3284        p_vci_ini_miss.trdid   = 0;
3285        p_vci_ini_miss.pktid   = 0;
3286       
3287        p_vci_ini_miss.rspack = true;
3288 
3289        break;
3290   
3291    case MISS_INIT_TLB_MISS_CMD:
3292        p_vci_ini_miss.cmdval  = true;
3293        p_vci_ini_miss.address = (paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK);
3294        p_vci_ini_miss.wdata   = 0x00000000;
3295        p_vci_ini_miss.plen    = m_words*(vci_param_d::B);
3296        p_vci_ini_miss.trdid   = 0;  //could be used as the index on a miss transaction table
3297        p_vci_ini_miss.cmd     = vci_param_d::CMD_READ;
3298        p_vci_ini_miss.eop     = true;
3299       
3300        p_vci_ini_miss.be      = 0xF;
3301        p_vci_ini_miss.pktid   = 0;
3302        p_vci_ini_miss.cons    = false;
3303        p_vci_ini_miss.wrap    = false;
3304        p_vci_ini_miss.contig  = true;
3305        p_vci_ini_miss.clen    = 0;
3306        p_vci_ini_miss.cfixed  = false;
3307        break;
3308
3309    } // end switch r_miss_init_fsm
3310} // end genMoore
3311
3312}}
3313
3314// Local Variables:
3315// tab-width: 4
3316// c-basic-offset: 4
3317// c-file-offsets:((innamespace . 0)(inline-open . 0))
3318// indent-tabs-mode: nil
3319// End:
3320
3321// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.