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

Last change on this file since 678 was 667, checked in by porquet, 11 years ago

add a new platform, known for running Linux properly

This platform is quite configurable:

  • number of cpus
  • optional framebuffer
  • optional blockdevice

This platform is also quite fast, thanks to the use of VciLocalCrossbar?
instead of DspinLocalCrossbar? (about 30% faster on Linux simulation).

File size: 18.2 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
51#define    address_width         32
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);
260
261#ifdef CONFIG_GDB_SERVER
262    typedef GdbServer<Mips32ElIss> proc_iss;
263    proc_iss::set_loader(loader);
264#else
265    typedef Mips32ElIss proc_iss;
266#endif
267
268    if (param.dummy_boot == true)
269    {
270        /* boot linux image directly */
271        uint64_t entry_addr = loader.get_entry_point_address();
272        std::cout << "setResetAdress: " << std::hex << entry_addr << std::endl << std::endl;
273        proc_iss::setResetAddress(entry_addr);
274    }
275
276    VciCcVCacheWrapper<vci_param, dspin_cmd_width, dspin_rsp_width, proc_iss > **proc;
277    proc = new VciCcVCacheWrapper<vci_param, dspin_cmd_width, dspin_rsp_width,
278         proc_iss >*[param.nr_cpus];
279    for (size_t i = 0; i < param.nr_cpus; i++)
280    {
281        std::ostringstream o;
282        o << "ccvache" << "[" << i << "]";
283        proc[i] = new VciCcVCacheWrapper<vci_param, dspin_cmd_width,
284            dspin_rsp_width, proc_iss >(
285                o.str().c_str(),    // name
286                i,                  // proc_id
287                maptabp,            // direct space
288                IntTab(0, i),       // srcid_d
289                i,                  // cc_global_id
290                8, 8,               // itlb size
291                8, 8,               // dtlb size
292                4, 64, 16,          // icache size
293                4, 64, 16,          // dcache size
294                4, 4,               // wbuf size
295                0, 0,               // x, y Width
296                MAX_FROZEN_CYCLES,  // max frozen cycles
297                param.trace_start_cycle,
298                param.trace_enabled);
299    }
300
301    VciSimpleRam<vci_param_ext> xram("xram", IntTab(0), maptabx, loader);
302
303    VciSimpleRam<vci_param> rom("rom", IntTab(0, 1), maptabp, loader);
304
305    VciMemCache<vci_param, vci_param_ext, dspin_rsp_width, dspin_cmd_width>
306        memc("memc",
307                maptabp,        // direct space
308                maptabx,        // xram space
309                IntTab(0),      // xram srcid
310                IntTab(0, 0),   // direct tgtid
311                0, 0,           // x, y width
312                16, 256, 16,    // cache size
313                3,              // max copies
314                4096, 8, 8, 8,  // HEAP size, TRT size, UPT size, IVT size
315                param.trace_start_cycle, param.trace_enabled);
316
317    VciXicu<vci_param> xicu("xicu", maptabp, IntTab(0, 2),
318            param.nr_cpus,  // #timers
319            3,              // #input hw irqs
320            param.nr_cpus,  // #ipis
321            param.nr_cpus); // #output irqs
322
323    VciMultiTty<vci_param> mtty("mtty", IntTab(0, 3), maptabp, "vcitty0", NULL);
324
325    VciBlockDeviceTsar<vci_param> *bd = NULL;
326    if (param.dsk == true)
327        bd = new VciBlockDeviceTsar<vci_param>("bd", maptabp,
328                IntTab(0, param.nr_cpus),   // srcid
329                IntTab(0, 4),               // tgtid
330                param.dsk_path);            // filename
331
332    VciFrameBuffer<vci_param> *fb = NULL;
333    if (param.framebuffer == true)
334        fb = new VciFrameBuffer<vci_param>("fb", IntTab(0, 5), maptabp,
335                FB_XSIZE, FB_YSIZE,     // window size
336                FbController::RGB_16);  // color type
337
338    /*
339     * Interconnects
340     */
341
342    /* data network */
343    VciLocalCrossbar<vci_param> xbar_d("xbar_d",
344            maptabp,        // mapping table
345            0,              // cluster coordinates
346            param.nr_cpus + 1, // #src
347            6,              // #dst
348            1);             // default target
349
350    /* coherence */
351    DspinLocalCrossbar<dspin_cmd_width> xbar_m2p_c("xbar_m2p_c",
352            maptabp,
353            0, 0,
354            0, 0,
355            srcid_width,
356            1, param.nr_cpus,
357            2, 2,
358            true,
359            false,
360            true);
361    DspinLocalCrossbar<dspin_rsp_width> xbar_p2m_c("xbar_p2m_c",
362            maptabp,
363            0, 0,
364            0, 0,
365            0,
366            param.nr_cpus, 1,
367            2, 2,
368            false,
369            false,
370            false);
371    DspinLocalCrossbar<dspin_cmd_width> xbar_clack_c("xbar_clack_c",
372            maptabp,
373            0, 0,
374            0, 0,
375            srcid_width,
376            1, param.nr_cpus,
377            1, 1,
378            true,
379            false,
380            false);
381
382    /*
383     * signals
384     */
385
386    /* clk and resetn */
387    sc_clock signal_clk ("clk");
388    sc_signal<bool> signal_resetn("resetn");
389
390    /* irq lines */
391    sc_signal<bool> **signal_proc_irq =
392        alloc_elems<sc_signal<bool> >("proc_irq", param.nr_cpus, proc_iss::n_irq);
393    sc_signal<bool> signal_mtty_irq("mtty_irq");
394    sc_signal<bool> signal_bd_irq("bd_irq");
395    sc_signal<bool> signal_memc_irq("memc_irq");
396
397    /* vci */
398    VciSignals<vci_param> *signal_vci_proc =
399        alloc_elems<VciSignals<vci_param> >("vci_proc", param.nr_cpus);
400    VciSignals<vci_param> signal_vci_ini_bd ("vci_ini_bd");
401
402    VciSignals<vci_param> signal_vci_memc ("vci_memc");
403    VciSignals<vci_param> signal_vci_rom ("vci_rom");
404    VciSignals<vci_param> signal_vci_xicu ("vci_xicu");
405    VciSignals<vci_param> signal_vci_tty ("vci_tty");
406    VciSignals<vci_param> signal_vci_tgt_bd ("vci_tgt_bd");
407    VciSignals<vci_param> signal_vci_fb ("vci_fb");
408
409    VciSignals<vci_param_ext> signal_vci_xram ("vci_xram");
410
411    /* fake signals for in/out of cluster */
412    VciSignals<vci_param> signal_vci_from_out("vci_from_out");
413    VciSignals<vci_param> signal_vci_to_out("vci_to_out");
414
415    /* Coherence DSPIN signals to local crossbar */
416    DspinSignals<dspin_cmd_width> signal_dspin_m2p_l2g;
417    DspinSignals<dspin_cmd_width> signal_dspin_m2p_g2l;
418    DspinSignals<dspin_rsp_width> signal_dspin_p2m_l2g;
419    DspinSignals<dspin_rsp_width> signal_dspin_p2m_g2l;
420    DspinSignals<dspin_cmd_width> signal_dspin_clack_l2g;
421    DspinSignals<dspin_cmd_width> signal_dspin_clack_g2l;
422
423    DspinSignals<dspin_cmd_width> signal_dspin_m2p_memc;
424    DspinSignals<dspin_cmd_width> signal_dspin_clack_memc;
425    DspinSignals<dspin_rsp_width> signal_dspin_p2m_memc;
426    DspinSignals<dspin_cmd_width> *signal_dspin_m2p_proc =
427        alloc_elems<DspinSignals<dspin_cmd_width> >("dspin_m2p_proc", param.nr_cpus);
428    DspinSignals<dspin_cmd_width> *signal_dspin_clack_proc =
429        alloc_elems<DspinSignals<dspin_cmd_width> >("dspin_clack_proc", param.nr_cpus);
430    DspinSignals<dspin_rsp_width> *signal_dspin_p2m_proc =
431        alloc_elems<DspinSignals<dspin_rsp_width> >("dspin_p2m_proc", param.nr_cpus);
432
433    /*
434     * netlist
435     */
436
437    /* components */
438    for (size_t i = 0; i < param.nr_cpus; i++)
439    {
440        proc[i]->p_clk(signal_clk);
441        proc[i]->p_resetn(signal_resetn);
442        for (size_t j = 0; j < proc_iss::n_irq; j++)
443            proc[i]->p_irq[j](signal_proc_irq[i][j]);
444        proc[i]->p_vci(signal_vci_proc[i]);
445        proc[i]->p_dspin_m2p(signal_dspin_m2p_proc[i]);
446        proc[i]->p_dspin_p2m(signal_dspin_p2m_proc[i]);
447        proc[i]->p_dspin_clack(signal_dspin_clack_proc[i]);
448    }
449
450    memc.p_clk(signal_clk);
451    memc.p_resetn(signal_resetn);
452    memc.p_irq(signal_memc_irq);
453    memc.p_vci_tgt(signal_vci_memc);
454    memc.p_dspin_p2m(signal_dspin_p2m_memc);
455    memc.p_dspin_m2p(signal_dspin_m2p_memc);
456    memc.p_dspin_clack(signal_dspin_clack_memc);
457    memc.p_vci_ixr(signal_vci_xram);
458
459    rom.p_clk(signal_clk);
460    rom.p_resetn(signal_resetn);
461    rom.p_vci(signal_vci_rom);
462
463    xicu.p_resetn(signal_resetn);
464    xicu.p_clk(signal_clk);
465    xicu.p_vci(signal_vci_xicu);
466    xicu.p_hwi[0](signal_mtty_irq);
467    xicu.p_hwi[1](signal_bd_irq);
468    xicu.p_hwi[2](signal_memc_irq);
469    for (size_t i = 0; i < param.nr_cpus; i++)
470        xicu.p_irq[i](signal_proc_irq[i][0]);
471
472    mtty.p_clk(signal_clk);
473    mtty.p_resetn(signal_resetn);
474    mtty.p_vci(signal_vci_tty);
475    mtty.p_irq[0](signal_mtty_irq);
476
477    if (param.dsk == true)
478    {
479        bd->p_clk(signal_clk);
480        bd->p_resetn(signal_resetn);
481        bd->p_vci_target(signal_vci_tgt_bd);
482        bd->p_vci_initiator(signal_vci_ini_bd);
483        bd->p_irq(signal_bd_irq);
484    }
485
486    if (param.framebuffer == true)
487    {
488        fb->p_clk(signal_clk);
489        fb->p_resetn(signal_resetn);
490        fb->p_vci(signal_vci_fb);
491    }
492
493    xram.p_clk(signal_clk);
494    xram.p_resetn(signal_resetn);
495    xram.p_vci(signal_vci_xram);
496
497    /* interconnects */
498    xbar_d.p_clk(signal_clk);
499    xbar_d.p_resetn(signal_resetn);
500    xbar_d.p_target_to_up(signal_vci_from_out);
501    xbar_d.p_initiator_to_up(signal_vci_to_out);
502    for (size_t i = 0; i < param.nr_cpus; i++)
503        xbar_d.p_to_initiator[i](signal_vci_proc[i]);
504    xbar_d.p_to_initiator[param.nr_cpus](signal_vci_ini_bd);
505    xbar_d.p_to_target[0](signal_vci_memc);
506    xbar_d.p_to_target[1](signal_vci_rom);
507    xbar_d.p_to_target[2](signal_vci_xicu);
508    xbar_d.p_to_target[3](signal_vci_tty);
509    xbar_d.p_to_target[4](signal_vci_tgt_bd);
510    xbar_d.p_to_target[5](signal_vci_fb);
511
512    xbar_m2p_c.p_clk(signal_clk);
513    xbar_m2p_c.p_resetn(signal_resetn);
514    xbar_m2p_c.p_global_out(signal_dspin_m2p_l2g);
515    xbar_m2p_c.p_global_in(signal_dspin_m2p_g2l);
516    xbar_m2p_c.p_local_in[0](signal_dspin_m2p_memc);
517    for (size_t i = 0; i < param.nr_cpus; i++)
518        xbar_m2p_c.p_local_out[i](signal_dspin_m2p_proc[i]);
519
520    xbar_clack_c.p_clk(signal_clk);
521    xbar_clack_c.p_resetn(signal_resetn);
522    xbar_clack_c.p_global_out(signal_dspin_clack_l2g);
523    xbar_clack_c.p_global_in(signal_dspin_clack_g2l);
524    xbar_clack_c.p_local_in[0](signal_dspin_clack_memc);
525    for (size_t i = 0; i < param.nr_cpus; i++)
526        xbar_clack_c.p_local_out[i](signal_dspin_clack_proc[i]);
527
528    xbar_p2m_c.p_clk(signal_clk);
529    xbar_p2m_c.p_resetn(signal_resetn);
530    xbar_p2m_c.p_global_out(signal_dspin_p2m_l2g);
531    xbar_p2m_c.p_global_in(signal_dspin_p2m_g2l);
532    xbar_p2m_c.p_local_out[0](signal_dspin_p2m_memc);
533    for (size_t i = 0; i < param.nr_cpus; i++)
534        xbar_p2m_c.p_local_in[i](signal_dspin_p2m_proc[i]);
535
536    /*
537     * simulation
538     */
539
540    for (size_t i = 0; i < param.nr_cpus; i++)
541        proc[i]->iss_set_debug_mask(0);
542
543    sc_start(sc_time(0, SC_NS));
544    signal_resetn = false;
545
546    sc_start(sc_time(1, SC_NS));
547    signal_resetn = true;
548
549    /* network boundaries initialization */
550    signal_dspin_m2p_l2g.write = false;
551    signal_dspin_m2p_l2g.read = true;
552    signal_dspin_m2p_g2l.write = false;
553    signal_dspin_m2p_g2l.read = true;
554
555    if (param.ncycles > 0)
556    {
557        for (size_t n = 1; n < param.ncycles; n++)
558        {
559            if (param.trace_enabled and (n > param.trace_start_cycle))
560            {
561                std::cout << "****************** cycle " << std::dec << n
562                    << " ************************************************" << std::endl;
563
564                proc[0]->print_trace();
565                memc.print_trace();
566
567                signal_vci_proc[0].print_trace("signal_vci_proc[0]");
568                signal_vci_memc.print_trace("signal_vci_memc");
569
570                signal_dspin_m2p_memc.print_trace("signal_m2p_memc");
571                signal_dspin_clack_memc.print_trace("signal_clack_memc");
572                signal_dspin_p2m_memc.print_trace("signal_p2m_memc");
573                for (size_t i = 0; i < param.nr_cpus; i++)
574                {
575                    std::ostringstream o;
576                    o << "signal_m2p_proc" << "[" << i << "]";
577                    signal_dspin_m2p_proc[i].print_trace(o.str().c_str());
578                }
579            }
580            sc_start(sc_core::sc_time(1, SC_NS));
581        }
582    } else {
583        sc_start();
584    }
585
586    return EXIT_SUCCESS;
587
588}
589
590int sc_main (int argc, char *argv[])
591{
592    try {
593        return _main(argc, argv);
594    } catch (std::exception &e) {
595        std::cout << e.what() << std::endl;
596    } catch (...) {
597        std::cout << "Unknown exception occured" << std::endl;
598        throw;
599    }
600    return EXIT_FAILURE;
601}
602
Note: See TracBrowser for help on using the repository browser.