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

Last change on this file since 858 was 829, checked in by porquet, 10 years ago

linux_monocluster: initialize memory with a default value to detect
possible bugs

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