source: trunk/platforms/linux_monocluster/top.cpp @ 978

Last change on this file since 978 was 950, checked in by porquet, 10 years ago

linux_monocluster: define 4 irq lines per cpu (to be coherent with LETI systems)

File size: 19.2 KB
Line 
1/*
2 * global config
3 */
4
5#define CONFIG_GDB_SERVER
6
7/*
8 * headers
9 */
10
11#include <systemc>
12#include <sys/time.h>
13#include <iostream>
14#include <cstdlib>
15#include <cstdarg>
16#include <inttypes.h>
17#include <limits.h>
18#ifdef _OPENMP
19#include <omp.h>
20#endif
21
22#ifdef CONFIG_GDB_SERVER
23#include "gdbserver.h"
24#endif
25
26#include "mapping_table.h"
27
28#include "mips32.h"
29#include "vci_mem_cache.h"
30#include "vci_cc_vcache_wrapper.h"
31#include "vci_block_device_tsar.h"
32
33#include "vci_simple_ram.h"
34#include "vci_multi_tty.h"
35#include "vci_xicu.h"
36#include "vci_framebuffer.h"
37
38#include "dspin_local_crossbar.h"
39#include "vci_local_crossbar.h"
40
41/*
42 * pf global config
43 */
44
45using namespace sc_core;
46using namespace soclib::caba;
47using namespace soclib::common;
48
49#define    cell_width            4
50#define    cell_width_ext        8
51#define    address_width         40
52#define    plen_width            8
53#define    error_width           1
54#define    clen_width            1
55#define    rflag_width           1
56#define    srcid_width           14
57#define    pktid_width           4
58#define    trdid_width           4
59#define    wrplen_width          1
60
61#define    dspin_cmd_width     39
62#define    dspin_rsp_width     32
63
64typedef VciParams<cell_width,
65        plen_width,
66        address_width,
67        error_width,
68        clen_width,
69        rflag_width,
70        srcid_width,
71        pktid_width,
72        trdid_width,
73        wrplen_width> vci_param;
74
75typedef VciParams<cell_width_ext,
76        plen_width,
77        address_width,
78        error_width,
79        clen_width,
80        rflag_width,
81        srcid_width,
82        pktid_width,
83        trdid_width,
84        wrplen_width> vci_param_ext;
85
86/*
87 * segmentation
88 */
89
90#include "segmentation.h"
91
92
93/*
94 * default parameters
95 */
96
97struct param_s {
98    size_t nr_cpus;
99    char *rom_path;
100    bool dsk;
101    char *dsk_path;
102    bool dummy_boot;
103    bool framebuffer;
104    bool trace_enabled;
105    size_t trace_start_cycle;
106    uint64_t ncycles;
107};
108
109#define PARAM_INITIALIZER   \
110{                           \
111    .nr_cpus = 1,           \
112    .rom_path = NULL,       \
113    .dsk = false,           \
114    .dsk_path = NULL,       \
115    .dummy_boot = false,    \
116    .framebuffer = false,   \
117    .trace_enabled = false, \
118    .trace_start_cycle = 0, \
119    .ncycles = 0,           \
120}
121
122static inline void print_param(const struct param_s &param)
123{
124    std::cout << std::endl;
125    std::cout << "simulation parameters:" << std::endl;
126    std::cout << "  nr_cpus     = " << param.nr_cpus << std::endl;
127    std::cout << "  rom         = " << param.rom_path << std::endl;
128    std::cout << "  dummy boot  = " << param.dummy_boot << std::endl;
129    std::cout << "  framebuffer = " << param.framebuffer << std::endl;
130    std::cout << "  dsk         = " << param.dsk << std::endl;
131    if (param.dsk)
132        std::cout << "    dsk_path  = " << param.dsk_path << std::endl;
133    std::cout << "  trace       = " << param.trace_enabled << std::endl;
134    if (param.trace_enabled)
135        std::cout << "    start cyc = " << param.trace_start_cycle << std::endl;
136    if (param.ncycles > 0)
137        std::cout << "    ncycles   = " << param.ncycles << std::endl;
138
139    std::cout << std::endl;
140}
141
142#define MAX_FROZEN_CYCLES 500000
143
144#define NB_IRQS_PER_CPU 4
145
146/*
147 * arguments parsing
148 */
149
150void args_parse(unsigned int argc, char *argv[], struct param_s &param)
151{
152    for (size_t n = 1; n < argc; n = n + 2)
153    {
154        if ((strcmp(argv[n], "--ncpus") == 0) && ((n + 1) < argc))
155        {
156            assert((param.nr_cpus = atoi(argv[n + 1]))
157                    && "insufficient memory");
158        }
159        else if ((strcmp(argv[n], "--rom") == 0) && ((n + 1) < argc))
160        {
161            assert((param.rom_path = strdup(argv[n + 1]))
162                    && "insufficient memory");
163        }
164        else if ((strcmp(argv[n], "--dsk") == 0) && ((n + 1) < argc))
165        {
166            param.dsk = true;
167            assert((param.dsk_path = strdup(argv[n + 1]))
168                    && "insufficient memory");
169        }
170        else if (strcmp(argv[n], "--dummy-boot") == 0)
171        {
172            param.dummy_boot = true;
173            /* we don't have an extra argument */
174            n = n - 1;
175        }
176        else if (strcmp(argv[n], "--framebuffer") == 0)
177        {
178            param.framebuffer = true;
179            /* we don't have an extra argument */
180            n = n - 1;
181        }
182        else if ((strcmp(argv[n], "--trace") == 0) && ((n + 1) < argc))
183        {
184            param.trace_enabled = true;
185            param.trace_start_cycle = atoi(argv[n + 1]);
186        }
187        else if ((strcmp(argv[n], "--ncycles") == 0) && ((n + 1) < argc))
188        {
189            param.ncycles = atoll(argv[n + 1]);
190        }
191        else
192        {
193            std::cout << "Error: don't understand option " << argv[n] << std::endl;
194            std::cout << "Accepted arguments are :" << std::endl;
195            std::cout << "--ncpus pathname" << std::endl;
196            std::cout << "--rom pathname" << std::endl;
197            std::cout << "[--dsk pathname]" << std::endl;
198            std::cout << "[--dummy-boot]" << std::endl;
199            std::cout << "[--framebuffer]" << std::endl;
200            std::cout << "[--trace trace_start_cycle]" << std::endl;
201            std::cout << "[--ncycles simulation_cycles]" << std::endl;
202            exit(0);
203        }
204    }
205
206    /* check parameters */
207    assert((param.nr_cpus <= 4) && "cannot support more than 4 cpus");
208    assert(param.rom_path && "--rom is not optional");
209
210    print_param(param);
211}
212
213
214/*
215 * netlist
216 */
217
218int _main(int argc, char *argv[])
219{
220#ifdef _OPENMP
221    omp_set_dynamic(false);
222    omp_set_num_threads(5);
223    std::cerr << "Built with openmp version " << _OPENMP << std::endl;
224#endif
225
226    struct param_s param = PARAM_INITIALIZER;
227
228    /* parse arguments */
229    args_parse(argc, argv, param);
230
231    /*
232     * mapping tables
233     */
234
235    /* data mapping table */
236    MappingTable maptabp(32, IntTab(0, 16), IntTab(0, srcid_width), 0xF0000000);
237
238    /* ram */
239    maptabp.add(Segment("mc_m", MEMC_BASE, MEMC_SIZE, IntTab(0, 0), true));
240    maptabp.add(Segment("boot", BOOT_BASE, BOOT_SIZE, IntTab(0, 1), true));
241
242    /* uncached peripherals */
243    maptabp.add(Segment("xicu", XICU_BASE, XICU_SIZE, IntTab(0, 2), false));
244    maptabp.add(Segment("tty",  MTTY_BASE, MTTY_SIZE, IntTab(0, 3), false));
245    maptabp.add(Segment("bd",   BD_BASE,   BD_SIZE,   IntTab(0, 4), false));
246    maptabp.add(Segment("fb",   FB_BASE,   FB_SIZE,   IntTab(0, 5), false));
247
248    std::cout << maptabp << std::endl;
249
250    /* xram mapping table */
251    MappingTable maptabx(32, IntTab(8), IntTab(8), 0x30000000);
252    maptabx.add(Segment("xram", MEMC_BASE, MEMC_SIZE, IntTab(0), false));
253
254    std::cout << maptabx << std::endl;
255
256    /*
257     * components
258     */
259
260    Loader loader;
261    loader.load_file(param.rom_path);
262    loader.memory_default(0x5c);
263
264#ifdef CONFIG_GDB_SERVER
265    typedef GdbServer<Mips32ElIss> proc_iss;
266    proc_iss::set_loader(loader);
267#else
268    typedef Mips32ElIss proc_iss;
269#endif
270
271    if (param.dummy_boot == true)
272    {
273        /* boot linux image directly */
274        uint64_t entry_addr = loader.get_entry_point_address();
275        std::cout << "setResetAdress: " << std::hex << entry_addr << std::endl << std::endl;
276        proc_iss::setResetAddress(entry_addr);
277    }
278
279    VciCcVCacheWrapper<vci_param, dspin_cmd_width, dspin_rsp_width, proc_iss > **proc;
280    proc = new VciCcVCacheWrapper<vci_param, dspin_cmd_width, dspin_rsp_width,
281         proc_iss >*[param.nr_cpus];
282    for (size_t i = 0; i < param.nr_cpus; i++)
283    {
284        std::ostringstream o;
285        o << "ccvache" << "[" << i << "]";
286        proc[i] = new VciCcVCacheWrapper<vci_param, dspin_cmd_width,
287            dspin_rsp_width, proc_iss >(
288                o.str().c_str(),    // name
289                i,                  // proc_id
290                maptabp,            // direct space
291                IntTab(0, i),       // srcid_d
292                i,                  // cc_global_id
293                8, 8,               // itlb size
294                8, 8,               // dtlb size
295                4, 64, 16,          // icache size
296                4, 64, 16,          // dcache size
297                4, 4,               // wbuf size
298                0, 0,               // x, y Width
299                MAX_FROZEN_CYCLES,  // max frozen cycles
300                param.trace_start_cycle,
301                param.trace_enabled);
302    }
303
304    VciSimpleRam<vci_param_ext> xram("xram", IntTab(0), maptabx, loader);
305
306    VciSimpleRam<vci_param> rom("rom", IntTab(0, 1), maptabp, loader);
307
308    VciMemCache<vci_param, vci_param_ext, dspin_rsp_width, dspin_cmd_width>
309        memc("memc",
310                maptabp,        // direct space
311                maptabx,        // xram space
312                IntTab(0),      // xram srcid
313                IntTab(0, 0),   // direct tgtid
314                0, 0,           // x, y width
315                16, 256, 16,    // cache size
316                3,              // max copies
317                4096, 8, 8, 8,  // HEAP size, TRT size, UPT size, IVT size
318                param.trace_start_cycle, param.trace_enabled);
319
320    VciXicu<vci_param> xicu("xicu", maptabp, IntTab(0, 2),
321            param.nr_cpus,  // #timers
322            3,              // #input hw irqs
323            param.nr_cpus,  // #ipis
324            param.nr_cpus * NB_IRQS_PER_CPU); // #output irqs
325
326    VciMultiTty<vci_param> mtty("mtty", IntTab(0, 3), maptabp, "vcitty0", NULL);
327
328    VciBlockDeviceTsar<vci_param> *bd = NULL;
329    if (param.dsk == true)
330        bd = new VciBlockDeviceTsar<vci_param>("bd", maptabp,
331                IntTab(0, param.nr_cpus),   // srcid
332                IntTab(0, 4),               // tgtid
333                param.dsk_path);            // filename
334
335    VciFrameBuffer<vci_param> *fb = NULL;
336    if (param.framebuffer == true)
337        fb = new VciFrameBuffer<vci_param>("fb", IntTab(0, 5), maptabp,
338                FB_XSIZE, FB_YSIZE,     // window size
339                FbController::RGB_16);  // color type
340
341    /*
342     * Interconnects
343     */
344
345    /* data network */
346    VciLocalCrossbar<vci_param> xbar_d("xbar_d",
347            maptabp,        // mapping table
348            0,              // cluster coordinates
349            param.nr_cpus + 1, // #src
350            6,              // #dst
351            1);             // default target
352
353    /* coherence */
354    DspinLocalCrossbar<dspin_cmd_width> xbar_m2p_c("xbar_m2p_c",
355            maptabp,
356            0, 0,
357            0, 0,
358            srcid_width,
359            1, param.nr_cpus,
360            2, 2,
361            true,
362            false,
363            true);
364    DspinLocalCrossbar<dspin_rsp_width> xbar_p2m_c("xbar_p2m_c",
365            maptabp,
366            0, 0,
367            0, 0,
368            0,
369            param.nr_cpus, 1,
370            2, 2,
371            false,
372            false,
373            false);
374    DspinLocalCrossbar<dspin_cmd_width> xbar_clack_c("xbar_clack_c",
375            maptabp,
376            0, 0,
377            0, 0,
378            srcid_width,
379            1, param.nr_cpus,
380            1, 1,
381            true,
382            false,
383            false);
384
385    /*
386     * signals
387     */
388
389    /* clk and resetn */
390    sc_clock signal_clk ("clk");
391    sc_signal<bool> signal_resetn("resetn");
392
393    /* irq lines */
394    sc_signal<bool> **signal_proc_irq =
395        alloc_elems<sc_signal<bool> >("proc_irq", param.nr_cpus, proc_iss::n_irq);
396    sc_signal<bool> signal_mtty_irq("mtty_irq");
397    sc_signal<bool> signal_bd_irq("bd_irq");
398    sc_signal<bool> signal_memc_irq("memc_irq");
399
400    /* vci */
401    VciSignals<vci_param> *signal_vci_proc =
402        alloc_elems<VciSignals<vci_param> >("vci_proc", param.nr_cpus);
403    VciSignals<vci_param> signal_vci_ini_bd ("vci_ini_bd");
404
405    VciSignals<vci_param> signal_vci_memc ("vci_memc");
406    VciSignals<vci_param> signal_vci_rom ("vci_rom");
407    VciSignals<vci_param> signal_vci_xicu ("vci_xicu");
408    VciSignals<vci_param> signal_vci_tty ("vci_tty");
409    VciSignals<vci_param> signal_vci_tgt_bd ("vci_tgt_bd");
410    VciSignals<vci_param> signal_vci_fb ("vci_fb");
411
412    VciSignals<vci_param_ext> signal_vci_xram ("vci_xram");
413
414    /* fake signals for in/out of cluster */
415    VciSignals<vci_param> signal_vci_from_out("vci_from_out");
416    VciSignals<vci_param> signal_vci_to_out("vci_to_out");
417
418    /* Coherence DSPIN signals to local crossbar */
419    DspinSignals<dspin_cmd_width> signal_dspin_m2p_l2g;
420    DspinSignals<dspin_cmd_width> signal_dspin_m2p_g2l;
421    DspinSignals<dspin_rsp_width> signal_dspin_p2m_l2g;
422    DspinSignals<dspin_rsp_width> signal_dspin_p2m_g2l;
423    DspinSignals<dspin_cmd_width> signal_dspin_clack_l2g;
424    DspinSignals<dspin_cmd_width> signal_dspin_clack_g2l;
425
426    DspinSignals<dspin_cmd_width> signal_dspin_m2p_memc;
427    DspinSignals<dspin_cmd_width> signal_dspin_clack_memc;
428    DspinSignals<dspin_rsp_width> signal_dspin_p2m_memc;
429    DspinSignals<dspin_cmd_width> *signal_dspin_m2p_proc =
430        alloc_elems<DspinSignals<dspin_cmd_width> >("dspin_m2p_proc", param.nr_cpus);
431    DspinSignals<dspin_cmd_width> *signal_dspin_clack_proc =
432        alloc_elems<DspinSignals<dspin_cmd_width> >("dspin_clack_proc", param.nr_cpus);
433    DspinSignals<dspin_rsp_width> *signal_dspin_p2m_proc =
434        alloc_elems<DspinSignals<dspin_rsp_width> >("dspin_p2m_proc", param.nr_cpus);
435
436    /*
437     * netlist
438     */
439
440    /* components */
441    for (size_t i = 0; i < param.nr_cpus; i++)
442    {
443        proc[i]->p_clk(signal_clk);
444        proc[i]->p_resetn(signal_resetn);
445        for (size_t j = 0; j < proc_iss::n_irq; j++)
446            proc[i]->p_irq[j](signal_proc_irq[i][j]);
447        proc[i]->p_vci(signal_vci_proc[i]);
448        proc[i]->p_dspin_m2p(signal_dspin_m2p_proc[i]);
449        proc[i]->p_dspin_p2m(signal_dspin_p2m_proc[i]);
450        proc[i]->p_dspin_clack(signal_dspin_clack_proc[i]);
451    }
452
453    memc.p_clk(signal_clk);
454    memc.p_resetn(signal_resetn);
455    memc.p_irq(signal_memc_irq);
456    memc.p_vci_tgt(signal_vci_memc);
457    memc.p_dspin_p2m(signal_dspin_p2m_memc);
458    memc.p_dspin_m2p(signal_dspin_m2p_memc);
459    memc.p_dspin_clack(signal_dspin_clack_memc);
460    memc.p_vci_ixr(signal_vci_xram);
461
462    rom.p_clk(signal_clk);
463    rom.p_resetn(signal_resetn);
464    rom.p_vci(signal_vci_rom);
465
466    xicu.p_resetn(signal_resetn);
467    xicu.p_clk(signal_clk);
468    xicu.p_vci(signal_vci_xicu);
469    xicu.p_hwi[0](signal_mtty_irq);
470    xicu.p_hwi[1](signal_bd_irq);
471    xicu.p_hwi[2](signal_memc_irq);
472    for (size_t i = 0; i < param.nr_cpus; i++) {
473        xicu.p_irq[i * NB_IRQS_PER_CPU + 0](signal_proc_irq[i][0]);
474        xicu.p_irq[i * NB_IRQS_PER_CPU + 1](signal_proc_irq[i][1]);
475        xicu.p_irq[i * NB_IRQS_PER_CPU + 2](signal_proc_irq[i][2]);
476        xicu.p_irq[i * NB_IRQS_PER_CPU + 3](signal_proc_irq[i][3]);
477    }
478
479    mtty.p_clk(signal_clk);
480    mtty.p_resetn(signal_resetn);
481    mtty.p_vci(signal_vci_tty);
482    mtty.p_irq[0](signal_mtty_irq);
483
484    if (param.dsk == true)
485    {
486        bd->p_clk(signal_clk);
487        bd->p_resetn(signal_resetn);
488        bd->p_vci_target(signal_vci_tgt_bd);
489        bd->p_vci_initiator(signal_vci_ini_bd);
490        bd->p_irq(signal_bd_irq);
491    }
492
493    if (param.framebuffer == true)
494    {
495        fb->p_clk(signal_clk);
496        fb->p_resetn(signal_resetn);
497        fb->p_vci(signal_vci_fb);
498    }
499
500    xram.p_clk(signal_clk);
501    xram.p_resetn(signal_resetn);
502    xram.p_vci(signal_vci_xram);
503
504    /* interconnects */
505    xbar_d.p_clk(signal_clk);
506    xbar_d.p_resetn(signal_resetn);
507    xbar_d.p_target_to_up(signal_vci_from_out);
508    xbar_d.p_initiator_to_up(signal_vci_to_out);
509    for (size_t i = 0; i < param.nr_cpus; i++)
510        xbar_d.p_to_initiator[i](signal_vci_proc[i]);
511    xbar_d.p_to_initiator[param.nr_cpus](signal_vci_ini_bd);
512    xbar_d.p_to_target[0](signal_vci_memc);
513    xbar_d.p_to_target[1](signal_vci_rom);
514    xbar_d.p_to_target[2](signal_vci_xicu);
515    xbar_d.p_to_target[3](signal_vci_tty);
516    xbar_d.p_to_target[4](signal_vci_tgt_bd);
517    xbar_d.p_to_target[5](signal_vci_fb);
518
519    xbar_m2p_c.p_clk(signal_clk);
520    xbar_m2p_c.p_resetn(signal_resetn);
521    xbar_m2p_c.p_global_out(signal_dspin_m2p_l2g);
522    xbar_m2p_c.p_global_in(signal_dspin_m2p_g2l);
523    xbar_m2p_c.p_local_in[0](signal_dspin_m2p_memc);
524    for (size_t i = 0; i < param.nr_cpus; i++)
525        xbar_m2p_c.p_local_out[i](signal_dspin_m2p_proc[i]);
526
527    xbar_clack_c.p_clk(signal_clk);
528    xbar_clack_c.p_resetn(signal_resetn);
529    xbar_clack_c.p_global_out(signal_dspin_clack_l2g);
530    xbar_clack_c.p_global_in(signal_dspin_clack_g2l);
531    xbar_clack_c.p_local_in[0](signal_dspin_clack_memc);
532    for (size_t i = 0; i < param.nr_cpus; i++)
533        xbar_clack_c.p_local_out[i](signal_dspin_clack_proc[i]);
534
535    xbar_p2m_c.p_clk(signal_clk);
536    xbar_p2m_c.p_resetn(signal_resetn);
537    xbar_p2m_c.p_global_out(signal_dspin_p2m_l2g);
538    xbar_p2m_c.p_global_in(signal_dspin_p2m_g2l);
539    xbar_p2m_c.p_local_out[0](signal_dspin_p2m_memc);
540    for (size_t i = 0; i < param.nr_cpus; i++)
541        xbar_p2m_c.p_local_in[i](signal_dspin_p2m_proc[i]);
542
543    /*
544     * simulation
545     */
546
547    for (size_t i = 0; i < param.nr_cpus; i++)
548        proc[i]->iss_set_debug_mask(0);
549
550    sc_start(sc_time(0, SC_NS));
551    signal_resetn = false;
552
553    sc_start(sc_time(1, SC_NS));
554    signal_resetn = true;
555
556    /* network boundaries initialization */
557    signal_dspin_m2p_l2g.write = false;
558    signal_dspin_m2p_l2g.read = true;
559    signal_dspin_m2p_g2l.write = false;
560    signal_dspin_m2p_g2l.read = true;
561
562    if (param.ncycles > 0)
563    {
564        for (size_t n = 1; n < param.ncycles; n++)
565        {
566            if (param.trace_enabled and (n > param.trace_start_cycle))
567            {
568                std::cout << "****************** cycle " << std::dec << n
569                    << " ************************************************" << std::endl;
570
571                proc[0]->print_trace();
572                memc.print_trace();
573
574                signal_vci_proc[0].print_trace("signal_vci_proc[0]");
575                signal_vci_memc.print_trace("signal_vci_memc");
576
577                signal_dspin_m2p_memc.print_trace("signal_m2p_memc");
578                signal_dspin_clack_memc.print_trace("signal_clack_memc");
579                signal_dspin_p2m_memc.print_trace("signal_p2m_memc");
580                for (size_t i = 0; i < param.nr_cpus; i++)
581                {
582                    std::ostringstream o;
583                    o << "signal_m2p_proc" << "[" << i << "]";
584                    signal_dspin_m2p_proc[i].print_trace(o.str().c_str());
585                }
586            }
587            sc_start(sc_core::sc_time(1, SC_NS));
588        }
589    } else {
590        uint64_t n;
591        struct timeval t1, t2;
592
593        gettimeofday(&t1, NULL);
594
595        for (n = 1; ; n++) {
596            /* stats display */
597            if ((n % 5000000) == 0) {
598                gettimeofday(&t2, NULL);
599
600                uint64_t ms1 = (uint64_t)t1.tv_sec * 1000ULL +
601                    (uint64_t)t1.tv_usec / 1000;
602                uint64_t ms2 = (uint64_t)t2.tv_sec * 1000ULL +
603                    (uint64_t)t2.tv_usec / 1000;
604                std::cerr << "platform clock frequency "
605                    << (double)5000000 / (double)(ms2 - ms1) << "Khz" << std::endl;
606
607                gettimeofday(&t1, NULL);
608            }
609
610            sc_start(sc_core::sc_time(1, SC_NS));
611        };
612    }
613
614    return EXIT_SUCCESS;
615
616}
617
618int sc_main (int argc, char *argv[])
619{
620    try {
621        return _main(argc, argv);
622    } catch (std::exception &e) {
623        std::cout << e.what() << std::endl;
624    } catch (...) {
625        std::cout << "Unknown exception occured" << std::endl;
626        throw;
627    }
628    return EXIT_FAILURE;
629}
630
Note: See TracBrowser for help on using the repository browser.