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

Last change on this file since 759 was 689, checked in by porquet, 12 years ago

hard_linux_monocluster: display simulation frequency

File size: 18.9 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 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 uint64_t n;
584 struct timeval t1, t2;
585
586 gettimeofday(&t1, NULL);
587
588 for (n = 1; ; n++) {
589 /* stats display */
590 if ((n % 5000000) == 0) {
591 gettimeofday(&t2, NULL);
592
593 uint64_t ms1 = (uint64_t)t1.tv_sec * 1000ULL +
594 (uint64_t)t1.tv_usec / 1000;
595 uint64_t ms2 = (uint64_t)t2.tv_sec * 1000ULL +
596 (uint64_t)t2.tv_usec / 1000;
597 std::cerr << "platform clock frequency "
598 << (double)5000000 / (double)(ms2 - ms1) << "Khz" << std::endl;
599
600 gettimeofday(&t1, NULL);
601 }
602
603 sc_start(sc_core::sc_time(1, SC_NS));
604 };
605 }
606
607 return EXIT_SUCCESS;
608
609}
610
611int sc_main (int argc, char *argv[])
612{
613 try {
614 return _main(argc, argv);
615 } catch (std::exception &e) {
616 std::cout << e.what() << std::endl;
617 } catch (...) {
618 std::cout << "Unknown exception occured" << std::endl;
619 throw;
620 }
621 return EXIT_FAILURE;
622}
623
Note: See TracBrowser for help on using the repository browser.