source: trunk/platforms/tsar_generic_leti/top.cpp @ 692

Last change on this file since 692 was 692, checked in by cfuguet, 10 years ago

tsar_generic_leti:

  • Replacing tsar_leti_cluster dspin_local_crossbar by vci_local_crossbar
  • Introducing in top.cpp the possibility to pass soft binary, disk image or ramdisk image files through command line args
File size: 58.8 KB
Line 
1/////////////////////////////////////////////////////////////////////////
2// File: top.cpp (for tsar_generic_leti)
3// Author: Alain Greiner
4// Copyright: UPMC/LIP6
5// Date : february 2014
6// This program is released under the GNU public license
7/////////////////////////////////////////////////////////////////////////
8// This file define a generic TSAR architecture, fully compatible
9// with the VLSI Hardware prototype developped by CEA-LETI and LIP6
10// in the framework of the SHARP project.
11//
12// The processor is a MIPS32 processor wrapped in a GDB server
13// (this is defined in the tsar_xbar_cluster).
14//
15// It does not use an external ROM, as the boot code is (pre)loaded
16// in cluster (0,0) memory at address 0x0.
17//
18// The physical address space is 40 bits.
19// The 8 address MSB bits define the cluster index.
20//
21// The main hardware parameters are the mesh size (X_SIZE & Y_SIZE),
22// and the number of processors per cluster (NB_PROCS_MAX).
23// The number of clusters cannot be larger than 128.
24// The number of processors per cluster cannot be larger than 4.
25//
26// Each cluster contains:
27// - 5 dspin_local_crossbar (local interconnect)
28// - 5 dspin_router (global interconnect)
29// - up to 4 vci_cc_vcache wrapping a MIPS32 processor
30// - 1 vci_mem_cache
31// - 1 vci_xicu
32// - 1 vci_simple_ram (to model the L3 cache).
33//
34// Each processor receives 4 consecutive IRQ lines from the local XICU.
35//
36// In all clusters, the MEMC IRQ line (signaling a late write error)
37// is connected to XICU HWI[8]
38// The cluster (0,0) contains two "backup" peripherals:
39// - one block device controller, whose IRQ is connected to XICU HWI[9].
40// - one single channel TTY controller, whose IRQ is connected to XICU HWI[10].
41//
42// The cluster internal architecture is defined in file tsar_leti_cluster,
43// that must be considered as an extension of this top.cpp file.
44//
45// Besides the hardware components in clusters, "external" peripherals
46// are connected to an external IO bus (implemented as a vci_local_crossbar):
47// - one disk controller
48// - one multi-channel ethernet controller
49// - one multi-channel chained buffer dma controller
50// - one multi-channel tty controller
51// - one frame buffer controller
52// - one 32 channels iopic controller
53//
54// This IOBUS is connected to the north  port of the DIR_CMD
55// and DIR_RSP routers, in cluster(X_SIZE-1, Y_SIZE-1).
56// For all external peripherals, the hardware interrupts (HWI) are
57// translated to write interrupts (WTI) by the iopic component:
58// - IOPIC HWI[1:0]     connected to IRQ_NIC_RX[1:0]
59// - IOPIC HWI[3:2]     connected to IRQ_NIC_TX[1:0]     
60// - IOPIC HWI[7:4]     connected to IRQ_CMA_TX[3:0]]
61// - IOPIC HWI[8]       connected to IRQ_BDEV
62// - IOPIC HWI[15:9]    unused       (grounded)
63// - IOPIC HWI[23:16]   connected to IRQ_TTY_RX[7:0]]
64// - IOPIC HWI[31:24]   connected to IRQ_TTY_TX[7:0]]
65////////////////////////////////////////////////////////////////////////////
66// The following parameters must be defined in the hard_config.h file :
67// - X_WIDTH          : number of bits for x coordinate (must be 4)
68// - Y_WIDTH          : number of bits for y coordinate (must be 4)
69// - X_SIZE           : number of clusters in a row (1,2,4,8,16)
70// - Y_SIZE           : number of clusters in a column (1,2,4,8)
71// - NB_PROCS_MAX     : number of processors per cluster (1, 2 or 4)
72// - NB_CMA_CHANNELS  : number of CMA channels in I/0 cluster (4 max)
73// - NB_TTY_CHANNELS  : number of TTY channels in I/O cluster (8 max)
74// - NB_NIC_CHANNELS  : number of NIC channels in I/O cluster (2 max)
75//
76// Some other hardware parameters are not used when compiling the OS,
77// and are only defined in this top.cpp file:
78// - XRAM_LATENCY     : external ram latency
79// - MEMC_WAYS        : L2 cache number of ways
80// - MEMC_SETS        : L2 cache number of sets
81// - L1_IWAYS         : L1 cache instruction number of ways
82// - L1_ISETS         : L1 cache instruction number of sets
83// - L1_DWAYS         : L1 cache data number of ways
84// - L1_DSETS         : L1 cache data number of sets
85// - FBUF_X_SIZE      : width of frame buffer (pixels)
86// - FBUF_Y_SIZE      : heigth of frame buffer (lines)
87// - BDEV_IMAGE_NAME  : file pathname for block device
88// - NIC_RX_NAME      : file pathname for NIC received packets
89// - NIC_TX_NAME      : file pathname for NIC transmited packets
90// - NIC_MAC4         : MAC address
91// - NIC_MAC2         : MAC address
92/////////////////////////////////////////////////////////////////////////
93// General policy for 40 bits physical address decoding:
94// All physical segments base addresses are multiple of 1 Mbytes
95// (=> the 24 LSB bits = 0, and the 16 MSB bits define the target)
96// The (X_WIDTH + Y_WIDTH) MSB bits (left aligned) define
97// the cluster index, and the LADR bits define the local index:
98//      |X_ID|Y_ID|  LADR |     OFFSET          |
99//      |  4 |  4 |   8   |       24            |
100/////////////////////////////////////////////////////////////////////////
101// General policy for 14 bits SRCID decoding:
102// Each component is identified by (x_id, y_id, l_id) tuple.
103//      |X_ID|Y_ID| L_ID |
104//      |  4 |  4 |  6   |
105/////////////////////////////////////////////////////////////////////////
106
107#include <systemc>
108#include <sys/time.h>
109#include <iostream>
110#include <sstream>
111#include <cstdlib>
112#include <cstdarg>
113#include <stdint.h>
114
115#include "gdbserver.h"
116#include "mapping_table.h"
117#include "tsar_leti_cluster.h"
118#include "vci_local_crossbar.h"
119#include "vci_dspin_initiator_wrapper.h"
120#include "vci_dspin_target_wrapper.h"
121#include "vci_multi_tty.h"
122#include "vci_multi_nic.h"
123#include "vci_chbuf_dma.h"
124#include "vci_block_device_tsar.h"
125#include "vci_framebuffer.h"
126#include "vci_iopic.h"
127#include "alloc_elems.h"
128
129//////////////////////////////////////////////////////////////////////////////////////////
130//    Parameters depending on the OS and software application         
131//    - path to hard_config file
132//    - path to binary code for the RAM loader
133//    - path to disk image for RAMDISK loader
134//    - path to disk image for IOC device
135//////////////////////////////////////////////////////////////////////////////////////////
136
137#define USE_GIET_VM     1
138#define USE_GIET_TSAR   0
139
140#if ( USE_GIET_VM and USE_GIET_TSAR )
141#error "Can't use Two different OS"
142#endif
143
144#if ( (not USE_GIET_VM) and (not USE_GIET_TSAR) )
145#error "You need to specify one OS"
146#endif
147
148#if USE_GIET_TSAR
149#include                         "hard_config.h"
150#define BINARY_PATH_FOR_LOADER   "../../softs/soft_transpose_giet/bin.soft"
151#define RAMDISK_PATH_FOR_LOADER  "../../softs/soft_transpose_giet/images.raw@0x00800000:"
152#define DISK_IMAGE_PATH_FOR_IOC  "../../softs/soft_transpose_giet/images.raw"
153#endif
154
155#if USE_GIET_VM
156#include                         "hard_config.h"
157#define BINARY_PATH_FOR_LOADER   "../../softs/tsar_boot/preloader.elf"
158#define RAMDISK_PATH_FOR_LOADER  "../../../giet_vm/hdd/virt_hdd.dmg@0x02000000:"
159#define DISK_IMAGE_PATH_FOR_IOC  "../../../giet_vm/hdd/virt_hdd.dmg"       
160#endif
161
162///////////////////////////////////////////////////
163//               Parallelisation
164///////////////////////////////////////////////////
165#define USE_OPENMP 0
166
167#if USE_OPENMP
168#include <omp.h>
169#endif
170
171///////////////////////////////////////////////////
172//  cluster index (from x,y coordinates)
173///////////////////////////////////////////////////
174
175#define cluster(x,y)   ((y) + ((x) << Y_WIDTH))
176
177///////////////////////////////////////////////////////////
178//          DSPIN parameters           
179///////////////////////////////////////////////////////////
180
181#define dspin_cmd_width      39
182#define dspin_rsp_width      32
183
184///////////////////////////////////////////////////////////
185//          VCI parameters           
186///////////////////////////////////////////////////////////
187
188#define vci_cell_width_int    4
189#define vci_cell_width_ext    8
190#define vci_address_width     40
191#define vci_plen_width        8
192#define vci_rerror_width      1
193#define vci_clen_width        1
194#define vci_rflag_width       1
195#define vci_srcid_width       14
196#define vci_pktid_width       4
197#define vci_trdid_width       4
198#define vci_wrplen_width      1
199
200
201/////////////////////////////////////////////////////////////////////////////////////////
202//    Secondary Hardware Parameters         
203/////////////////////////////////////////////////////////////////////////////////////////
204
205#define RESET_ADDRESS         0x0
206
207#define MAX_TTY_CHANNELS      8
208#define MAX_CMA_CHANNELS      4
209#define MAX_NIC_CHANNELS      2
210
211#define XRAM_LATENCY          0
212#define XRAM_SIZE             0x04000000    // 64 Mbytes per cluster
213
214#define MEMC_WAYS             16
215#define MEMC_SETS             256
216
217#define L1_IWAYS              4
218#define L1_ISETS              64
219
220#define L1_DWAYS              4
221#define L1_DSETS              64
222
223#define FBUF_X_SIZE           128
224#define FBUF_Y_SIZE           128
225
226#define NIC_MAC4              0XBABEF00D
227#define NIC_MAC2              0xBEEF
228#define NIC_RX_NAME           "./fake"
229#define NIC_TX_NAME           "./fake"
230
231#define NORTH                 0
232#define SOUTH                 1
233#define EAST                  2
234#define WEST                  3
235
236///////////////////////////////////////////////////////////////////////////////////////
237//     DEBUG Parameters default values         
238///////////////////////////////////////////////////////////////////////////////////////
239
240#define MAX_FROZEN_CYCLES     500000
241
242///////////////////////////////////////////////////////////////////////////////////////
243//     LOCAL TGTID & SRCID definition
244// For all components:  global TGTID = global SRCID = cluster_index
245///////////////////////////////////////////////////////////////////////////////////////
246
247#define MEMC_TGTID            0
248#define XICU_TGTID            1
249#define MTTY_TGTID            2
250#define BDEV_TGTID            3
251#define FBUF_TGTID            4
252#define MNIC_TGTID            5
253#define CDMA_TGTID            6
254#define IOPI_TGTID            7
255
256#define BDEV_SRCID            NB_PROCS_MAX
257#define CDMA_SRCID            NB_PROCS_MAX + 1
258#define IOPI_SRCID            NB_PROCS_MAX + 2
259
260//////////////////////////////////////////////////////////////////////////////////////
261//    Physical segments definition
262//////////////////////////////////////////////////////////////////////////////////////
263// - 3 segments are replicated in all clusters
264// - 2 segments are only in cluster[0,0]
265// - 4 segments are only in cluster [X_SIZE-1,Y_SIZE]
266// The following values are for segments in cluster 0,
267// and these 32 bits values must be concatenate with the cluster
268// index (on 8 bits) to obtain the 40 bits address.
269//////////////////////////////////////////////////////////////////////////////////////
270
271// in cluster [0,0] & [X_SIZE-1,Y_SIZE]
272
273#define MTTY_BASE    0xF4000000
274#define MTTY_SIZE    0x00001000   // 4 Kbytes
275
276#define BDEV_BASE    0xF2000000
277#define BDEV_SIZE    0x00001000   // 4 Kbytes
278
279// in cluster [X_SIZE-1,Y_SIZE]
280
281#define FBUF_BASE    0xF3000000
282#define FBUF_SIZE    (FBUF_X_SIZE * FBUF_Y_SIZE * 2)
283
284#define MNIC_BASE    0xF7000000
285#define MNIC_SIZE    0x00800000   // 512 Kbytes (for 8 channels)
286
287#define CDMA_BASE    0xF8000000
288#define CDMA_SIZE    0x00004000 * NB_CMA_CHANNELS
289
290#define IOPI_BASE    0xF9000000
291#define IOPI_SIZE    0x00001000   // 4 Kbytes
292
293// replicated segments : address is extended to 40 bits by cluster_xy
294
295#define MEMC_BASE    0x00000000
296#define MEMC_SIZE    XRAM_SIZE
297
298#define MCFG_BASE    0xE0000000
299#define MCFG_SIZE    0x00001000   // 4 Kbytes
300
301#define XICU_BASE    0xF0000000
302#define XICU_SIZE    0x00001000   // 4 Kbytes
303
304bool stop_called = false;
305
306/////////////////////////////////
307int _main(int argc, char *argv[])
308{
309   using namespace sc_core;
310   using namespace soclib::caba;
311   using namespace soclib::common;
312
313   uint32_t ncycles           = 0xFFFFFFFF; // max simulated cycles
314   size_t   threads           = 1;          // simulator's threads number
315   bool     trace_ok          = false;      // trace activated
316   uint32_t trace_from        = 0;          // trace start cycle
317   bool     trace_proc_ok     = false;      // detailed proc trace activated
318   size_t   trace_memc_ok     = false;      // detailed memc trace activated
319   size_t   trace_memc_id     = 0;          // index of memc to be traced
320   size_t   trace_proc_id     = 0;          // index of proc to be traced
321   uint32_t frozen_cycles     = MAX_FROZEN_CYCLES;
322   char     soft_name[256]    = BINARY_PATH_FOR_LOADER;
323   char     disk_name[256]    = DISK_IMAGE_PATH_FOR_IOC;
324   char     ramdisk_name[256] = RAMDISK_PATH_FOR_LOADER;
325   struct   timeval t1,t2;
326   uint64_t ms1,ms2;
327
328   ////////////// command line arguments //////////////////////
329   if (argc > 1)
330   {
331      for (int n = 1; n < argc; n = n + 2)
332      {
333         if ((strcmp(argv[n], "-NCYCLES") == 0) && (n + 1 < argc))
334         {
335            ncycles = (uint64_t) strtol(argv[n + 1], NULL, 0);
336         }
337         else if ((strcmp(argv[n],"-DEBUG") == 0) && (n + 1 < argc))
338         {
339            trace_ok = true;
340            trace_from = (uint32_t) strtol(argv[n + 1], NULL, 0);
341         }
342         else if ((strcmp(argv[n], "-MEMCID") == 0) && (n + 1 < argc))
343         {
344            trace_memc_ok = true;
345            trace_memc_id = (size_t) strtol(argv[n + 1], NULL, 0);
346            size_t x = trace_memc_id >> Y_WIDTH;
347            size_t y = trace_memc_id & ((1<<Y_WIDTH)-1);
348
349            assert( (x < X_SIZE) and (y < (Y_SIZE)) and
350                  "MEMCID parameter refers a not valid memory cache");
351         }
352         else if ((strcmp(argv[n], "-PROCID") == 0) && (n + 1 < argc))
353         {
354            trace_proc_ok = true;
355            trace_proc_id = (size_t) strtol(argv[n + 1], NULL, 0);
356            size_t cluster_xy = trace_proc_id / NB_PROCS_MAX ;
357            size_t x          = cluster_xy >> Y_WIDTH;
358            size_t y          = cluster_xy & ((1<<Y_WIDTH)-1);
359            size_t l          = trace_proc_id % NB_PROCS_MAX ;
360
361            assert( (x < X_SIZE) and (y < Y_SIZE) and (l < NB_PROCS_MAX) and
362                  "PROCID parameter refers a not valid processor");
363         }
364         else if ((strcmp(argv[n], "-SOFT") == 0) && ((n + 1) < argc))
365         {
366            strcpy(soft_name, argv[n + 1]); 
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], "-RAMDISK") == 0) && ((n + 1) < argc))
373         {
374            strcpy(ramdisk_name, argv[n + 1]); 
375         }
376         else if ((strcmp(argv[n], "-THREADS") == 0) && ((n + 1) < argc))
377         {
378            threads = (size_t) strtol(argv[n + 1], NULL, 0);
379            threads = (threads < 1) ? 1 : threads;
380         }
381         else if ((strcmp(argv[n], "-FROZEN") == 0) && (n + 1 < argc))
382         {
383            frozen_cycles = (uint32_t) strtol(argv[n + 1], NULL, 0);
384         }
385         else
386         {
387            std::cout << "   Arguments are (key,value) couples." << std::endl;
388            std::cout << "   The order is not important." << std::endl;
389            std::cout << "   Accepted arguments are :" << std::endl << std::endl;
390            std::cout << "     -NCYCLES number_of_simulated_cycles" << std::endl;
391            std::cout << "     -DEBUG debug_start_cycle" << std::endl;
392            std::cout << "     -SOFT path to soft" << std::endl;
393            std::cout << "     -DISK path to disk image" << std::endl;
394            std::cout << "     -RAMDISK path to ramdisk image" << std::endl;
395            std::cout << "     -THREADS simulator's threads number" << std::endl;
396            std::cout << "     -FROZEN max_number_of_lines" << std::endl;
397            std::cout << "     -PERIOD number_of_cycles between trace" << std::endl;
398            std::cout << "     -MEMCID index_memc_to_be_traced" << std::endl;
399            std::cout << "     -PROCID index_proc_to_be_traced" << std::endl;
400            exit(0);
401         }
402      }
403   }
404
405    // checking hardware parameters
406    assert( ((X_SIZE==1) or (X_SIZE==2) or (X_SIZE==4) or (X_SIZE==8) or (X_SIZE==16)) and
407            "Illegal X_SIZE parameter" );
408
409    assert( ((Y_SIZE==1) or (Y_SIZE==2) or (Y_SIZE==4) or (Y_SIZE==8)) and
410            "Illegal Y_SIZE parameter" );
411
412    assert( (NB_PROCS_MAX <= 4) and
413            "Illegal NB_PROCS_MAX parameter" );
414
415    assert( (NB_CMA_CHANNELS <= MAX_CMA_CHANNELS) and
416            "The NB_CMA_CHANNELS parameter cannot be larger than 4" );
417
418    assert( (NB_TTY_CHANNELS <= MAX_TTY_CHANNELS) and
419            "The NB_TTY_CHANNELS parameter cannot be larger than 8" );
420
421    assert( (NB_NIC_CHANNELS <= MAX_NIC_CHANNELS) and
422            "The NB_NIC_CHANNELS parameter cannot be larger than 2" );
423
424    assert( (vci_address_width == 40) and
425            "VCI address width with the GIET must be 40 bits" );
426
427    assert( (X_WIDTH == 4) and (Y_WIDTH == 4) and
428            "ERROR: you must have X_WIDTH == Y_WIDTH == 4");
429 
430    std::cout << std::endl;
431
432    std::cout << " - X_SIZE           = " << X_SIZE << std::endl;
433    std::cout << " - Y_SIZE           = " << Y_SIZE << std::endl;
434    std::cout << " - NB_PROCS_MAX     = " << NB_PROCS_MAX <<  std::endl;
435    std::cout << " - NB_DMA_CHANNELS  = " << NB_DMA_CHANNELS <<  std::endl;
436    std::cout << " - NB_TTY_CHANNELS  = " << NB_TTY_CHANNELS <<  std::endl;
437    std::cout << " - NB_NIC_CHANNELS  = " << NB_NIC_CHANNELS <<  std::endl;
438    std::cout << " - MEMC_WAYS        = " << MEMC_WAYS << std::endl;
439    std::cout << " - MEMC_SETS        = " << MEMC_SETS << std::endl;
440    std::cout << " - RAM_LATENCY      = " << XRAM_LATENCY << std::endl;
441    std::cout << " - MAX_FROZEN       = " << frozen_cycles << std::endl;
442    std::cout << " - MAX_CYCLES       = " << ncycles << std::endl;
443    std::cout << " - RESET_ADDRESS    = " << RESET_ADDRESS << std::endl;
444    std::cout << " - SOFT_FILENAME    = " << soft_name << std::endl;
445    std::cout << " - DISK_IMAGENAME   = " << disk_name << std::endl;
446    std::cout << " - RAMDISK_FILENAME = " << ramdisk_name << std::endl;
447    std::cout << " - OPENMP THREADS   = " << threads << std::endl;
448
449    std::cout << std::endl;
450
451    // Internal and External VCI parameters definition
452    typedef soclib::caba::VciParams<vci_cell_width_int,
453                                    vci_plen_width,
454                                    vci_address_width,
455                                    vci_rerror_width,
456                                    vci_clen_width,
457                                    vci_rflag_width,
458                                    vci_srcid_width,
459                                    vci_pktid_width,
460                                    vci_trdid_width,
461                                    vci_wrplen_width> vci_param_int;
462
463    typedef soclib::caba::VciParams<vci_cell_width_ext,
464                                    vci_plen_width,
465                                    vci_address_width,
466                                    vci_rerror_width,
467                                    vci_clen_width,
468                                    vci_rflag_width,
469                                    vci_srcid_width,
470                                    vci_pktid_width,
471                                    vci_trdid_width,
472                                    vci_wrplen_width> vci_param_ext;
473
474#if USE_OPENMP
475   omp_set_dynamic(false);
476   omp_set_num_threads(threads);
477   std::cerr << "Built with openmp version " << _OPENMP << std::endl;
478#endif
479
480
481   ///////////////////////////////////////
482   //  Direct Network Mapping Table
483   ///////////////////////////////////////
484
485   MappingTable maptabd(vci_address_width, 
486                        IntTab(X_WIDTH + Y_WIDTH, 16 - X_WIDTH - Y_WIDTH), 
487                        IntTab(X_WIDTH + Y_WIDTH, vci_srcid_width - X_WIDTH - Y_WIDTH), 
488                        0x00FF000000ULL);
489
490   // replicated segments
491   for (size_t x = 0; x < X_SIZE; x++)
492   {
493      for (size_t y = 0; y < (Y_SIZE) ; y++)
494      {
495         sc_uint<vci_address_width> offset;
496         offset = ((sc_uint<vci_address_width>)cluster(x,y)) << 32;
497
498         std::ostringstream    si;
499         si << "seg_xicu_" << x << "_" << y;
500         maptabd.add(Segment(si.str(), XICU_BASE + offset, XICU_SIZE, 
501                  IntTab(cluster(x,y),XICU_TGTID), false));
502
503         std::ostringstream    sd;
504         sd << "seg_mcfg_" << x << "_" << y;
505         maptabd.add(Segment(sd.str(), MCFG_BASE + offset, MCFG_SIZE, 
506                  IntTab(cluster(x,y),MEMC_TGTID), false));
507
508         std::ostringstream    sh;
509         sh << "seg_memc_" << x << "_" << y;
510         maptabd.add(Segment(sh.str(), MEMC_BASE + offset, MEMC_SIZE, 
511                  IntTab(cluster(x,y),MEMC_TGTID), true));
512      }
513   }
514
515   // segments for peripherals in cluster(0,0)
516   maptabd.add(Segment("seg_tty0", MTTY_BASE, MTTY_SIZE, 
517               IntTab(cluster(0,0),MTTY_TGTID), false));
518
519   maptabd.add(Segment("seg_ioc0", BDEV_BASE, BDEV_SIZE, 
520               IntTab(cluster(0,0),BDEV_TGTID), false));
521
522   // segments for peripherals in cluster_io (X_SIZE-1,Y_SIZE)
523   sc_uint<vci_address_width> offset;
524   offset = ((sc_uint<vci_address_width>)cluster(X_SIZE-1,Y_SIZE)) << 32;
525
526   maptabd.add(Segment("seg_mtty", MTTY_BASE + offset, MTTY_SIZE, 
527               IntTab(cluster(X_SIZE-1, Y_SIZE),MTTY_TGTID), false));
528
529   maptabd.add(Segment("seg_fbuf", FBUF_BASE + offset, FBUF_SIZE, 
530               IntTab(cluster(X_SIZE-1, Y_SIZE),FBUF_TGTID), false));
531
532   maptabd.add(Segment("seg_bdev", BDEV_BASE + offset, BDEV_SIZE, 
533               IntTab(cluster(X_SIZE-1, Y_SIZE),BDEV_TGTID), false));
534
535   maptabd.add(Segment("seg_mnic", MNIC_BASE + offset, MNIC_SIZE, 
536               IntTab(cluster(X_SIZE-1, Y_SIZE),MNIC_TGTID), false));
537
538   maptabd.add(Segment("seg_cdma", CDMA_BASE + offset, CDMA_SIZE, 
539               IntTab(cluster(X_SIZE-1, Y_SIZE),CDMA_TGTID), false));
540
541   maptabd.add(Segment("seg_iopi", IOPI_BASE + offset, IOPI_SIZE, 
542               IntTab(cluster(X_SIZE-1, Y_SIZE),IOPI_TGTID), false));
543
544   std::cout << maptabd << std::endl;
545
546    /////////////////////////////////////////////////
547    // Ram network mapping table
548    /////////////////////////////////////////////////
549
550    MappingTable maptabx(vci_address_width, 
551                         IntTab(X_WIDTH+Y_WIDTH), 
552                         IntTab(X_WIDTH+Y_WIDTH), 
553                         0x00FF000000ULL);
554
555    for (size_t x = 0; x < X_SIZE; x++)
556    {
557        for (size_t y = 0; y < (Y_SIZE) ; y++)
558        { 
559            sc_uint<vci_address_width> offset;
560            offset = (sc_uint<vci_address_width>)cluster(x,y) 
561                      << (vci_address_width-X_WIDTH-Y_WIDTH);
562
563            std::ostringstream sh;
564            sh << "x_seg_memc_" << x << "_" << y;
565
566            maptabx.add(Segment(sh.str(), MEMC_BASE + offset, 
567                     MEMC_SIZE, IntTab(cluster(x,y)), false));
568        }
569    }
570    std::cout << maptabx << std::endl;
571
572    ////////////////////
573    // Signals
574    ///////////////////
575
576    sc_clock                          signal_clk("clk");
577    sc_signal<bool>                   signal_resetn("resetn");
578
579    // IRQs from external peripherals
580    sc_signal<bool>                   signal_irq_bdev;
581    sc_signal<bool>                   signal_irq_mnic_rx[NB_NIC_CHANNELS];
582    sc_signal<bool>                   signal_irq_mnic_tx[NB_NIC_CHANNELS];
583    sc_signal<bool>                   signal_irq_mtty_rx[NB_TTY_CHANNELS];
584//  sc_signal<bool>                   signal_irq_mtty_tx[NB_TTY_CHANNELS];
585    sc_signal<bool>                   signal_irq_cdma[NB_CMA_CHANNELS];
586    sc_signal<bool>                   signal_irq_false;
587
588   // Horizontal inter-clusters DSPIN signals
589   DspinSignals<dspin_cmd_width>** signal_dspin_h_cmd_inc =
590      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_inc", X_SIZE-1, Y_SIZE);
591   DspinSignals<dspin_cmd_width>** signal_dspin_h_cmd_dec =
592      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_dec", X_SIZE-1, Y_SIZE);
593
594   DspinSignals<dspin_rsp_width>** signal_dspin_h_rsp_inc =
595      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_inc", X_SIZE-1, Y_SIZE);
596   DspinSignals<dspin_rsp_width>** signal_dspin_h_rsp_dec =
597      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_dec", X_SIZE-1, Y_SIZE);
598
599   DspinSignals<dspin_cmd_width>** signal_dspin_h_m2p_inc =
600      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_m2p_inc", X_SIZE-1, Y_SIZE);
601   DspinSignals<dspin_cmd_width>** signal_dspin_h_m2p_dec =
602      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_m2p_dec", X_SIZE-1, Y_SIZE);
603
604   DspinSignals<dspin_rsp_width>** signal_dspin_h_p2m_inc =
605      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_p2m_inc", X_SIZE-1, Y_SIZE);
606   DspinSignals<dspin_rsp_width>** signal_dspin_h_p2m_dec =
607      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_p2m_dec", X_SIZE-1, Y_SIZE);
608
609   DspinSignals<dspin_cmd_width>** signal_dspin_h_cla_inc =
610      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cla_inc", X_SIZE-1, Y_SIZE);
611   DspinSignals<dspin_cmd_width>** signal_dspin_h_cla_dec =
612      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cla_dec", X_SIZE-1, Y_SIZE);
613
614   // Vertical inter-clusters DSPIN signals
615   DspinSignals<dspin_cmd_width>** signal_dspin_v_cmd_inc =
616      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_inc", X_SIZE, Y_SIZE-1);
617   DspinSignals<dspin_cmd_width>** signal_dspin_v_cmd_dec =
618      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_dec", X_SIZE, Y_SIZE-1);
619
620   DspinSignals<dspin_rsp_width>** signal_dspin_v_rsp_inc =
621      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_inc", X_SIZE, Y_SIZE-1);
622   DspinSignals<dspin_rsp_width>** signal_dspin_v_rsp_dec =
623      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_dec", X_SIZE, Y_SIZE-1);
624
625   DspinSignals<dspin_cmd_width>** signal_dspin_v_m2p_inc =
626      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_m2p_inc", X_SIZE, Y_SIZE-1);
627   DspinSignals<dspin_cmd_width>** signal_dspin_v_m2p_dec =
628      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_m2p_dec", X_SIZE, Y_SIZE-1);
629
630   DspinSignals<dspin_rsp_width>** signal_dspin_v_p2m_inc =
631      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_p2m_inc", X_SIZE, Y_SIZE-1);
632   DspinSignals<dspin_rsp_width>** signal_dspin_v_p2m_dec =
633      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_p2m_dec", X_SIZE, Y_SIZE-1);
634
635   DspinSignals<dspin_cmd_width>** signal_dspin_v_cla_inc =
636      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cla_inc", X_SIZE, Y_SIZE-1);
637   DspinSignals<dspin_cmd_width>** signal_dspin_v_cla_dec =
638      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cla_dec", X_SIZE, Y_SIZE-1);
639
640   // Mesh boundaries DSPIN signals (Most of those signals are not used...)
641   DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cmd_in =
642      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cmd_in" , X_SIZE, Y_SIZE, 4);
643   DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cmd_out =
644      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cmd_out", X_SIZE, Y_SIZE, 4);
645
646   DspinSignals<dspin_rsp_width>*** signal_dspin_bound_rsp_in =
647      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_rsp_in" , X_SIZE, Y_SIZE, 4);
648   DspinSignals<dspin_rsp_width>*** signal_dspin_bound_rsp_out =
649      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_rsp_out", X_SIZE, Y_SIZE, 4);
650
651   DspinSignals<dspin_cmd_width>*** signal_dspin_bound_m2p_in =
652      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_m2p_in" , X_SIZE, Y_SIZE, 4);
653   DspinSignals<dspin_cmd_width>*** signal_dspin_bound_m2p_out =
654      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_m2p_out", X_SIZE, Y_SIZE, 4);
655
656   DspinSignals<dspin_rsp_width>*** signal_dspin_bound_p2m_in =
657      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_p2m_in" , X_SIZE, Y_SIZE, 4);
658   DspinSignals<dspin_rsp_width>*** signal_dspin_bound_p2m_out =
659      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_p2m_out", X_SIZE, Y_SIZE, 4);
660
661   DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cla_in =
662      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cla_in" , X_SIZE, Y_SIZE, 4);
663   DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cla_out =
664      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cla_out", X_SIZE, Y_SIZE, 4);
665
666   // VCI signals for iobus and peripherals
667   VciSignals<vci_param_int>    signal_vci_ini_bdev("signal_vci_ini_bdev");
668   VciSignals<vci_param_int>    signal_vci_ini_cdma("signal_vci_ini_cdma");
669   VciSignals<vci_param_int>    signal_vci_ini_iopi("signal_vci_ini_iopi");
670
671   VciSignals<vci_param_int>*   signal_vci_ini_proc = 
672       alloc_elems<VciSignals<vci_param_int> >("signal_vci_ini_proc", NB_PROCS_MAX );
673
674   VciSignals<vci_param_int>    signal_vci_tgt_memc("signal_vci_tgt_memc");
675   VciSignals<vci_param_int>    signal_vci_tgt_xicu("signal_vci_tgt_xicu");
676   VciSignals<vci_param_int>    signal_vci_tgt_bdev("signal_vci_tgt_bdev");
677   VciSignals<vci_param_int>    signal_vci_tgt_mtty("signal_vci_tgt_mtty");
678   VciSignals<vci_param_int>    signal_vci_tgt_fbuf("signal_vci_tgt_fbuf");
679   VciSignals<vci_param_int>    signal_vci_tgt_mnic("signal_vci_tgt_mnic");
680   VciSignals<vci_param_int>    signal_vci_tgt_cdma("signal_vci_tgt_cdma");
681   VciSignals<vci_param_int>    signal_vci_tgt_iopi("signal_vci_tgt_iopi");
682
683   VciSignals<vci_param_int>    signal_vci_cmd_to_noc("signal_vci_cmd_to_noc");
684   VciSignals<vci_param_int>    signal_vci_cmd_from_noc("signal_vci_cmd_from_noc");
685   
686   ////////////////////////////
687   //      Loader   
688   ////////////////////////////
689
690#if USE_IOC_RDK
691   soclib::common::Loader loader( soft_name, ramdisk_name );
692#else
693   soclib::common::Loader loader( soft_name );
694#endif
695
696   ///////////////////////////
697   //  processor iss
698   ///////////////////////////
699
700   typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;
701   proc_iss::set_loader( loader );
702
703   //////////////////////////////////////////////////////////////
704   // mesh construction: only (X_SIZE) * (Y_SIZE) clusters
705   //////////////////////////////////////////////////////////////
706
707   TsarLetiCluster<dspin_cmd_width,
708                   dspin_rsp_width,
709                   vci_param_int,
710                   vci_param_ext>*          clusters[X_SIZE][Y_SIZE];
711
712#if USE_OPENMP
713#pragma omp parallel
714    {
715#pragma omp for
716#endif
717        for (size_t i = 0; i  < (X_SIZE * (Y_SIZE)); i++)
718        {
719            size_t x = i / (Y_SIZE);
720            size_t y = i % (Y_SIZE);
721
722#if USE_OPENMP
723#pragma omp critical
724            {
725#endif
726            std::cout << std::endl;
727            std::cout << "Cluster_" << std::dec << x << "_" << y
728                      << " with cluster_xy = " << std::hex << cluster(x,y) << std::endl;
729            std::cout << std::endl;
730
731            std::ostringstream cluster_name;
732            cluster_name <<  "cluster_" << std::dec << x << "_" << y;
733
734            clusters[x][y] = new TsarLetiCluster<dspin_cmd_width,
735                                                 dspin_rsp_width,
736                                                 vci_param_int,
737                                                 vci_param_ext>
738            (
739                cluster_name.str().c_str(),
740                NB_PROCS_MAX,
741                x,
742                y,
743                cluster(x,y),
744                maptabd,
745                maptabx,
746                RESET_ADDRESS,
747                X_WIDTH,
748                Y_WIDTH,
749                vci_srcid_width - X_WIDTH - Y_WIDTH,   // l_id width,
750                MEMC_TGTID,
751                XICU_TGTID,
752                MTTY_TGTID,
753                BDEV_TGTID,
754                disk_name,
755                MEMC_WAYS,
756                MEMC_SETS,
757                L1_IWAYS,
758                L1_ISETS,
759                L1_DWAYS,
760                L1_DSETS,
761                XRAM_LATENCY,
762                loader,
763                frozen_cycles,
764                trace_from,
765                trace_proc_ok, 
766                trace_proc_id,
767                trace_memc_ok, 
768                trace_memc_id
769            );
770
771#if USE_OPENMP
772            } // end critical
773#endif
774        } // end for
775#if USE_OPENMP
776    }
777#endif
778
779    //////////////////////////////////////////////////////////////////
780    // IO bus and external peripherals in cluster[X_SIZE-1,Y_SIZE]
781    // - 6 local targets    : FBF, TTY, CMA, NIC, PIC, IOC
782    // - 3 local initiators : IOC, CMA, PIC
783    // There is no PROC, no MEMC and no XICU in this cluster,
784    // but the crossbar has (NB_PROCS_MAX + 3) intiators and
785    // 8 targets, in order to use the same SRCID and TGTID space
786    // (same mapping table for the internal components,
787    //  and for the external peripherals)
788    //////////////////////////////////////////////////////////////////
789
790    std::cout << std::endl;
791    std::cout << " Building IO cluster (external peripherals)" << std::endl;
792    std::cout << std::endl;
793 
794    size_t cluster_io = cluster(X_SIZE-1, Y_SIZE);
795
796    //////////// vci_local_crossbar 
797    VciLocalCrossbar<vci_param_int>*
798    iobus = new VciLocalCrossbar<vci_param_int>(
799                "iobus",
800                maptabd,                      // mapping table
801                cluster_io,                   // cluster_xy
802                NB_PROCS_MAX + 3,             // number of local initiators
803                8,                            // number of local targets
804                BDEV_TGTID );                 // default target index
805
806    //////////// vci_framebuffer                       
807    VciFrameBuffer<vci_param_int>*
808    fbuf = new VciFrameBuffer<vci_param_int>(
809                "fbuf",
810                IntTab(cluster_io, FBUF_TGTID),
811                maptabd,
812                FBUF_X_SIZE, FBUF_Y_SIZE );
813
814    ////////////  vci_block_device               
815    VciBlockDeviceTsar<vci_param_int>*
816    bdev = new VciBlockDeviceTsar<vci_param_int>(
817                "bdev",
818                maptabd,
819                IntTab(cluster_io, BDEV_SRCID),
820                IntTab(cluster_io, BDEV_TGTID),
821                disk_name,
822                512,                          // block size
823                64 );                         // burst size
824
825    //////////// vci_multi_nic               
826    VciMultiNic<vci_param_int>*
827    mnic = new VciMultiNic<vci_param_int>(
828             "mnic",
829                IntTab(cluster_io, MNIC_TGTID),
830                maptabd,
831                NB_NIC_CHANNELS,
832                NIC_MAC4,
833                NIC_MAC2,
834                NIC_RX_NAME,
835                NIC_TX_NAME );
836
837    ///////////// vci_chbuf_dma                   
838    VciChbufDma<vci_param_int>*
839    cdma = new VciChbufDma<vci_param_int>(
840                "cdma",
841                maptabd,
842                IntTab(cluster_io, CDMA_SRCID),
843                IntTab(cluster_io, CDMA_TGTID),
844                64,                          // burst size
845                NB_CMA_CHANNELS ); 
846
847    ////////////// vci_multi_tty
848    std::vector<std::string> vect_names;
849    for (size_t id = 0; id < NB_TTY_CHANNELS; id++)
850    {
851        std::ostringstream term_name;
852        term_name <<  "ext_" << id;
853        vect_names.push_back(term_name.str().c_str());
854    }
855
856    VciMultiTty<vci_param_int>* 
857    mtty = new VciMultiTty<vci_param_int>(
858                "mtty",
859                IntTab(cluster_io, MTTY_TGTID),
860                maptabd,
861                vect_names );
862
863    ///////////// vci_iopic
864    VciIopic<vci_param_int>*
865    iopic = new VciIopic<vci_param_int>(
866                "iopic",
867                maptabd,
868                IntTab(cluster_io, IOPI_SRCID),
869                IntTab(cluster_io, IOPI_TGTID),
870                32,
871                5000 );
872
873    ////////////// vci_dspin wrappers
874    VciDspinTargetWrapper<vci_param_int, dspin_cmd_width, dspin_rsp_width>*
875    wt_iobus = new VciDspinTargetWrapper<vci_param_int, dspin_cmd_width, dspin_rsp_width>(
876                "wt_bdev",
877                vci_srcid_width );
878
879    VciDspinInitiatorWrapper<vci_param_int, dspin_cmd_width, dspin_rsp_width>*
880    wi_iobus = new VciDspinInitiatorWrapper<vci_param_int, dspin_cmd_width, dspin_rsp_width>(
881                "wi_bdev",
882                vci_srcid_width );
883
884    ///////////////////////////////////////////////////////////////
885    //     Net-list
886    ///////////////////////////////////////////////////////////////
887
888    // iobus
889    iobus->p_clk                       (signal_clk); 
890    iobus->p_resetn                    (signal_resetn);
891
892    iobus->p_target_to_up              (signal_vci_cmd_from_noc);
893    iobus->p_initiator_to_up           (signal_vci_cmd_to_noc);
894
895    iobus->p_to_target[MEMC_TGTID]     (signal_vci_tgt_memc);
896    iobus->p_to_target[XICU_TGTID]     (signal_vci_tgt_xicu);
897    iobus->p_to_target[MTTY_TGTID]     (signal_vci_tgt_mtty);
898    iobus->p_to_target[FBUF_TGTID]     (signal_vci_tgt_fbuf);
899    iobus->p_to_target[MNIC_TGTID]     (signal_vci_tgt_mnic);
900    iobus->p_to_target[BDEV_TGTID]     (signal_vci_tgt_bdev);
901    iobus->p_to_target[CDMA_TGTID]     (signal_vci_tgt_cdma);
902    iobus->p_to_target[IOPI_TGTID]     (signal_vci_tgt_iopi);
903
904    for( size_t p=0 ; p<NB_PROCS_MAX ; p++ )
905    {
906        iobus->p_to_initiator[p]       (signal_vci_ini_proc[p]);
907    }
908    iobus->p_to_initiator[BDEV_SRCID]  (signal_vci_ini_bdev);
909    iobus->p_to_initiator[CDMA_SRCID]  (signal_vci_ini_cdma);
910    iobus->p_to_initiator[IOPI_SRCID]  (signal_vci_ini_iopi);
911
912    std::cout << "  - IOBUS connected" << std::endl;
913
914    // block_device
915    bdev->p_clk                        (signal_clk);
916    bdev->p_resetn                     (signal_resetn);
917    bdev->p_vci_target                 (signal_vci_tgt_bdev);
918    bdev->p_vci_initiator              (signal_vci_ini_bdev);
919    bdev->p_irq                        (signal_irq_bdev);
920
921    std::cout << "  - BDEV connected" << std::endl;
922
923    // frame_buffer
924    fbuf->p_clk                        (signal_clk);
925    fbuf->p_resetn                     (signal_resetn);
926    fbuf->p_vci                        (signal_vci_tgt_fbuf);
927
928    std::cout << "  - FBUF connected" << std::endl;
929
930    // multi_nic
931    mnic->p_clk                        (signal_clk);
932    mnic->p_resetn                     (signal_resetn);
933    mnic->p_vci                        (signal_vci_tgt_mnic);
934    for ( size_t i=0 ; i<NB_NIC_CHANNELS ; i++ )
935    {
936         mnic->p_rx_irq[i]             (signal_irq_mnic_rx[i]);
937         mnic->p_tx_irq[i]             (signal_irq_mnic_tx[i]);
938    }
939
940    std::cout << "  - MNIC connected" << std::endl;
941
942    // chbuf_dma
943    cdma->p_clk                        (signal_clk);
944    cdma->p_resetn                     (signal_resetn);
945    cdma->p_vci_target                 (signal_vci_tgt_cdma);
946    cdma->p_vci_initiator              (signal_vci_ini_cdma);
947    for ( size_t i=0 ; i<NB_CMA_CHANNELS ; i++)
948    {
949        cdma->p_irq[i]                 (signal_irq_cdma[i]);
950    }
951
952    std::cout << "  - CDMA connected" << std::endl;
953
954    // multi_tty
955    mtty->p_clk                        (signal_clk);
956    mtty->p_resetn                     (signal_resetn);
957    mtty->p_vci                        (signal_vci_tgt_mtty);
958    for ( size_t i=0 ; i<NB_TTY_CHANNELS ; i++ )
959    {
960        mtty->p_irq[i]                  (signal_irq_mtty_rx[i]);
961    }
962
963    std::cout << "  - MTTY connected" << std::endl;
964
965    // iopic
966    // NB_NIC_CHANNELS <= 2
967    // NB_CMA_CHANNELS <= 4
968    // NB_TTY_CHANNELS <= 8
969    iopic->p_clk                       (signal_clk);
970    iopic->p_resetn                    (signal_resetn);
971    iopic->p_vci_target                (signal_vci_tgt_iopi);
972    iopic->p_vci_initiator             (signal_vci_ini_iopi);
973    for ( size_t i=0 ; i<32 ; i++)
974    {
975       if     (i < NB_NIC_CHANNELS)    iopic->p_hwi[i] (signal_irq_mnic_rx[i]);
976       else if(i < 2 )                 iopic->p_hwi[i] (signal_irq_false);
977       else if(i < 2+NB_NIC_CHANNELS)  iopic->p_hwi[i] (signal_irq_mnic_tx[i-2]);
978       else if(i < 4 )                 iopic->p_hwi[i] (signal_irq_false);
979       else if(i < 4+NB_CMA_CHANNELS)  iopic->p_hwi[i] (signal_irq_cdma[i-4]);
980       else if(i < 8)                  iopic->p_hwi[i] (signal_irq_false);
981       else if(i == 8)                 iopic->p_hwi[i] (signal_irq_bdev);
982       else if(i < 16)                 iopic->p_hwi[i] (signal_irq_false);
983       else if(i < 16+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_mtty_rx[i-16]);
984       else if(i < 24)                 iopic->p_hwi[i] (signal_irq_false);
985       else if(i < 24+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_false);
986//     else if(i < 24+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_mtty_tx[i-24]);
987       else                            iopic->p_hwi[i] (signal_irq_false);
988    }
989
990    std::cout << "  - IOPIC connected" << std::endl;
991
992    // vci/dspin wrappers
993    wi_iobus->p_clk                    (signal_clk);
994    wi_iobus->p_resetn                 (signal_resetn);
995    wi_iobus->p_vci                    (signal_vci_cmd_to_noc);
996    wi_iobus->p_dspin_cmd              (signal_dspin_bound_cmd_in[X_SIZE-1][Y_SIZE-1][NORTH]);
997    wi_iobus->p_dspin_rsp              (signal_dspin_bound_rsp_out[X_SIZE-1][Y_SIZE-1][NORTH]);
998
999    // vci/dspin wrappers
1000    wt_iobus->p_clk                    (signal_clk);
1001    wt_iobus->p_resetn                 (signal_resetn);
1002    wt_iobus->p_vci                    (signal_vci_cmd_from_noc);
1003    wt_iobus->p_dspin_cmd              (signal_dspin_bound_cmd_out[X_SIZE-1][Y_SIZE-1][NORTH]);
1004    wt_iobus->p_dspin_rsp              (signal_dspin_bound_rsp_in[X_SIZE-1][Y_SIZE-1][NORTH]);
1005
1006    // Clock & RESET for clusters
1007    for (size_t x = 0; x < (X_SIZE); x++)
1008    {
1009        for (size_t y = 0; y < (Y_SIZE); y++)
1010        {
1011            clusters[x][y]->p_clk                    (signal_clk);
1012            clusters[x][y]->p_resetn                 (signal_resetn);
1013        }
1014    }
1015
1016    // Inter Clusters horizontal connections
1017    if (X_SIZE > 1)
1018    {
1019        for (size_t x = 0; x < (X_SIZE-1); x++)
1020        {
1021            for (size_t y = 0; y < (Y_SIZE); y++)
1022            {
1023                clusters[x][y]->p_cmd_out[EAST]      (signal_dspin_h_cmd_inc[x][y]);
1024                clusters[x+1][y]->p_cmd_in[WEST]     (signal_dspin_h_cmd_inc[x][y]);
1025                clusters[x][y]->p_cmd_in[EAST]       (signal_dspin_h_cmd_dec[x][y]);
1026                clusters[x+1][y]->p_cmd_out[WEST]    (signal_dspin_h_cmd_dec[x][y]);
1027
1028                clusters[x][y]->p_rsp_out[EAST]      (signal_dspin_h_rsp_inc[x][y]);
1029                clusters[x+1][y]->p_rsp_in[WEST]     (signal_dspin_h_rsp_inc[x][y]);
1030                clusters[x][y]->p_rsp_in[EAST]       (signal_dspin_h_rsp_dec[x][y]);
1031                clusters[x+1][y]->p_rsp_out[WEST]    (signal_dspin_h_rsp_dec[x][y]);
1032
1033                clusters[x][y]->p_m2p_out[EAST]      (signal_dspin_h_m2p_inc[x][y]);
1034                clusters[x+1][y]->p_m2p_in[WEST]     (signal_dspin_h_m2p_inc[x][y]);
1035                clusters[x][y]->p_m2p_in[EAST]       (signal_dspin_h_m2p_dec[x][y]);
1036                clusters[x+1][y]->p_m2p_out[WEST]    (signal_dspin_h_m2p_dec[x][y]);
1037
1038                clusters[x][y]->p_p2m_out[EAST]      (signal_dspin_h_p2m_inc[x][y]);
1039                clusters[x+1][y]->p_p2m_in[WEST]     (signal_dspin_h_p2m_inc[x][y]);
1040                clusters[x][y]->p_p2m_in[EAST]       (signal_dspin_h_p2m_dec[x][y]);
1041                clusters[x+1][y]->p_p2m_out[WEST]    (signal_dspin_h_p2m_dec[x][y]);
1042
1043                clusters[x][y]->p_cla_out[EAST]      (signal_dspin_h_cla_inc[x][y]);
1044                clusters[x+1][y]->p_cla_in[WEST]     (signal_dspin_h_cla_inc[x][y]);
1045                clusters[x][y]->p_cla_in[EAST]       (signal_dspin_h_cla_dec[x][y]);
1046                clusters[x+1][y]->p_cla_out[WEST]    (signal_dspin_h_cla_dec[x][y]);
1047            }
1048        }
1049    }
1050    std::cout << std::endl << "Horizontal connections done" << std::endl;   
1051
1052    // Inter Clusters vertical connections
1053    if (Y_SIZE > 1) 
1054    {
1055        for (size_t y = 0; y < (Y_SIZE-1); y++)
1056        {
1057            for (size_t x = 0; x < X_SIZE; x++)
1058            {
1059                clusters[x][y]->p_cmd_out[NORTH]     (signal_dspin_v_cmd_inc[x][y]);
1060                clusters[x][y+1]->p_cmd_in[SOUTH]    (signal_dspin_v_cmd_inc[x][y]);
1061                clusters[x][y]->p_cmd_in[NORTH]      (signal_dspin_v_cmd_dec[x][y]);
1062                clusters[x][y+1]->p_cmd_out[SOUTH]   (signal_dspin_v_cmd_dec[x][y]);
1063
1064                clusters[x][y]->p_rsp_out[NORTH]     (signal_dspin_v_rsp_inc[x][y]);
1065                clusters[x][y+1]->p_rsp_in[SOUTH]    (signal_dspin_v_rsp_inc[x][y]);
1066                clusters[x][y]->p_rsp_in[NORTH]      (signal_dspin_v_rsp_dec[x][y]);
1067                clusters[x][y+1]->p_rsp_out[SOUTH]   (signal_dspin_v_rsp_dec[x][y]);
1068
1069                clusters[x][y]->p_m2p_out[NORTH]     (signal_dspin_v_m2p_inc[x][y]);
1070                clusters[x][y+1]->p_m2p_in[SOUTH]    (signal_dspin_v_m2p_inc[x][y]);
1071                clusters[x][y]->p_m2p_in[NORTH]      (signal_dspin_v_m2p_dec[x][y]);
1072                clusters[x][y+1]->p_m2p_out[SOUTH]   (signal_dspin_v_m2p_dec[x][y]);
1073
1074                clusters[x][y]->p_p2m_out[NORTH]     (signal_dspin_v_p2m_inc[x][y]);
1075                clusters[x][y+1]->p_p2m_in[SOUTH]    (signal_dspin_v_p2m_inc[x][y]);
1076                clusters[x][y]->p_p2m_in[NORTH]      (signal_dspin_v_p2m_dec[x][y]);
1077                clusters[x][y+1]->p_p2m_out[SOUTH]   (signal_dspin_v_p2m_dec[x][y]);
1078
1079                clusters[x][y]->p_cla_out[NORTH]     (signal_dspin_v_cla_inc[x][y]);
1080                clusters[x][y+1]->p_cla_in[SOUTH]    (signal_dspin_v_cla_inc[x][y]);
1081                clusters[x][y]->p_cla_in[NORTH]      (signal_dspin_v_cla_dec[x][y]);
1082                clusters[x][y+1]->p_cla_out[SOUTH]   (signal_dspin_v_cla_dec[x][y]);
1083            }
1084        }
1085    }
1086    std::cout << std::endl << "Vertical connections done" << std::endl;
1087
1088    // East & West boundary cluster connections
1089    for (size_t y = 0; y < (Y_SIZE); y++)
1090    {
1091        clusters[0][y]->p_cmd_in[WEST]           (signal_dspin_bound_cmd_in[0][y][WEST]);
1092        clusters[0][y]->p_cmd_out[WEST]          (signal_dspin_bound_cmd_out[0][y][WEST]);
1093        clusters[X_SIZE-1][y]->p_cmd_in[EAST]    (signal_dspin_bound_cmd_in[X_SIZE-1][y][EAST]);
1094        clusters[X_SIZE-1][y]->p_cmd_out[EAST]   (signal_dspin_bound_cmd_out[X_SIZE-1][y][EAST]);
1095
1096        clusters[0][y]->p_rsp_in[WEST]           (signal_dspin_bound_rsp_in[0][y][WEST]);
1097        clusters[0][y]->p_rsp_out[WEST]          (signal_dspin_bound_rsp_out[0][y][WEST]);
1098        clusters[X_SIZE-1][y]->p_rsp_in[EAST]    (signal_dspin_bound_rsp_in[X_SIZE-1][y][EAST]);
1099        clusters[X_SIZE-1][y]->p_rsp_out[EAST]   (signal_dspin_bound_rsp_out[X_SIZE-1][y][EAST]);
1100
1101        clusters[0][y]->p_m2p_in[WEST]           (signal_dspin_bound_m2p_in[0][y][WEST]);
1102        clusters[0][y]->p_m2p_out[WEST]          (signal_dspin_bound_m2p_out[0][y][WEST]);
1103        clusters[X_SIZE-1][y]->p_m2p_in[EAST]    (signal_dspin_bound_m2p_in[X_SIZE-1][y][EAST]);
1104        clusters[X_SIZE-1][y]->p_m2p_out[EAST]   (signal_dspin_bound_m2p_out[X_SIZE-1][y][EAST]);
1105
1106        clusters[0][y]->p_p2m_in[WEST]           (signal_dspin_bound_p2m_in[0][y][WEST]);
1107        clusters[0][y]->p_p2m_out[WEST]          (signal_dspin_bound_p2m_out[0][y][WEST]);
1108        clusters[X_SIZE-1][y]->p_p2m_in[EAST]    (signal_dspin_bound_p2m_in[X_SIZE-1][y][EAST]);
1109        clusters[X_SIZE-1][y]->p_p2m_out[EAST]   (signal_dspin_bound_p2m_out[X_SIZE-1][y][EAST]);
1110
1111        clusters[0][y]->p_cla_in[WEST]           (signal_dspin_bound_cla_in[0][y][WEST]);
1112        clusters[0][y]->p_cla_out[WEST]          (signal_dspin_bound_cla_out[0][y][WEST]);
1113        clusters[X_SIZE-1][y]->p_cla_in[EAST]    (signal_dspin_bound_cla_in[X_SIZE-1][y][EAST]);
1114        clusters[X_SIZE-1][y]->p_cla_out[EAST]   (signal_dspin_bound_cla_out[X_SIZE-1][y][EAST]);
1115    }
1116
1117    std::cout << std::endl << "West & East boundaries connections done" << std::endl;
1118
1119    // North & South boundary clusters connections
1120    for (size_t x = 0; x < X_SIZE; x++)
1121    {
1122        clusters[x][0]->p_cmd_in[SOUTH]          (signal_dspin_bound_cmd_in[x][0][SOUTH]);
1123        clusters[x][0]->p_cmd_out[SOUTH]         (signal_dspin_bound_cmd_out[x][0][SOUTH]);
1124        clusters[x][Y_SIZE-1]->p_cmd_in[NORTH]   (signal_dspin_bound_cmd_in[x][Y_SIZE-1][NORTH]);
1125        clusters[x][Y_SIZE-1]->p_cmd_out[NORTH]  (signal_dspin_bound_cmd_out[x][Y_SIZE-1][NORTH]);
1126
1127        clusters[x][0]->p_rsp_in[SOUTH]          (signal_dspin_bound_rsp_in[x][0][SOUTH]);
1128        clusters[x][0]->p_rsp_out[SOUTH]         (signal_dspin_bound_rsp_out[x][0][SOUTH]);
1129        clusters[x][Y_SIZE-1]->p_rsp_in[NORTH]   (signal_dspin_bound_rsp_in[x][Y_SIZE-1][NORTH]);
1130        clusters[x][Y_SIZE-1]->p_rsp_out[NORTH]  (signal_dspin_bound_rsp_out[x][Y_SIZE-1][NORTH]);
1131
1132        clusters[x][0]->p_m2p_in[SOUTH]          (signal_dspin_bound_m2p_in[x][0][SOUTH]);
1133        clusters[x][0]->p_m2p_out[SOUTH]         (signal_dspin_bound_m2p_out[x][0][SOUTH]);
1134        clusters[x][Y_SIZE-1]->p_m2p_in[NORTH]   (signal_dspin_bound_m2p_in[x][Y_SIZE-1][NORTH]);
1135        clusters[x][Y_SIZE-1]->p_m2p_out[NORTH]  (signal_dspin_bound_m2p_out[x][Y_SIZE-1][NORTH]);
1136
1137        clusters[x][0]->p_p2m_in[SOUTH]          (signal_dspin_bound_p2m_in[x][0][SOUTH]);
1138        clusters[x][0]->p_p2m_out[SOUTH]         (signal_dspin_bound_p2m_out[x][0][SOUTH]);
1139        clusters[x][Y_SIZE-1]->p_p2m_in[NORTH]   (signal_dspin_bound_p2m_in[x][Y_SIZE-1][NORTH]);
1140        clusters[x][Y_SIZE-1]->p_p2m_out[NORTH]  (signal_dspin_bound_p2m_out[x][Y_SIZE-1][NORTH]);
1141
1142        clusters[x][0]->p_cla_in[SOUTH]          (signal_dspin_bound_cla_in[x][0][SOUTH]);
1143        clusters[x][0]->p_cla_out[SOUTH]         (signal_dspin_bound_cla_out[x][0][SOUTH]);
1144        clusters[x][Y_SIZE-1]->p_cla_in[NORTH]   (signal_dspin_bound_cla_in[x][Y_SIZE-1][NORTH]);
1145        clusters[x][Y_SIZE-1]->p_cla_out[NORTH]  (signal_dspin_bound_cla_out[x][Y_SIZE-1][NORTH]);
1146    }
1147
1148    std::cout << std::endl << "North & South boundaries connections done" << std::endl;
1149
1150    std::cout << std::endl;
1151
1152    ////////////////////////////////////////////////////////
1153    //   Simulation
1154    ///////////////////////////////////////////////////////
1155
1156    sc_start(sc_core::sc_time(0, SC_NS));
1157    signal_resetn    = false;
1158    signal_irq_false = false;
1159
1160    // set network boundaries signals default values
1161    // for all boundary clusters but the IO cluster
1162    for (size_t x = 0; x < X_SIZE ; x++)
1163    {
1164        for (size_t y = 0; y < Y_SIZE ; y++)
1165        {
1166            for (size_t face = 0; face < 4; face++)
1167            {
1168                if ( (x != X_SIZE-1) or (y != Y_SIZE-1) or (face != NORTH) )
1169                {
1170                    signal_dspin_bound_cmd_in [x][y][face].write = false;
1171                    signal_dspin_bound_cmd_in [x][y][face].read  = true;
1172                    signal_dspin_bound_cmd_out[x][y][face].write = false;
1173                    signal_dspin_bound_cmd_out[x][y][face].read  = true;
1174
1175                    signal_dspin_bound_rsp_in [x][y][face].write = false;
1176                    signal_dspin_bound_rsp_in [x][y][face].read  = true;
1177                    signal_dspin_bound_rsp_out[x][y][face].write = false;
1178                    signal_dspin_bound_rsp_out[x][y][face].read  = true;
1179                }
1180
1181                signal_dspin_bound_m2p_in [x][y][face].write = false;
1182                signal_dspin_bound_m2p_in [x][y][face].read  = true;
1183                signal_dspin_bound_m2p_out[x][y][face].write = false;
1184                signal_dspin_bound_m2p_out[x][y][face].read  = true;
1185
1186                signal_dspin_bound_p2m_in [x][y][face].write = false;
1187                signal_dspin_bound_p2m_in [x][y][face].read  = true;
1188                signal_dspin_bound_p2m_out[x][y][face].write = false;
1189                signal_dspin_bound_p2m_out[x][y][face].read  = true;
1190
1191                signal_dspin_bound_cla_in [x][y][face].write = false;
1192                signal_dspin_bound_cla_in [x][y][face].read  = true;
1193                signal_dspin_bound_cla_out[x][y][face].write = false;
1194                signal_dspin_bound_cla_out[x][y][face].read  = true;
1195            }
1196        }
1197    }
1198
1199    // set default values for VCI signals connected to unused ports on iobus
1200    signal_vci_tgt_memc.rspval = false;
1201    signal_vci_tgt_xicu.rspval = false;
1202    for ( size_t p = 0 ; p < NB_PROCS_MAX ; p++ ) signal_vci_ini_proc[p].cmdval = false;
1203
1204    sc_start(sc_core::sc_time(1, SC_NS));
1205    signal_resetn = true;
1206
1207    if (gettimeofday(&t1, NULL) != 0) 
1208    {
1209        perror("gettimeofday");
1210        return EXIT_FAILURE;
1211    }
1212
1213    // variable used for IRQ trace
1214    bool prev_irq_bdev = false;
1215    bool prev_irq_mtty_rx[8];
1216    bool prev_irq_proc[16][16][4];
1217
1218    for( size_t x = 0 ; x<8  ; x++ ) prev_irq_mtty_rx[x] = false;
1219
1220    for( size_t x = 0 ; x<16 ; x++ )
1221    for( size_t y = 0 ; y<16 ; y++ )
1222    for( size_t i = 0 ; i<4  ; i++ ) prev_irq_proc[x][y][i] = false;
1223
1224    for (uint64_t n = 1; n < ncycles && !stop_called; n++)
1225    {
1226        // Monitor a specific address for L1 & L2 caches
1227        // clusters[0][0]->proc[0]->cache_monitor(0x110002C078ULL);
1228        // clusters[1][1]->memc->cache_monitor(0x110002c078ULL);
1229
1230        // stats display
1231        if( (n % 5000000) == 0)
1232        {
1233
1234            if (gettimeofday(&t2, NULL) != 0) 
1235            {
1236                perror("gettimeofday");
1237                return EXIT_FAILURE;
1238            }
1239
1240            ms1 = (uint64_t) t1.tv_sec * 1000ULL + (uint64_t) t1.tv_usec / 1000;
1241            ms2 = (uint64_t) t2.tv_sec * 1000ULL + (uint64_t) t2.tv_usec / 1000;
1242            std::cerr << "platform clock frequency " 
1243                      << (double) 5000000 / (double) (ms2 - ms1) << "Khz" << std::endl;
1244
1245            if (gettimeofday(&t1, NULL) != 0) 
1246            {
1247                perror("gettimeofday");
1248                return EXIT_FAILURE;
1249            }
1250        }
1251
1252        // trace display
1253        if ( trace_ok and (n > trace_from) )
1254        {
1255            std::cout << "****************** cycle " << std::dec << n ;
1256            std::cout << " ************************************************" << std::endl;
1257
1258            size_t l = 0;
1259            size_t x = 0;
1260            size_t y = 0;
1261
1262            if ( trace_proc_ok )
1263            {
1264                l = trace_proc_id % NB_PROCS_MAX ;
1265                x = (trace_proc_id / NB_PROCS_MAX) >> Y_WIDTH ;
1266                y = (trace_proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
1267
1268                std::ostringstream proc_signame;
1269                proc_signame << "[SIG]PROC_" << x << "_" << y << "_" << l ;
1270                clusters[x][y]->proc[l]->print_trace(1);
1271                clusters[x][y]->signal_vci_ini_proc[l].print_trace(proc_signame.str());
1272
1273                std::ostringstream xicu_signame;
1274                xicu_signame << "[SIG]XICU_" << x << "_" << y ;
1275                clusters[x][y]->xicu->print_trace(0);
1276                clusters[x][y]->signal_vci_tgt_xicu.print_trace(xicu_signame.str());
1277            }
1278
1279            if ( trace_memc_ok )
1280            {
1281                x = trace_memc_id >> Y_WIDTH;
1282                y = trace_memc_id & ((1<<Y_WIDTH) - 1);
1283
1284                std::ostringstream smemc;
1285                smemc << "[SIG]MEMC_" << x << "_" << y;
1286                std::ostringstream sxram;
1287                sxram << "[SIG]XRAM_" << x << "_" << y;
1288
1289                clusters[x][y]->memc->print_trace();
1290                clusters[x][y]->signal_vci_tgt_memc.print_trace(smemc.str());
1291                clusters[x][y]->signal_vci_xram.print_trace(sxram.str());
1292            }   
1293
1294            // trace coherence signals
1295            // clusters[0][0]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_0_0]");
1296            // clusters[0][1]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_0_1]");
1297            // clusters[1][0]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_1_0]");
1298            // clusters[1][1]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_1_1]");
1299
1300            // clusters[0][0]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_0_0]");
1301            // clusters[0][1]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_0_1]");
1302            // clusters[1][0]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_1_0]");
1303            // clusters[1][1]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_1_1]");
1304
1305            // trace xbar(s) m2p
1306            // clusters[0][0]->xbar_m2p->print_trace();
1307            // clusters[1][0]->xbar_m2p->print_trace();
1308            // clusters[0][1]->xbar_m2p->print_trace();
1309            // clusters[1][1]->xbar_m2p->print_trace();
1310       
1311            // trace router(s) m2p
1312            // clusters[0][0]->router_m2p->print_trace();
1313            // clusters[1][0]->router_m2p->print_trace();
1314            // clusters[0][1]->router_m2p->print_trace();
1315            // clusters[1][1]->router_m2p->print_trace();
1316       
1317            // trace external ioc
1318            bdev->print_trace();
1319            signal_vci_tgt_bdev.print_trace("[SIG]BDEV_TGT");
1320            signal_vci_ini_bdev.print_trace("[SIG]BDEV_INI");
1321
1322            // trace external iopic
1323            iopic->print_trace();
1324            signal_vci_tgt_iopi.print_trace("[SIG]IOPI_TGT");
1325            signal_vci_ini_iopi.print_trace("[SIG]IOPI_INI");
1326
1327            // trace internal tty
1328            // clusters[0][0]->mtty->print_trace();
1329            // clusters[0][0]->signal_vci_tgt_mtty.print_trace("[SIG]MTTY");
1330
1331        }  // end trace
1332
1333        if (0)
1334        {
1335            // trace BDV interrupts events
1336            if ( signal_irq_bdev.read() != prev_irq_bdev ) 
1337            {
1338                prev_irq_bdev = signal_irq_bdev.read();
1339                std::cout << std::dec << "@@@ IRQ_BDEV = " << signal_irq_bdev.read()
1340                          << " at cycle " << n << std::endl;
1341            }
1342       
1343            // trace TTY interrupts events
1344            for ( size_t x = 0 ; x < 8 ; x++ )
1345            {
1346                if ( signal_irq_mtty_rx[x].read() != prev_irq_mtty_rx[x] ) 
1347                {
1348                    prev_irq_mtty_rx[x] = signal_irq_mtty_rx[x].read();
1349                    std::cout << std::dec << "@@@ IRQ_MTTY["<<x<<"] = " 
1350                              << signal_irq_mtty_rx[x].read()
1351                              << " at cycle " << n << std::endl;
1352                }
1353            }
1354
1355            // trace processor interrupts events
1356            for ( size_t x = 0 ; x < X_SIZE ; x++ )
1357            for ( size_t y = 0 ; y < Y_SIZE ; y++ )
1358            for ( size_t i = 0 ; i < NB_PROCS_MAX ; i++ )
1359            {
1360                if ( clusters[x][y]->signal_proc_irq[i] != prev_irq_proc[x][y][i] )
1361                { 
1362                    prev_irq_proc[x][y][i] = clusters[x][y]->signal_proc_irq[i];
1363                    std::cout << std::dec << "@@@ IRQ_PROC["<<x<<","<<y<<","<<i<<"] = "
1364                              << clusters[x][y]->signal_proc_irq[i]
1365                              << " at cycle " << n << std::endl;
1366                }
1367            }
1368
1369            // trace VCI transactions on IOPIC and XCU(0,0)
1370            signal_vci_tgt_iopi.print_trace("@@@ IOPI_TGT");
1371            signal_vci_ini_iopi.print_trace("@@@ IOPI_INI");
1372            clusters[0][0]->signal_vci_tgt_xicu.print_trace("@@@ XCU_0_0");
1373        }
1374
1375        sc_start(sc_core::sc_time(1, SC_NS));
1376    }
1377    // Free memory
1378    for (size_t i = 0 ; i  < (X_SIZE * Y_SIZE) ; i++)
1379    {
1380        size_t x = i / (Y_SIZE);
1381        size_t y = i % (Y_SIZE);
1382        delete clusters[x][y];
1383    }
1384
1385    return EXIT_SUCCESS;
1386}
1387
1388
1389void handler(int dummy = 0) 
1390{
1391   stop_called = true;
1392   sc_stop();
1393}
1394
1395void voidhandler(int dummy = 0) {}
1396
1397int sc_main (int argc, char *argv[])
1398{
1399   signal(SIGINT, handler);
1400   signal(SIGPIPE, voidhandler);
1401
1402   try {
1403      return _main(argc, argv);
1404   } catch (std::exception &e) {
1405      std::cout << e.what() << std::endl;
1406   } catch (...) {
1407      std::cout << "Unknown exception occured" << std::endl;
1408      throw;
1409   }
1410   return 1;
1411}
1412
1413
1414// Local Variables:
1415// tab-width: 3
1416// c-basic-offset: 3
1417// c-file-offsets:((innamespace . 0)(inline-open . 0))
1418// indent-tabs-mode: nil
1419// End:
1420
1421// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
Note: See TracBrowser for help on using the repository browser.