source: branches/v4/platforms/tsarv4_generic_xbar/top.cpp @ 485

Last change on this file since 485 was 172, checked in by alain, 13 years ago
File size: 37.4 KB
Line 
1/////////////////////////////////////////////////////////////////////////
2// File: tsarv4_generic_xbar.cpp
3// Author: Alain Greiner
4// Copyright: UPMC/LIP6
5// Date : april 2011
6// This program is released under the GNU public license
7/////////////////////////////////////////////////////////////////////////
8// This file define a generic TSAR architecture without virtual memory.
9// - It uses vci_local_crossbar as local interconnect
10// - It uses virtual_dspin as global interconnect
11// - It uses the vci_cc_xcache_wrapper_v4
12// - It uses the vci_mem_cache_v4
13// - It uses the vci_xicu, with one vci_multi_tty, and one
14//   vci_multi_dma controlers per cluster.
15// The physical address space is 32 bits.
16// The number of clusters cannot be larger than 256.
17// The number of processors per cluster cannot be larger than 4.
18// The parameters must be power of 2.
19// - xmax   : number of clusters in a row
20// - ymax   : number of clusters in a column
21// - nprocs : number of processors per cluster
22//
23// The peripherals BDEV, FBUF, and the boot BROM
24// are in the cluster containing address 0xBFC00000.
25// - The nprocs TTY IRQs are connected to IRQ_IN[0] to IRQ_IN[3]
26// - The nprocs DMA IRQs are connected to IRQ_IN[4] to IRQ_IN[7]
27// - The IOC IRQ is connected to IRQ_IN[8]
28//
29// General policy for 32 bits address decoding in direct space:
30// All segments base addresses are multiple of 64 Kbytes
31// Therefore the 16 address MSB bits completely define the target:
32// The (x_width + y_width) MSB bits (left aligned) define
33// the cluster index, and the 8 LSB bits define the local index:
34//
35//      | X_ID  | Y_ID  |---| LADR |     OFFSET          |
36//      |x_width|y_width|---|  8   |       16            |
37//
38// Half of all clusters being in the protected address space domain
39// (addresses larger than 0x8000000), software must execute in
40// kernel mode to access memory if we want to exploit locality,
41// because some stacks and heaps will be in the protected domain.
42/////////////////////////////////////////////////////////////////////////
43
44#include <systemc>
45#include <sys/time.h>
46#include <iostream>
47#include <sstream>
48#include <cstdlib>
49#include <cstdarg>
50#include <stdint.h>
51
52#include "gdbserver.h"
53#include "mapping_table.h"
54#include "tsarv4_cluster_xbar.h"
55#include "alloc_elems.h"
56
57///////////////////////////////////////////////////
58//               Parallelisation
59///////////////////////////////////////////////////
60
61#define OMP_THREADS             8
62
63#ifdef _OPENMP
64#include <omp.h>
65#endif
66
67
68//  cluster index (computed from x,y coordinates)
69#define cluster(x,y)    (y + ymax*x)
70
71// flit widths for the DSPIN network
72#define cmd_width                40
73#define rsp_width                33
74
75// VCI format
76#define cell_width               4
77#define address_width            32
78#define plen_width               8
79#define error_width              2
80#define clen_width               1
81#define rflag_width              1
82#define srcid_width              14
83#define pktid_width              4
84#define trdid_width              4
85#define wrplen_width             1
86
87///////////////////////////////////////////////////
88//     Parameters default values         
89///////////////////////////////////////////////////
90
91#define MESH_XMAX               2
92#define MESH_YMAX               2
93
94#define NPROCS                  4
95#define XRAM_LATENCY            0
96
97#define MEMC_WAYS               16
98#define MEMC_SETS               256
99
100#define L1_IWAYS                4
101#define L1_ISETS                64
102
103#define L1_DWAYS                4
104#define L1_DSETS                64
105
106#define FBUF_X_SIZE             1024
107#define FBUF_Y_SIZE             1024
108
109#define BDEV_SECTOR_SIZE        1024
110#define BDEV_IMAGE_NAME         "../../softs/soft_filter_giet/philips_image.raw"
111
112#define BOOT_SOFT_NAME          "../../softs/soft_filter_giet/bin.soft"
113
114/////////////////////////////////////////////////////////
115// Segments definition
116/////////////////////////////////////////////////////////
117// There is 5 segments replicated in all clusters:
118// - seg_icu    -> ICU  / LADR = 0xF0
119// - seg_tty    -> MTTY / LADR = 0xF1
120// - seg_dma    -> CDMA / LADR = 0xF2
121// - seg_stack  -> RAM  / LADR = 0x80 to 0x8F
122// - seg_heap   -> RAM  / LADR = 0x30 to 0x7F
123//
124// There is 3 specific segments in the "IO" cluster
125// (containing address 0xBF000000)
126// - seg_reset  -> BROM / LADR = 0xC0 to 0xCF
127// - seg_fbuf   -> FBUF / LADR = 0xD0 to OxEF
128// - seg_bdev   -> BDEV / LADR = 0xF3
129//
130// There is 3 specific segments in the "kcode" cluster
131// (containing address 0x80000000)
132// - seg_kcode  -> RAM  / LADR = 0x00 to 0x0F
133// - seg_kdata  -> RAM  / LADR = 0x10 to 0x1F
134// - seg_kunc   -> RAM  / LADR = 0x20 to 0x2F
135//
136// There is 2 specific segments in the "code" cluster
137// (containing address 0x00000000)
138// - seg_code   -> RAM  / LADR = 0x00 to Ox0F
139// - seg_data   -> RAM  / LADR = 0x10 to 0x1F
140//
141// There is one special segment corresponding to
142// the processors in the coherence address space
143// - seg_proc   -> PROCS / LADR = 0xB0 to 0xBF
144///////////////////////////////////////////////////
145
146// specific segments in "kcode" cluster
147
148#define KCOD_BASE               0x80000000     
149#define KCOD_SIZE               0x00010000
150
151#define KDAT_BASE               0x80100000     
152#define KDAT_SIZE               0x00010000
153
154#define KUNC_BASE               0x80200000     
155#define KUNC_SIZE               0x00010000
156
157// specific segments in "code" cluster
158
159#define CODE_BASE               0x00000000     
160#define CODE_SIZE               0x00010000
161
162#define DATA_BASE               0x00100000     
163#define DATA_SIZE               0x00010000
164
165// specific segments in "IO" cluster
166
167#define BROM_BASE               0xBFC00000     
168#define BROM_SIZE               0x00010000
169
170#define FBUF_BASE               0xBFD00000     
171#define FBUF_SIZE               0x00200000
172
173#define BDEV_BASE               0xBFF30000     
174#define BDEV_SIZE               0x00000020
175
176// replicated segments
177
178#define HEAP_BASE               0x00300000     
179#define HEAP_SIZE               0x00500000
180
181#define STAK_BASE               0x00800000     
182#define STAK_SIZE               0x00100000
183
184#define XICU_BASE               0x00F00000     
185#define XICU_SIZE               0x00001000
186
187#define MTTY_BASE               0x00F10000     
188#define MTTY_SIZE               0x00000040
189
190#define CDMA_BASE               0x00F20000     
191#define CDMA_SIZE               0x00000080
192
193#define PROC_BASE               0x00B00000     
194#define PROC_SIZE               0x00000010
195
196////////////////////////////////////////////////////////////////////
197//     TGTID definition in direct space
198// For all components:  global TGTID = global SRCID = cluster_index
199////////////////////////////////////////////////////////////////////
200
201#define MEMC_TGTID               0
202#define XICU_TGTID               1
203#define MTTY_TGTID               2
204#define CDMA_TGTID               3
205#define FBUF_TGTID               4
206#define BROM_TGTID               5
207#define BDEV_TGTID               6
208
209///////////////////////////////////////////////////
210// service functions for VCI & DSIN signal trace
211//////////////////////////////////////////////////
212
213template <typename T>
214void  print_vci_signal(std::string name, T &sig) 
215{
216    if ( sig.cmdval )
217    {
218        std::cout << name << std::hex << " CMD VCI : "; 
219        if ( sig.cmd.read() == 1 )      std::cout << "RD ";
220        if ( sig.cmd.read() == 2 )      std::cout << "WR ";
221        if ( sig.cmd.read() == 3 )      std::cout << "LL ";
222        if ( sig.cmd.read() == 0 )      std::cout << "SC ";
223        std::cout  << " @ = " << sig.address
224                   << " | wdata = " << sig.wdata 
225                   << " | srcid = " << sig.srcid
226                   << " | trdid = " << sig.trdid
227                   << " | eop = " << sig.eop
228                   << " | ack = " << sig.cmdack << std::endl;
229    }
230    if ( sig.rspval )
231    {
232         std::cout << name << std::hex
233                   << " RSP VCI : rerror = " << sig.rerror
234                   << " | rdata = " << sig.rdata
235                   << " | rsrcid = " << sig.rsrcid
236                   << " | rtrdid = " << sig.rtrdid
237                   << " | reop = " << sig.reop
238                   << " | ack = " << sig.rspack << std::endl;
239    }
240}
241
242template <typename T>
243void print_dspin_signal(std::string name, T &sig)
244{
245    if ( sig.write )
246    {
247        std::cout << name << " DSPIN : data = " << std::hex << sig.data
248                  << " | ack = " << sig.read << std::endl;
249    }
250}
251
252/////////////////////////////////
253int _main(int argc, char *argv[])
254{
255    using namespace sc_core;
256    using namespace soclib::caba;
257    using namespace soclib::common;
258   
259   
260    char    soft_name[256] = BOOT_SOFT_NAME;    // pathname to binary code
261    size_t  ncycles        = 1000000000;        // simulated cycles
262    size_t  xmax           = MESH_XMAX;         // number of clusters in a row
263    size_t  ymax           = MESH_YMAX;         // number of clusters in a column
264    size_t  nprocs         = NPROCS;            // number of processors per cluster
265    size_t  xfb            = FBUF_X_SIZE;       // frameBuffer column number
266    size_t  yfb            = FBUF_Y_SIZE;       // frameBuffer lines number
267    size_t  memc_ways      = MEMC_WAYS;
268    size_t  memc_sets      = MEMC_SETS;
269    size_t  l1_d_ways      = L1_DWAYS;
270    size_t  l1_d_sets      = L1_DSETS;
271    size_t  l1_i_ways      = L1_IWAYS;
272    size_t  l1_i_sets      = L1_ISETS;
273    char    disk_name[256] = BDEV_IMAGE_NAME;   // pathname to the disk image
274    size_t  blk_size       = BDEV_SECTOR_SIZE;  // block size (in bytes)
275    size_t  xram_latency   = XRAM_LATENCY;      // external RAM latency
276    bool    trace_ok       = false;             // debug activated
277    size_t  from_cycle     = 0;                 // debug start cycle
278    size_t  omp_threads    = OMP_THREADS;       // number of cores for OpenMP
279
280    ////////////// command line arguments //////////////////////
281    if (argc > 1)
282    {
283        for( int n=1 ; n<argc ; n=n+2 )
284        {
285            if( (strcmp(argv[n],"-NCYCLES") == 0) && (n+1<argc) )
286            {
287                ncycles = atoi(argv[n+1]);
288            }
289            else if( (strcmp(argv[n],"-NPROCS") == 0) && (n+1<argc) )
290            {
291                nprocs = atoi(argv[n+1]);
292                assert( ((nprocs == 1) || (nprocs == 2) || (nprocs == 4)) &&
293                        "NPROCS must be equal to 1, 2, or 4");
294            }
295            else if( (strcmp(argv[n],"-THREADS") == 0) && (n+1<argc) )
296            {
297                omp_threads = atoi(argv[n+1]);
298            }
299            else if( (strcmp(argv[n],"-XMAX") == 0) && (n+1<argc) )
300            {
301                xmax = atoi(argv[n+1]);
302                assert( ((xmax == 1) || (xmax == 2) || (xmax == 4) || (xmax == 8) || (xmax == 16)) 
303                         && "The XMAX parameter must be 2, 4, 8, or 16" );
304            }
305           
306            else if( (strcmp(argv[n],"-YMAX") == 0) && (n+1<argc) )
307            {
308                ymax = atoi(argv[n+1]);
309                assert( ((ymax == 1) || (ymax == 2) || (ymax == 4) || (ymax == 8) || (ymax == 16)) 
310                         && "The YMAX parameter must be 2, 4, 8, or 16" );
311            }
312            else if( (strcmp(argv[n],"-XFB") == 0) && (n+1<argc) )
313            {
314                xfb = atoi(argv[n+1]);
315            }
316            else if( (strcmp(argv[n],"-YFB") == 0) && (n+1<argc) )
317            {
318                yfb = atoi(argv[n+1]);
319            }
320            else if( (strcmp(argv[n],"-SOFT") == 0) && (n+1<argc) )
321            {
322                strcpy(soft_name, argv[n+1]);
323            }
324            else if( (strcmp(argv[n],"-DISK") == 0) && (n+1<argc) )
325            {
326                strcpy(disk_name, argv[n+1]);
327            }
328            else if( (strcmp(argv[n],"-TRACE") == 0) && (n+1<argc) )
329            {
330                trace_ok = true;
331                from_cycle = atoi(argv[n+1]);
332            }
333            else if((strcmp(argv[n], "-MCWAYS") == 0) && (n+1 < argc))
334            {
335                memc_ways = atoi(argv[n+1]);
336            }
337            else if((strcmp(argv[n], "-MCSETS") == 0) && (n+1 < argc))
338            {
339                memc_sets = atoi(argv[n+1]);
340            }
341            else if((strcmp(argv[n], "-XLATENCY") == 0) && (n+1 < argc))
342            {
343                xram_latency = atoi(argv[n+1]);
344            }
345            else
346            {
347                std::cout << "   Arguments on the command line are (key,value) couples." << std::endl;
348                std::cout << "   The order is not important." << std::endl;
349                std::cout << "   Accepted arguments are :" << std::endl << std::endl;
350                std::cout << "     -SOFT pathname_for_embedded_soft" << std::endl;
351                std::cout << "     -DISK pathname_for_disk_image" << std::endl;
352                std::cout << "     -NCYCLES number_of_simulated_cycles" << std::endl;
353                std::cout << "     -NPROCS number_of_processors_per_cluster" << std::endl;
354                std::cout << "     -XMAX number_of_clusters_in_a_row" << std::endl;
355                std::cout << "     -YMAX number_of_clusters_in_a_column" << std::endl;
356                std::cout << "     -TRACE debug_start_cycle" << std::endl;
357                std::cout << "     -MCWAYS memory_cache_number_of_ways" << std::endl;
358                std::cout << "     -MCSETS memory_cache_number_of_sets" << std::endl;
359                std::cout << "     -XLATENCY external_ram_latency_value" << std::endl;
360                std::cout << "     -XFB fram_buffer_number_of_pixels" << std::endl;
361                std::cout << "     -YFB fram_buffer_number_of_lines" << std::endl;
362                std::cout << "     -THREADS number_of_cores_for_OpenMP" << std::endl;
363                exit(0);
364            }
365        }
366    }
367
368    std::cout << std::endl;
369    std::cout << " - NPROCS    = " << nprocs <<  std::endl;
370    std::cout << " - NCLUSTERS = " << xmax*ymax << std::endl;
371    std::cout << std::endl;
372
373#ifdef _OPENMP
374        omp_set_dynamic(false);
375        omp_set_num_threads(omp_threads);
376        std::cout << "Built with openmp version " << _OPENMP << std::endl;
377        std::cout << "Number of threads = " << omp_threads << std::endl;
378#endif
379
380    // Define VCI parameters
381    typedef soclib::caba::VciParams<cell_width,
382                                    plen_width,
383                                    address_width,
384                                    error_width,                                   
385                                    clen_width,
386                                    rflag_width,
387                                    srcid_width,
388                                    pktid_width,
389                                    trdid_width,
390                                    wrplen_width> vci_param;
391
392    size_t      cluster_io_index;
393    size_t      cluster_code_index;
394    size_t      cluster_kcode_index;
395    size_t      x_width;
396    size_t      y_width;
397
398    if      (xmax == 1) x_width = 0;
399    else if (xmax == 2) x_width = 1;
400    else if (xmax <= 4) x_width = 2;
401    else if (xmax <= 8) x_width = 3;
402    else                x_width = 4;
403
404    if      (ymax == 1) y_width = 0;
405    else if (ymax == 2) y_width = 1;
406    else if (ymax <= 4) y_width = 2;
407    else if (ymax <= 8) y_width = 3;
408    else                y_width = 4;
409
410    cluster_io_index = 0xBF >> (8 - x_width - y_width);
411    cluster_kcode_index = 0x80 >> (8 - x_width - y_width);
412    cluster_code_index = 0;
413   
414    /////////////////////
415    //  Mapping Tables
416    /////////////////////
417
418    // direct network
419    MappingTable maptabd(address_width, 
420                         IntTab(x_width + y_width, 16 - x_width - y_width), 
421                         IntTab(x_width + y_width, srcid_width - x_width - y_width), 
422                         0x00FF0000);
423
424    for ( size_t x = 0 ; x < xmax ; x++)
425    {
426        for ( size_t y = 0 ; y < ymax ; y++)
427        {
428            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
429
430            std::ostringstream  sh;
431            sh << "d_seg_heap_" << x << "_" << y;
432            maptabd.add(Segment(sh.str(), HEAP_BASE+offset, HEAP_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
433
434            std::ostringstream  ss;
435            ss << "d_seg_stak_" << x << "_" << y;
436            maptabd.add(Segment(ss.str(), STAK_BASE+offset, STAK_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
437
438            std::ostringstream  si;
439            si << "d_seg_xicu_" << x << "_" << y;
440            maptabd.add(Segment(si.str(), XICU_BASE+offset, XICU_SIZE, IntTab(cluster(x,y),XICU_TGTID), false));
441
442            std::ostringstream  st;
443            st << "d_seg_mtty_" << x << "_" << y;
444            maptabd.add(Segment(st.str(), MTTY_BASE+offset, MTTY_SIZE, IntTab(cluster(x,y),MTTY_TGTID), false));
445
446            std::ostringstream  sd;
447            sd << "d_seg_cdma_" << x << "_" << y;
448            maptabd.add(Segment(sd.str(), CDMA_BASE+offset, CDMA_SIZE, IntTab(cluster(x,y),CDMA_TGTID), false));
449
450            if ( cluster(x,y) == cluster_io_index )
451            {
452              maptabd.add(Segment("d_seg_fbuf    ", FBUF_BASE, FBUF_SIZE, IntTab(cluster(x,y),FBUF_TGTID), false));
453              maptabd.add(Segment("d_seg_bdev    ", BDEV_BASE, BDEV_SIZE, IntTab(cluster(x,y),BDEV_TGTID), false));
454              maptabd.add(Segment("d_seg_brom    ", BROM_BASE, BROM_SIZE, IntTab(cluster(x,y),BROM_TGTID), true));
455            }
456            if ( cluster(x,y) == cluster_code_index )
457            {
458              maptabd.add(Segment("d_seg_code    ", CODE_BASE, CODE_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
459              maptabd.add(Segment("d_seg_data    ", DATA_BASE, DATA_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
460            }
461            if ( cluster(x,y) == cluster_kcode_index )
462            {
463              maptabd.add(Segment("d_seg_kcod    ", KCOD_BASE, KCOD_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
464              maptabd.add(Segment("d_seg_kdat    ", KDAT_BASE, KDAT_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
465              maptabd.add(Segment("d_seg_kunc    ", KUNC_BASE, KUNC_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
466            }
467        }
468    }
469    std::cout << maptabd << std::endl;
470
471    // coherence network
472    // - tgtid_c_proc = srcid_c_proc = local procid
473    // - tgtid_c_memc = srcid_c_memc = nprocs
474    MappingTable maptabc(address_width, 
475                         IntTab(x_width + y_width, 16 - x_width - y_width), 
476                         IntTab(x_width + y_width, srcid_width - x_width - y_width), 
477                         0x00FF0000);
478
479    for ( size_t x = 0 ; x < xmax ; x++)
480    {
481        for ( size_t y = 0 ; y < ymax ; y++)
482        {
483            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
484
485            // cleanup requests regarding the heap segment must be routed to the memory cache
486            std::ostringstream sh;
487            sh << "c_seg_heap_" << x << "_" << y;
488            maptabc.add(Segment(sh.str(), HEAP_BASE+offset, HEAP_SIZE, IntTab(cluster(x,y), nprocs), false));
489
490            // cleanup requests regarding the stack segmentmust be routed to the memory cache
491            std::ostringstream ss;
492            ss << "c_seg_stak_" << x << "_" << y;
493            maptabc.add(Segment(ss.str(), STAK_BASE+offset, STAK_SIZE, IntTab(cluster(x,y), nprocs), false));
494
495            // cleanup requests regarding the BROM segment are also be routed to the memory cache
496            if ( cluster(x,y) == cluster_io_index )
497            {
498                maptabc.add(Segment("c_seg_brom    ", BROM_BASE, BROM_SIZE, IntTab(cluster(x,y), nprocs), false));
499            }
500
501            // cleanup requests regarding the code and data segment musts be send to the memory cache
502            if ( cluster(x,y) == cluster_code_index )
503            {
504                maptabc.add(Segment("c_seg_code    ", CODE_BASE, CODE_SIZE, IntTab(cluster(x,y), nprocs), false));
505                maptabc.add(Segment("c_seg_data    ", DATA_BASE, DATA_SIZE, IntTab(cluster(x,y), nprocs), false));
506            }
507            // cleanup requests regarding the kcode, kunc, and kdata segments must be send to the memory cache
508            if ( cluster(x,y) == cluster_kcode_index )
509            {
510                maptabc.add(Segment("c_seg_kcod    ", KCOD_BASE, KCOD_SIZE, IntTab(cluster(x,y), nprocs), false));
511                maptabc.add(Segment("c_seg_kdat    ", KDAT_BASE, KDAT_SIZE, IntTab(cluster(x,y), nprocs), false));
512                maptabc.add(Segment("c_seg_kunc    ", KUNC_BASE, KUNC_SIZE, IntTab(cluster(x,y), nprocs), false));
513            }
514
515            // update & invalidate requests must be routed to the proper processor
516            for ( size_t p = 0 ; p < nprocs ; p++)
517            {
518                std::ostringstream sp;
519                sp << "c_seg_proc_" << x << "_" << y << "_" << p;
520                maptabc.add(Segment(sp.str(), PROC_BASE+offset+(p*0x10000), PROC_SIZE, 
521                            IntTab(cluster(x,y), p), false, true, IntTab(cluster(x,y), p))); 
522            }
523        }
524    }
525    std::cout << maptabc << std::endl;
526
527    // external network
528    MappingTable maptabx(address_width, IntTab(1), IntTab(x_width+y_width), 0xF0000000);
529
530    for ( size_t x = 0 ; x < xmax ; x++)
531    {
532        for ( size_t y = 0 ; y < ymax ; y++)
533        { 
534
535            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
536
537            std::ostringstream sh;
538            sh << "x_seg_heap_" << x << "_" << y;
539            maptabx.add(Segment(sh.str(), HEAP_BASE+offset, HEAP_SIZE, IntTab(cluster(x,y)), false));
540
541            std::ostringstream ss;
542            ss << "x_seg_stak_" << x << "_" << y;
543            maptabx.add(Segment(ss.str(), STAK_BASE+offset, STAK_SIZE, IntTab(cluster(x,y)), false));
544
545            if ( cluster(x,y) == cluster_code_index )
546            {
547                maptabx.add(Segment("x_seg_code    ", CODE_BASE, CODE_SIZE, IntTab(cluster(x,y)), false));
548                maptabx.add(Segment("x_seg_data    ", DATA_BASE, DATA_SIZE, IntTab(cluster(x,y)), false));
549            }
550            if ( cluster(x,y) == cluster_kcode_index )
551            {
552                maptabx.add(Segment("x_seg_kcod    ", KCOD_BASE, KCOD_SIZE, IntTab(cluster(x,y)), false));
553                maptabx.add(Segment("x_seg_kdat    ", KDAT_BASE, KDAT_SIZE, IntTab(cluster(x,y)), false));
554                maptabx.add(Segment("x_seg_kunc    ", KUNC_BASE, KUNC_SIZE, IntTab(cluster(x,y)), false));
555            }
556        }
557    }
558    std::cout << maptabx << std::endl;
559
560    ////////////////////
561    // Signals
562    ///////////////////
563
564    sc_clock            signal_clk("clk");
565    sc_signal<bool>     signal_resetn("resetn");
566
567    // Horizontal inter-clusters DSPIN signals
568    DspinSignals<cmd_width>*** signal_dspin_h_cmd_inc =
569      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_inc", xmax-1, ymax, 2);
570    DspinSignals<cmd_width>*** signal_dspin_h_cmd_dec =
571      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_dec", xmax-1, ymax, 2);
572    DspinSignals<rsp_width>*** signal_dspin_h_rsp_inc =
573      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_inc", xmax-1, ymax, 2);
574    DspinSignals<rsp_width>*** signal_dspin_h_rsp_dec =
575      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_dec", xmax-1, ymax, 2);
576
577    // Vertical inter-clusters DSPIN signals
578    DspinSignals<cmd_width>*** signal_dspin_v_cmd_inc =
579        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_inc", xmax, ymax-1, 2);
580    DspinSignals<cmd_width>*** signal_dspin_v_cmd_dec =
581        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_dec", xmax, ymax-1, 2);
582    DspinSignals<rsp_width>*** signal_dspin_v_rsp_inc =
583        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_inc", xmax, ymax-1, 2);
584    DspinSignals<rsp_width>*** signal_dspin_v_rsp_dec =
585        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_dec", xmax, ymax-1, 2);
586
587    // Mesh boundaries DSPIN signals
588    DspinSignals<cmd_width>**** signal_dspin_false_cmd_in =
589        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_in", xmax, ymax, 2, 4);
590    DspinSignals<cmd_width>**** signal_dspin_false_cmd_out =
591        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_out", xmax, ymax, 2, 4);
592    DspinSignals<rsp_width>**** signal_dspin_false_rsp_in =
593        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_in", xmax, ymax, 2, 4);
594    DspinSignals<rsp_width>**** signal_dspin_false_rsp_out =
595        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_out", xmax, ymax, 2, 4);
596
597
598    ////////////////////////////
599    //      Components
600    ////////////////////////////
601
602#if USE_ALMOS
603    soclib::common::Loader loader("bootloader.bin",
604                                  "arch-info.bin@"TO_STR(BOOT_INFO_BLOCK)":D",
605                                  "kernel-soclib.bin@"TO_STR(KERNEL_BIN_IMG)":D");
606#else
607    soclib::common::Loader loader(soft_name);
608#endif
609
610    typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;
611    proc_iss::set_loader(loader);
612
613    TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>* clusters[xmax][ymax];
614
615#ifdef _OPENMP
616
617#pragma omp parallel
618{
619#pragma omp for
620    for( int i = 0 ; i  < (int)(xmax * ymax); i++)
621    {
622        size_t x = i / ymax;
623        size_t y = i % ymax;
624
625#pragma omp critical
626        {
627        std::ostringstream sc;
628        sc << "cluster_" << x << "_" << y;
629        clusters[x][y] = new TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>
630            (sc.str().c_str(),
631             nprocs,
632             x,
633             y,
634             cluster(x,y),
635             maptabd,
636             maptabc,
637             maptabx,
638             x_width,
639             y_width,
640             MEMC_TGTID,
641             XICU_TGTID,
642             FBUF_TGTID,
643             MTTY_TGTID,
644             BROM_TGTID,
645             BDEV_TGTID,
646             CDMA_TGTID,
647             memc_ways,
648             memc_sets,
649             l1_i_ways,
650             l1_i_sets,
651             l1_d_ways,
652             l1_d_sets,
653             xram_latency,
654             (cluster(x,y) == cluster_io_index),
655             xfb,
656             yfb,
657             disk_name,
658             blk_size,
659             loader);
660        }
661    }
662}
663
664#else  // _OPENMP
665
666    for( size_t x = 0 ; x  < xmax ; x++)
667    {
668        for( size_t y = 0 ; y < ymax ; y++ )
669        {
670
671std::cout << "building cluster_" << x << "_" << y << std::endl;
672
673            std::ostringstream sc;
674            sc << "cluster_" << x << "_" << y;
675            clusters[x][y] = new TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>
676            (sc.str().c_str(),
677             nprocs,
678             x,
679             y,
680             cluster(x,y),
681             maptabd,
682             maptabc,
683             maptabx,
684             x_width,
685             y_width,
686             MEMC_TGTID,
687             XICU_TGTID,
688             FBUF_TGTID,
689             MTTY_TGTID,
690             BROM_TGTID,
691             BDEV_TGTID,
692             CDMA_TGTID,
693             memc_ways,
694             memc_sets,
695             l1_i_ways,
696             l1_i_sets,
697             l1_d_ways,
698             l1_d_sets,
699             xram_latency,
700             (cluster(x,y) == cluster_io_index),
701             xfb,
702             yfb,
703             disk_name,
704             blk_size,
705             loader);
706
707std::cout << "cluster_" << x << "_" << y << " constructed" << std::endl;
708
709        }
710    }
711   
712#endif  // _OPENMP
713
714    ///////////////////////////////////////////////////////////////
715    //     Net-list
716    ///////////////////////////////////////////////////////////////
717
718    // Clock & RESET
719    for ( size_t x = 0 ; x < (xmax) ; x++ )
720    {
721        for ( size_t y = 0 ; y < ymax ; y++ )
722        {
723            clusters[x][y]->p_clk                       (signal_clk);
724            clusters[x][y]->p_resetn                    (signal_resetn);
725        }
726    }
727
728    // Inter Clusters horizontal connections
729    if ( xmax > 1 )
730    {
731        for ( size_t x = 0 ; x < (xmax-1) ; x++ )
732        {
733            for ( size_t y = 0 ; y < ymax ; y++ )
734            {
735                for ( size_t k = 0 ; k < 2 ; k++ )
736                {
737                clusters[x][y]->p_cmd_out[k][EAST]      (signal_dspin_h_cmd_inc[x][y][k]);
738                clusters[x+1][y]->p_cmd_in[k][WEST]     (signal_dspin_h_cmd_inc[x][y][k]);
739                clusters[x][y]->p_cmd_in[k][EAST]       (signal_dspin_h_cmd_dec[x][y][k]);
740                clusters[x+1][y]->p_cmd_out[k][WEST]    (signal_dspin_h_cmd_dec[x][y][k]);
741                clusters[x][y]->p_rsp_out[k][EAST]      (signal_dspin_h_rsp_inc[x][y][k]);
742                clusters[x+1][y]->p_rsp_in[k][WEST]     (signal_dspin_h_rsp_inc[x][y][k]);
743                clusters[x][y]->p_rsp_in[k][EAST]       (signal_dspin_h_rsp_dec[x][y][k]);
744                clusters[x+1][y]->p_rsp_out[k][WEST]    (signal_dspin_h_rsp_dec[x][y][k]);
745                }
746            }
747        }
748    }
749    std::cout << "Horizontal connections established" << std::endl;     
750
751    // Inter Clusters vertical connections
752    if ( ymax > 1 )
753    {
754        for ( size_t y = 0 ; y < (ymax-1) ; y++ )
755        {
756            for ( size_t x = 0 ; x < xmax ; x++ )
757            {
758                for ( size_t k = 0 ; k < 2 ; k++ )
759                {
760                clusters[x][y]->p_cmd_out[k][NORTH]     (signal_dspin_v_cmd_inc[x][y][k]);
761                clusters[x][y+1]->p_cmd_in[k][SOUTH]    (signal_dspin_v_cmd_inc[x][y][k]);
762                clusters[x][y]->p_cmd_in[k][NORTH]      (signal_dspin_v_cmd_dec[x][y][k]);
763                clusters[x][y+1]->p_cmd_out[k][SOUTH]   (signal_dspin_v_cmd_dec[x][y][k]);
764                clusters[x][y]->p_rsp_out[k][NORTH]     (signal_dspin_v_rsp_inc[x][y][k]);
765                clusters[x][y+1]->p_rsp_in[k][SOUTH]    (signal_dspin_v_rsp_inc[x][y][k]);
766                clusters[x][y]->p_rsp_in[k][NORTH]      (signal_dspin_v_rsp_dec[x][y][k]);
767                clusters[x][y+1]->p_rsp_out[k][SOUTH]   (signal_dspin_v_rsp_dec[x][y][k]);
768                }
769            }
770        }
771    }
772    std::cout << "Vertical connections established" << std::endl;
773
774    // East & West boundary cluster connections
775    for ( size_t y = 0 ; y < ymax ; y++ )
776    {
777        for ( size_t k = 0 ; k < 2 ; k++ )
778        {
779            clusters[0][y]->p_cmd_in[k][WEST]           (signal_dspin_false_cmd_in[0][y][k][WEST]);
780            clusters[0][y]->p_cmd_out[k][WEST]          (signal_dspin_false_cmd_out[0][y][k][WEST]);
781            clusters[0][y]->p_rsp_in[k][WEST]           (signal_dspin_false_rsp_in[0][y][k][WEST]);
782            clusters[0][y]->p_rsp_out[k][WEST]          (signal_dspin_false_rsp_out[0][y][k][WEST]);
783         
784            clusters[xmax-1][y]->p_cmd_in[k][EAST]      (signal_dspin_false_cmd_in[xmax-1][y][k][EAST]);
785            clusters[xmax-1][y]->p_cmd_out[k][EAST]     (signal_dspin_false_cmd_out[xmax-1][y][k][EAST]);
786            clusters[xmax-1][y]->p_rsp_in[k][EAST]      (signal_dspin_false_rsp_in[xmax-1][y][k][EAST]);
787            clusters[xmax-1][y]->p_rsp_out[k][EAST]     (signal_dspin_false_rsp_out[xmax-1][y][k][EAST]);
788        }
789    }
790   
791    // North & South boundary clusters connections
792    for ( size_t x = 0 ; x < xmax ; x++ )
793    {
794        for ( size_t k = 0 ; k < 2 ; k++ )
795        {
796            clusters[x][0]->p_cmd_in[k][SOUTH]          (signal_dspin_false_cmd_in[x][0][k][SOUTH]);
797            clusters[x][0]->p_cmd_out[k][SOUTH]         (signal_dspin_false_cmd_out[x][0][k][SOUTH]);
798            clusters[x][0]->p_rsp_in[k][SOUTH]          (signal_dspin_false_rsp_in[x][0][k][SOUTH]);
799            clusters[x][0]->p_rsp_out[k][SOUTH]         (signal_dspin_false_rsp_out[x][0][k][SOUTH]);
800           
801            clusters[x][ymax-1]->p_cmd_in[k][NORTH]     (signal_dspin_false_cmd_in[x][ymax-1][k][NORTH]);
802            clusters[x][ymax-1]->p_cmd_out[k][NORTH]    (signal_dspin_false_cmd_out[x][ymax-1][k][NORTH]);
803            clusters[x][ymax-1]->p_rsp_in[k][NORTH]     (signal_dspin_false_rsp_in[x][ymax-1][k][NORTH]);
804            clusters[x][ymax-1]->p_rsp_out[k][NORTH]    (signal_dspin_false_rsp_out[x][ymax-1][k][NORTH]);
805        }
806    }
807     
808
809    ////////////////////////////////////////////////////////
810    //   Simulation
811    ///////////////////////////////////////////////////////
812
813    sc_start(sc_core::sc_time(0, SC_NS));
814    signal_resetn = false;
815
816    // network boundaries signals
817    for(size_t x=0; x<xmax ; x++)
818    {
819        for(size_t y=0 ; y<ymax ; y++)
820        {
821            for (size_t k=0; k<2; k++)
822            {
823                for(size_t a=0; a<4; a++)
824                {
825                        signal_dspin_false_cmd_in[x][y][k][a].write = false;
826                        signal_dspin_false_cmd_in[x][y][k][a].read = true;
827                        signal_dspin_false_cmd_out[x][y][k][a].write = false;
828                        signal_dspin_false_cmd_out[x][y][k][a].read = true;
829
830                        signal_dspin_false_rsp_in[x][y][k][a].write = false;
831                        signal_dspin_false_rsp_in[x][y][k][a].read = true;
832                        signal_dspin_false_rsp_out[x][y][k][a].write = false;
833                        signal_dspin_false_rsp_out[x][y][k][a].read = true;
834                }
835            }
836        }
837    }
838
839    sc_start(sc_core::sc_time(1, SC_NS));
840    signal_resetn = true;
841
842    sc_start(sc_core::sc_time(ncycles, SC_NS));
843
844/*
845    for ( size_t n=0 ; n<ncycles ; n++)
846    {
847        sc_start(sc_core::sc_time(1, SC_NS));
848
849        if ( trace_ok && (n > from_cycle) )
850        {
851            std::cout << "****************** cycle " << std::dec << n ;
852            std::cout << " ***********************************" << std::endl;
853            clusters[5][7]->proc[2]->print_trace();
854            print_vci_signal("proc_5_7_2_d", clusters[5][7]->signal_vci_ini_d_proc[2]);
855
856            clusters[0][0]->proc[1]->print_trace();
857            clusters[0][0]->proc[2]->print_trace();
858            clusters[0][0]->proc[3]->print_trace();
859            std::cout << std::endl; 
860
861            clusters[0][1]->proc[0]->print_trace();
862            clusters[0][1]->proc[1]->print_trace();
863            clusters[0][1]->proc[2]->print_trace();
864            clusters[0][1]->proc[3]->print_trace();
865
866            std::cout << std::endl; 
867
868            clusters[1][0]->proc[0]->print_trace();
869            clusters[1][0]->proc[1]->print_trace();
870            clusters[1][0]->iniwrapperd->print_trace();
871            clusters[1][0]->proc[2]->print_trace();
872            print_vci_signal("proc_1_0_2_tgt_c", clusters[1][0]->signal_vci_tgt_c_proc[2]);
873            print_vci_signal("proc_1_0_2_d", clusters[1][0]->signal_vci_ini_d_proc[2]);
874            print_vci_signal("memc_0_0_d", clusters[0][0]->signal_vci_tgt_d_memc);
875            print_vci_signal("g2l_0_0_d", clusters[0][0]->signal_vci_g2l_d);
876            print_dspin_signal("l2g_0_0_d RSP", clusters[0][0]->signal_dspin_rsp_l2g_d);
877            print_dspin_signal("c10_to_c00 RSP", signal_dspin_h_rsp_dec[0][0][0]);
878            print_dspin_signal("c00_to_c10 RSP", signal_dspin_h_rsp_inc[0][0][0]);
879            print_dspin_signal("g2l_1_0_d RSP", clusters[1][0]->signal_dspin_rsp_g2l_d);
880            print_vci_signal("l2g_1_0_d", clusters[1][0]->signal_vci_l2g_d);
881            clusters[1][0]->proc[3]->print_trace();
882
883            std::cout << std::endl; 
884
885            clusters[1][1]->proc[0]->print_trace();
886            clusters[1][1]->proc[1]->print_trace();
887            clusters[1][1]->proc[2]->print_trace();
888            clusters[1][1]->proc[3]->print_trace();
889
890            std::cout << std::endl; 
891
892            clusters[0][0]->memc->print_trace();
893            clusters[0][1]->memc->print_trace();
894            clusters[1][0]->memc->print_trace();
895            clusters[1][1]->memc->print_trace();
896
897            clusters[0][0]->iniwrapperd->print_trace();
898            clusters[0][0]->tgtwrapperd->print_trace();
899            clusters[1][0]->iniwrapperd->print_trace();
900            clusters[1][0]->tgtwrapperd->print_trace();
901            clusters[0][1]->iniwrapperd->print_trace();
902            clusters[0][1]->tgtwrapperd->print_trace();
903            clusters[1][1]->iniwrapperd->print_trace();
904            clusters[1][1]->tgtwrapperd->print_trace();
905
906            std::cout << std::endl; 
907
908            print_vci_signal("proc_0_0_0_d", clusters[0][0]->signal_vci_ini_d_proc[0]);
909            print_vci_signal("proc_1_0_0_d", clusters[1][0]->signal_vci_ini_d_proc[0]);
910            print_vci_signal("proc_0_1_0_d", clusters[0][1]->signal_vci_ini_d_proc[0]);
911            print_vci_signal("proc_1_1_0_d", clusters[1][1]->signal_vci_ini_d_proc[0]);
912
913            print_vci_signal("proc_0_0_0_c", clusters[0][0]->signal_vci_tgt_c_proc[0]);
914            print_vci_signal("proc_1_0_0_c", clusters[1][0]->signal_vci_tgt_c_proc[0]);
915            print_vci_signal("proc_0_1_0_c", clusters[0][1]->signal_vci_tgt_c_proc[0]);
916            print_vci_signal("proc_1_1_0_c", clusters[1][1]->signal_vci_tgt_c_proc[0]);
917
918            print_vci_signal("memc_0_0_d", clusters[0][0]->signal_vci_tgt_d_memc);
919            print_vci_signal("memc_1_0_d", clusters[1][0]->signal_vci_tgt_d_memc);
920            print_vci_signal("memc_0_1_d", clusters[0][1]->signal_vci_tgt_d_memc);
921            print_vci_signal("memc_1_1_d", clusters[1][1]->signal_vci_tgt_d_memc);
922
923            print_vci_signal("memc_1_0_ini_c", clusters[1][0]->signal_vci_ini_c_memc);
924
925            print_vci_signal("l2g_1_0_c", clusters[1][0]->signal_vci_l2g_c);
926
927            print_dspin_signal("l2g_1_0_c CMD", clusters[1][0]->signal_dspin_cmd_l2g_c);
928
929            print_vci_signal("l2g_0_0_d", clusters[0][0]->signal_vci_l2g_d);
930            print_vci_signal("g2l_0_0_d", clusters[0][0]->signal_vci_g2l_d);
931
932            print_vci_signal("l2g_1_0_d", clusters[1][0]->signal_vci_l2g_d);
933            print_vci_signal("g2l_1_0_d", clusters[1][0]->signal_vci_g2l_d);
934
935            print_dspin_signal("l2g_0_0_d CMD", clusters[0][0]->signal_dspin_cmd_l2g_d);
936            print_dspin_signal("g2l_0_0_d CMD", clusters[0][0]->signal_dspin_cmd_g2l_d);
937            print_dspin_signal("l2g_0_0_d RSP", clusters[0][0]->signal_dspin_rsp_l2g_d);
938            print_dspin_signal("g2l_0_0_d RSP", clusters[0][0]->signal_dspin_rsp_g2l_d);
939
940            print_dspin_signal("l2g_1_0_d CMD", clusters[1][0]->signal_dspin_cmd_l2g_d);
941            print_dspin_signal("g2l_1_0_d CMD", clusters[1][0]->signal_dspin_cmd_g2l_d);
942            print_dspin_signal("l2g_1_0_d RSP", clusters[1][0]->signal_dspin_rsp_l2g_d);
943            print_dspin_signal("g2l_1_0_d RSP", clusters[1][0]->signal_dspin_rsp_g2l_d);
944
945            print_vci_signal("bdev_tgt", clusters[1][0]->signal_vci_tgt_d_bdev);
946            print_vci_signal("bdev_ini", clusters[1][0]->signal_vci_ini_d_bdev);
947
948            print_vci_signal("brom_tgt", clusters[1][0]->signal_vci_tgt_d_brom);
949           
950            if ( clusters[0][0]->signal_irq_bdev.read() != 0) std::cout << " IRQ_BDEV" << std::endl;
951            if ( clusters[0][0]->signal_proc_it[0].read() != 0) std::cout << " IRQ_PROC" << std::endl;
952        }
953    }
954*/
955
956    return EXIT_SUCCESS;
957}
958
959int sc_main (int argc, char *argv[])
960{
961        try {
962                return _main(argc, argv);
963        } catch (std::exception &e) {
964                std::cout << e.what() << std::endl;
965        } catch (...) {
966                std::cout << "Unknown exception occured" << std::endl;
967                throw;
968        }
969        return 1;
970}
Note: See TracBrowser for help on using the repository browser.