source: branches/v4/platforms/tsarv4_mono_mmu_ioc/top.cpp @ 641

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

make the framebuffer being optional (via --framebuffer)

File size: 13.3 KB
RevLine 
[410]1/*
2 * global config
3 */
4
5#define CONFIG_GDB_SERVER
6
7
8/*
9 * headers
10 */
11
12#ifdef _OPENMP
13#include <omp.h>
14#endif
15
16#include <systemc>
17#include <iostream>
18#include <cstdlib>
19
20#ifdef CONFIG_GDB_SERVER
21#include "gdbserver.h"
22#endif
23
24#include "mapping_table.h"
25
26#include "mips32.h"
27#include "vci_cc_vcache_wrapper_v4.h"
28#include "vci_simple_ram.h"
29#include "vci_mem_cache_v4.h"
30
[636]31#include "vci_icu.h"
[410]32#include "vci_multi_tty.h"
[636]33#include "vci_timer.h"
[410]34#include "vci_block_device_tsar_v4.h"
[640]35#include "vci_framebuffer.h"
[410]36
37#include "vci_vgmn.h"
38
39#include "alloc_elems.h"
40
41
42/*
43 * pf global config
44 */
45
46using namespace sc_core;
47using namespace soclib::caba;
48using namespace soclib::common;
49
50#define cell_width      4
51#define address_width   32
52#define plen_width      8
53#define error_width     2
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
61typedef VciParams<cell_width,
62        plen_width,
63        address_width,
64        error_width,
65        clen_width,
66        rflag_width,
67        srcid_width,
68        pktid_width,
69        trdid_width,
70        wrplen_width> vci_param;
71
72/* mapping table for data */
73MappingTable maptabd(32, IntTab(6), IntTab(6), 0xf0000000);
74/* mapping table for coherence */
75MappingTable maptabc(32, IntTab(srcid_width), IntTab(srcid_width), 0xf0000000);
76
77
78/*
79 * segmentation
80 */
81
82#include "segmentation.h"
83
84
85/*
86 * default parameters
87 */
88
[420]89struct param_s {
90    char *rom_path;
91    char *dsk_path;
92    bool dummy_boot;
[641]93    bool framebuffer;
[420]94    bool trace_enabled;
95    size_t trace_start_cycle;
96};
[410]97
[420]98#define PARAM_INITIALIZER   \
99{                           \
[641]100    .rom_path = NULL,       \
101    .dsk_path = NULL,       \
[420]102    .dummy_boot = false,    \
[641]103    .framebuffer = false,   \
[420]104    .trace_enabled = false, \
105    .trace_start_cycle = 0  \
106}
107
108static inline void print_param(const struct param_s &param)
109{
110    std::cout << std::endl;
111    std::cout << "simulation parameters:" << std::endl;
112    std::cout << "  rom         = " << param.rom_path << std::endl;
113    std::cout << "  dummy boot  = " << param.dummy_boot << std::endl;
[641]114    std::cout << "  framebuffer = " << param.framebuffer << std::endl;
[420]115    std::cout << "  dsk         = " << param.dsk_path << std::endl;
116    std::cout << "  trace       = " << param.trace_enabled << std::endl;
117    if (param.trace_enabled)
118        std::cout << "    start cyc = " << param.trace_start_cycle << std::endl;
119
120    std::cout << std::endl;
121}
122
123
[410]124/*
125 * arguments parsing
126 */
127
[420]128void args_parse(unsigned int argc, char *argv[], struct param_s &param)
[410]129{
[420]130    for (size_t n = 1; n < argc; n = n + 2)
[410]131    {
[420]132        if ((strcmp(argv[n], "--rom") == 0) && ((n + 1) < argc))
[410]133        {
[420]134            assert((param.rom_path = strdup(argv[n + 1]))
135                    && "insufficient memory");
[410]136        }
[420]137        else if ((strcmp(argv[n], "--dsk") == 0) && ((n + 1) < argc))
138        {
139            assert((param.dsk_path = strdup(argv[n + 1]))
140                    && "insufficient memory");
141        }
142        else if (strcmp(argv[n], "--dummy-boot") == 0)
143        {
144            param.dummy_boot = true;
145            /* we don't have an extra argument */
146            n = n - 1;
147        }
[641]148        else if (strcmp(argv[n], "--framebuffer") == 0)
149        {
150            param.framebuffer = true;
151            /* we don't have an extra argument */
152            n = n - 1;
153        }
[420]154        else if ((strcmp(argv[n], "--trace") == 0) && ((n + 1) < argc))
155        {
156            param.trace_enabled = true;
157            param.trace_start_cycle = atoi(argv[n + 1]);
158        }
159        else
160        {
161            std::cout << "Error: don't understand option " << argv[n] << std::endl;
162            std::cout << "Accepted arguments are :" << std::endl;
163            std::cout << "--rom pathname" << std::endl;
164            std::cout << "--dsk pathname" << std::endl;
165            std::cout << "[--dummy-boot]" << std::endl;
[641]166            std::cout << "[--framebuffer]" << std::endl;
[636]167            std::cout << "[--trace trace_start_cycle]" << std::endl;
[420]168            exit(0);
169        }
[410]170    }
171
[420]172    /* check parameters */
173    assert(param.rom_path && "--rom is not optional");
174    assert(param.dsk_path && "--dsk is not optional");
175
176    print_param(param);
[410]177}
178
179
180/*
181 * netlist
182 */
183
184int _main(int argc, char *argv[])
185{
186#ifdef _OPENMP
187    omp_set_dynamic(false);
188    omp_set_num_threads(1);
189    std::cerr << "Built with openmp version " << _OPENMP << std::endl;
190#endif
191
[420]192    struct param_s param = PARAM_INITIALIZER;
193
[410]194    /* parse arguments */
[420]195    args_parse(argc, argv, param);
[410]196
197    /*
[636]198     * mapping table (data and coherence)
[410]199     */
200
201    // caches ram bank
202    maptabd.add(Segment("memc_d" , MEMC_BASE , MEMC_SIZE , IntTab(0), true));
203    maptabd.add(Segment("boot_d" , BOOT_BASE , BOOT_SIZE , IntTab(1), true));
204
205    // uncached peripherals
[636]206    maptabd.add(Segment("icu_d"   , ICU_BASE   , ICU_SIZE   , IntTab(2), false));
207    maptabd.add(Segment("mtty_d"  , MTTY_BASE  , MTTY_SIZE  , IntTab(3), false));
208    maptabd.add(Segment("timer_d" , TIMER_BASE , TIMER_SIZE , IntTab(4), false));
209    maptabd.add(Segment("bd_d"    , BD_BASE    , BD_SIZE    , IntTab(5), false));
[640]210    maptabd.add(Segment("fb_d"    , FB_BASE    , FB_SIZE    , IntTab(6), false));
[410]211
212    std::cout << maptabd << std::endl;
213
214    // procs
215    maptabc.add(Segment("proc_c" , 0x0000000 , 0x10 , IntTab(0) , false));
216    maptabc.add(Segment("memc_c" , 1 << (address_width - srcid_width) , 0x10 , IntTab(1) , false));
217
218    std::cout << maptabc << std::endl;
219
220    /*
221     * components
222     */
223
224    Loader loader;
[420]225    loader.load_file(param.rom_path);
[410]226
227#ifdef CONFIG_GDB_SERVER
228    typedef GdbServer<Mips32ElIss> proc_iss;
229    proc_iss::set_loader(loader);
230#else
231    typedef Mips32ElIss proc_iss;
232#endif
233
[420]234    if (param.dummy_boot == true)
235    {
236        /* boot linux image directly */
[636]237        uint64_t entry_addr = loader.get_entry_point_address();
238        std::cout << "setResetAdress: " << std::hex << entry_addr << std::endl << std::endl;
239        proc_iss::setResetAddress(entry_addr);
[420]240    }
241
[410]242    VciCcVCacheWrapperV4<vci_param, proc_iss > proc("ccvcache",
243                0,          // proc_id
244                maptabd,    // direct space
245                maptabc,    // coherence space
246                IntTab(0),  // srcid_d
247                IntTab(0),  // srcid_c
248                IntTab(0),  // tgtid_c
249                8, 8,       // itlb size
250                8, 8,       // dtlb size
251                4, 64, 16,  // icache size
252                4, 64, 16,  // dcache size
253                4, 4,       // wbuf size
254                0, 0,       // x, y Width
255                1,          // memory cache local id
256                1000,       // max frozen cycles
[420]257                param.trace_start_cycle,
258                param.trace_enabled);
[410]259
[636]260    VciSimpleRam<vci_param> ram("ram", IntTab(0), maptabd, loader);
[410]261
262    VciSimpleRam<vci_param> rom("rom", IntTab(1), maptabd, loader);
263
264    VciMemCacheV4<vci_param> memc("memc",
265            maptabd, maptabc, maptabd,
266            IntTab(0), IntTab(1), IntTab(0), IntTab(1), // srcid_d, srcid_c, tgtid_d, tgtid_c
267            16, 256, 16,    // cache size
268            1024, 4, 4,     // HEAP size, TRT size, UPT size
[420]269            param.trace_start_cycle, param.trace_enabled);
[410]270
[636]271    VciIcu<vci_param> icu("icu", IntTab(2), maptabd,
272            3); // #input_irqs
[410]273
274    VciMultiTty<vci_param> mtty("mtty", IntTab(3), maptabd, "vcitty0", NULL);
275
[636]276    VciTimer<vci_param> timer("timer", IntTab(4), maptabd,
277            1); // #timers
278
279    VciBlockDeviceTsarV4<vci_param> bd("bd", maptabd, IntTab(1), IntTab(5),
[420]280            param.dsk_path); // mapped_file[, block_size=512, latency=0]
[410]281
[641]282    VciFrameBuffer<vci_param> *fb = NULL;
283    if (param.framebuffer == true)
284        fb = new VciFrameBuffer<vci_param>("fb", IntTab(6), maptabd,
285                FB_XSIZE, FB_YSIZE,
286                FbController::RGB_16);
[640]287
[636]288    VciVgmn<vci_param> vgmnd("vgmnd", maptabd,
[640]289            2, 7,       // #initiators, #targets
[420]290            2, 8,       // min_latency, FIFO depth
291            IntTab(1)); // default target
[410]292
[636]293    VciVgmn<vci_param> vgmnc("vgmnc", maptabc,
[410]294            2, 2,   // #initiators, #targets
295            2, 8);  // min_latency, FIFO depth
296
297    /*
298     * signals
299     */
300
301    /* clock and reset */
302    sc_clock signal_clk("signal_clk");
303    sc_signal<bool> signal_resetn("signal_resetn");
304
305    /* irq lines */
306    sc_signal<bool> *signal_proc_irq =
307        alloc_elems<sc_signal<bool> >("signal_proc_irq", proc_iss::n_irq);
308    sc_signal<bool> signal_mtty_irq("signal_mtty_irq");
[636]309    sc_signal<bool> signal_timer_irq("signal_timer_irq");
310    sc_signal<bool> signal_bd_irq("signal_bd_irq");
[410]311
312    /* vci */
313    VciSignals<vci_param> signal_vci_ini_d_proc("vci_ini_d_proc");
314    VciSignals<vci_param> signal_vci_ini_c_proc("vci_ini_c_proc");
315    VciSignals<vci_param> signal_vci_tgt_c_proc("vci_tgt_c_proc");
316
[636]317    VciSignals<vci_param> signal_vci_ram("signal_vci_ram");
[410]318
[636]319    VciSignals<vci_param> signal_vci_tgt_d_rom("signal_vci_tgt_d_rom");
[410]320
321    VciSignals<vci_param> signal_vci_ini_c_memc("signal_vci_ini_c_memc");
322    VciSignals<vci_param> signal_vci_tgt_d_memc("signal_vci_tgt_d_memc");
323    VciSignals<vci_param> signal_vci_tgt_c_memc("signal_vci_tgt_c_memc");
324
[636]325    VciSignals<vci_param> signal_vci_tgt_d_icu("signal_vci_tgt_d_icu");
[410]326
327    VciSignals<vci_param> signal_vci_tgt_d_mtty("signal_vci_tgt_d_mtty");
328
[636]329    VciSignals<vci_param> signal_vci_tgt_d_timer("signal_vci_tgt_d_timer");
[410]330
[636]331    VciSignals<vci_param> signal_vci_ini_d_bd("signal_vci_ini_d_bd");
332    VciSignals<vci_param> signal_vci_tgt_d_bd("signal_vci_tgt_d_bd");
333
[640]334    VciSignals<vci_param> signal_vci_tgt_d_fb("signal_vci_tgt_d_fb");
335
[410]336    /*
337     * netlist
338     */
339
340    proc.p_clk(signal_clk);
341    proc.p_resetn(signal_resetn);
342    for (size_t i = 0; i < proc_iss::n_irq; i++)
343        proc.p_irq[i](signal_proc_irq[i]);
344    proc.p_vci_ini_d(signal_vci_ini_d_proc);
345    proc.p_vci_ini_c(signal_vci_ini_c_proc);
346    proc.p_vci_tgt_c(signal_vci_tgt_c_proc);
347
[636]348    ram.p_clk(signal_clk);
349    ram.p_resetn(signal_resetn);
350    ram.p_vci(signal_vci_ram);
[410]351
352    rom.p_clk(signal_clk);
353    rom.p_resetn(signal_resetn);
[636]354    rom.p_vci(signal_vci_tgt_d_rom);
[410]355
356    memc.p_clk(signal_clk);
357    memc.p_resetn(signal_resetn);
358    memc.p_vci_tgt(signal_vci_tgt_d_memc);
359    memc.p_vci_tgt_cleanup(signal_vci_tgt_c_memc);
360    memc.p_vci_ini(signal_vci_ini_c_memc);
[636]361    memc.p_vci_ixr(signal_vci_ram);
[410]362
[636]363    icu.p_resetn(signal_resetn);
364    icu.p_clk(signal_clk);
365    icu.p_vci(signal_vci_tgt_d_icu);
366    icu.p_irq_in[0](signal_mtty_irq);
367    icu.p_irq_in[1](signal_timer_irq);
368    icu.p_irq_in[2](signal_bd_irq);
369    icu.p_irq(signal_proc_irq[0]);
[410]370
371    mtty.p_clk(signal_clk);
372    mtty.p_resetn(signal_resetn);
373    mtty.p_vci(signal_vci_tgt_d_mtty);
374    mtty.p_irq[0](signal_mtty_irq);
375
[636]376    timer.p_clk(signal_clk);
377    timer.p_resetn(signal_resetn);
378    timer.p_vci(signal_vci_tgt_d_timer);
379    timer.p_irq[0](signal_timer_irq);
[410]380
[636]381    bd.p_clk(signal_clk);
382    bd.p_resetn(signal_resetn);
383    bd.p_vci_target(signal_vci_tgt_d_bd);
384    bd.p_vci_initiator(signal_vci_ini_d_bd);
385    bd.p_irq(signal_bd_irq);
[410]386
[641]387    if (param.framebuffer == true)
388    {
389        fb->p_clk(signal_clk);
390        fb->p_resetn(signal_resetn);
391        fb->p_vci(signal_vci_tgt_d_fb);
392    }
[640]393
[636]394    vgmnd.p_clk(signal_clk);
395    vgmnd.p_resetn(signal_resetn);
396    vgmnd.p_to_initiator[0](signal_vci_ini_d_proc);
397    vgmnd.p_to_initiator[1](signal_vci_ini_d_bd);
398    vgmnd.p_to_target[0](signal_vci_tgt_d_memc);
399    vgmnd.p_to_target[1](signal_vci_tgt_d_rom);
400    vgmnd.p_to_target[2](signal_vci_tgt_d_icu);
401    vgmnd.p_to_target[3](signal_vci_tgt_d_mtty);
402    vgmnd.p_to_target[4](signal_vci_tgt_d_timer);
403    vgmnd.p_to_target[5](signal_vci_tgt_d_bd);
[640]404    vgmnd.p_to_target[6](signal_vci_tgt_d_fb);
[410]405
[636]406    vgmnc.p_clk(signal_clk);
407    vgmnc.p_resetn(signal_resetn);
408    vgmnc.p_to_initiator[0](signal_vci_ini_c_proc);
409    vgmnc.p_to_initiator[1](signal_vci_ini_c_memc);
410    vgmnc.p_to_target[0](signal_vci_tgt_c_proc);
411    vgmnc.p_to_target[1](signal_vci_tgt_c_memc);
412
[410]413    /*
414     * simulation
415     */
416
417    sc_start(sc_time(0, SC_NS));
418    signal_resetn = false;
419
420    sc_start(sc_time(1, SC_NS));
421    signal_resetn = true;
422
[420]423    if (param.trace_enabled)
[410]424    {
[420]425        if (param.trace_start_cycle > 1)
[410]426            // simulate without output until trace_start_cycle
[420]427            sc_start(sc_time(param.trace_start_cycle, SC_NS));
[410]428
429        // enable debugging output
[420]430        for (size_t n = param.trace_start_cycle ;; n++)
[410]431        {
432            std::cout << "****************** cycle " << std::dec << n
433                << " ************************************************" << std::endl;
434            proc.print_trace();
435            memc.print_trace();
436            signal_vci_ini_d_proc.print_trace("proc_ini_d");
437            signal_vci_tgt_c_proc.print_trace("proc_tgt_c");
438            signal_vci_ini_c_proc.print_trace("proc_ini_c");
439            signal_vci_tgt_d_memc.print_trace("memc_tgt_d");
440            signal_vci_tgt_c_memc.print_trace("memc_tgt_c");
441            signal_vci_ini_c_memc.print_trace("memc_ini_c");
442            if (signal_proc_irq[0].read())
443                std::cout << "---- IRQ ----" << std::endl;
444            sc_start(sc_time(1, SC_NS));
445        }
446    } else
447        sc_start();
448
449    return EXIT_SUCCESS;
450}
451
452int sc_main (int argc, char *argv[])
453{
454    try {
455        return _main(argc, argv);
456    } catch (std::exception &e) {
457        std::cout << e.what() << std::endl;
458    } catch (...) {
459        std::cout << "Unknown exception occurred" << std::endl;
460        throw;
461    }
462    return EXIT_FAILURE;
463}
Note: See TracBrowser for help on using the repository browser.