source: branches/reconfiguration/platforms/tsar_generic_iob/top.cpp @ 1002

Last change on this file since 1002 was 1001, checked in by cfuguet, 9 years ago

reconf: introducing a hardware barrier in the global-local interface of
the local interconnects.

  • This barrier is controlled by a port (barrier enable) in the dspin and vci local interconnects.
  • The barrier enable port is connected to a configuration register of the XICU component to allow the software to control this barrier. The barrier is enabled when the barrier enable port value is different of 0xFFFFFFFF. As the configuration register of the XICU component are reset to 0, this barrier is enabled by default.
  • This barrier allows to isolate the cluster from the rest of the architecture and only if it self-diagnoses as functional, it release the barrier to communicate with the others.
  • The same barrier enable signal is connected to the five local interconnects. Therefore, either all are released or all are disabled.
  • If a local initiator or an external initiator sends a packet out or into the cluster respectively, and the barrier is enabled, the packet is dropped.
File size: 74.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2// File: top.cpp  (for tsar_generic_iob platform)
3// Author: Alain Greiner
4// Copyright: UPMC/LIP6
5// Date : august 2013
6// This program is released under the GNU public license
7//
8// Modified by: Cesar Fuguet
9///////////////////////////////////////////////////////////////////////////////
10// This file define a generic TSAR architecture with an IO network emulating
11// an external bus (i.e. Hypertransport) to access 7 external peripherals:
12//
13// - FBUF : Frame Buffer
14// - MTTY : multi TTY (one channel)
15// - MNIC : Network controller (up to 2 channels)
16// - CDMA : Chained Buffer DMA controller (up to 4 channels)
17// - BDEV : Dlock Device controler (one channel)
18// - IOPI : HWI to SWI translator.
19// - SIMH : Simulation Helper
20//
21// The internal physical address space is 40 bits, and the cluster index
22// is defined by the 8 MSB bits, using a fixed format: X is encoded on 4 bits,
23// Y is encodes on 4 bits, whatever the actual mesh size.
24// => at most 16 * 16 clusters. Each cluster contains up to 4 processors.
25//
26// It contains 3 networks:
27//
28// 1) the "INT" network supports Read/Write transactions
29//    between processors and L2 caches or peripherals.
30//    (VCI ADDDRESS = 40 bits / VCI DATA width = 32 bits)
31//    It supports also coherence transactions between L1 & L2 caches.
32// 3) the "RAM" network emulates the 3D network between L2 caches
33//    and L3 caches, and is implemented as a 2D mesh between the L2 caches,
34//    the two IO bridges and the physical RAMs disributed in all clusters.
35//    (VCI ADDRESS = 40 bits / VCI DATA = 64 bits)
36// 4) the IOX network connects the two IO bridge components to the
37//    7 external peripheral controllers.
38//    (VCI ADDDRESS = 40 bits / VCI DATA width = 64 bits)
39//
40// The external peripherals HWI IRQs are translated to WTI IRQs by the
41// external IOPIC component, that must be configured by the OS to route
42// these WTI IRQS to one or several internal XICU components.
43// - IOPIC HWI[1:0]     connected to IRQ_NIC_RX[1:0]
44// - IOPIC HWI[3:2]     connected to IRQ_NIC_TX[1:0]
45// - IOPIC HWI[7:4]     connected to IRQ_CMA_TX[3:0]]
46// - IOPIC HWI[8]       connected to IRQ_BDEV
47// - IOPIC HWI[31:16]   connected to IRQ_TTY_RX[15:0]
48//
49// Besides the external peripherals, each cluster contains one XICU component,
50// and one multi channels DMA component.
51// The XICU component is mainly used to handle WTI IRQs, as only 5 HWI IRQs
52// are connected to XICU in each cluster:
53// - IRQ_IN[0] : MMC
54// - IRQ_IN[1] : DMA channel 0
55// - IRQ_IN[2] : DMA channel 1
56// - IRQ_IN[3] : DMA channel 2
57// - IRQ_IN[4] : DMA channel 3
58//
59// All clusters are identical, but cluster(0, 0) and cluster(X_SIZE-1, Y_SIZE-1)
60// contain an extra IO bridge component. These IOB0 & IOB1 components are
61// connected to the three networks (INT, RAM, IOX).
62//
63// - It uses two dspin_local_crossbar per cluster to implement the
64//   local interconnect correponding to the INT network.
65// - It uses three dspin_local_crossbar per cluster to implement the
66//   local interconnect correponding to the coherence INT network.
67// - It uses two virtual_dspin_router per cluster to implement
68//   the INT network (routing both the direct and coherence trafic).
69// - It uses two dspin_router per cluster to implement the RAM network.
70// - It uses the vci_cc_vcache_wrapper.
71// - It uses the vci_mem_cache.
72// - It contains one vci_xicu and one vci_multi_dma per cluster.
73// - It contains one vci_simple ram per cluster to model the L3 cache.
74//
75// The TsarIobCluster component is defined in files
76// tsar_iob_cluster.* (with * = cpp, h, sd)
77//
78// The main hardware parameters must be defined in the hard_config.h file :
79// - X_SIZE           : number of clusters in a row
80// - Y_SIZE           : number of clusters in a column
81// - NB_PROCS_MAX     : number of processors per cluster (power of 2)
82// - NB_TTY_CHANNELS  : number of TTY channels in I/O network (up to 16)
83// - NB_NIC_CHANNELS  : number of NIC channels in I/O network (up to 2)
84// - NB_CMA_CHANNELS  : number of CMA channels in I/O network (up to 4)
85// - FBUF_X_SIZE      : width of frame buffer (pixels)
86// - FBUF_Y_SIZE      : heigth of frame buffer (lines)
87// - XCU_NB_HWI       : number of HWIs
88// - XCU_NB_PTI       : number of PTIs
89// - XCU_NB_WTI       : number of WTIs
90// - XCU_NB_OUT       : number of OUTs
91//
92// Some secondary hardware parameters must be defined in this top.cpp file:
93// - XRAM_LATENCY     : external ram latency
94// - MEMC_WAYS        : L2 cache number of ways
95// - MEMC_SETS        : L2 cache number of sets
96// - L1_IWAYS
97// - L1_ISETS
98// - L1_DWAYS
99// - L1_DSETS
100// - BDEV_IMAGE_NAME  : file pathname for block device
101// - NIC_TIMEOUT      : max number of cycles before closing a container
102//
103// General policy for 40 bits physical address decoding:
104// All physical segments base addresses are multiple of 1 Mbytes
105// (=> the 24 LSB bits = 0, and the 16 MSB bits define the target)
106// The (X_WIDTH + Y_WIDTH) MSB bits (left aligned) define
107// the cluster index, and the LADR bits define the local index:
108//      |X_ID|Y_ID|  LADR  |     OFFSET          |
109//      |  4 |  4 |   8    |       24            |
110//
111// General policy for 14 bits SRCID decoding:
112// Each component is identified by (x_id, y_id, l_id) tuple.
113//      |X_ID|Y_ID| L_ID |
114//      |  4 |  4 |  6   |
115/////////////////////////////////////////////////////////////////////////
116
117#include <systemc>
118#include <sys/time.h>
119#include <iostream>
120#include <sstream>
121#include <cstdlib>
122#include <cstdarg>
123#include <climits>
124#include <stdint.h>
125#include <vector>
126
127#include "gdbserver.h"
128#include "mapping_table.h"
129
130#include "tsar_iob_cluster.h"
131#include "vci_chbuf_dma.h"
132#include "vci_multi_tty.h"
133#include "vci_multi_nic.h"
134#include "vci_target_error.h"
135#include "vci_simple_rom.h"
136#include "vci_block_device_tsar.h"
137#include "vci_framebuffer.h"
138#include "vci_iox_network.h"
139#include "vci_iopic.h"
140#include "vci_simhelper.h"
141
142#include "alloc_elems.h"
143
144///////////////////////////////////////////////////
145//      OS
146///////////////////////////////////////////////////
147#define USE_ALMOS 0
148
149#define almos_bootloader_pathname "bootloader.bin"
150#define almos_kernel_pathname     "kernel-soclib.bin@0xbfc10000:D"
151#define almos_archinfo_pathname   "arch-info.bin@0xBFC08000:D"
152
153///////////////////////////////////////////////////
154//               Parallelisation
155///////////////////////////////////////////////////
156#define USE_OPENMP _OPENMP
157
158#if USE_OPENMP
159#include <omp.h>
160#endif
161
162///////////////////////////////////////////////////////////
163//          DSPIN parameters
164///////////////////////////////////////////////////////////
165
166#define dspin_int_cmd_width   39
167#define dspin_int_rsp_width   32
168
169#define dspin_ram_cmd_width   64
170#define dspin_ram_rsp_width   64
171
172///////////////////////////////////////////////////////////
173//         VCI fields width  for the 3 VCI networks
174///////////////////////////////////////////////////////////
175
176#define vci_cell_width_int    4
177#define vci_cell_width_ext    8
178
179#define vci_plen_width        8
180#define vci_address_width     40
181#define vci_rerror_width      1
182#define vci_clen_width        1
183#define vci_rflag_width       1
184#define vci_srcid_width       14
185#define vci_pktid_width       4
186#define vci_trdid_width       4
187#define vci_wrplen_width      1
188
189////////////////////////////////////////////////////////////
190//    Main Hardware Parameters values
191//////////////////////i/////////////////////////////////////
192
193#include "hard_config.h"
194
195////////////////////////////////////////////////////////////
196//    Secondary Hardware Parameters values
197//////////////////////i/////////////////////////////////////
198
199#define XRAM_LATENCY          0
200
201#define MEMC_WAYS             16
202#define MEMC_SETS             256
203
204#define L1_IWAYS              4
205#define L1_ISETS              64
206
207#define L1_DWAYS              4
208#define L1_DSETS              64
209
210#define BDEV_IMAGE_NAME       "../../../giet_vm/hdd/virt_hdd.dmg"
211
212#define NIC_TIMEOUT           10000
213
214#define NORTH                 0
215#define SOUTH                 1
216#define EAST                  2
217#define WEST                  3
218
219#define cluster(x, y)   ((y) + ((x) << Y_WIDTH))
220
221////////////////////////////////////////////////////////////
222//     DEBUG Parameters default values
223//////////////////////i/////////////////////////////////////
224
225#define MAX_FROZEN_CYCLES     200000
226
227/////////////////////////////////////////////////////////
228//    Physical segments definition
229/////////////////////////////////////////////////////////
230
231// All physical segments base addresses and sizes are defined
232// in the hard_config.h file. For replicated segments, the
233// base address is incremented by a cluster offset:
234// offset  = cluster(x, y) << (address_width-X_WIDTH-Y_WIDTH);
235
236////////////////////////////////////////////////////////////////////////
237//          SRCID definition
238////////////////////////////////////////////////////////////////////////
239// All initiators are in the same indexing space (14 bits).
240// The SRCID is structured in two fields:
241// - The 8 MSB bits define the cluster index (left aligned)
242// - The 6 LSB bits define the local index.
243// Two different initiators cannot have the same SRCID, but a given
244// initiator can have two alias SRCIDs:
245// - Internal initiators (procs, mdma) are replicated in all clusters,
246//   and each initiator has one single SRCID.
247// - External initiators (bdev, cdma) are not replicated, but can be
248//   accessed in 2 clusters : cluster_iob0 and cluster_iob1.
249//   They have the same local index, but two different cluster indexes.
250//
251// As cluster_iob0 and cluster_iob1 contain both internal initiators
252// and external initiators, they must have different local indexes.
253// Consequence: For a local interconnect, the INI_ID port index
254// is NOT equal to the SRCID local index, and the local interconnect
255// must make a translation: SRCID => INI_ID
256////////////////////////////////////////////////////////////////////////
257
258#define PROC_LOCAL_SRCID             0x0    // from 0 to 7
259#define MDMA_LOCAL_SRCID             0x8
260#define IOBX_LOCAL_SRCID             0x9
261#define MEMC_LOCAL_SRCID             0xA
262#define CDMA_LOCAL_SRCID             0xB
263#define BDEV_LOCAL_SRCID             0xC
264#define IOPI_LOCAL_SRCID             0xD
265
266///////////////////////////////////////////////////////////////////////
267//     TGT_ID and INI_ID port indexing for INT local interconnect
268///////////////////////////////////////////////////////////////////////
269
270#define INT_MEMC_TGT_ID              0
271#define INT_XICU_TGT_ID              1
272#define INT_MDMA_TGT_ID              2
273#define INT_DROM_TGT_ID              3
274#define INT_IOBX_TGT_ID              4
275
276#define INT_PROC_INI_ID              0   // from 0 to (NB_PROCS_MAX-1)
277#define INT_MDMA_INI_ID              (NB_PROCS_MAX)
278#define INT_IOBX_INI_ID              (NB_PROCS_MAX+1)
279
280///////////////////////////////////////////////////////////////////////
281//     TGT_ID and INI_ID port indexing for RAM local interconnect
282///////////////////////////////////////////////////////////////////////
283
284#define RAM_XRAM_TGT_ID              0
285
286#define RAM_MEMC_INI_ID              0
287#define RAM_IOBX_INI_ID              1
288
289///////////////////////////////////////////////////////////////////////
290//     TGT_ID and INI_ID port indexing for I0X local interconnect
291///////////////////////////////////////////////////////////////////////
292
293#define IOX_FBUF_TGT_ID              0
294#define IOX_BDEV_TGT_ID              1
295#define IOX_MNIC_TGT_ID              2
296#define IOX_CDMA_TGT_ID              3
297#define IOX_MTTY_TGT_ID              4
298#define IOX_IOPI_TGT_ID              5
299#define IOX_SIMH_TGT_ID              6
300#define IOX_ROM_TGT_ID               7
301#define IOX_IOB0_TGT_ID              8
302#define IOX_IOB1_TGT_ID              9
303
304#define IOX_BDEV_INI_ID              0
305#define IOX_CDMA_INI_ID              1
306#define IOX_IOPI_INI_ID              2
307#define IOX_IOB0_INI_ID              3
308#define IOX_IOB1_INI_ID              4
309
310////////////////////////////////////////////////////////////////////////
311int _main(int argc, char *argv[])
312////////////////////////////////////////////////////////////////////////
313{
314   using namespace sc_core;
315   using namespace soclib::caba;
316   using namespace soclib::common;
317
318
319   char     dsoft_name[256]  = "";                // pathname: binary code
320   char     soft_name[256]   = "";                // pathname: binary code
321   size_t   ncycles          = UINT_MAX;          // simulated cycles
322   char     disk_name[256]   = BDEV_IMAGE_NAME;   // pathname: disk image
323   ssize_t  threads_nr       = 1;                 // simulator's threads number
324   size_t   faulty_mask      = 0x1F;              // interface mask for the faulty router
325   bool     debug_ok         = false;             // trace activated
326   size_t   debug_period     = 1;                 // trace period
327   size_t   debug_memc_id    = 0xFFFFFFFF;        // index of traced memc
328   size_t   debug_proc_id    = 0xFFFFFFFF;        // index of traced proc
329   size_t   debug_xram_id    = 0xFFFFFFFF;        // index of traced xram
330   bool     debug_iob        = false;             // trace iob0 & iob1 when true
331   uint32_t debug_from       = 0;                 // trace start cycle
332   uint32_t frozen_cycles    = MAX_FROZEN_CYCLES; // monitoring frozen processor
333
334   std::vector<size_t> faulty_routers;
335
336   assert( (X_WIDTH == 4) and (Y_WIDTH == 4) and
337   "ERROR: we must have X_WIDTH == Y_WIDTH == 4");
338
339   ////////////// command line arguments //////////////////////
340   if (argc > 1)
341   {
342      for (int n = 1; n < argc; n = n + 2)
343      {
344         if ((strcmp(argv[n], "-NCYCLES") == 0) && (n+1<argc))
345         {
346            ncycles = strtol(argv[n+1], NULL, 0);
347         }
348         else if ((strcmp(argv[n], "-SOFT") == 0) && (n+1<argc) )
349         {
350            strcpy(soft_name, argv[n+1]);
351         }
352         else if ((strcmp(argv[n], "-DSOFT") == 0) && (n+1<argc) )
353         {
354            strcpy(dsoft_name, argv[n+1]);
355         }
356         else if ((strcmp(argv[n], "-DEBUG") == 0) && (n+1<argc) )
357         {
358            debug_ok = true;
359            debug_from = strtol(argv[n+1], NULL, 0);
360         }
361         else if ((strcmp(argv[n], "-DISK") == 0) && (n+1<argc) )
362         {
363            strcpy(disk_name, argv[n+1]);
364         }
365         else if ((strcmp(argv[n], "-MEMCID") == 0) && (n+1<argc) )
366         {
367            debug_memc_id = strtol(argv[n+1], NULL, 0);
368            size_t x = debug_memc_id >> Y_WIDTH;
369            size_t y = debug_memc_id & ((1 << Y_WIDTH) - 1);
370            if( (x>=X_SIZE) || (y>=Y_SIZE) )
371            {
372                std::cout << "MEMCID parameter does'nt fit X_SIZE/Y_SIZE" << std::endl;
373                exit(0);
374            }
375         }
376         else if ((strcmp(argv[n], "-XRAMID") == 0) && (n+1<argc) )
377         {
378            debug_xram_id = strtol(argv[n+1], NULL, 0);
379            size_t x = debug_xram_id >> Y_WIDTH;
380            size_t y = debug_xram_id & ((1 << Y_WIDTH) - 1);
381            if( (x>=X_SIZE) || (y>=Y_SIZE) )
382            {
383                std::cout << "XRAMID parameter does'nt fit X_SIZE/Y_SIZE" << std::endl;
384                exit(0);
385            }
386         }
387         else if ((strcmp(argv[n], "-IOB") == 0) && (n+1<argc) )
388         {
389            debug_iob = strtol(argv[n+1], NULL, 0);
390         }
391         else if ((strcmp(argv[n], "-PROCID") == 0) && (n+1<argc) )
392         {
393            debug_proc_id     = strtol(argv[n+1], NULL, 0);
394            size_t cluster_xy = debug_proc_id >> P_WIDTH;
395            size_t x          = cluster_xy >> Y_WIDTH;
396            size_t y          = cluster_xy & ((1 << Y_WIDTH) - 1);
397            if( (x>=X_SIZE) || (y>=Y_SIZE) )
398            {
399                std::cout << "PROCID parameter does'nt fit X_SIZE/Y_SIZE" << std::endl;
400                exit(0);
401            }
402         }
403         else if ((strcmp(argv[n], "-THREADS") == 0) && ((n+1) < argc))
404         {
405            threads_nr = strtol(argv[n+1], NULL, 0);
406            threads_nr = (threads_nr < 1) ? 1 : threads_nr;
407         }
408         else if ((strcmp(argv[n], "-FROZEN") == 0) && (n+1 < argc))
409         {
410            frozen_cycles = strtol(argv[n+1], NULL, 0);
411         }
412         else if ((strcmp(argv[n], "-PERIOD") == 0) && (n+1 < argc))
413         {
414            debug_period = strtol(argv[n+1], NULL, 0);
415         }
416         else if ((strcmp(argv[n], "-FAULTY_ROUTER") == 0) && (n+3 < argc) )
417         {
418            size_t t = strtol(argv[n+1], NULL, 0);
419            size_t x = strtol(argv[n+2], NULL, 0);
420            size_t y = strtol(argv[n+3], NULL, 0);
421            n+=2;
422            if( (t > 4) )
423            {
424                std::cout << "FAULTY_ROUTER NoC index is too big (index > 4)" << std::endl;
425                exit(0);
426            }
427            if( (x>=X_SIZE) || (y>=Y_SIZE) )
428            {
429                std::cout << "FAULTY_ROUTER parameter doesn't fit X_SIZE/Y_SIZE" << std::endl;
430                exit(0);
431            }
432            faulty_routers.push_back((t << (X_WIDTH + Y_WIDTH)) |
433                                     (x << (Y_WIDTH)) |
434                                     (y));
435         }
436         else if ((strcmp(argv[n], "-FAULTY_MASK") == 0) && (n+1 < argc) )
437         {
438            faulty_mask = strtol(argv[n+1], NULL, 0);
439            if( faulty_mask > 0x1F )
440            {
441                std::cout << "FAULTY_MASK parameter max value is 0x1F" << std::endl;
442                exit(0);
443            }
444         }
445         else
446         {
447            std::cout << "   Arguments are (key, value) couples." << std::endl;
448            std::cout << "   The order is not important." << std::endl;
449            std::cout << "   Accepted arguments are :" << std::endl << std::endl;
450            std::cout << "     -SOFT pathname_for_embedded_soft" << std::endl;
451            std::cout << "     -DSOFT pathname_for_distributed_embedded_soft" << std::endl;
452            std::cout << "     -DISK pathname_for_disk_image" << std::endl;
453            std::cout << "     -NCYCLES number_of_simulated_cycles" << std::endl;
454            std::cout << "     -DEBUG debug_start_cycle" << std::endl;
455            std::cout << "     -THREADS simulator's threads number" << std::endl;
456            std::cout << "     -FROZEN max_number_of_lines" << std::endl;
457            std::cout << "     -PERIOD number_of_cycles between trace" << std::endl;
458            std::cout << "     -MEMCID index_memc_to_be_traced" << std::endl;
459            std::cout << "     -XRAMID index_xram_to_be_traced" << std::endl;
460            std::cout << "     -PROCID index_proc_to_be_traced" << std::endl;
461            std::cout << "     -IOB    non_zero_value" << std::endl;
462            exit(0);
463         }
464      }
465   }
466
467   // Activate Distributed Boot (set by environment variable)
468   // When this is activated, every processor boots with its instruction and data
469   // physical address extension register initialized to its cluster index
470   // (X_LOCAL, Y_LOCAL). To support this feature, a distributed ROM is
471   // implemented in each cluster.
472
473   const bool distributed_boot = (getenv("DISTRIBUTED_BOOT") != NULL);
474
475   // checking hardware parameters
476   assert( (X_SIZE <= (1 << X_WIDTH)) and
477           "The X_SIZE parameter cannot be larger than 16" );
478
479   assert( (Y_SIZE <= (1 << Y_WIDTH)) and
480           "The Y_SIZE parameter cannot be larger than 16" );
481
482   assert( (NB_PROCS_MAX <= (1 << P_WIDTH)) and
483           "NB_PROCS_MAX parameter cannot be larger than 2^P_WIDTH" );
484
485   assert( (NB_DMA_CHANNELS <= 4) and
486           "The NB_DMA_CHANNELS parameter cannot be larger than 4" );
487
488   assert( (NB_TTY_CHANNELS >= 1) and (NB_TTY_CHANNELS <= 16) and
489           "The NB_TTY_CHANNELS parameter cannot be larger than 16" );
490
491#if USE_NIC
492   assert( (NB_NIC_CHANNELS == 2) and
493           "The NB_NIC_CHANNELS parameter must be 2" );
494#endif
495
496   std::cout << std::endl << std::dec
497             << " - X_SIZE          = " << X_SIZE << std::endl
498             << " - Y_SIZE          = " << Y_SIZE << std::endl
499             << " - NB_PROCS_MAX    = " << NB_PROCS_MAX <<  std::endl
500             << " - NB_TTY_CHANNELS = " << NB_TTY_CHANNELS <<  std::endl
501             << " - NB_DMA_CHANNELS = " << NB_DMA_CHANNELS <<  std::endl
502             << " - NB_NIC_CHANNELS = " << NB_NIC_CHANNELS <<  std::endl
503             << " - MEMC_WAYS       = " << MEMC_WAYS << std::endl
504             << " - MEMC_SETS       = " << MEMC_SETS << std::endl
505             << " - RAM_LATENCY     = " << XRAM_LATENCY << std::endl
506             << " - MAX_FROZEN      = " << frozen_cycles << std::endl
507             << " - DIST_BOOT       = " << distributed_boot << std::endl
508             << " - DEBUG_PROCID    = " << debug_proc_id << std::endl
509             << " - DEBUG_MEMCID    = " << debug_memc_id << std::endl
510             << " - DEBUG_XRAMID    = " << debug_xram_id << std::endl;
511
512   std::cout << std::endl;
513
514#if USE_OPENMP
515   omp_set_dynamic(false);
516   omp_set_num_threads(threads_nr);
517   std::cerr << "Built with openmp version " << _OPENMP
518             << " / numthreads = " << threads_nr << std::endl;
519#endif
520
521   // Define VciParams objects
522   typedef soclib::caba::VciParams<vci_cell_width_int,
523                                   vci_plen_width,
524                                   vci_address_width,
525                                   vci_rerror_width,
526                                   vci_clen_width,
527                                   vci_rflag_width,
528                                   vci_srcid_width,
529                                   vci_pktid_width,
530                                   vci_trdid_width,
531                                   vci_wrplen_width> vci_param_int;
532
533   typedef soclib::caba::VciParams<vci_cell_width_ext,
534                                   vci_plen_width,
535                                   vci_address_width,
536                                   vci_rerror_width,
537                                   vci_clen_width,
538                                   vci_rflag_width,
539                                   vci_srcid_width,
540                                   vci_pktid_width,
541                                   vci_trdid_width,
542                                   vci_wrplen_width> vci_param_ext;
543
544   const size_t cluster_iob0 = cluster(0, 0);               // cluster containing IOB0
545   const size_t cluster_iob1 = cluster(X_SIZE-1, Y_SIZE-1); // cluster containing IOB1
546
547   /////////////////////////////////////////////////////////////////////
548   // INT network mapping table
549   // - two levels address decoding for commands
550   // - two levels srcid decoding for responses
551   // - NB_PROCS_MAX + 2 (MDMA, IOBX) local initiators per cluster
552   // - 4 local targets (MEMC, XICU, MDMA, IOBX) per cluster
553   /////////////////////////////////////////////////////////////////////
554   MappingTable maptab_int( vci_address_width,
555                            IntTab(X_WIDTH + Y_WIDTH, 16 - X_WIDTH - Y_WIDTH),
556                            IntTab(X_WIDTH + Y_WIDTH, vci_srcid_width - X_WIDTH - Y_WIDTH),
557                            0x00FF000000);
558
559   for (size_t x = 0; x < X_SIZE; x++)
560   {
561      for (size_t y = 0; y < Y_SIZE; y++)
562      {
563         uint64_t offset = ((uint64_t)cluster(x, y))
564                              << (vci_address_width-X_WIDTH-Y_WIDTH);
565         bool config    = true;
566         bool cacheable = true;
567
568         // the four following segments are defined in all clusters
569
570         std::ostringstream    smemc_conf;
571         smemc_conf << "int_seg_memc_conf_" << x << "_" << y;
572         maptab_int.add(Segment(smemc_conf.str(), SEG_MMC_BASE+offset, SEG_MMC_SIZE,
573                     IntTab(cluster(x, y), INT_MEMC_TGT_ID), not cacheable, config ));
574
575         std::ostringstream    smemc_xram;
576         smemc_xram << "int_seg_memc_xram_" << x << "_" << y;
577         maptab_int.add(Segment(smemc_xram.str(), SEG_RAM_BASE+offset, SEG_RAM_SIZE,
578                     IntTab(cluster(x, y), INT_MEMC_TGT_ID), cacheable));
579
580         std::ostringstream    sxicu;
581         sxicu << "int_seg_xicu_" << x << "_" << y;
582         maptab_int.add(Segment(sxicu.str(), SEG_XCU_BASE+offset, SEG_XCU_SIZE,
583                     IntTab(cluster(x, y), INT_XICU_TGT_ID), not cacheable));
584
585         std::ostringstream    smdma;
586         smdma << "int_seg_mdma_" << x << "_" << y;
587         maptab_int.add(Segment(smdma.str(), SEG_DMA_BASE+offset, SEG_DMA_SIZE,
588                     IntTab(cluster(x, y), INT_MDMA_TGT_ID), not cacheable));
589
590         std::ostringstream    sdrom;
591         sdrom << "int_seg_drom_" << x << "_" << y;
592         maptab_int.add(Segment(sdrom.str(), SEG_DROM_BASE+offset, SEG_DROM_SIZE,
593                     IntTab(cluster(x, y), INT_DROM_TGT_ID), cacheable));
594
595         // the following segments are only defined in cluster_iob0 or in cluster_iob1
596
597         if ( (cluster(x, y) == cluster_iob0) or (cluster(x, y) == cluster_iob1) )
598         {
599            std::ostringstream    siobx;
600            siobx << "int_seg_iobx_" << x << "_" << y;
601            maptab_int.add(Segment(siobx.str(), SEG_IOB_BASE+offset, SEG_IOB_SIZE,
602                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable, config ));
603
604            std::ostringstream    stty;
605            stty << "int_seg_mtty_" << x << "_" << y;
606            maptab_int.add(Segment(stty.str(), SEG_TTY_BASE+offset, SEG_TTY_SIZE,
607                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
608
609            std::ostringstream    sfbf;
610            sfbf << "int_seg_fbuf_" << x << "_" << y;
611            maptab_int.add(Segment(sfbf.str(), SEG_FBF_BASE+offset, SEG_FBF_SIZE,
612                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
613
614            std::ostringstream    sbdv;
615            sbdv << "int_seg_bdev_" << x << "_" << y;
616            maptab_int.add(Segment(sbdv.str(), SEG_IOC_BASE+offset, SEG_IOC_SIZE,
617                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
618
619            std::ostringstream    snic;
620            snic << "int_seg_mnic_" << x << "_" << y;
621            maptab_int.add(Segment(snic.str(), SEG_NIC_BASE+offset, SEG_NIC_SIZE,
622                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
623
624            std::ostringstream    sdma;
625            sdma << "int_seg_cdma_" << x << "_" << y;
626            maptab_int.add(Segment(sdma.str(), SEG_CMA_BASE+offset, SEG_CMA_SIZE,
627                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
628
629            std::ostringstream    spic;
630            spic << "int_seg_iopi_" << x << "_" << y;
631            maptab_int.add(Segment(spic.str(), SEG_PIC_BASE+offset, SEG_PIC_SIZE,
632                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
633
634            std::ostringstream    ssim;
635            ssim << "int_seg_simh_" << x << "_" << y;
636            maptab_int.add(Segment(ssim.str(), SEG_SIM_BASE+offset, SEG_SIM_SIZE,
637                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), not cacheable));
638
639            std::ostringstream    srom;
640            srom << "int_seg_rom_" << x << "_" << y;
641            maptab_int.add(Segment(srom.str(), SEG_ROM_BASE+offset, SEG_ROM_SIZE,
642                        IntTab(cluster(x, y), INT_IOBX_TGT_ID), cacheable));
643         }
644
645         // This define the mapping between the SRCIDs
646         // and the port index on the local interconnect.
647
648         maptab_int.srcid_map( IntTab( cluster(x, y), MDMA_LOCAL_SRCID ),
649                               IntTab( cluster(x, y), INT_MDMA_INI_ID ) );
650
651         maptab_int.srcid_map( IntTab( cluster(x, y), IOBX_LOCAL_SRCID ),
652                               IntTab( cluster(x, y), INT_IOBX_INI_ID ) );
653
654         maptab_int.srcid_map( IntTab( cluster(x, y), IOPI_LOCAL_SRCID ),
655                               IntTab( cluster(x, y), INT_IOBX_INI_ID ) );
656
657         for ( size_t p = 0 ; p < NB_PROCS_MAX ; p++ )
658         maptab_int.srcid_map( IntTab( cluster(x, y), PROC_LOCAL_SRCID+p ),
659                               IntTab( cluster(x, y), INT_PROC_INI_ID+p ) );
660      }
661   }
662   std::cout << "INT network " << maptab_int << std::endl;
663
664    /////////////////////////////////////////////////////////////////////////
665    // RAM network mapping table
666    // - two levels address decoding for commands
667    // - two levels srcid decoding for responses
668    // - 2 local initiators (MEMC, IOBX) per cluster
669    //   (IOBX component only in cluster_iob0 and cluster_iob1)
670    // - 1 local target (XRAM) per cluster
671    ////////////////////////////////////////////////////////////////////////
672    MappingTable maptab_ram( vci_address_width,
673                             IntTab(X_WIDTH+Y_WIDTH, 0),
674                             IntTab(X_WIDTH+Y_WIDTH, vci_srcid_width - X_WIDTH - Y_WIDTH),
675                             0x00FF000000);
676
677    for (size_t x = 0; x < X_SIZE; x++)
678    {
679        for (size_t y = 0; y < Y_SIZE ; y++)
680        {
681            uint64_t offset = ((uint64_t)cluster(x, y))
682                                << (vci_address_width-X_WIDTH-Y_WIDTH);
683
684            std::ostringstream sxram;
685            sxram << "ext_seg_xram_" << x << "_" << y;
686            maptab_ram.add(Segment(sxram.str(), SEG_RAM_BASE+offset,
687                           SEG_RAM_SIZE, IntTab(cluster(x, y), RAM_XRAM_TGT_ID), false));
688        }
689    }
690
691    // This define the mapping between the initiators SRCID
692    // and the port index on the RAM local interconnect.
693    // External initiator have two alias SRCID (iob0 / iob1)
694
695    maptab_ram.srcid_map( IntTab( cluster_iob0, CDMA_LOCAL_SRCID ),
696                          IntTab( cluster_iob0, RAM_IOBX_INI_ID ) );
697
698    maptab_ram.srcid_map( IntTab( cluster_iob1, CDMA_LOCAL_SRCID ),
699                          IntTab( cluster_iob1, RAM_IOBX_INI_ID ) );
700
701    maptab_ram.srcid_map( IntTab( cluster_iob0, BDEV_LOCAL_SRCID ),
702                          IntTab( cluster_iob0, RAM_IOBX_INI_ID ) );
703
704    maptab_ram.srcid_map( IntTab( cluster_iob1, BDEV_LOCAL_SRCID ),
705                          IntTab( cluster_iob1, RAM_IOBX_INI_ID ) );
706
707    maptab_ram.srcid_map( IntTab( cluster_iob0, IOPI_LOCAL_SRCID ),
708                          IntTab( cluster_iob0, RAM_IOBX_INI_ID ) );
709
710    maptab_ram.srcid_map( IntTab( cluster_iob1, IOPI_LOCAL_SRCID ),
711                          IntTab( cluster_iob1, RAM_IOBX_INI_ID ) );
712
713    maptab_ram.srcid_map( IntTab( cluster_iob0, MEMC_LOCAL_SRCID ),
714                          IntTab( cluster_iob0, RAM_MEMC_INI_ID ) );
715
716    maptab_ram.srcid_map( IntTab( cluster_iob1, MEMC_LOCAL_SRCID ),
717                          IntTab( cluster_iob1, RAM_MEMC_INI_ID ) );
718
719    std::cout << "RAM network " << maptab_ram << std::endl;
720
721    ///////////////////////////////////////////////////////////////////////
722    // IOX network mapping table
723    // - two levels address decoding for commands (9, 7) bits
724    // - two levels srcid decoding for responses
725    // - 5 initiators (IOB0, IOB1, BDEV, CDMA, IOPI)
726    // - 9 targets (IOB0, IOB1, BDEV, CDMA, MTTY, FBUF, ROM, MNIC, IOPI)
727    //
728    // Address bit 32 is used to determine if a command must be routed to
729    // IOB0 or IOB1.
730    ///////////////////////////////////////////////////////////////////////
731    MappingTable maptab_iox(
732          vci_address_width,
733          IntTab(X_WIDTH + Y_WIDTH - 1, 16 - X_WIDTH - Y_WIDTH + 1),
734          IntTab(X_WIDTH + Y_WIDTH    , vci_param_ext::S - X_WIDTH - Y_WIDTH),
735          0x00FF000000);
736
737    // External peripherals segments
738    // When there is more than one cluster, external peripherals can be accessed
739    // through two segments, depending on the used IOB (IOB0 or IOB1).
740
741    const uint64_t iob0_base = ((uint64_t)cluster_iob0)
742       << (vci_address_width - X_WIDTH - Y_WIDTH);
743
744    maptab_iox.add(Segment("iox_seg_mtty_0", SEG_TTY_BASE + iob0_base, SEG_TTY_SIZE,
745                   IntTab(0, IOX_MTTY_TGT_ID), false));
746    maptab_iox.add(Segment("iox_seg_fbuf_0", SEG_FBF_BASE + iob0_base, SEG_FBF_SIZE,
747                   IntTab(0, IOX_FBUF_TGT_ID), false));
748    maptab_iox.add(Segment("iox_seg_bdev_0", SEG_IOC_BASE + iob0_base, SEG_IOC_SIZE,
749                   IntTab(0, IOX_BDEV_TGT_ID), false));
750    maptab_iox.add(Segment("iox_seg_mnic_0", SEG_NIC_BASE + iob0_base, SEG_NIC_SIZE,
751                   IntTab(0, IOX_MNIC_TGT_ID), false));
752    maptab_iox.add(Segment("iox_seg_cdma_0", SEG_CMA_BASE + iob0_base, SEG_CMA_SIZE,
753                   IntTab(0, IOX_CDMA_TGT_ID), false));
754    maptab_iox.add(Segment("iox_seg_iopi_0", SEG_PIC_BASE + iob0_base, SEG_PIC_SIZE,
755                   IntTab(0, IOX_IOPI_TGT_ID), false));
756    maptab_iox.add(Segment("iox_seg_simh_0", SEG_SIM_BASE + iob0_base, SEG_SIM_SIZE,
757                   IntTab(0, IOX_SIMH_TGT_ID), false));
758    maptab_iox.add(Segment("iox_seg_rom_0", SEG_ROM_BASE + iob0_base, SEG_ROM_SIZE,
759                   IntTab(0, IOX_ROM_TGT_ID), false));
760
761    if ( cluster_iob0 != cluster_iob1 )
762    {
763       const uint64_t iob1_base = ((uint64_t)cluster_iob1)
764          << (vci_address_width - X_WIDTH - Y_WIDTH);
765
766        maptab_iox.add(Segment("iox_seg_mtty_1", SEG_TTY_BASE + iob1_base, SEG_TTY_SIZE,
767                   IntTab(0, IOX_MTTY_TGT_ID), false));
768        maptab_iox.add(Segment("iox_seg_fbuf_1", SEG_FBF_BASE + iob1_base, SEG_FBF_SIZE,
769                   IntTab(0, IOX_FBUF_TGT_ID), false));
770        maptab_iox.add(Segment("iox_seg_bdev_1", SEG_IOC_BASE + iob1_base, SEG_IOC_SIZE,
771                   IntTab(0, IOX_BDEV_TGT_ID), false));
772        maptab_iox.add(Segment("iox_seg_mnic_1", SEG_NIC_BASE + iob1_base, SEG_NIC_SIZE,
773                   IntTab(0, IOX_MNIC_TGT_ID), false));
774        maptab_iox.add(Segment("iox_seg_cdma_1", SEG_CMA_BASE + iob1_base, SEG_CMA_SIZE,
775                   IntTab(0, IOX_CDMA_TGT_ID), false));
776        maptab_iox.add(Segment("iox_seg_iopi_1", SEG_PIC_BASE + iob1_base, SEG_PIC_SIZE,
777                   IntTab(0, IOX_IOPI_TGT_ID), false));
778        maptab_iox.add(Segment("iox_seg_simh_1", SEG_SIM_BASE + iob1_base, SEG_SIM_SIZE,
779                   IntTab(0, IOX_SIMH_TGT_ID), false));
780        maptab_iox.add(Segment("iox_seg_rom_1", SEG_ROM_BASE + iob1_base, SEG_ROM_SIZE,
781                   IntTab(0, IOX_ROM_TGT_ID), false));
782    }
783
784    // If there is more than one cluster, external peripherals
785    // can access RAM through two segments (IOB0 / IOB1).
786    // As IOMMU is not activated, addresses are 40 bits (physical addresses),
787    // and the choice depends on address bit A[32].
788    for (size_t x = 0; x < X_SIZE; x++)
789    {
790        for (size_t y = 0; y < Y_SIZE ; y++)
791        {
792            const bool wti       = true;
793            const bool cacheable = true;
794
795            const uint64_t offset = ((uint64_t)cluster(x, y))
796                << (vci_address_width-X_WIDTH-Y_WIDTH);
797
798            const uint64_t xicu_base = SEG_XCU_BASE + offset;
799
800            if ( (y & 0x1) == 0 ) // use IOB0
801            {
802                std::ostringstream sxcu0;
803                sxcu0 << "iox_seg_xcu0_" << x << "_" << y;
804                maptab_iox.add(Segment(sxcu0.str(), xicu_base, SEG_XCU_SIZE,
805                            IntTab(0, IOX_IOB0_TGT_ID), not cacheable, wti));
806
807                std::ostringstream siob0;
808                siob0 << "iox_seg_ram0_" << x << "_" << y;
809                maptab_iox.add(Segment(siob0.str(), offset, SEG_XCU_BASE,
810                            IntTab(0, IOX_IOB0_TGT_ID), not cacheable, not wti));
811            }
812            else                  // USE IOB1
813            {
814                std::ostringstream sxcu1;
815                sxcu1 << "iox_seg_xcu1_" << x << "_" << y;
816                maptab_iox.add(Segment(sxcu1.str(), xicu_base, SEG_XCU_SIZE,
817                            IntTab(0, IOX_IOB1_TGT_ID), not cacheable, wti));
818
819                std::ostringstream siob1;
820                siob1 << "iox_seg_ram1_" << x << "_" << y;
821                maptab_iox.add(Segment(siob1.str(), offset, SEG_XCU_BASE,
822                            IntTab(0, IOX_IOB1_TGT_ID), not cacheable, not wti));
823            }
824        }
825    }
826
827    // This define the mapping between the external initiators (SRCID)
828    // and the port index on the IOX local interconnect.
829
830    maptab_iox.srcid_map( IntTab( 0, CDMA_LOCAL_SRCID ) ,
831                          IntTab( 0, IOX_CDMA_INI_ID  ) );
832    maptab_iox.srcid_map( IntTab( 0, BDEV_LOCAL_SRCID ) ,
833                          IntTab( 0, IOX_BDEV_INI_ID  ) );
834    maptab_iox.srcid_map( IntTab( 0, IOPI_LOCAL_SRCID ) ,
835                          IntTab( 0, IOX_IOPI_INI_ID  ) );
836    maptab_iox.srcid_map( IntTab( 0, IOX_IOB0_INI_ID  ) ,
837                          IntTab( 0, IOX_IOB0_INI_ID  ) );
838
839    if ( cluster_iob0 != cluster_iob1 )
840    {
841        maptab_iox.srcid_map( IntTab( 0, IOX_IOB1_INI_ID ) ,
842                              IntTab( 0, IOX_IOB1_INI_ID ) );
843    }
844
845    std::cout << "IOX network " << maptab_iox << std::endl;
846
847    ////////////////////
848    // Signals
849    ///////////////////
850
851    sc_clock                          signal_clk("clk");
852    sc_signal<bool>                   signal_resetn("resetn");
853
854    sc_signal<bool>                   signal_false;
855
856    sc_signal<bool>                   signal_irq_bdev;
857    sc_signal<bool>                   signal_irq_mtty_rx[NB_TTY_CHANNELS];
858    sc_signal<bool>                   signal_irq_mnic_rx[NB_NIC_CHANNELS];
859    sc_signal<bool>                   signal_irq_mnic_tx[NB_NIC_CHANNELS];
860    sc_signal<bool>                   signal_irq_cdma[NB_CMA_CHANNELS];
861
862    // VCI signals for IOX network
863    VciSignals<vci_param_ext>         signal_vci_ini_iob0("signal_vci_ini_iob0");
864    VciSignals<vci_param_ext>         signal_vci_ini_iob1("signal_vci_ini_iob1");
865    VciSignals<vci_param_ext>         signal_vci_ini_bdev("signal_vci_ini_bdev");
866    VciSignals<vci_param_ext>         signal_vci_ini_cdma("signal_vci_ini_cdma");
867    VciSignals<vci_param_ext>         signal_vci_ini_iopi("signal_vci_ini_iopi");
868
869    VciSignals<vci_param_ext>         signal_vci_tgt_iob0("signal_vci_tgt_iob0");
870    VciSignals<vci_param_ext>         signal_vci_tgt_iob1("signal_vci_tgt_iob1");
871    VciSignals<vci_param_ext>         signal_vci_tgt_mtty("signal_vci_tgt_mtty");
872    VciSignals<vci_param_ext>         signal_vci_tgt_fbuf("signal_vci_tgt_fbuf");
873    VciSignals<vci_param_ext>         signal_vci_tgt_mnic("signal_vci_tgt_mnic");
874    VciSignals<vci_param_ext>         signal_vci_tgt_bdev("signal_vci_tgt_bdev");
875    VciSignals<vci_param_ext>         signal_vci_tgt_cdma("signal_vci_tgt_cdma");
876    VciSignals<vci_param_ext>         signal_vci_tgt_iopi("signal_vci_tgt_iopi");
877    VciSignals<vci_param_ext>         signal_vci_tgt_simh("signal_vci_tgt_simh");
878    VciSignals<vci_param_ext>         signal_vci_tgt_rom("signal_vci_tgt_rom");
879
880   // Horizontal inter-clusters INT network DSPIN
881   DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_h_inc =
882      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_inc", X_SIZE-1, Y_SIZE, 3);
883   DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_h_dec =
884      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_dec", X_SIZE-1, Y_SIZE, 3);
885   DspinSignals<dspin_int_rsp_width>*** signal_dspin_int_rsp_h_inc =
886      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_h_inc", X_SIZE-1, Y_SIZE, 2);
887   DspinSignals<dspin_int_rsp_width>*** signal_dspin_int_rsp_h_dec =
888      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_h_dec", X_SIZE-1, Y_SIZE, 2);
889
890   // Vertical inter-clusters INT network DSPIN
891   DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_v_inc =
892      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_v_inc", X_SIZE, Y_SIZE-1, 3);
893   DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_v_dec =
894      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_v_dec", X_SIZE, Y_SIZE-1, 3);
895   DspinSignals<dspin_int_rsp_width>*** signal_dspin_int_rsp_v_inc =
896      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_v_inc", X_SIZE, Y_SIZE-1, 2);
897   DspinSignals<dspin_int_rsp_width>*** signal_dspin_int_rsp_v_dec =
898      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_v_dec", X_SIZE, Y_SIZE-1, 2);
899
900   // Mesh boundaries INT network DSPIN
901   DspinSignals<dspin_int_cmd_width>**** signal_dspin_false_int_cmd_in =
902      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_in", X_SIZE, Y_SIZE, 4, 3);
903   DspinSignals<dspin_int_cmd_width>**** signal_dspin_false_int_cmd_out =
904      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_out", X_SIZE, Y_SIZE, 4, 3);
905   DspinSignals<dspin_int_rsp_width>**** signal_dspin_false_int_rsp_in =
906      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_false_int_rsp_in", X_SIZE, Y_SIZE, 4, 2);
907   DspinSignals<dspin_int_rsp_width>**** signal_dspin_false_int_rsp_out =
908      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_false_int_rsp_out", X_SIZE, Y_SIZE, 4, 2);
909
910
911   // Horizontal inter-clusters RAM network DSPIN
912   DspinSignals<dspin_ram_cmd_width>** signal_dspin_ram_cmd_h_inc =
913      alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_ram_cmd_h_inc", X_SIZE-1, Y_SIZE);
914   DspinSignals<dspin_ram_cmd_width>** signal_dspin_ram_cmd_h_dec =
915      alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_ram_cmd_h_dec", X_SIZE-1, Y_SIZE);
916   DspinSignals<dspin_ram_rsp_width>** signal_dspin_ram_rsp_h_inc =
917      alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_ram_rsp_h_inc", X_SIZE-1, Y_SIZE);
918   DspinSignals<dspin_ram_rsp_width>** signal_dspin_ram_rsp_h_dec =
919      alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_ram_rsp_h_dec", X_SIZE-1, Y_SIZE);
920
921   // Vertical inter-clusters RAM network DSPIN
922   DspinSignals<dspin_ram_cmd_width>** signal_dspin_ram_cmd_v_inc =
923      alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_ram_cmd_v_inc", X_SIZE, Y_SIZE-1);
924   DspinSignals<dspin_ram_cmd_width>** signal_dspin_ram_cmd_v_dec =
925      alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_ram_cmd_v_dec", X_SIZE, Y_SIZE-1);
926   DspinSignals<dspin_ram_rsp_width>** signal_dspin_ram_rsp_v_inc =
927      alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_ram_rsp_v_inc", X_SIZE, Y_SIZE-1);
928   DspinSignals<dspin_ram_rsp_width>** signal_dspin_ram_rsp_v_dec =
929      alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_ram_rsp_v_dec", X_SIZE, Y_SIZE-1);
930
931   // Mesh boundaries RAM network DSPIN
932   DspinSignals<dspin_ram_cmd_width>*** signal_dspin_false_ram_cmd_in =
933      alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_false_ram_cmd_in", X_SIZE, Y_SIZE, 4);
934   DspinSignals<dspin_ram_cmd_width>*** signal_dspin_false_ram_cmd_out =
935      alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_false_ram_cmd_out", X_SIZE, Y_SIZE, 4);
936   DspinSignals<dspin_ram_rsp_width>*** signal_dspin_false_ram_rsp_in =
937      alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_false_ram_rsp_in", X_SIZE, Y_SIZE, 4);
938   DspinSignals<dspin_ram_rsp_width>*** signal_dspin_false_ram_rsp_out =
939      alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_false_ram_rsp_out", X_SIZE, Y_SIZE, 4);
940
941   ////////////////////////////
942   //      Loader
943   ////////////////////////////
944   soclib::common::Loader *loader;
945
946#if USE_ALMOS
947   loader = new soclib::common::Loader (almos_bootloader_pathname,
948                                        almos_archinfo_pathname,
949                                        almos_kernel_pathname);
950#else
951   if (strcmp(soft_name, "") == 0)
952   {
953      loader = new soclib::common::Loader (dsoft_name);
954   }
955   else
956   {
957      loader = new soclib::common::Loader (soft_name, dsoft_name);
958   }
959#endif
960
961   // initialize memory with a value different than 0 (expose software errors
962   // dues to uninitialized data)
963   loader->memory_default(0xA0);
964
965   typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;
966   proc_iss::set_loader(loader);
967
968   ////////////////////////////////////////
969   //  Instanciated Hardware Components
970   ////////////////////////////////////////
971
972   std::cout << std::endl << "External Bus and Peripherals" << std::endl << std::endl;
973
974   const size_t nb_iox_initiators = (cluster_iob0 != cluster_iob1) ? 5 : 4;
975   const size_t nb_iox_targets = (cluster_iob0 != cluster_iob1) ? 10 : 9;
976
977   // IOX network
978   VciIoxNetwork<vci_param_ext>* iox_network;
979   iox_network = new VciIoxNetwork<vci_param_ext>( "iox_network",
980                                                   maptab_iox,
981                                                   nb_iox_targets,
982                                                   nb_iox_initiators );
983
984   // Network Controller
985#if USE_NIC
986   VciMultiNic<vci_param_ext>*  mnic;
987   int nicMode = VciMultiNic<vci_param_ext>::NIC_MODE_SYNTHESIS;
988   mnic = new VciMultiNic<vci_param_ext>( "mnic",
989                                          IntTab(0, IOX_MNIC_TGT_ID),
990                                          maptab_iox,
991                                          NB_NIC_CHANNELS,
992                                          0,                // mac_4 address
993                                          0,                // mac_2 address
994                                          nicMode );
995
996   // Chained Buffer DMA controller
997   VciChbufDma<vci_param_ext>*  cdma;
998   cdma = new VciChbufDma<vci_param_ext>( "cdma",
999                                          maptab_iox,
1000                                          IntTab(0, CDMA_LOCAL_SRCID),
1001                                          IntTab(0, IOX_CDMA_TGT_ID),
1002                                          64,          // burst size (bytes)
1003                                          2*NB_NIC_CHANNELS );
1004#else
1005   VciTargetError<vci_param_ext> merror_nic( "merror_nic",
1006                                             IntTab(0, IOX_MNIC_TGT_ID),
1007                                             maptab_iox );
1008
1009   VciTargetError<vci_param_ext> merror_dma( "merror_dma",
1010                                             IntTab(0, IOX_CDMA_TGT_ID),
1011                                             maptab_iox );
1012#endif
1013
1014   // Frame Buffer
1015   VciFrameBuffer<vci_param_ext>*  fbuf;
1016   fbuf = new VciFrameBuffer<vci_param_ext>( "fbuf",
1017                                             IntTab(0, IOX_FBUF_TGT_ID),
1018                                             maptab_iox,
1019                                             FBUF_X_SIZE, FBUF_Y_SIZE );
1020
1021   // Block Device
1022   // for AHCI
1023   // std::vector<std::string> filenames;
1024   // filenames.push_back(disk_name);            // one single disk
1025   VciBlockDeviceTsar<vci_param_ext>*  bdev;
1026   bdev = new VciBlockDeviceTsar<vci_param_ext>( "bdev",
1027                                                  maptab_iox,
1028                                                  IntTab(0, BDEV_LOCAL_SRCID),
1029                                                  IntTab(0, IOX_BDEV_TGT_ID),
1030                                                  disk_name,
1031                                                  512,        // block size
1032                                                  64,         // burst size (bytes)
1033                                                  0 );        // disk latency
1034
1035   // Multi-TTY controller
1036   std::vector<std::string> vect_names;
1037   for( size_t tid = 0 ; tid < NB_TTY_CHANNELS ; tid++ )
1038   {
1039      std::ostringstream term_name;
1040      term_name <<  "term" << tid;
1041      vect_names.push_back(term_name.str().c_str());
1042   }
1043   VciMultiTty<vci_param_ext>*  mtty;
1044   mtty = new VciMultiTty<vci_param_ext>( "mtty",
1045         IntTab(0, IOX_MTTY_TGT_ID),
1046         maptab_iox,
1047         vect_names);
1048
1049   // IOPIC
1050   VciIopic<vci_param_ext>* iopi;
1051   iopi = new VciIopic<vci_param_ext>( "iopi",
1052                                       maptab_iox,
1053                                       IntTab(0, IOPI_LOCAL_SRCID),
1054                                       IntTab(0, IOX_IOPI_TGT_ID),
1055                                       32 );        // number of input HWI
1056
1057   // Simhelper
1058   VciSimhelper<vci_param_ext>* simh;
1059   simh = new VciSimhelper<vci_param_ext>("simh",
1060                                          IntTab(0, IOX_SIMH_TGT_ID),
1061                                          maptab_iox );
1062
1063   // External ROM
1064   VciSimpleRom<vci_param_ext>* rom;
1065   rom = new VciSimpleRom<vci_param_ext>("rom",
1066                                          IntTab(0, IOX_ROM_TGT_ID),
1067                                          maptab_iox,
1068                                          *loader,
1069                                          X_WIDTH + Y_WIDTH );
1070
1071   // Clusters
1072   typedef TsarIobCluster<
1073      vci_param_int, vci_param_ext,
1074      dspin_int_cmd_width, dspin_int_rsp_width,
1075      dspin_ram_cmd_width, dspin_ram_rsp_width> TsarCluster;
1076
1077   TsarCluster* clusters[X_SIZE][Y_SIZE];
1078
1079#if USE_OPENMP
1080#pragma omp parallel
1081    {
1082#pragma omp for
1083#endif
1084        for(size_t i = 0; i  < (X_SIZE * Y_SIZE); i++)
1085        {
1086            size_t x = i / Y_SIZE;
1087            size_t y = i % Y_SIZE;
1088
1089#if USE_OPENMP
1090#pragma omp critical
1091            {
1092#endif
1093            std::cout << std::endl;
1094            std::cout << "Cluster_" << std::dec << x << "_" << y << std::endl;
1095            std::cout << std::endl;
1096
1097            const bool is_iob0 = (cluster(x, y) == cluster_iob0);
1098            const bool is_iob1 = (cluster(x, y) == cluster_iob1);
1099            const bool is_io_cluster = is_iob0 || is_iob1;
1100
1101            const int iox_iob_ini_id = is_iob0 ?
1102                IOX_IOB0_INI_ID :
1103                IOX_IOB1_INI_ID ;
1104            const int iox_iob_tgt_id = is_iob0 ?
1105                IOX_IOB0_TGT_ID :
1106                IOX_IOB1_TGT_ID ;
1107
1108            std::ostringstream sc;
1109            sc << "cluster_" << x << "_" << y;
1110            clusters[x][y] = new TsarCluster (
1111                sc.str().c_str(),
1112                NB_PROCS_MAX,
1113                NB_DMA_CHANNELS,
1114                x,
1115                y,
1116                X_SIZE,
1117                Y_SIZE,
1118
1119                P_WIDTH,
1120
1121                maptab_int,
1122                maptab_ram,
1123                maptab_iox,
1124
1125                X_WIDTH,
1126                Y_WIDTH,
1127                vci_srcid_width - X_WIDTH - Y_WIDTH,            // l_id width,
1128
1129                INT_MEMC_TGT_ID,
1130                INT_XICU_TGT_ID,
1131                INT_MDMA_TGT_ID,
1132                INT_DROM_TGT_ID,
1133                INT_IOBX_TGT_ID,
1134
1135                INT_PROC_INI_ID,
1136                INT_MDMA_INI_ID,
1137                INT_IOBX_INI_ID,
1138
1139                RAM_XRAM_TGT_ID,
1140
1141                RAM_MEMC_INI_ID,
1142                RAM_IOBX_INI_ID,
1143
1144                is_io_cluster,
1145                iox_iob_tgt_id,
1146                iox_iob_ini_id,
1147
1148                MEMC_WAYS,
1149                MEMC_SETS,
1150                L1_IWAYS,
1151                L1_ISETS,
1152                L1_DWAYS,
1153                L1_DSETS,
1154                XRAM_LATENCY,
1155                XCU_NB_HWI,
1156                XCU_NB_PTI,
1157                XCU_NB_WTI,
1158                XCU_NB_OUT,
1159                IRQ_PER_PROCESSOR,
1160
1161                distributed_boot,
1162
1163                *loader,
1164
1165                frozen_cycles,
1166                debug_from,
1167                debug_ok and (cluster(x, y) == debug_memc_id),
1168                debug_ok and (cluster(x, y) == (debug_proc_id >> P_WIDTH)),
1169                debug_ok and debug_iob
1170            );
1171
1172#if USE_OPENMP
1173            } // end critical
1174#endif
1175        } // end for
1176#if USE_OPENMP
1177    }
1178#endif
1179
1180    // disable all interfaces of the faulty CMD routers
1181    std::cout << "\n*** List of deactivated routers ***\n";
1182    for (std::vector<size_t>::iterator it = faulty_routers.begin();
1183         it != faulty_routers.end();
1184         ++it)
1185    {
1186       int ry = (*it) & ((1 << Y_WIDTH) - 1);
1187       int rx = (*it >> Y_WIDTH) & ((1 << X_WIDTH) - 1);
1188       int rt = (*it) >> (X_WIDTH + Y_WIDTH);
1189
1190       if (rt == 0)
1191       {
1192          std::cout << "Deactivate CMD router (" << rx << "," << ry << ")"
1193                    << std::endl;
1194          clusters[rx][ry]->int_router_cmd[0]->set_disable_mask(faulty_mask);
1195          continue;
1196       }
1197       if (rt == 1)
1198       {
1199          std::cout << "Deactivate RSP router (" << rx << "," << ry << ")"
1200                    << std::endl;
1201          clusters[rx][ry]->int_router_rsp[0]->set_disable_mask(faulty_mask);
1202          continue;
1203       }
1204       if (rt == 2)
1205       {
1206          std::cout << "Deactivate M2P router (" << rx << "," << ry << ")"
1207                    << std::endl;
1208          clusters[rx][ry]->int_router_cmd[1]->set_disable_mask(faulty_mask);
1209          continue;
1210       }
1211       if (rt == 3)
1212       {
1213          std::cout << "Deactivate P2M router (" << rx << "," << ry << ")"
1214                    << std::endl;
1215          clusters[rx][ry]->int_router_rsp[1]->set_disable_mask(faulty_mask);
1216          continue;
1217       }
1218       if (rt == 4)
1219       {
1220          std::cout << "Deactivate CLACK router (" << rx << "," << ry << ")"
1221                    << std::endl;
1222          clusters[rx][ry]->int_router_cmd[2]->set_disable_mask(faulty_mask);
1223          continue;
1224       }
1225    }
1226
1227    std::cout << std::endl;
1228
1229    //clusters[0][0]->xicu->set_faulty_wti(4, 0);
1230
1231    ///////////////////////////////////////////////////////////////////////////////
1232    //     Net-list
1233    ///////////////////////////////////////////////////////////////////////////////
1234
1235    // IOX network connexion
1236    iox_network->p_clk                                   (signal_clk);
1237    iox_network->p_resetn                                (signal_resetn);
1238    iox_network->p_to_ini[IOX_IOB0_INI_ID]               (signal_vci_ini_iob0);
1239    iox_network->p_to_ini[IOX_BDEV_INI_ID]               (signal_vci_ini_bdev);
1240    iox_network->p_to_ini[IOX_CDMA_INI_ID]               (signal_vci_ini_cdma);
1241    iox_network->p_to_ini[IOX_IOPI_INI_ID]               (signal_vci_ini_iopi);
1242
1243    iox_network->p_to_tgt[IOX_IOB0_TGT_ID]               (signal_vci_tgt_iob0);
1244    iox_network->p_to_tgt[IOX_MTTY_TGT_ID]               (signal_vci_tgt_mtty);
1245    iox_network->p_to_tgt[IOX_FBUF_TGT_ID]               (signal_vci_tgt_fbuf);
1246    iox_network->p_to_tgt[IOX_MNIC_TGT_ID]               (signal_vci_tgt_mnic);
1247    iox_network->p_to_tgt[IOX_BDEV_TGT_ID]               (signal_vci_tgt_bdev);
1248    iox_network->p_to_tgt[IOX_CDMA_TGT_ID]               (signal_vci_tgt_cdma);
1249    iox_network->p_to_tgt[IOX_IOPI_TGT_ID]               (signal_vci_tgt_iopi);
1250    iox_network->p_to_tgt[IOX_SIMH_TGT_ID]               (signal_vci_tgt_simh);
1251    iox_network->p_to_tgt[IOX_ROM_TGT_ID]                (signal_vci_tgt_rom);
1252
1253    if (cluster_iob0 != cluster_iob1)
1254    {
1255        iox_network->p_to_ini[IOX_IOB1_INI_ID]           (signal_vci_ini_iob1);
1256        iox_network->p_to_tgt[IOX_IOB1_TGT_ID]           (signal_vci_tgt_iob1);
1257    }
1258
1259    // BDEV connexion
1260    bdev->p_clk                                          (signal_clk);
1261    bdev->p_resetn                                       (signal_resetn);
1262    bdev->p_irq                                          (signal_irq_bdev);
1263    bdev->p_vci_target                                   (signal_vci_tgt_bdev);
1264    bdev->p_vci_initiator                                (signal_vci_ini_bdev);
1265
1266    std::cout << "  - BDEV connected" << std::endl;
1267
1268    // FBUF connexion
1269    fbuf->p_clk                                          (signal_clk);
1270    fbuf->p_resetn                                       (signal_resetn);
1271    fbuf->p_vci                                          (signal_vci_tgt_fbuf);
1272
1273    std::cout << "  - FBUF connected" << std::endl;
1274
1275#if USE_NIC
1276    // MNIC connexion
1277    mnic->p_clk                                          (signal_clk);
1278    mnic->p_resetn                                       (signal_resetn);
1279    mnic->p_vci                                          (signal_vci_tgt_mnic);
1280    for ( size_t i=0 ; i<NB_NIC_CHANNELS ; i++ )
1281    {
1282         mnic->p_rx_irq[i]                               (signal_irq_mnic_rx[i]);
1283         mnic->p_tx_irq[i]                               (signal_irq_mnic_tx[i]);
1284    }
1285    std::cout << "  - MNIC connected" << std::endl;
1286
1287    // CDMA connexion
1288    cdma->p_clk                                          (signal_clk);
1289    cdma->p_resetn                                       (signal_resetn);
1290    cdma->p_vci_target                                   (signal_vci_tgt_cdma);
1291    cdma->p_vci_initiator                                (signal_vci_ini_cdma);
1292    for ( size_t i=0 ; i<(NB_NIC_CHANNELS*2) ; i++)
1293    {
1294        cdma->p_irq[i]                                   (signal_irq_cdma[i]);
1295    }
1296    std::cout << "  - CDMA connected" << std::endl;
1297
1298#else
1299    merror_nic.p_clk                                     (signal_clk);
1300    merror_nic.p_resetn                                  (signal_resetn);
1301    merror_nic.p_vci                                     (signal_vci_tgt_mnic);
1302
1303    merror_dma.p_clk                                     (signal_clk);
1304    merror_dma.p_resetn                                  (signal_resetn);
1305    merror_dma.p_vci                                     (signal_vci_tgt_cdma);
1306#endif
1307
1308    // MTTY connexion
1309    mtty->p_clk                                          (signal_clk);
1310    mtty->p_resetn                                       (signal_resetn);
1311    mtty->p_vci                                          (signal_vci_tgt_mtty);
1312    for ( size_t i=0 ; i<NB_TTY_CHANNELS ; i++ )
1313    {
1314        mtty->p_irq[i]                                   (signal_irq_mtty_rx[i]);
1315    }
1316    std::cout << "  - MTTY connected" << std::endl;
1317
1318    // IOPI connexion
1319    iopi->p_clk                                          (signal_clk);
1320    iopi->p_resetn                                       (signal_resetn);
1321    iopi->p_vci_target                                   (signal_vci_tgt_iopi);
1322    iopi->p_vci_initiator                                (signal_vci_ini_iopi);
1323    for ( size_t i=0 ; i<32 ; i++)
1324    {
1325       if     (i < NB_NIC_CHANNELS)    iopi->p_hwi[i] (signal_irq_mnic_rx[i]);
1326       else if(i < 2 )                 iopi->p_hwi[i] (signal_false);
1327       else if(i < 2+NB_NIC_CHANNELS)  iopi->p_hwi[i] (signal_irq_mnic_tx[i-2]);
1328       else if(i < 4 )                 iopi->p_hwi[i] (signal_false);
1329       else if(i < 4+NB_CMA_CHANNELS)  iopi->p_hwi[i] (signal_irq_cdma[i-4]);
1330       else if(i < 8)                  iopi->p_hwi[i] (signal_false);
1331       else if(i < 9)                  iopi->p_hwi[i] (signal_irq_bdev);
1332       else if(i < 16)                 iopi->p_hwi[i] (signal_false);
1333       else if(i < 16+NB_TTY_CHANNELS) iopi->p_hwi[i] (signal_irq_mtty_rx[i-16]);
1334       else                            iopi->p_hwi[i] (signal_false);
1335    }
1336
1337    std::cout << "  - IOPIC connected" << std::endl;
1338
1339    // Simhelper connexion
1340    simh->p_clk(signal_clk);
1341    simh->p_resetn(signal_resetn);
1342    simh->p_vci(signal_vci_tgt_simh);
1343
1344    // External ROM connexion
1345    rom->p_clk(signal_clk);
1346    rom->p_resetn(signal_resetn);
1347    rom->p_vci(signal_vci_tgt_rom);
1348
1349    // IOB0 cluster connexion to IOX network
1350    (*clusters[0][0]->p_vci_iob_iox_ini) (signal_vci_ini_iob0);
1351    (*clusters[0][0]->p_vci_iob_iox_tgt) (signal_vci_tgt_iob0);
1352
1353    // IOB1 cluster connexion to IOX network
1354    // (only when there is more than 1 cluster)
1355    if ( cluster_iob0 != cluster_iob1 )
1356    {
1357        (*clusters[X_SIZE-1][Y_SIZE-1]->p_vci_iob_iox_ini) (signal_vci_ini_iob1);
1358        (*clusters[X_SIZE-1][Y_SIZE-1]->p_vci_iob_iox_tgt) (signal_vci_tgt_iob1);
1359    }
1360
1361    // All clusters Clock & RESET connexions
1362    for ( size_t x = 0; x < (X_SIZE); x++ )
1363    {
1364        for (size_t y = 0; y < Y_SIZE; y++)
1365        {
1366            clusters[x][y]->p_clk     (signal_clk);
1367            clusters[x][y]->p_resetn  (signal_resetn);
1368            clusters[x][y]->p_false   (signal_false);
1369        }
1370    }
1371
1372   // Inter Clusters horizontal connections
1373   if (X_SIZE > 1)
1374   {
1375      for (size_t x = 0; x < (X_SIZE-1); x++)
1376      {
1377         for (size_t y = 0; y < Y_SIZE; y++)
1378         {
1379            for (size_t k = 0; k < 3; k++)
1380            {
1381               clusters[x][y]->p_dspin_int_cmd_out[EAST][k]      (signal_dspin_int_cmd_h_inc[x][y][k]);
1382               clusters[x+1][y]->p_dspin_int_cmd_in[WEST][k]     (signal_dspin_int_cmd_h_inc[x][y][k]);
1383               clusters[x][y]->p_dspin_int_cmd_in[EAST][k]       (signal_dspin_int_cmd_h_dec[x][y][k]);
1384               clusters[x+1][y]->p_dspin_int_cmd_out[WEST][k]    (signal_dspin_int_cmd_h_dec[x][y][k]);
1385            }
1386
1387            for (size_t k = 0; k < 2; k++)
1388            {
1389               clusters[x][y]->p_dspin_int_rsp_out[EAST][k]      (signal_dspin_int_rsp_h_inc[x][y][k]);
1390               clusters[x+1][y]->p_dspin_int_rsp_in[WEST][k]     (signal_dspin_int_rsp_h_inc[x][y][k]);
1391               clusters[x][y]->p_dspin_int_rsp_in[EAST][k]       (signal_dspin_int_rsp_h_dec[x][y][k]);
1392               clusters[x+1][y]->p_dspin_int_rsp_out[WEST][k]    (signal_dspin_int_rsp_h_dec[x][y][k]);
1393            }
1394
1395            clusters[x][y]->p_dspin_ram_cmd_out[EAST]      (signal_dspin_ram_cmd_h_inc[x][y]);
1396            clusters[x+1][y]->p_dspin_ram_cmd_in[WEST]     (signal_dspin_ram_cmd_h_inc[x][y]);
1397            clusters[x][y]->p_dspin_ram_cmd_in[EAST]       (signal_dspin_ram_cmd_h_dec[x][y]);
1398            clusters[x+1][y]->p_dspin_ram_cmd_out[WEST]    (signal_dspin_ram_cmd_h_dec[x][y]);
1399            clusters[x][y]->p_dspin_ram_rsp_out[EAST]      (signal_dspin_ram_rsp_h_inc[x][y]);
1400            clusters[x+1][y]->p_dspin_ram_rsp_in[WEST]     (signal_dspin_ram_rsp_h_inc[x][y]);
1401            clusters[x][y]->p_dspin_ram_rsp_in[EAST]       (signal_dspin_ram_rsp_h_dec[x][y]);
1402            clusters[x+1][y]->p_dspin_ram_rsp_out[WEST]    (signal_dspin_ram_rsp_h_dec[x][y]);
1403         }
1404      }
1405   }
1406
1407   std::cout << std::endl << "Horizontal connections established" << std::endl;
1408
1409   // Inter Clusters vertical connections
1410   if (Y_SIZE > 1)
1411   {
1412      for (size_t y = 0; y < (Y_SIZE-1); y++)
1413      {
1414         for (size_t x = 0; x < X_SIZE; x++)
1415         {
1416            for (size_t k = 0; k < 3; k++)
1417            {
1418               clusters[x][y]->p_dspin_int_cmd_out[NORTH][k]     (signal_dspin_int_cmd_v_inc[x][y][k]);
1419               clusters[x][y+1]->p_dspin_int_cmd_in[SOUTH][k]    (signal_dspin_int_cmd_v_inc[x][y][k]);
1420               clusters[x][y]->p_dspin_int_cmd_in[NORTH][k]      (signal_dspin_int_cmd_v_dec[x][y][k]);
1421               clusters[x][y+1]->p_dspin_int_cmd_out[SOUTH][k]   (signal_dspin_int_cmd_v_dec[x][y][k]);
1422            }
1423
1424            for (size_t k = 0; k < 2; k++)
1425            {
1426               clusters[x][y]->p_dspin_int_rsp_out[NORTH][k]     (signal_dspin_int_rsp_v_inc[x][y][k]);
1427               clusters[x][y+1]->p_dspin_int_rsp_in[SOUTH][k]    (signal_dspin_int_rsp_v_inc[x][y][k]);
1428               clusters[x][y]->p_dspin_int_rsp_in[NORTH][k]      (signal_dspin_int_rsp_v_dec[x][y][k]);
1429               clusters[x][y+1]->p_dspin_int_rsp_out[SOUTH][k]   (signal_dspin_int_rsp_v_dec[x][y][k]);
1430            }
1431
1432            clusters[x][y]->p_dspin_ram_cmd_out[NORTH]     (signal_dspin_ram_cmd_v_inc[x][y]);
1433            clusters[x][y+1]->p_dspin_ram_cmd_in[SOUTH]    (signal_dspin_ram_cmd_v_inc[x][y]);
1434            clusters[x][y]->p_dspin_ram_cmd_in[NORTH]      (signal_dspin_ram_cmd_v_dec[x][y]);
1435            clusters[x][y+1]->p_dspin_ram_cmd_out[SOUTH]   (signal_dspin_ram_cmd_v_dec[x][y]);
1436            clusters[x][y]->p_dspin_ram_rsp_out[NORTH]     (signal_dspin_ram_rsp_v_inc[x][y]);
1437            clusters[x][y+1]->p_dspin_ram_rsp_in[SOUTH]    (signal_dspin_ram_rsp_v_inc[x][y]);
1438            clusters[x][y]->p_dspin_ram_rsp_in[NORTH]      (signal_dspin_ram_rsp_v_dec[x][y]);
1439            clusters[x][y+1]->p_dspin_ram_rsp_out[SOUTH]   (signal_dspin_ram_rsp_v_dec[x][y]);
1440         }
1441      }
1442   }
1443
1444   std::cout << "Vertical connections established" << std::endl;
1445
1446   // East & West boundary cluster connections
1447   for (size_t y = 0; y < Y_SIZE; y++)
1448   {
1449      for (size_t k = 0; k < 3; k++)
1450      {
1451         clusters[0][y]->p_dspin_int_cmd_in[WEST][k]          (signal_dspin_false_int_cmd_in[0][y][WEST][k]);
1452         clusters[0][y]->p_dspin_int_cmd_out[WEST][k]         (signal_dspin_false_int_cmd_out[0][y][WEST][k]);
1453         clusters[X_SIZE-1][y]->p_dspin_int_cmd_in[EAST][k]   (signal_dspin_false_int_cmd_in[X_SIZE-1][y][EAST][k]);
1454         clusters[X_SIZE-1][y]->p_dspin_int_cmd_out[EAST][k]  (signal_dspin_false_int_cmd_out[X_SIZE-1][y][EAST][k]);
1455      }
1456
1457      for (size_t k = 0; k < 2; k++)
1458      {
1459         clusters[0][y]->p_dspin_int_rsp_in[WEST][k]          (signal_dspin_false_int_rsp_in[0][y][WEST][k]);
1460         clusters[0][y]->p_dspin_int_rsp_out[WEST][k]         (signal_dspin_false_int_rsp_out[0][y][WEST][k]);
1461         clusters[X_SIZE-1][y]->p_dspin_int_rsp_in[EAST][k]   (signal_dspin_false_int_rsp_in[X_SIZE-1][y][EAST][k]);
1462         clusters[X_SIZE-1][y]->p_dspin_int_rsp_out[EAST][k]  (signal_dspin_false_int_rsp_out[X_SIZE-1][y][EAST][k]);
1463      }
1464
1465     clusters[0][y]->p_dspin_ram_cmd_in[WEST]       (signal_dspin_false_ram_cmd_in[0][y][WEST]);
1466     clusters[0][y]->p_dspin_ram_cmd_out[WEST]      (signal_dspin_false_ram_cmd_out[0][y][WEST]);
1467     clusters[0][y]->p_dspin_ram_rsp_in[WEST]       (signal_dspin_false_ram_rsp_in[0][y][WEST]);
1468     clusters[0][y]->p_dspin_ram_rsp_out[WEST]      (signal_dspin_false_ram_rsp_out[0][y][WEST]);
1469
1470     clusters[X_SIZE-1][y]->p_dspin_ram_cmd_in[EAST]  (signal_dspin_false_ram_cmd_in[X_SIZE-1][y][EAST]);
1471     clusters[X_SIZE-1][y]->p_dspin_ram_cmd_out[EAST] (signal_dspin_false_ram_cmd_out[X_SIZE-1][y][EAST]);
1472     clusters[X_SIZE-1][y]->p_dspin_ram_rsp_in[EAST]  (signal_dspin_false_ram_rsp_in[X_SIZE-1][y][EAST]);
1473     clusters[X_SIZE-1][y]->p_dspin_ram_rsp_out[EAST] (signal_dspin_false_ram_rsp_out[X_SIZE-1][y][EAST]);
1474   }
1475
1476   std::cout << "East & West boundaries established" << std::endl;
1477
1478   // North & South boundary clusters connections
1479   for (size_t x = 0; x < X_SIZE; x++)
1480   {
1481      for (size_t k = 0; k < 3; k++)
1482      {
1483         clusters[x][0]->p_dspin_int_cmd_in[SOUTH][k]         (signal_dspin_false_int_cmd_in[x][0][SOUTH][k]);
1484         clusters[x][0]->p_dspin_int_cmd_out[SOUTH][k]        (signal_dspin_false_int_cmd_out[x][0][SOUTH][k]);
1485         clusters[x][Y_SIZE-1]->p_dspin_int_cmd_in[NORTH][k]  (signal_dspin_false_int_cmd_in[x][Y_SIZE-1][NORTH][k]);
1486         clusters[x][Y_SIZE-1]->p_dspin_int_cmd_out[NORTH][k] (signal_dspin_false_int_cmd_out[x][Y_SIZE-1][NORTH][k]);
1487      }
1488
1489      for (size_t k = 0; k < 2; k++)
1490      {
1491         clusters[x][0]->p_dspin_int_rsp_in[SOUTH][k]         (signal_dspin_false_int_rsp_in[x][0][SOUTH][k]);
1492         clusters[x][0]->p_dspin_int_rsp_out[SOUTH][k]        (signal_dspin_false_int_rsp_out[x][0][SOUTH][k]);
1493         clusters[x][Y_SIZE-1]->p_dspin_int_rsp_in[NORTH][k]  (signal_dspin_false_int_rsp_in[x][Y_SIZE-1][NORTH][k]);
1494         clusters[x][Y_SIZE-1]->p_dspin_int_rsp_out[NORTH][k] (signal_dspin_false_int_rsp_out[x][Y_SIZE-1][NORTH][k]);
1495      }
1496
1497      clusters[x][0]->p_dspin_ram_cmd_in[SOUTH]       (signal_dspin_false_ram_cmd_in[x][0][SOUTH]);
1498      clusters[x][0]->p_dspin_ram_cmd_out[SOUTH]      (signal_dspin_false_ram_cmd_out[x][0][SOUTH]);
1499      clusters[x][0]->p_dspin_ram_rsp_in[SOUTH]       (signal_dspin_false_ram_rsp_in[x][0][SOUTH]);
1500      clusters[x][0]->p_dspin_ram_rsp_out[SOUTH]      (signal_dspin_false_ram_rsp_out[x][0][SOUTH]);
1501
1502      clusters[x][Y_SIZE-1]->p_dspin_ram_cmd_in[NORTH]  (signal_dspin_false_ram_cmd_in[x][Y_SIZE-1][NORTH]);
1503      clusters[x][Y_SIZE-1]->p_dspin_ram_cmd_out[NORTH] (signal_dspin_false_ram_cmd_out[x][Y_SIZE-1][NORTH]);
1504      clusters[x][Y_SIZE-1]->p_dspin_ram_rsp_in[NORTH]  (signal_dspin_false_ram_rsp_in[x][Y_SIZE-1][NORTH]);
1505      clusters[x][Y_SIZE-1]->p_dspin_ram_rsp_out[NORTH] (signal_dspin_false_ram_rsp_out[x][Y_SIZE-1][NORTH]);
1506   }
1507
1508   std::cout << "North & South boundaries established" << std::endl << std::endl;
1509
1510   ////////////////////////////////////////////////////////
1511   //   Simulation
1512   ///////////////////////////////////////////////////////
1513
1514   sc_start(sc_core::sc_time(0, SC_NS));
1515
1516   signal_resetn = false;
1517   signal_false  = false;
1518
1519   // network boundaries signals
1520   for (size_t x = 0; x < X_SIZE ; x++)
1521   {
1522      for (size_t y = 0; y < Y_SIZE ; y++)
1523      {
1524         for (size_t a = 0; a < 4; a++)
1525         {
1526            for (size_t k = 0; k < 3; k++)
1527            {
1528               signal_dspin_false_int_cmd_in[x][y][a][k].write = false;
1529               signal_dspin_false_int_cmd_in[x][y][a][k].read = true;
1530               signal_dspin_false_int_cmd_out[x][y][a][k].write = false;
1531               signal_dspin_false_int_cmd_out[x][y][a][k].read = true;
1532            }
1533
1534            for (size_t k = 0; k < 2; k++)
1535            {
1536               signal_dspin_false_int_rsp_in[x][y][a][k].write = false;
1537               signal_dspin_false_int_rsp_in[x][y][a][k].read = true;
1538               signal_dspin_false_int_rsp_out[x][y][a][k].write = false;
1539               signal_dspin_false_int_rsp_out[x][y][a][k].read = true;
1540            }
1541
1542            signal_dspin_false_ram_cmd_in[x][y][a].write = false;
1543            signal_dspin_false_ram_cmd_in[x][y][a].read = true;
1544            signal_dspin_false_ram_cmd_out[x][y][a].write = false;
1545            signal_dspin_false_ram_cmd_out[x][y][a].read = true;
1546
1547            signal_dspin_false_ram_rsp_in[x][y][a].write = false;
1548            signal_dspin_false_ram_rsp_in[x][y][a].read = true;
1549            signal_dspin_false_ram_rsp_out[x][y][a].write = false;
1550            signal_dspin_false_ram_rsp_out[x][y][a].read = true;
1551         }
1552      }
1553   }
1554
1555#if !USE_NIC
1556   for (int i = 0; i < NB_NIC_CHANNELS; i++)
1557   {
1558       signal_irq_mnic_rx[i].write(false);
1559       signal_irq_mnic_tx[i].write(false);
1560   }
1561
1562   signal_vci_ini_cdma.cmdval.write(false);
1563   signal_vci_ini_cdma.rspack.write(true);
1564   for (int i = 0; i < (NB_NIC_CHANNELS*2); i++)
1565   {
1566       signal_irq_cdma[i].write(false);
1567   }
1568#endif
1569
1570   sc_start(sc_core::sc_time(1, SC_NS));
1571   signal_resetn = true;
1572
1573   // simulation loop
1574   struct timeval t1, t2;
1575
1576   // cycles between stats
1577   const size_t stats_period = 500000;
1578   const size_t simul_period = debug_ok ? debug_period : stats_period;
1579
1580   for (size_t n = 0; n < ncycles; n += simul_period)
1581   {
1582      // stats display
1583      if((n % stats_period) == 0)
1584      {
1585         if (n > 0)
1586         {
1587            gettimeofday(&t2, NULL);
1588
1589            uint64_t ms1 = (uint64_t) t1.tv_sec  * 1000ULL +
1590               (uint64_t) t1.tv_usec / 1000;
1591            uint64_t ms2 = (uint64_t) t2.tv_sec  * 1000ULL +
1592               (uint64_t) t2.tv_usec / 1000;
1593            std::cerr << "### cycle = " << std::dec << n << " / frequency (Khz) = "
1594               << (double) stats_period / (double) (ms2 - ms1) << std::endl;
1595         }
1596
1597         gettimeofday(&t1, NULL);
1598      }
1599
1600      if (debug_ok and (n > debug_from) and (n % debug_period == 0))
1601      {
1602         std::cout << "****************** cycle " << std::dec << n ;
1603         std::cout << " ************************************************" << std::endl;
1604
1605         // trace proc[debug_proc_id]
1606         if ( debug_proc_id != 0xFFFFFFFF )
1607         {
1608            size_t l          = debug_proc_id & ((1 << P_WIDTH) - 1);
1609            size_t cluster_xy = debug_proc_id >> P_WIDTH ;
1610            size_t x          = cluster_xy >> Y_WIDTH;
1611            size_t y          = cluster_xy & ((1 << Y_WIDTH) - 1);
1612
1613            TsarCluster *c = clusters[x][y];
1614
1615            c->proc[l]->print_trace(1);
1616            std::ostringstream proc_signame;
1617            proc_signame << "[SIG]PROC_" << x << "_" << y << "_" << l ;
1618            c->signal_int_vci_ini_proc[l].print_trace(proc_signame.str());
1619
1620            c->xicu->print_trace(l);
1621            std::ostringstream xicu_signame;
1622            xicu_signame << "[SIG]XICU_" << x << "_" << y;
1623            c->signal_int_vci_tgt_xicu.print_trace(xicu_signame.str());
1624
1625            if( c->signal_proc_it[l].read() )
1626               std::cout << "### IRQ_PROC_" << std::dec
1627                  << x << "_" << y << "_" << l << " ACTIVE" << std::endl;
1628
1629            c->int_xbar_d->print_trace();
1630         }
1631
1632         // trace memc[debug_memc_id]
1633         if ( debug_memc_id != 0xFFFFFFFF )
1634         {
1635            size_t x = debug_memc_id >> Y_WIDTH;
1636            size_t y = debug_memc_id & ((1 << Y_WIDTH) - 1);
1637
1638            TsarCluster *c = clusters[x][y];
1639
1640            c->memc->print_trace(0);
1641            std::ostringstream smemc_tgt;
1642            smemc_tgt << "[SIG]MEMC_TGT_" << x << "_" << y;
1643            c->signal_int_vci_tgt_memc.print_trace(smemc_tgt.str());
1644            std::ostringstream smemc_ini;
1645            smemc_ini << "[SIG]MEMC_INI_" << x << "_" << y;
1646            c->signal_ram_vci_ini_memc.print_trace(smemc_ini.str());
1647
1648            c->drom->print_trace();
1649            std::ostringstream sdrom_tgt;
1650            sdrom_tgt << "[SIG]DROM_TGT_" << x << "_" << y;
1651            c->signal_int_vci_tgt_drom.print_trace(sdrom_tgt.str());
1652
1653            c->xram->print_trace();
1654            std::ostringstream sxram_tgt;
1655            sxram_tgt << "[SIG]XRAM_TGT_" << x << "_" << y;
1656            c->signal_ram_vci_tgt_xram.print_trace(sxram_tgt.str());
1657         }
1658
1659
1660         // trace XRAM and XRAM network routers in cluster[debug_xram_id]
1661         if ( debug_xram_id != 0xFFFFFFFF )
1662         {
1663            size_t x = debug_xram_id >> Y_WIDTH;
1664            size_t y = debug_xram_id & ((1 << Y_WIDTH) - 1);
1665
1666            TsarCluster *c = clusters[x][y];
1667
1668            c->xram->print_trace();
1669            std::ostringstream sxram_tgt;
1670            sxram_tgt << "[SIG]XRAM_TGT_" << x << "_" << y;
1671            c->signal_ram_vci_tgt_xram.print_trace(sxram_tgt.str());
1672
1673            c->ram_router_cmd->print_trace();
1674            c->ram_router_rsp->print_trace();
1675         }
1676
1677         // trace iob, iox and external peripherals
1678         if ( debug_iob )
1679         {
1680            TsarCluster* c;
1681
1682            c = clusters[0][0];
1683            c->iob->print_trace();
1684            c->signal_int_vci_tgt_iobx.print_trace("[SIG]IOB0_INT_TGT");
1685            c->signal_int_vci_ini_iobx.print_trace("[SIG]IOB0_INT_INI");
1686            c->signal_ram_vci_ini_iobx.print_trace("[SIG]IOB0_RAM_INI");
1687            signal_vci_ini_iob0.print_trace("[SIG]IOB0_IOX_INI");
1688            signal_vci_tgt_iob0.print_trace("[SIG]IOB0_IOX_TGT");
1689
1690            c = clusters[X_SIZE-1][Y_SIZE-1];
1691            c->iob->print_trace();
1692            c->signal_int_vci_tgt_iobx.print_trace("[SIG]IOB1_INT_TGT");
1693            c->signal_int_vci_ini_iobx.print_trace("[SIG]IOB1_INT_INI");
1694            c->signal_ram_vci_ini_iobx.print_trace("[SIG]IOB1_RAM_INI");
1695            signal_vci_ini_iob1.print_trace("[SIG]IOB1_IOX_INI");
1696            signal_vci_tgt_iob1.print_trace("[SIG]IOB1_IOX_TGT");
1697
1698            mtty->print_trace();
1699            signal_vci_tgt_mtty.print_trace("[SIG]IOX_MTTY_TGT");
1700
1701            bdev->print_trace();
1702            signal_vci_tgt_bdev.print_trace("[SIG]BDEV_TGT");
1703            signal_vci_ini_bdev.print_trace("[SIG]BDEV_INI");
1704
1705            iopi->print_trace();
1706            signal_vci_ini_iopi.print_trace("[SIG]IOPI_INI");
1707            signal_vci_tgt_iopi.print_trace("[SIG]IOPI_TGT");
1708
1709            // interrupts
1710            if (signal_irq_bdev)
1711               std::cout << "### IRQ_BDEV ACTIVE" << std::endl;
1712            if (signal_irq_mtty_rx[0])
1713               std::cout << "### IRQ_MTTY ACTIVE" << std::endl;
1714
1715#if USE_NIC
1716            for ( size_t i=0 ; i<NB_NIC_CHANNELS ; ++i )
1717               if (signal_irq_mnic_rx[i])
1718                  std::cout << "### IRQ_MNIC_RX[" << i << "] ACTIVE" << std::endl;
1719               if (signal_irq_mnic_tx[i])
1720                  std::cout << "### IRQ_MNIC_TX[" << i << "] ACTIVE" << std::endl;
1721#endif
1722         }
1723      }
1724
1725      sc_start(sc_core::sc_time(simul_period, SC_NS));
1726   }
1727   return EXIT_SUCCESS;
1728}
1729
1730int sc_main (int argc, char *argv[])
1731{
1732   try {
1733      return _main(argc, argv);
1734   } catch (soclib::exception::RunTimeError &e) {
1735      std::cout << "RunTimeError: " << e.what() << std::endl;
1736   } catch (std::exception &e) {
1737      std::cout << e.what() << std::endl;
1738   } catch (...) {
1739      std::cout << "Unknown exception occured" << std::endl;
1740      throw;
1741   }
1742   return 1;
1743}
1744
1745
1746// Local Variables:
1747// tab-width: 3
1748// c-basic-offset: 3
1749// c-file-offsets:((innamespace . 0)(inline-open . 0))
1750// indent-tabs-mode: nil
1751// End:
1752
1753// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
Note: See TracBrowser for help on using the repository browser.