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

Last change on this file since 1018 was 1015, checked in by cfuguet, 9 years ago

reconf: when a local router in a cluster is faulty, the cores are kept
deactivated.

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