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

Last change on this file since 240 was 240, checked in by fraga, 12 years ago

Adding component vci_io_bridge

File size: 123.3 KB
RevLine 
[240]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_d::B ==  vci_param_io::B) and
363            "DATA field must have the same size in Direct 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 treatmentcontrols the following ressources:
1700    // - r_config_cmd_fsm
1701    //
1702    // - r_config_cmd_rsp_erase_req (set)
1703    // - r_config_tlb_req (set)
1704    /////////////////////////////////////////////////////////////////////
1705
1706    switch( r_config_cmd_fsm.read() ) 
1707    {
1708    //////////////
1709    case CONFIG_CMD_IDLE:
1710    {
1711        if ( p_vci_tgt_config.cmdval.read() ) 
1712        {
1713#if DEBUG_CONFIG_CMD
1714if( m_debug_config_cmd_fsm )
1715{
1716    std::cout << "  <IOB.CONFIG_CMD_IDLE> Configuration command received!" <<std::endl;
1717    std::cout << " address = " << std::hex << p_vci_tgt_config.address.read()
1718              << " srcid = " << std::dec << p_vci_tgt_config.srcid.read()
1719              << " trdid = " << p_vci_tgt_config.trdid.read()
1720              << " wdata = " << std::hex << p_vci_tgt_config.wdata.read()
1721              << " be = " << p_vci_tgt_config.be.read()
1722              << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl;
1723}
1724#endif
1725            paddr_t config_paddr = p_vci_tgt_config.address.read();
1726   
1727//           // Just to verify
1728//           if(! m_locality_table_config[config_paddr] ) //cannot receive remote packets
1729//           {
1730//           std::cout << "IOB ERROR " << name() << " CONFIG_CMD_IDLE state" << std::endl
1731//                         << "Received a remote packet" << std::endl;
1732//               exit(0);
1733//           }
1734
1735            bool read = (p_vci_tgt_config.cmd.read() == vci_param_d::CMD_READ);
1736           
1737            uint32_t              cell    = (uint32_t)((config_paddr & 0x1FF)>>2); 
1738           
1739            // Treatement of received command
1740            // Verifies error, tests if the the command is for IOB itself
1741 
1742            // To IOB itself
1743            if(m_segment_config.contains(config_paddr))
1744            {
1745                if(!read && (cell == IOB_IOMMU_PTPR)) 
1746                    r_config_cmd_fsm = CONFIG_CMD_PTPR_WRITE;
1747                else if(read && (cell == IOB_IOMMU_PTPR)) 
1748                    r_config_cmd_fsm = CONFIG_CMD_PTPR_READ;
1749                else if(!read && (cell == IOB_IOMMU_ACTIVE)) 
1750                    r_config_cmd_fsm = CONFIG_CMD_ACTIVE_WRITE;
1751                else if(read && (cell == IOB_IOMMU_ACTIVE)) 
1752                    r_config_cmd_fsm = CONFIG_CMD_ACTIVE_READ;
1753                else if(read && (cell == IOB_IOMMU_BVAR)) 
1754                    r_config_cmd_fsm = CONFIG_CMD_BVAR_READ;
1755                else if(read && (cell == IOB_IOMMU_ETR)) 
1756                    r_config_cmd_fsm = CONFIG_CMD_ETR_READ;
1757                else if(read && (cell == IOB_IOMMU_BAD_ID)) 
1758                    r_config_cmd_fsm = CONFIG_CMD_BAD_ID_READ;
1759                // PTE invalidation signaled by the OS
1760                else if(!read && (cell == IOB_INVAL_PTE))
1761                    r_config_cmd_fsm = CONFIG_CMD_INVAL_REQ;
1762                else if(!read && (cell == IOB_IT_ADDR_IOMMU_LO)) 
1763                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1;
1764                else if(read && (cell == IOB_IT_ADDR_IOMMU_LO)) 
1765                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_1;
1766                else if( !read && ((cell >= IOB_IT_ADDR_BEGIN)&&
1767                        ( cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1) ) ) )
1768                {
1769                    // a factor two shows up because the registres come in couples
1770                    r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2;
1771                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_1;
1772                } 
1773                else if( read && ((cell >= IOB_IT_ADDR_BEGIN)&&
1774                        (cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1))) ) 
1775                {
1776                    r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2;
1777                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_1;
1778                }
1779                else
1780                //Error. Wrong address, or invalid operation.
1781                {
1782                    if(read)    r_config_error_type = READ_ERROR;
1783                    else        r_config_error_type = WRITE_ERROR;
1784                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1785                }
1786            }
1787            // Must route the command to the correct IO
1788            else
1789            {
1790                if(!p_vci_tgt_config.eop.read())
1791                {
1792                    //Error
1793                    if(read)    r_config_error_type = READ_ERROR;
1794                    else        r_config_error_type = WRITE_ERROR;
1795                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1796                }
1797               
1798                // Find the corresponding address on IO Space
1799//                int tgt_index = m_routing_table_config[config_paddr];
1800//#if DEBUG_CONFIG_CMD
1801//if( m_debug_config_cmd_fsm )
1802//{
1803//    std::cout << "  <IOB.CONFIG_CMD_IDLE> Routing a configuration packet" <<std::endl
1804//            << "Target Index on Direct NoC: " << tgt_index << std::endl;
1805//}
1806//#endif
1807//                soclib::common::Segment io_segment = m_mtio.getSegment(IntTab(tgt_index));
1808//               #define L2 soclib::common::uint32_log2
1809//               paddr_t offset_mask = ( (1 << L2(io_segment.size())) - 1);
1810//               #undef L2
1811//               r_config_vaddr = (vaddr_t)( io_segment.baseAddress() |
1812//                               (vaddr_t)(config_paddr & offset_mask) );
1813               
1814                // TODO So far, it is in identity mapping
1815                r_config_vaddr = (vaddr_t) config_paddr ; 
1816                r_config_cmd_fsm        = CONFIG_CMD_TRT_LOCK;
1817
1818            }
1819
1820
1821        } // end if cmdval
1822        break;
1823    }
1824    /////////////////////////
1825    case CONFIG_CMD_TRT_LOCK: // Waiting for the lock to modify Transaction Table
1826    {
1827        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 
1828        {
1829
1830#if DEBUG_CONFIG_CMD
1831if( m_debug_config_cmd_fsm )
1832{
1833    std::cout << "  <IOB.CONFIG_CMD_TRT_LOCK> Check the TRT" << std::endl;
1834}
1835#endif
1836            size_t              wok_index = 0;
1837            bool                wok       = !m_transaction_tab_config.full(wok_index);
1838
1839            if ( wok )  // TRT isn't full. Write the new transaction.
1840            {
1841                r_config_cmd_trt_index = (vci_trdid_t)wok_index;
1842                r_config_cmd_fsm       = CONFIG_CMD_TRT_SET;
1843            } 
1844            else                // wait an empty entry in TRT
1845            {
1846                r_config_cmd_fsm       = CONFIG_CMD_TRT_WAIT;
1847                r_config_cmd_rsp_erase_req = true;
1848#if DEBUG_CONFIG_CMD
1849if( m_debug_config_cmd_fsm )
1850{
1851    std::cout << "  <IOB.CONFIG_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl;
1852}
1853#endif
1854           
1855#ifdef INSTRUMENTATION       
1856m_cpt_trt_config_full++;
1857#endif
1858            }
1859        }
1860        break;
1861    }
1862    ////////////////
1863    case CONFIG_CMD_TRT_WAIT:   // release the lock protecting the transaction tab
1864                                // waits that RSP erases an entry
1865    { 
1866#ifdef INSTRUMENTATION       
1867m_cpt_trt_config_full_cost++;
1868#endif
1869        // CONFIG_RSP will notify an erase action by reseting this register
1870        if(!r_config_cmd_rsp_erase_req.read())
1871        {
1872            r_config_cmd_fsm = CONFIG_CMD_TRT_LOCK; // take the lock again
1873        }
1874        break;
1875    }
1876    ////////////////////////
1877    case CONFIG_CMD_TRT_SET:    // register a new transaction in TRT
1878    { 
1879        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 
1880        {
1881            m_transaction_tab_config.set(   r_config_cmd_trt_index.read(),
1882                                            p_vci_tgt_config.srcid.read(), 
1883                                            p_vci_tgt_config.trdid.read() );
1884           
1885            r_config_cmd_fsm = CONFIG_CMD_FIFO_PUT;
1886#if DEBUG_CONFIG_CMD
1887if( m_debug_config_cmd_fsm )
1888{
1889    std::cout << "  <IOB.CONFIG_CMD_TRT_SET> Set a new entry in TRT" << std::endl;
1890}
1891#endif
1892        }
1893        break;
1894    } 
1895    ///////////////////////
1896    case CONFIG_CMD_FIFO_PUT:   
1897    {
1898        if ( p_vci_tgt_config.cmdval && m_config_cmd_addr_fifo.wok() ) 
1899        {
1900            config_cmd_fifo_put = true;
1901            if(  p_vci_tgt_config.eop )    r_config_cmd_fsm = CONFIG_CMD_IDLE;
1902           
1903#if DEBUG_CONFIG_CMD
1904if( m_debug_config_cmd_fsm ) 
1905{
1906    std::cout << "  <IOB.CONFIG_CMD_FIFO_PUT> Push into config_cmd_fifo:" 
1907              << " address = " << std::hex << r_config_vaddr.read()
1908              << " srcid = " << std::dec << m_srcid_config
1909              << " trdid = " << r_config_cmd_trt_index.read()
1910              << " wdata = " << std::hex << p_vci_tgt_config.wdata.read()
1911              << " be = " << p_vci_tgt_config.be.read()
1912              << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl;
1913}
1914#endif
1915        }
1916        break;
1917    }
1918   
1919    ///////////////////////////////
1920    // Private Configuration States
1921    ///////////////////////////////
1922
1923    //////////////////
1924    case CONFIG_CMD_PTPR_WRITE: // Convention- The word received is in the format:
1925                                // 00000 BASE_ADDRESS[39:13]
1926                                // Same pattern as in iommu_ptpr register
1927    {
1928        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok()
1929            && r_dma_tlb_fsm == DMA_TLB_IDLE )
1930        {
1931            // This verification could have been done on IDLE state
1932            // It would save us one cycle
1933            if ( !p_vci_tgt_config.eop.read() )
1934            {
1935                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_PTPR_WRITE state" << std::endl;
1936                std::cout << " PTPR write command must contain one single flit" << std::endl;
1937                r_config_error_type = WRITE_ERROR;
1938                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1939                break;
1940            }
1941           
1942            // Depends on the convention
1943            r_iommu_ptpr = (uint32_t)(p_vci_tgt_config.wdata.read()); 
1944           
1945            config_local_fifo_put = true;
1946            r_config_cmd_fsm = CONFIG_CMD_IDLE;
1947
1948#if DEBUG_CONFIG_CMD
1949if( m_debug_config_cmd_fsm ) 
1950{
1951    std::cout << "  <IOB.CONFIG_CMD_PTPR_WRITE> PTPR received:" 
1952              << "r_iommu_ptpr = " << std::hex << (p_vci_tgt_config.wdata.read())
1953              <<std::endl;
1954}
1955#endif
1956        } 
1957        break;
1958    }
1959    /////////////////////
1960    case CONFIG_CMD_ACTIVE_WRITE: 
1961    {
1962        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() 
1963            && r_dma_tlb_fsm == DMA_TLB_IDLE )
1964        {
1965            // This verification could have been done on IDLE state
1966            // It would save us one cycle
1967            if ( !p_vci_tgt_config.eop.read() )
1968            {
1969                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_ACTIVE_WRITE state" << std::endl;
1970                std::cout << " ACTIVE write command must contain one single flit" << std::endl;
1971                r_config_error_type = WRITE_ERROR;
1972                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
1973                break;
1974            }
1975           
1976            r_iommu_active = (p_vci_tgt_config.wdata.read() != 0);
1977           
1978            config_local_fifo_put = true;
1979            r_config_cmd_fsm = CONFIG_CMD_IDLE;
1980        } 
1981        break;
1982    }
1983    ///////////////////
1984    case CONFIG_CMD_INVAL_REQ: // Blocks in case of untreated request
1985    {   
1986        if ( !r_config_tlb_req.read() )
1987        {
1988            r_config_tlb_req = true;     
1989            r_config_cmd_fsm = CONFIG_CMD_INVAL;
1990        } 
1991        break;
1992    }
1993    ///////////////////
1994    case CONFIG_CMD_INVAL: // Consuming the 32bit Virtual Address of the invalidated page
1995    {
1996        if ( p_vci_tgt_config.cmdval.read() && 
1997                m_config_local_data_fifo.wok() ) 
1998        {
1999           
2000            if ( !p_vci_tgt_config.eop.read() )
2001            {
2002                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_INVAL state" << std::endl;
2003                std::cout << " PTE invalidation commands must contain one single flit" << std::endl;
2004                r_config_error_type = WRITE_ERROR;
2005                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2006                break;
2007            }
2008           
2009            assert( (p_vci_tgt_config.wdata.read()& K_PAGE_OFFSET_MASK) == 0 
2010                    and " Error : Invalid format for Page Virtual Address. At least the 12 LSB bits must be zero");
2011
2012            r_config_tlb_inval_vaddr = (vaddr_t)(p_vci_tgt_config.wdata.read());
2013             
2014            config_local_fifo_put = true;
2015            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2016        } 
2017        break;
2018    }
2019    //////////////////
2020    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1: 
2021    {
2022        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok())
2023        {
2024            if(vci_param_d::N <= 32)
2025            {
2026            // address holds in one single flit
2027                if (!p_vci_tgt_config.eop.read() )
2028                {
2029                   
2030                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl;
2031                    std::cout << " PTE invalidation command should contain just one flit" << std::endl;
2032                    r_config_error_type = WRITE_ERROR;
2033                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT;
2034                }
2035                else
2036                {
2037                    // If physical address holds on a single word
2038                    r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 
2039                 
2040                    config_local_fifo_put = true; 
2041                    r_config_cmd_fsm = CONFIG_CMD_IDLE;
2042                }
2043       
2044            }
2045            else
2046            {
2047            // two flits are required to send address
2048                if ( p_vci_tgt_config.eop.read() )
2049                {
2050                   
2051                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl;
2052                    std::cout << " PTE invalidation commands should contain two flits" << std::endl;
2053                    r_config_error_type = WRITE_ERROR;
2054                    r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP;
2055                }
2056                else
2057                {
2058                    r_config_first_word = p_vci_tgt_config.wdata.read(); 
2059                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2;
2060                }
2061            }
2062        } 
2063        break;
2064    }
2065    /////////////////
2066    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2: 
2067    {
2068        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2069        {
2070            if ( !p_vci_tgt_config.eop.read() )
2071            {
2072                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_IOMMU_WRITE_2 state" << std::endl;
2073                std::cout << " PTE invalidation commands must contain two flits" << std::endl;
2074                r_config_error_type = WRITE_ERROR;
2075                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2076                break;
2077            }
2078           
2079            // Depends on the convention
2080            size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ;
2081            r_it_addr_iommu = (paddr_t)(r_config_first_word.read() |
2082                                   ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 
2083             
2084            config_local_fifo_put = true;
2085            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2086        } 
2087    }
2088    //////////////////
2089    case CONFIG_CMD_IT_ADDR_WRITE_1: 
2090    {
2091        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok())
2092        {
2093            if(vci_param_d::N <= 32)
2094            {
2095            // address holds in one single flit
2096                if (!p_vci_tgt_config.eop.read() )
2097                {
2098                   
2099                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl;
2100                    std::cout << " PTE invalidation command should contain just one flit" << std::endl;
2101                    r_config_error_type = WRITE_ERROR;
2102                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT;
2103                   
2104                   
2105                }
2106                else
2107                {
2108                    // If physical address holds on a single word
2109                    r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 
2110                 
2111                    config_local_fifo_put = true; 
2112                    r_config_cmd_fsm = CONFIG_CMD_IDLE;
2113                }
2114       
2115            }
2116            else
2117            {
2118            // two flits are required to send address
2119                if ( p_vci_tgt_config.eop.read() )
2120                {
2121                   
2122                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl;
2123                    std::cout << " PTE invalidation commands should contain two flits" << std::endl;
2124                    r_config_error_type = WRITE_ERROR;
2125                    r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP;
2126                }
2127                else
2128                {
2129                    r_config_first_word = p_vci_tgt_config.wdata.read();
2130                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_2;
2131                }
2132            } 
2133        } 
2134        break;
2135    }
2136    /////////////////
2137    case CONFIG_CMD_IT_ADDR_WRITE_2: 
2138    {
2139        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2140        {
2141            if ( !p_vci_tgt_config.eop.read() )
2142            {
2143                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_2 state" << std::endl;
2144                std::cout << " PTE invalidation commands must contain two flits" << std::endl;
2145                r_config_error_type = WRITE_ERROR;
2146                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2147                break;
2148            }
2149           
2150            // Depends on the convention
2151            size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ;
2152            r_it_addr[r_it_index.read()] = (paddr_t)(r_config_first_word.read() |
2153                                ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 
2154             
2155            config_local_fifo_put = true;
2156            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2157        } 
2158    }
2159    //////////////////
2160    case CONFIG_CMD_PTPR_READ: 
2161    case CONFIG_CMD_ACTIVE_READ:
2162    case CONFIG_CMD_BVAR_READ:
2163    case CONFIG_CMD_ETR_READ:
2164    case CONFIG_CMD_BAD_ID_READ:
2165    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
2166    case CONFIG_CMD_IT_ADDR_READ_1:
2167    {
2168        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2169        {
2170            // This verification could have been done on IDLE state
2171            // It would save us one cycle
2172            if ( !p_vci_tgt_config.eop.read() )
2173            {
2174                std::cout << "CONFIG_CMD ERROR " << name() << config_cmd_fsm_state_str[r_config_cmd_fsm.read()] << std::endl;
2175                std::cout << " Read commands must contain one single flit" << std::endl;
2176                r_config_error_type = READ_ERROR;
2177                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
2178                break;
2179            }
2180           
2181            // fifo data receives the content of the corresponding register
2182            // (depending on the current state)
2183            config_local_fifo_put = true;
2184            if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_READ_1)
2185            r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_2;
2186            else if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_IOMMU_READ_1)
2187            r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_2;
2188            else
2189            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2190        } 
2191        break;
2192    }
2193    //////////////////
2194    case CONFIG_CMD_IT_ADDR_READ_2:
2195    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
2196    {
2197        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
2198        {
2199            config_local_fifo_put = true;
2200            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2201        } 
2202    }
2203    //////////////////
2204    case CONFIG_CMD_ERROR_WAIT: //receives the other flits of the same transaction
2205    {
2206        if ( p_vci_tgt_config.cmdval.read() && p_vci_tgt_config.eop.read() ) 
2207        r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP; 
2208    }
2209    ///////////////////
2210    case CONFIG_CMD_ERROR_RSP:
2211    {
2212        if ( m_config_local_data_fifo.wok() )
2213        {
2214            config_local_fifo_put = true;
2215            r_config_cmd_fsm = CONFIG_CMD_IDLE;
2216        }
2217        break;
2218    }
2219
2220    } // end switch CONFIG_CMD FSM
2221
2222    /////////////////////////////////////////////////////////////////////
2223    // The CONFIG_RSP_FSM controls the following ressources:
2224    // - r_config_rsp_fsm
2225    // - r_config_cmd_rsp_erase_req (reset)
2226    // -
2227    // -
2228    //////////////////////////////////////////////////////////////////////////////
2229    switch( r_config_rsp_fsm.read() ) 
2230    {
2231    /////////////////////
2232    case CONFIG_RSP_IDLE:
2233    {           
2234        if(p_vci_ini_config.rspval.read()) 
2235                {
2236            r_config_rsp_fsm = CONFIG_RSP_TRT_LOCK;
2237                }
2238                break;
2239    }
2240    /////////////////////
2241    case CONFIG_RSP_TRT_LOCK:
2242    {           
2243        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_RSP ) 
2244        {
2245           
2246#if DEBUG_CONFIG_RSP
2247if( m_debug_config_rsp_fsm )
2248{
2249    std::cout << "  <IOB.CONFIG_RSP_TRT_LOCK> Read and erase entry" << std::endl;
2250}
2251#endif
2252            uint32_t trdid_iospace = p_vci_ini_config.rtrdid.read(); 
2253           
2254            r_config_rsrcid = (vci_srcid_t)m_transaction_tab_config.readSrcid(trdid_iospace);
2255            r_config_rtrdid = (vci_trdid_t)m_transaction_tab_config.readTrdid(trdid_iospace);
2256            m_transaction_tab_config.erase(trdid_iospace);
2257            if (r_config_cmd_rsp_erase_req.read()) r_config_cmd_rsp_erase_req = false;
2258            r_config_rsp_fsm       = CONFIG_RSP_FIFO_PUT;
2259        }       
2260                break;
2261    }
2262    //////////////////
2263    case CONFIG_RSP_FIFO_PUT:
2264    {
2265        if(p_vci_ini_config.rspval.read() && m_config_rsp_data_fifo.wok())
2266        {
2267            config_rsp_fifo_put = true;
2268            if(p_vci_ini_config.reop.read())   r_config_rsp_fsm = CONFIG_RSP_IDLE;     
2269
2270#if DEBUG_CONFIG_RSP
2271if( m_debug_config_rsp_fsm ) 
2272{
2273    std::cout << "  <IOB.CONFIG_RSP_FIFO_PUT> Push into rsp_fifo:" 
2274              << " rsrcid = " << std::dec << r_config_rsrcid.read()
2275              << " rtrdid = " << r_config_rtrdid.read()
2276              << " rdata = " << std::hex << p_vci_ini_config.rdata.read()
2277    << std::endl;
2278}
2279#endif
2280                       
2281        }
2282        break;
2283    }
2284    } // end switch CONFIG_RSP FSM
2285
2286
2287    ////////////////////////////////////////////////////////////////////////////
2288    // The ALLOC_TRT_CONFIG fsm allocates the access to the Transaction Table (m_transaction_tab_config)
2289    // with a round robin priority between 2 user FSMs :
2290    // - CONFIG_CMD : to set a new entry
2291    // - CONFIG_RSP : to read and erase an entry
2292    // The ressource is always allocated.
2293    ////////////////////////////////////////////////////////////////////////////////////
2294   
2295    switch ( r_alloc_trt_config_fsm.read() ) 
2296    {
2297    ///////////////////
2298    case ALLOC_TRT_CONFIG_CMD:
2299    {
2300        if ( r_config_cmd_fsm.read() != CONFIG_CMD_TRT_LOCK ) 
2301        {
2302          if (r_config_rsp_fsm.read() == CONFIG_RSP_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_RSP;
2303        }
2304    }
2305    ///////////////////
2306    case ALLOC_TRT_CONFIG_RSP:
2307    {
2308        if (r_config_rsp_fsm.read() != CONFIG_RSP_TRT_LOCK) 
2309        {
2310            if (r_config_cmd_fsm.read() == CONFIG_CMD_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_CMD;
2311        }
2312    }
2313    } // end switch r_alloc_trt_config_fsm
2314
2315    ////////////////////////////////////////////////////////////////////////////
2316    // The MISS_INIT FSM sends a page table entry miss request into Direct Noc
2317    // It controls the following ressources:
2318    // - r_miss_init_fsm
2319    // - r_tlb_miss_init_req (reset)
2320    // - r_miss_buf_data
2321    // - r_miss_buf_valid
2322    // - r_miss_buf_tag
2323    ////////////////////////////////////////////////////////////////////////////////////
2324
2325    // Building the interruption vector (systematically)
2326    uint32_t irq_demands = 0;
2327    for ( size_t i = 0; i<m_nb_periph; ++i )
2328        irq_demands |= (p_irq_in[i].read() ? 1 : 0) << i;
2329   
2330    // For next cycle:
2331        // Afectation of the new pending vector.
2332        // Not useful, unless Irq choice is postponed to next cycle
2333    r_irq_pending = irq_demands & r_irq_mask.read();
2334        // Updating Mask
2335    r_irq_mask = r_irq_mask.read()| ~irq_demands; 
2336   
2337 
2338    switch ( r_miss_init_fsm.read() ) 
2339    {
2340        //////////////
2341        case MISS_INIT_IDLE_MISS:
2342        {
2343            if(r_tlb_miss_init_req.read())
2344            {
2345                r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD;
2346            }
2347            else if (irq_demands & r_irq_mask.read()){
2348                // Choosing one interruption to send           
2349                // Find the first bit 1
2350                // starting by the bit just after the last chosen
2351                size_t i = (r_irq_chosen.read() + 1)% m_nb_periph;
2352                bool found = false;
2353                do
2354                {
2355                    if(irq_demands & r_irq_mask.read() & (1<<i)) 
2356                    {
2357                        r_irq_chosen = i;
2358                        found = true;
2359                    }
2360                    i = (i+1) % m_nb_periph;
2361                }
2362                while(i != r_irq_chosen.read()+1 && !found); 
2363
2364                r_miss_init_fsm = MISS_INIT_IRQ_CMD;
2365            }
2366                        break;
2367        }
2368        //////////////
2369        case MISS_INIT_IDLE_IRQ:
2370        {
2371            if (irq_demands & r_irq_mask.read()){
2372                // Choosing one interruption to send           
2373                // Find the first bit 1
2374                // starting by the bit just after the last chosen
2375                size_t i = (r_irq_chosen.read() + 1)% m_nb_periph;
2376                bool found = false;
2377                do
2378                {
2379                    if(irq_demands & r_irq_mask.read() & (1<<i)) 
2380                    {
2381                        r_irq_chosen = i;
2382                        found = true;
2383                    }
2384                    i = (i+1) % m_nb_periph;
2385                }
2386                while(i != r_irq_chosen.read()+1 && !found); 
2387
2388                r_miss_init_fsm = MISS_INIT_IRQ_CMD;
2389            }
2390            else if(r_tlb_miss_init_req.read())
2391            {
2392                r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD;
2393            }
2394                        break;
2395        }
2396        /////////////////////////       // send a read request to Direct Network
2397        case MISS_INIT_IRQ_CMD: 
2398        {
2399        if ( p_vci_ini_miss.cmdack ) 
2400        {
2401            // Masking chosen interruption, until it is resolved
2402            r_irq_mask = r_irq_mask.read() & ~(1<<r_irq_chosen.read());
2403            r_miss_init_fsm = MISS_INIT_IRQ_RSP;               
2404
2405#if DEBUG_MISS_INIT
2406if( m_debug_miss_init_fsm )
2407{
2408    std::cout << "  <IOB.MISS_INIT_IRQ_CMD> Send write (irq) command to XICU"
2409              << " irq ID = " << std::dec << r_irq_chosen.read()
2410              << " new mask = " << std::hex << (r_irq_mask.read() & ~(1<<r_irq_chosen.read()))
2411     << std::endl;
2412}
2413#endif
2414        }
2415            break;
2416        }
2417        //////////////////
2418        case MISS_INIT_IRQ_RSP: 
2419        {
2420            if ( p_vci_ini_miss.rspval.read() ) 
2421            {
2422                // It is a WRITE command, response in one single flit long
2423                assert( p_vci_ini_miss.reop.read() and "Write answer should have one single flit" ); 
2424                bool error;
2425               
2426                if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 )  // error reported
2427                {
2428                    // TODO traiter error
2429                    error = true;
2430                }
2431                r_miss_init_fsm = MISS_INIT_IDLE_MISS;
2432            }
2433            break;
2434        }
2435        /////////////////////////       // send a read request to Direct Network
2436        case MISS_INIT_TLB_MISS_CMD: 
2437        {
2438        if ( p_vci_ini_miss.cmdack ) 
2439        {
2440            r_miss_rsp_cpt  = 0;    //counter for the response flits
2441            r_miss_buf_tag  = ( (r_iotlb_paddr.read()) & CACHE_LINE_MASK ); 
2442            r_miss_buf_valid = true;
2443           
2444            if(r_tlb_miss_type.read()== PTE1_MISS)
2445                r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET);
2446            else
2447                r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET);
2448               
2449            r_miss_init_fsm = MISS_INIT_TLB_MISS_RSP;           
2450
2451#if DEBUG_MISS_INIT
2452if( m_debug_miss_init_fsm )
2453{
2454    std::cout << "  <IOB.MISS_INIT_TLB_MISS_CMD> Send read (tlb entry) request to MEM CACHE: "
2455    << " | address :  "<< std::hex <<(paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK)
2456    << std::endl;
2457}
2458#endif
2459        }
2460            break;
2461        }
2462        //////////////////
2463        case MISS_INIT_TLB_MISS_RSP:   
2464        {
2465            if ( p_vci_ini_miss.rspval.read() ) 
2466            {
2467                if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 )  // error reported
2468                {
2469                    r_miss_init_error = true;
2470                    if ( p_vci_ini_miss.reop.read() ) 
2471                    {   
2472                        r_miss_init_fsm = MISS_INIT_IDLE_IRQ;
2473                        r_tlb_miss_init_req = false; 
2474                    }
2475#if DEBUG_MISS_INIT
2476if( m_debug_miss_init_fsm ) 
2477{
2478    std::cout << " <IOB.MISS_INIT_TLB_MISS_RSP> ERROR " << std::endl; 
2479}
2480#endif
2481                }
2482                else
2483                { 
2484                    bool   eop          = p_vci_ini_miss.reop.read();
2485
2486
2487#if DEBUG_MISS_INIT
2488if( m_debug_miss_init_fsm ) 
2489{
2490    std::cout << "  <IOB.MISS_INIT_TLB_MISS_RSP> Response from Mem Cache to a read (tlb entry) transaction. Count = " << r_miss_rsp_cpt.read()
2491    <<" | Data = " << std::hex << p_vci_ini_miss.rdata.read() << std::endl; 
2492}
2493#endif
2494
2495                    assert(((eop == (r_miss_rsp_cpt.read() == (m_words-1))) ) 
2496                        and "Error : invalid length for a response from MEM CACHE");
2497                    r_miss_buf_data[r_miss_rsp_cpt] =  (uint32_t)p_vci_ini_miss.rdata.read();
2498                   
2499                    r_miss_rsp_cpt = r_miss_rsp_cpt.read() + 1;
2500                   
2501                    if ( eop ) 
2502                    {
2503                        r_tlb_miss_init_req = false;     //reset the request flip-flop
2504                        r_miss_init_fsm = MISS_INIT_IDLE_IRQ;           
2505                    }
2506
2507                }
2508            }
2509            break;
2510        }
2511
2512    } // end  switch r_miss_init_fsm
2513   
2514    //////////////////////////////////
2515    // Fifo consumption arbitration //
2516    //////////////////////////////////
2517   
2518    // Round Robin priority for CONFIG_RSP FIFO consumption
2519    r_config_rsp_fifo_local_priority = ! r_config_rsp_fifo_local_priority.read(); 
2520   
2521    //DMA CMD
2522    dma_cmd_fifo_get = (p_vci_ini_dma.cmdack.read() && m_dma_cmd_addr_fifo.rok());
2523    // DMA RSP
2524    dma_rsp_fifo_get = (p_vci_tgt_dma.rspack.read() && m_dma_rsp_data_fifo.rok());
2525    // CONFIG CMD
2526    config_cmd_fifo_get = (p_vci_ini_config.cmdack.read() && m_config_cmd_addr_fifo.rok() );
2527    // CONFIG RSP, detemines wich fifo to consume
2528    if(r_config_rsp_fifo_local_priority)
2529    {
2530        if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read();
2531        else if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read();
2532           
2533    }
2534    else
2535    {
2536        if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read();
2537        else if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read();
2538    }
2539    ///////////////
2540    //DMA_CMD Fifo
2541    ///////////////
2542    if(r_miss_interrupt)
2543    {
2544        m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get,
2545                                    dma_cmd_fifo_put,
2546                                    r_miss_paddr.read() );
2547        m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get,
2548                                    dma_cmd_fifo_put,
2549                                    r_miss_cmd.read() );
2550        m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
2551                                    dma_cmd_fifo_put,
2552                                    r_miss_contig.read() );
2553        m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get,
2554                                    dma_cmd_fifo_put,
2555                                    r_miss_cons.read() );
2556        m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get,
2557                                    dma_cmd_fifo_put,
2558                                    r_miss_plen.read() );
2559        m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get,
2560                                    dma_cmd_fifo_put,
2561                                    r_miss_wrap.read() );
2562        m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
2563                                    dma_cmd_fifo_put,
2564                                    r_miss_cfixed.read() );
2565        m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get,
2566                                    dma_cmd_fifo_put,
2567                                    r_miss_clen.read() );
2568        m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get,
2569                                    dma_cmd_fifo_put,
2570                                    m_srcid_dma ); //r_miss_srcid.read()
2571        m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get,
2572                                    dma_cmd_fifo_put,
2573                                    r_miss_trdid.read() );
2574        m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get,
2575                                    dma_cmd_fifo_put,
2576                                    r_miss_pktid.read() );
2577        m_dma_cmd_data_fifo.update( dma_cmd_fifo_get,
2578                                    dma_cmd_fifo_put,
2579                                    r_miss_data[r_dma_cmd_count.read()-1] );
2580        m_dma_cmd_be_fifo.update( dma_cmd_fifo_get,
2581                                    dma_cmd_fifo_put,
2582                                    r_miss_be[r_dma_cmd_count.read()-1] );
2583        m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get,
2584                                    dma_cmd_fifo_put,
2585                                    (r_dma_cmd_count.read() == 1) );
2586    }
2587    else 
2588    {
2589        m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get,
2590                                    dma_cmd_fifo_put,
2591                                    r_dma_paddr.read() ); 
2592        m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get,
2593                                    dma_cmd_fifo_put,
2594                                    p_vci_tgt_dma.cmd.read() );
2595        m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
2596                                    dma_cmd_fifo_put,
2597                                    p_vci_tgt_dma.contig.read() );
2598        m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get,
2599                                    dma_cmd_fifo_put,
2600                                    p_vci_tgt_dma.cons.read() );
2601        m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get,
2602                                    dma_cmd_fifo_put,
2603                                    p_vci_tgt_dma.plen.read() );
2604        m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get,
2605                                    dma_cmd_fifo_put,
2606                                    p_vci_tgt_dma.wrap.read() );
2607        m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
2608                                    dma_cmd_fifo_put,
2609                                    p_vci_tgt_dma.cfixed.read() );
2610        m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get,
2611                                    dma_cmd_fifo_put,
2612                                    p_vci_tgt_dma.clen.read() );
2613        m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get,
2614                                    dma_cmd_fifo_put,
2615                                    m_srcid_dma );
2616        m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get,
2617                                    dma_cmd_fifo_put,
2618                                    r_dma_cmd_trt_index.read() );
2619        m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get,
2620                                    dma_cmd_fifo_put,
2621                                    p_vci_tgt_dma.pktid.read() );
2622        m_dma_cmd_data_fifo.update( dma_cmd_fifo_get,
2623                                    dma_cmd_fifo_put,
2624                                    p_vci_tgt_dma.wdata.read() ); // TODO change
2625                                                            // For 64bits XRAM
2626        m_dma_cmd_be_fifo.update( dma_cmd_fifo_get,
2627                                    dma_cmd_fifo_put,
2628                                    p_vci_tgt_dma.be.read() ); 
2629        m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get,
2630                                    dma_cmd_fifo_put,
2631                                     p_vci_tgt_dma.eop.read() );
2632    }
2633
2634    ///////////////
2635    //DMA_RSP Fifo
2636    ///////////////
2637    if(r_dma_rsp_fsm.read() == DMA_RSP_FIFO_ERROR_PUT)
2638    {
2639        m_dma_rsp_data_fifo.update( dma_rsp_fifo_get,
2640                                    dma_rsp_fifo_put,
2641                                    0 );
2642        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
2643                                    dma_rsp_fifo_put,
2644                                    r_iommu_bad_id.read() ); 
2645        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
2646                                    dma_rsp_fifo_put,
2647                                    r_dma_error_trdid.read() ); 
2648        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
2649                                    dma_rsp_fifo_put,
2650                                    r_dma_error_pktid.read() );
2651        m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,
2652                                   dma_rsp_fifo_put,
2653                                   true );
2654        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
2655                                      dma_rsp_fifo_put,
2656                                      r_dma_error_type.read() );
2657    }
2658    else
2659    {
2660        m_dma_rsp_data_fifo.update( dma_rsp_fifo_get,
2661                                    dma_rsp_fifo_put,
2662                                    p_vci_ini_dma.rdata.read() );
2663        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
2664                                    dma_rsp_fifo_put,
2665                                    r_dma_rsrcid.read() ); 
2666        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
2667                                    dma_rsp_fifo_put,
2668                                    r_dma_rtrdid.read() ); 
2669        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
2670                                    dma_rsp_fifo_put,
2671                                    p_vci_ini_dma.rpktid.read() );
2672        m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,
2673                                   dma_rsp_fifo_put,
2674                                   p_vci_ini_dma.reop.read() );
2675        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
2676                                      dma_rsp_fifo_put,
2677                                      p_vci_ini_dma.rerror.read() );
2678    }
2679
2680    //////////////////
2681    //CONFIG_CMD Fifo
2682    //////////////////
2683    m_config_cmd_addr_fifo.update( config_cmd_fifo_get,
2684                                config_cmd_fifo_put,
2685                                r_config_vaddr.read() ); 
2686    m_config_cmd_cmd_fifo.update( config_cmd_fifo_get,
2687                                config_cmd_fifo_put,
2688                                p_vci_tgt_config.cmd.read() );
2689    m_config_cmd_contig_fifo.update( config_cmd_fifo_get,
2690                                config_cmd_fifo_put,
2691                                p_vci_tgt_config.contig.read() );
2692    m_config_cmd_cons_fifo.update( config_cmd_fifo_get,
2693                                config_cmd_fifo_put,
2694                                p_vci_tgt_config.cons.read() );
2695    m_config_cmd_plen_fifo.update( config_cmd_fifo_get,
2696                                config_cmd_fifo_put,
2697                                p_vci_tgt_config.plen.read() );
2698    m_config_cmd_wrap_fifo.update( config_cmd_fifo_get,
2699                                config_cmd_fifo_put,
2700                                p_vci_tgt_config.wrap.read() );
2701    m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get,
2702                                config_cmd_fifo_put,
2703                                p_vci_tgt_config.cfixed.read() );
2704    m_config_cmd_clen_fifo.update( config_cmd_fifo_get,
2705                                config_cmd_fifo_put,
2706                                p_vci_tgt_config.clen.read() );
2707    m_config_cmd_srcid_fifo.update( config_cmd_fifo_get,
2708                                config_cmd_fifo_put,
2709                                m_srcid_config );
2710    m_config_cmd_trdid_fifo.update( config_cmd_fifo_get,
2711                                config_cmd_fifo_put,
2712                                r_config_cmd_trt_index.read() ); 
2713    m_config_cmd_pktid_fifo.update( config_cmd_fifo_get,
2714                                config_cmd_fifo_put,
2715                                p_vci_tgt_config.pktid.read() );
2716    m_config_cmd_data_fifo.update( config_cmd_fifo_get,
2717                                config_cmd_fifo_put,
2718                                p_vci_tgt_config.wdata.read() );
2719    m_config_cmd_be_fifo.update( config_cmd_fifo_get,
2720                                config_cmd_fifo_put,
2721                                p_vci_tgt_config.be.read() );
2722    m_config_cmd_eop_fifo.update( config_cmd_fifo_get,
2723                                    config_cmd_fifo_put,
2724                                     p_vci_tgt_config.eop.read() );
2725   
2726    //////////////////
2727    //CONFIG_RSP Fifo
2728    //////////////////
2729    m_config_rsp_data_fifo.update( config_rsp_fifo_get,
2730                                config_rsp_fifo_put,
2731                                p_vci_ini_config.rdata.read() );
2732    m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get,
2733                                config_rsp_fifo_put,
2734                                r_config_rsrcid.read() );
2735    m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get,
2736                                config_rsp_fifo_put,
2737                                r_config_rtrdid.read() );
2738    m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get,
2739                                config_rsp_fifo_put,
2740                                p_vci_ini_config.rpktid.read() );
2741    m_config_rsp_reop_fifo.update( config_rsp_fifo_get,
2742                               config_rsp_fifo_put,
2743                               p_vci_ini_config.reop.read() );
2744    m_config_rsp_rerror_fifo.update( config_rsp_fifo_get,
2745                                  config_rsp_fifo_put,
2746                                  p_vci_ini_config.rerror.read() );
2747   
2748    ///////////////////////
2749    //CONFIG Local RSP Fifo
2750    ///////////////////////
2751    m_config_local_rsrcid_fifo.update( config_local_fifo_get,
2752                                config_local_fifo_put,
2753                                p_vci_tgt_config.srcid.read() );
2754    m_config_local_rtrdid_fifo.update( config_local_fifo_get,
2755                                config_local_fifo_put,
2756                                p_vci_tgt_config.trdid.read() );
2757    m_config_local_rpktid_fifo.update( config_local_fifo_get,
2758                                config_local_fifo_put,
2759                                p_vci_tgt_config.pktid.read() );
2760   
2761    switch( r_config_cmd_fsm.read() ) 
2762    {
2763    case CONFIG_CMD_PTPR_WRITE:
2764    case CONFIG_CMD_ACTIVE_WRITE:
2765    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:
2766    case CONFIG_CMD_IT_ADDR_WRITE_2:
2767    case CONFIG_CMD_INVAL:
2768        m_config_local_data_fifo.update( config_local_fifo_get,
2769                                config_local_fifo_put,
2770                                0); 
2771        m_config_local_rerror_fifo.update( config_local_fifo_get,
2772                                        config_local_fifo_put,
2773                                        WRITE_OK );
2774        m_config_local_reop_fifo.update( config_local_fifo_get,
2775                                        config_local_fifo_put,
2776                                        true );
2777        break;
2778    case CONFIG_CMD_PTPR_READ:
2779        m_config_local_data_fifo.update( config_local_fifo_get,
2780                                config_local_fifo_put,
2781                                r_iommu_ptpr.read()); 
2782        m_config_local_rerror_fifo.update( config_local_fifo_get,
2783                                        config_local_fifo_put,
2784                                        READ_OK );
2785        m_config_local_reop_fifo.update( config_local_fifo_get,
2786                                        config_local_fifo_put,
2787                                        true );
2788        break;
2789    case CONFIG_CMD_ACTIVE_READ:
2790        m_config_local_data_fifo.update( config_local_fifo_get,
2791                                config_local_fifo_put,
2792                                r_iommu_active.read()); 
2793        m_config_local_rerror_fifo.update( config_local_fifo_get,
2794                                        config_local_fifo_put,
2795                                        READ_OK );
2796        m_config_local_reop_fifo.update( config_local_fifo_get,
2797                                        config_local_fifo_put,
2798                                        true );
2799        break;
2800    case CONFIG_CMD_BVAR_READ:
2801        m_config_local_data_fifo.update( config_local_fifo_get,
2802                                config_local_fifo_put,
2803                                r_iommu_bvar.read()); 
2804        m_config_local_rerror_fifo.update( config_local_fifo_get,
2805                                        config_local_fifo_put,
2806                                        READ_OK );
2807        m_config_local_reop_fifo.update( config_local_fifo_get,
2808                                        config_local_fifo_put,
2809                                        true );
2810        break;
2811    case CONFIG_CMD_ETR_READ:
2812        m_config_local_data_fifo.update( config_local_fifo_get,
2813                                config_local_fifo_put,
2814                                r_iommu_etr.read()); 
2815        m_config_local_rerror_fifo.update( config_local_fifo_get,
2816                                        config_local_fifo_put,
2817                                        READ_OK );
2818        m_config_local_reop_fifo.update( config_local_fifo_get,
2819                                        config_local_fifo_put,
2820                                        true );
2821        break;
2822    case CONFIG_CMD_BAD_ID_READ:
2823        m_config_local_data_fifo.update( config_local_fifo_get,
2824                                config_local_fifo_put,
2825                                r_iommu_bad_id.read()); 
2826        m_config_local_rerror_fifo.update( config_local_fifo_get,
2827                                        config_local_fifo_put,
2828                                        READ_OK );
2829        m_config_local_reop_fifo.update( config_local_fifo_get,
2830                                        config_local_fifo_put,
2831                                        true );
2832        break;
2833    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
2834        m_config_local_data_fifo.update( config_local_fifo_get,
2835                                config_local_fifo_put,
2836                                (uint32_t)(r_it_addr_iommu.read() & 0xFFFFFFFF) ); 
2837        m_config_local_rerror_fifo.update( config_local_fifo_get,
2838                                        config_local_fifo_put,
2839                                        READ_OK );
2840        m_config_local_reop_fifo.update( config_local_fifo_get,
2841                                        config_local_fifo_put,
2842                                        false );
2843        break;
2844    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
2845        m_config_local_data_fifo.update( config_local_fifo_get,
2846                                config_local_fifo_put,
2847                               (uint32_t)((r_it_addr_iommu.read()>>32)&0xFF) ); 
2848        m_config_local_rerror_fifo.update( config_local_fifo_get,
2849                                        config_local_fifo_put,
2850                                        READ_OK );
2851        m_config_local_reop_fifo.update( config_local_fifo_get,
2852                                        config_local_fifo_put,
2853                                        true );
2854        break;
2855    case CONFIG_CMD_IT_ADDR_READ_1:
2856        m_config_local_data_fifo.update( config_local_fifo_get,
2857                                config_local_fifo_put,
2858                               (uint32_t)(r_it_addr[r_it_index.read()] & 0xFFFFFFFF) ); 
2859        m_config_local_rerror_fifo.update( config_local_fifo_get,
2860                                        config_local_fifo_put,
2861                                        READ_OK );
2862        m_config_local_reop_fifo.update( config_local_fifo_get,
2863                                        config_local_fifo_put,
2864                                        false );
2865        break;
2866    case CONFIG_CMD_IT_ADDR_READ_2:
2867        m_config_local_data_fifo.update( config_local_fifo_get,
2868                                config_local_fifo_put,
2869                                (uint32_t)((r_it_addr[r_it_index.read()]>>32)&0xFF) ); 
2870        m_config_local_rerror_fifo.update( config_local_fifo_get,
2871                                        config_local_fifo_put,
2872                                        READ_OK );
2873        m_config_local_reop_fifo.update( config_local_fifo_get,
2874                                        config_local_fifo_put,
2875                                        true );
2876        break;
2877    case CONFIG_CMD_ERROR_RSP:
2878        m_config_local_data_fifo.update( config_local_fifo_get,
2879                                        config_local_fifo_put,
2880                                        0); 
2881        m_config_local_rerror_fifo.update( config_local_fifo_get,
2882                                        config_local_fifo_put,
2883                                        r_config_error_type.read() );
2884        m_config_local_reop_fifo.update( config_local_fifo_get,
2885                                        config_local_fifo_put,
2886                                        true );
2887        break;
2888    default:
2889        m_config_local_data_fifo.update( config_local_fifo_get,
2890                                config_local_fifo_put,
2891                                0); 
2892        m_config_local_rerror_fifo.update( config_local_fifo_get,
2893                                        config_local_fifo_put,
2894                                        0 );
2895        m_config_local_reop_fifo.update( config_local_fifo_get,
2896                               config_local_fifo_put,
2897                               false );
2898        break;
2899    }
2900
2901} // end transition()
2902
2903///////////////////////
2904tmpl(void)::genMoore()
2905///////////////////////
2906{
2907    //////////////////
2908    // DMA Commands //
2909    //////////////////
2910   
2911    // VCI initiator command on the xram network
2912    if(m_dma_cmd_addr_fifo.rok()) 
2913    //&& p_vci_ini_dma.cmdack.read())
2914    {
2915        p_vci_ini_dma.cmdval  = true;
2916        #if NEW_XRAM_VCI
2917        p_vci_ini_dma.address = (paddr_t_x)(m_dma_cmd_addr_fifo.read() >> 6 )
2918        #else
2919        p_vci_ini_dma.address = m_dma_cmd_addr_fifo.read();
2920        #endif
2921       
2922        p_vci_ini_dma.be      = m_dma_cmd_be_fifo.read();
2923        p_vci_ini_dma.cmd     = m_dma_cmd_cmd_fifo.read();
2924        p_vci_ini_dma.contig  = m_dma_cmd_contig_fifo.read();
2925        #if NEW_XRAM_VCI
2926        //TODO for 64 bits field
2927        #else
2928        p_vci_ini_dma.wdata   = m_dma_cmd_data_fifo.read(); // The first is in param_x
2929                                                    // the second in param_io
2930        #endif
2931        p_vci_ini_dma.eop     = m_dma_cmd_eop_fifo.read();
2932        p_vci_ini_dma.cons    = m_dma_cmd_cons_fifo.read();
2933        p_vci_ini_dma.plen    = m_dma_cmd_plen_fifo.read();
2934        p_vci_ini_dma.wrap    = m_dma_cmd_wrap_fifo.read();
2935        p_vci_ini_dma.cfixed  = m_dma_cmd_cfixed_fifo.read();
2936        p_vci_ini_dma.clen    = m_dma_cmd_clen_fifo.read();
2937        p_vci_ini_dma.trdid   = m_dma_cmd_trdid_fifo.read();
2938        p_vci_ini_dma.pktid   = m_dma_cmd_pktid_fifo.read();
2939        p_vci_ini_dma.srcid   = m_dma_cmd_srcid_fifo.read();
2940    }
2941    else
2942    {
2943        p_vci_ini_dma.cmdval  = false;
2944        p_vci_ini_dma.address = 0;
2945        p_vci_ini_dma.be      = 0;
2946        p_vci_ini_dma.cmd     = vci_param_x::CMD_NOP;
2947        p_vci_ini_dma.contig  = false;
2948        p_vci_ini_dma.wdata   = 0;
2949        p_vci_ini_dma.eop     = false;
2950        p_vci_ini_dma.cons    = true;
2951        p_vci_ini_dma.plen    = 0;
2952        p_vci_ini_dma.wrap    = false;
2953        p_vci_ini_dma.cfixed  = false;
2954        p_vci_ini_dma.clen    = 0;
2955        p_vci_ini_dma.trdid   = 0;
2956        p_vci_ini_dma.pktid   = 0; 
2957    }
2958   
2959    // VCI target command on the IO network
2960    // it depends on the DMA_CMD FSM state
2961
2962    switch ( r_dma_cmd_fsm.read() ) 
2963    {
2964    case DMA_CMD_IDLE:
2965    case DMA_CMD_TRT_LOCK:     
2966    case DMA_CMD_TRT_WAIT:     
2967    case DMA_CMD_TRT_SET:       
2968        p_vci_tgt_dma.cmdack  = false;
2969        break;
2970    case DMA_CMD_FIFO_PUT:
2971    case DMA_CMD_FIFO_MISS_PUT:
2972        p_vci_tgt_dma.cmdack  = m_dma_cmd_addr_fifo.wok();
2973        break;
2974    case DMA_CMD_TLB_MISS_WAIT:
2975        p_vci_tgt_dma.cmdack  = false;
2976        break;
2977    case DMA_CMD_TLB_MISS_STORE:
2978        p_vci_tgt_dma.cmdack  = true;
2979        break;
2980    case DMA_CMD_ERROR:
2981        p_vci_tgt_dma.cmdack  = !r_dma_cmd_error_req.read();
2982        break; 
2983    }// end switch r_dma_cmd_fsm
2984
2985    //////////////////
2986    // DMA Responses//
2987    //////////////////
2988   
2989    // VCI target response on the IO network
2990    if(m_dma_rsp_data_fifo.rok())
2991    {
2992        p_vci_tgt_dma.rspval  = true;
2993                p_vci_tgt_dma.rsrcid  = m_dma_rsp_rsrcid_fifo.read();
2994        p_vci_tgt_dma.rtrdid  = m_dma_rsp_rtrdid_fifo.read();
2995       
2996        p_vci_tgt_dma.rpktid  = m_dma_rsp_rpktid_fifo.read();
2997   
2998        #if NEW_XRAM_VCI
2999        //TODO for 64 bit data field
3000        #else
3001        p_vci_tgt_dma.rdata   = m_dma_rsp_data_fifo.read(); // The first is in param_io
3002                                                    // the second in param_x
3003        #endif
3004       
3005        p_vci_tgt_dma.rerror  = m_dma_rsp_rerror_fifo.read();
3006        p_vci_tgt_dma.reop    = m_dma_rsp_reop_fifo.read();
3007    }
3008    else
3009    {
3010        p_vci_tgt_dma.rspval  = false;
3011       
3012                p_vci_tgt_dma.rsrcid  = 0;
3013                p_vci_tgt_dma.rdata   = 0;
3014                p_vci_tgt_dma.rpktid  = 0;
3015                p_vci_tgt_dma.rtrdid  = 0;
3016                p_vci_tgt_dma.rerror  = 0;
3017                p_vci_tgt_dma.reop    = false;
3018
3019    }
3020
3021    // VCI initiator response on the Xram Network
3022    // it depends on the DMA_RSP FSM state
3023    switch ( r_dma_rsp_fsm.read() ) 
3024    {
3025    case DMA_RSP_IDLE:
3026    case DMA_RSP_TRT_LOCK:
3027    case DMA_RSP_FIFO_ERROR_PUT:
3028    {
3029                p_vci_ini_dma.rspack = false;
3030        break;
3031    }
3032    case DMA_RSP_FIFO_PUT:
3033        {
3034        p_vci_ini_dma.rspack = m_dma_rsp_data_fifo.wok();
3035        break;
3036    }
3037    }// end switch r_dma_rsp_fsm
3038
3039    /////////////////////
3040    // CONFIG Commands //
3041    /////////////////////
3042
3043    // VCI initiator command on the IO network
3044    if(m_config_cmd_addr_fifo.rok())
3045    {
3046        p_vci_ini_config.cmdval  = true;
3047        #if NEW_XRAM_VCI
3048        p_vci_ini_config.address = (paddr_t_x)(m_config_cmd_addr_fifo.read() >> 6 )
3049        #else
3050        p_vci_ini_config.address = m_config_cmd_addr_fifo.read();
3051        #endif
3052       
3053        p_vci_ini_config.be      = m_config_cmd_be_fifo.read();
3054        p_vci_ini_config.cmd     = m_config_cmd_cmd_fifo.read();
3055        p_vci_ini_config.contig  = m_config_cmd_contig_fifo.read();
3056        #if NEW_XRAM_VCI
3057        //TODO
3058        #else
3059        p_vci_ini_config.wdata   = m_config_cmd_data_fifo.read(); // The first is in param_x
3060                                                    // the second in param_io
3061        #endif
3062        p_vci_ini_config.eop     = m_config_cmd_eop_fifo.read();
3063        p_vci_ini_config.cons    = m_config_cmd_cons_fifo.read();
3064        p_vci_ini_config.plen    = m_config_cmd_plen_fifo.read();
3065        p_vci_ini_config.wrap    = m_config_cmd_wrap_fifo.read();
3066        p_vci_ini_config.cfixed  = m_config_cmd_cfixed_fifo.read();
3067        p_vci_ini_config.clen    = m_config_cmd_clen_fifo.read();
3068        p_vci_ini_config.trdid   = m_config_cmd_trdid_fifo.read();
3069        p_vci_ini_config.pktid   = m_config_cmd_pktid_fifo.read();
3070    }
3071    else
3072    {
3073        p_vci_ini_config.cmdval  = false;
3074        p_vci_ini_config.address = 0;
3075        p_vci_ini_config.be      = 0;
3076        p_vci_ini_config.cmd     = vci_param_io::CMD_NOP;
3077        p_vci_ini_config.contig  = false;
3078        p_vci_ini_config.wdata   = 0;
3079        p_vci_ini_config.eop     = false;
3080        p_vci_ini_config.cons    = true;
3081        p_vci_ini_config.plen    = 0;
3082        p_vci_ini_config.wrap    = false;
3083        p_vci_ini_config.cfixed  = false;
3084        p_vci_ini_config.clen    = 0;
3085        p_vci_ini_config.trdid   = 0;
3086        p_vci_ini_config.pktid   = 0; 
3087    }
3088   
3089    // VCI target command on the Direct network
3090    // it depends on the CONFIG_CMD FSM state
3091
3092    switch ( r_config_cmd_fsm.read() ) 
3093    {
3094    case CONFIG_CMD_IDLE:
3095    case CONFIG_CMD_TRT_LOCK:   
3096    case CONFIG_CMD_TRT_WAIT: 
3097    case CONFIG_CMD_TRT_SET: 
3098    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
3099    case CONFIG_CMD_IT_ADDR_READ_1:
3100    case CONFIG_CMD_ERROR_RSP: 
3101    case CONFIG_CMD_INVAL_REQ:
3102        p_vci_tgt_config.cmdack  = false;
3103        break;
3104    case CONFIG_CMD_FIFO_PUT:     
3105    case CONFIG_CMD_PTPR_WRITE:
3106    case CONFIG_CMD_PTPR_READ:
3107    case CONFIG_CMD_ACTIVE_WRITE:
3108    case CONFIG_CMD_ACTIVE_READ:
3109    case CONFIG_CMD_BVAR_READ:
3110    case CONFIG_CMD_ETR_READ:
3111    case CONFIG_CMD_BAD_ID_READ:
3112    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:
3113    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
3114    case CONFIG_CMD_IT_ADDR_WRITE_2:
3115    case CONFIG_CMD_IT_ADDR_READ_2:
3116    case CONFIG_CMD_INVAL: 
3117        p_vci_tgt_config.cmdack  = m_config_cmd_addr_fifo.wok();
3118        break;
3119    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1:
3120    case CONFIG_CMD_IT_ADDR_WRITE_1:
3121    case CONFIG_CMD_ERROR_WAIT: 
3122        p_vci_tgt_config.cmdack = true; 
3123        break;
3124    default: 
3125        p_vci_tgt_config.cmdack  = false;
3126        break;
3127    }// end switch r_config_cmd_fsm
3128
3129    /////////////////////
3130    // CONFIG Responses//
3131    /////////////////////
3132   
3133    // VCI target response on the Direct network
3134    if(r_config_rsp_fifo_local_priority)
3135    {
3136    if( m_config_local_data_fifo.rok() )
3137    {
3138        p_vci_tgt_config.rspval  = true;
3139                p_vci_tgt_config.rsrcid  = m_config_local_rsrcid_fifo.read();
3140        p_vci_tgt_config.rtrdid  = m_config_local_rtrdid_fifo.read();
3141        p_vci_tgt_config.rpktid  = m_config_local_rpktid_fifo.read();
3142        p_vci_tgt_config.rdata   = m_config_local_data_fifo.read();
3143        p_vci_tgt_config.rerror  = m_config_local_rerror_fifo.read();
3144        p_vci_tgt_config.reop    = m_config_local_reop_fifo.read();
3145    }
3146    else if(m_config_rsp_data_fifo.rok() )
3147    {
3148        p_vci_tgt_config.rspval  = true;
3149                p_vci_tgt_config.rsrcid  = m_config_rsp_rsrcid_fifo.read();
3150        p_vci_tgt_config.rtrdid  = m_config_rsp_rtrdid_fifo.read();
3151       
3152        p_vci_tgt_config.rpktid  = m_config_rsp_rpktid_fifo.read();
3153   
3154        p_vci_tgt_config.rdata   = m_config_rsp_data_fifo.read(); // The first is in param_d
3155                                                    // the second in param_io
3156        p_vci_tgt_config.rerror  = m_config_rsp_rerror_fifo.read();
3157        p_vci_tgt_config.reop    = m_config_rsp_reop_fifo.read();
3158    }
3159    else
3160    {
3161        p_vci_tgt_config.rspval  = false;
3162       
3163                p_vci_tgt_config.rsrcid  = 0;
3164                p_vci_tgt_config.rdata   = 0;
3165                p_vci_tgt_config.rpktid  = 0;
3166                p_vci_tgt_config.rtrdid  = 0;
3167                p_vci_tgt_config.rerror  = 0;
3168                p_vci_tgt_config.reop    = false;
3169
3170    }
3171    }
3172    else
3173    {
3174    if(m_config_rsp_data_fifo.rok() )
3175    {
3176        p_vci_tgt_config.rspval  = true;
3177                p_vci_tgt_config.rsrcid  = m_config_rsp_rsrcid_fifo.read();
3178        p_vci_tgt_config.rtrdid  = m_config_rsp_rtrdid_fifo.read();
3179       
3180        p_vci_tgt_config.rpktid  = m_config_rsp_rpktid_fifo.read();
3181   
3182        p_vci_tgt_config.rdata   = m_config_rsp_data_fifo.read(); // The first is in param_d
3183                                                    // the second in param_io
3184        p_vci_tgt_config.rerror  = m_config_rsp_rerror_fifo.read();
3185        p_vci_tgt_config.reop    = m_config_rsp_reop_fifo.read();
3186    }
3187    else if( m_config_local_data_fifo.rok() )
3188    {
3189        p_vci_tgt_config.rspval  = true;
3190                p_vci_tgt_config.rsrcid  = m_config_local_rsrcid_fifo.read();
3191        p_vci_tgt_config.rtrdid  = m_config_local_rtrdid_fifo.read();
3192        p_vci_tgt_config.rpktid  = m_config_local_rpktid_fifo.read();
3193        p_vci_tgt_config.rdata   = m_config_local_data_fifo.read();
3194        p_vci_tgt_config.rerror  = m_config_local_rerror_fifo.read();
3195        p_vci_tgt_config.reop    = m_config_local_reop_fifo.read();
3196    }
3197    else
3198    {
3199        p_vci_tgt_config.rspval  = false;
3200       
3201                p_vci_tgt_config.rsrcid  = 0;
3202                p_vci_tgt_config.rdata   = 0;
3203                p_vci_tgt_config.rpktid  = 0;
3204                p_vci_tgt_config.rtrdid  = 0;
3205                p_vci_tgt_config.rerror  = 0;
3206                p_vci_tgt_config.reop    = false;
3207
3208    }
3209    }
3210   
3211    // VCI initiator response on the IO Network
3212    // it depends on the CONFIG_RSP FSM state
3213    switch ( r_config_rsp_fsm.read() ) 
3214    {
3215    case CONFIG_RSP_IDLE:
3216    case CONFIG_RSP_TRT_LOCK:
3217        p_vci_ini_config.rspack = false;
3218        break;
3219    case CONFIG_RSP_FIFO_PUT:
3220                p_vci_ini_config.rspack = m_config_rsp_data_fifo.wok();
3221        break;
3222    }// end switch r_config_rsp_fsm
3223
3224    ////////////////////////////////////////////////////////////////
3225    // VCI initiator command and response on from the Direct network
3226    // for Miss Transactions
3227    p_vci_ini_miss.srcid   = m_srcid_miss;
3228   
3229    switch ( r_miss_init_fsm.read() ) 
3230    {   
3231    case MISS_INIT_IDLE_MISS:
3232    case MISS_INIT_IDLE_IRQ:
3233                p_vci_ini_miss.cmdval  = false;
3234        p_vci_ini_miss.address = 0;
3235        p_vci_ini_miss.be      = 0;
3236        p_vci_ini_miss.cmd     = vci_param_d::CMD_NOP;
3237        p_vci_ini_miss.contig  = false;
3238        p_vci_ini_miss.wdata   = 0;
3239        p_vci_ini_miss.eop     = false;
3240        p_vci_ini_miss.cons    = true;
3241        p_vci_ini_miss.plen    = 0;
3242        p_vci_ini_miss.wrap    = false;
3243        p_vci_ini_miss.cfixed  = false;
3244        p_vci_ini_miss.clen    = 0;
3245        p_vci_ini_miss.trdid   = 0;
3246        p_vci_ini_miss.pktid   = 0;
3247
3248                p_vci_ini_miss.rspack = false;
3249        break;
3250   
3251    case MISS_INIT_IRQ_CMD:
3252        p_vci_ini_miss.cmdval  = true;
3253        p_vci_ini_miss.address = (paddr_t)r_it_addr[r_irq_chosen.read()]; 
3254        p_vci_ini_miss.wdata   = 0;
3255        p_vci_ini_miss.plen    = vci_param_d::B;
3256        p_vci_ini_miss.trdid   = 0; 
3257        p_vci_ini_miss.cmd     = vci_param_d::CMD_READ;
3258        p_vci_ini_miss.eop     = true;
3259       
3260        p_vci_ini_miss.be      = 0xF;
3261        p_vci_ini_miss.pktid   = 0;
3262        p_vci_ini_miss.cons    = false;
3263        p_vci_ini_miss.wrap    = false;
3264        p_vci_ini_miss.contig  = true;
3265        p_vci_ini_miss.clen    = 0;
3266        p_vci_ini_miss.cfixed  = false;
3267        break;
3268   
3269    case MISS_INIT_IRQ_RSP:
3270    case MISS_INIT_TLB_MISS_RSP:
3271        p_vci_ini_miss.cmdval  = false;
3272        p_vci_ini_miss.address = 0;
3273        p_vci_ini_miss.be      = 0;
3274        p_vci_ini_miss.cmd     = vci_param_d::CMD_NOP;
3275        p_vci_ini_miss.contig  = false;
3276        p_vci_ini_miss.wdata   = 0;
3277        p_vci_ini_miss.eop     = false;
3278        p_vci_ini_miss.cons    = true;
3279        p_vci_ini_miss.plen    = 0;
3280        p_vci_ini_miss.wrap    = false;
3281        p_vci_ini_miss.cfixed  = false;
3282        p_vci_ini_miss.clen    = 0;
3283        p_vci_ini_miss.trdid   = 0;
3284        p_vci_ini_miss.pktid   = 0;
3285       
3286        p_vci_ini_miss.rspack = true;
3287 
3288        break;
3289   
3290    case MISS_INIT_TLB_MISS_CMD:
3291        p_vci_ini_miss.cmdval  = true;
3292        p_vci_ini_miss.address = (paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK);
3293        p_vci_ini_miss.wdata   = 0x00000000;
3294        p_vci_ini_miss.plen    = m_words*(vci_param_d::B);
3295        p_vci_ini_miss.trdid   = 0;  //could be used as the index on a miss transaction table
3296        p_vci_ini_miss.cmd     = vci_param_d::CMD_READ;
3297        p_vci_ini_miss.eop     = true;
3298       
3299        p_vci_ini_miss.be      = 0xF;
3300        p_vci_ini_miss.pktid   = 0;
3301        p_vci_ini_miss.cons    = false;
3302        p_vci_ini_miss.wrap    = false;
3303        p_vci_ini_miss.contig  = true;
3304        p_vci_ini_miss.clen    = 0;
3305        p_vci_ini_miss.cfixed  = false;
3306        break;
3307
3308    } // end switch r_miss_init_fsm
3309} // end genMoore
3310
3311}}
3312
3313// Local Variables:
3314// tab-width: 4
3315// c-basic-offset: 4
3316// c-file-offsets:((innamespace . 0)(inline-open . 0))
3317// indent-tabs-mode: nil
3318// End:
3319
3320// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.