source: trunk/platforms/tsar_mono_fpga/top.cpp @ 957

Last change on this file since 957 was 957, checked in by cfuguet, 9 years ago

Introduce a SocLib? platform implementing the FPGA mono cluster platform

  • This mono cluster platform is the one used for NetBSD and Linux on TSAR demonstrators.
  • It is based on the LETI platform but it contains an internal ROM and all the DSPIN routers have been removed.
File size: 18.7 KB
Line 
1/////////////////////////////////////////////////////////////////////////
2// File: top.cpp (for tsar_mono_fpga)
3// Author: Cesar Fuguet
4// Copyright: UPMC/LIP6
5// Date : March 2015
6// This program is released under the GNU public license
7/////////////////////////////////////////////////////////////////////////
8#include <systemc>
9#include <sys/time.h>
10#include <iostream>
11#include <sstream>
12#include <cstdlib>
13#include <cstdarg>
14#include <stdint.h>
15
16#include "gdbserver.h"
17#include "mapping_table.h"
18#include "tsar_fpga_cluster.h"
19#include "vci_local_crossbar.h"
20#include "vci_dspin_initiator_wrapper.h"
21#include "vci_dspin_target_wrapper.h"
22#include "vci_multi_tty.h"
23#include "vci_block_device_tsar.h"
24#include "vci_framebuffer.h"
25#include "alloc_elems.h"
26
27#include "hard_config.h"
28
29///////////////////////////////////////////////////
30//               Parallelisation
31///////////////////////////////////////////////////
32#define USE_OPENMP _OPENMP
33
34#if USE_OPENMP
35#include <omp.h>
36#endif
37
38///////////////////////////////////////////////////
39//  cluster index (from x,y coordinates)
40///////////////////////////////////////////////////
41
42#define cluster(x,y)   ((y) + ((x) << Y_WIDTH))
43
44///////////////////////////////////////////////////////////
45//          DSPIN parameters
46///////////////////////////////////////////////////////////
47
48#define dspin_cmd_width      39
49#define dspin_rsp_width      32
50
51///////////////////////////////////////////////////////////
52//          VCI parameters
53///////////////////////////////////////////////////////////
54
55#define vci_cell_width_int    4
56#define vci_cell_width_ext    8
57#define vci_address_width     40
58#define vci_plen_width        8
59#define vci_rerror_width      1
60#define vci_clen_width        1
61#define vci_rflag_width       1
62#define vci_srcid_width       14
63#define vci_pktid_width       4
64#define vci_trdid_width       4
65#define vci_wrplen_width      1
66
67
68///////////////////////////////////////////////////////////////////////////////////////
69//    Secondary Hardware Parameters
70///////////////////////////////////////////////////////////////////////////////////////
71
72#define XMAX                  X_SIZE   // actual number of columns in 2D mesh
73#define YMAX                  Y_SIZE   // actual number of rows in 2D mesh
74
75#define XRAM_LATENCY          0
76
77#define MEMC_WAYS             16
78#define MEMC_SETS             256
79
80#define L1_IWAYS              4
81#define L1_ISETS              64
82
83#define L1_DWAYS              4
84#define L1_DSETS              64
85
86#define BDEV_IMAGE_NAME       "../../../giet_vm/hdd/virt_hdd.dmg"
87
88#define ROM_SOFT_NAME         "../../softs/tsar_boot/preloader.elf"
89
90#define NORTH                 0
91#define SOUTH                 1
92#define EAST                  2
93#define WEST                  3
94
95///////////////////////////////////////////////////////////////////////////////////////
96//     DEBUG Parameters default values
97///////////////////////////////////////////////////////////////////////////////////////
98
99#define MAX_FROZEN_CYCLES     500000
100
101///////////////////////////////////////////////////////////////////////////////////////
102//     LOCAL TGTID & SRCID definition
103// For all components:  global TGTID = global SRCID = cluster_index
104///////////////////////////////////////////////////////////////////////////////////////
105
106#define MEMC_TGTID            0
107#define XICU_TGTID            1
108#define XROM_TGTID            2
109#define MTTY_TGTID            3
110#define BDEV_TGTID            4
111#define FBUF_TGTID            5
112
113#define BDEV_SRCID            NB_PROCS_MAX
114
115bool stop_called = false;
116
117#define SIMULATION_PERIOD     5000000
118
119/////////////////////////////////
120int _main(int argc, char *argv[])
121{
122    using namespace sc_core;
123    using namespace soclib::caba;
124    using namespace soclib::common;
125
126    uint64_t ncycles           = UINT64_MAX;         // max simulated cycles
127    size_t   threads           = 1;                  // simulator's threads number
128    bool     trace_ok          = false;              // trace activated
129    uint32_t trace_from        = 0;                  // trace start cycle
130    bool     trace_proc_ok     = false;              // detailed proc trace activated
131    size_t   trace_memc_ok     = false;              // detailed memc trace activated
132    size_t   trace_memc_id     = 0;                  // index of memc to be traced
133    size_t   trace_proc_id     = 0;                  // index of proc to be traced
134    char     soft_name[256]    = ROM_SOFT_NAME;      // pathname for ROM binary code
135    char     disk_name[256]    = BDEV_IMAGE_NAME;    // pathname for DISK image
136    uint32_t frozen_cycles     = MAX_FROZEN_CYCLES;  // for debug
137    uint64_t simulation_period = SIMULATION_PERIOD;
138
139    ////////////// command line arguments //////////////////////
140    if (argc > 1)
141    {
142        for (int n = 1; n < argc; n = n + 2)
143        {
144            if ((strcmp(argv[n], "-NCYCLES") == 0) && (n + 1 < argc))
145            {
146                ncycles = (uint64_t) strtol(argv[n + 1], NULL, 0);
147            }
148            else if ((strcmp(argv[n],"-DEBUG") == 0) && (n + 1 < argc))
149            {
150                trace_ok = true;
151                trace_from = (uint32_t) strtol(argv[n + 1], NULL, 0);
152                simulation_period = 1;
153            }
154            else if ((strcmp(argv[n], "-MEMCID") == 0) && (n + 1 < argc))
155            {
156                trace_memc_ok = true;
157                trace_memc_id = (size_t) strtol(argv[n + 1], NULL, 0);
158                size_t x = trace_memc_id >> Y_WIDTH;
159                size_t y = trace_memc_id & ((1<<Y_WIDTH)-1);
160
161                assert( (x < XMAX) and (y < (YMAX)) and
162                        "MEMCID parameter refers a not valid memory cache");
163            }
164            else if ((strcmp(argv[n], "-PROCID") == 0) && (n + 1 < argc))
165            {
166                trace_proc_ok = true;
167                trace_proc_id = (size_t) strtol(argv[n + 1], NULL, 0);
168                size_t cluster_xy = trace_proc_id >> P_WIDTH ;
169                size_t x          = cluster_xy >> Y_WIDTH;
170                size_t y          = cluster_xy & ((1<<Y_WIDTH)-1);
171                size_t l          = trace_proc_id & ((1<<P_WIDTH)-1) ;
172
173                assert( (x < XMAX) and (y < YMAX) and (l < NB_PROCS_MAX) and
174                        "PROCID parameter refers a not valid processor");
175            }
176            else if ((strcmp(argv[n], "-ROM") == 0) && ((n + 1) < argc))
177            {
178                strcpy(soft_name, argv[n + 1]);
179            }
180            else if ((strcmp(argv[n], "-DISK") == 0) && ((n + 1) < argc))
181            {
182                strcpy(disk_name, argv[n + 1]);
183            }
184            else if ((strcmp(argv[n], "-THREADS") == 0) && ((n + 1) < argc))
185            {
186                threads = (size_t) strtol(argv[n + 1], NULL, 0);
187                threads = (threads < 1) ? 1 : threads;
188            }
189            else if ((strcmp(argv[n], "-FROZEN") == 0) && (n + 1 < argc))
190            {
191                frozen_cycles = (uint32_t) strtol(argv[n + 1], NULL, 0);
192            }
193            else
194            {
195                std::cout << "   Arguments are (key,value) couples." << std::endl;
196                std::cout << "   The order is not important." << std::endl;
197                std::cout << "   Accepted arguments are :" << std::endl << std::endl;
198                std::cout << "     - NCYCLES number_of_simulated_cycles" << std::endl;
199                std::cout << "     - DEBUG debug_start_cycle" << std::endl;
200                std::cout << "     - ROM path to ROM image" << std::endl;
201                std::cout << "     - DISK path to disk image" << std::endl;
202                std::cout << "     - THREADS simulator's threads number" << std::endl;
203                std::cout << "     - FROZEN max_number_of_lines" << std::endl;
204                std::cout << "     - PERIOD number_of_cycles between trace" << std::endl;
205                std::cout << "     - MEMCID index_memc_to_be_traced" << std::endl;
206                std::cout << "     - PROCID index_proc_to_be_traced" << std::endl;
207                exit(0);
208            }
209        }
210    }
211
212    // checking hardware parameters
213    assert( (X_SIZE == 1) && (Y_SIZE == 1) );
214    assert( (X_WIDTH == 4) && (Y_WIDTH == 4) );
215    assert( (P_WIDTH == 2) );
216    assert( (NB_PROCS_MAX <= 4));
217    assert( (NB_TTY_CHANNELS == 1));
218
219    std::cout << std::endl;
220    std::cout << " - XMAX             = " << XMAX << std::endl;
221    std::cout << " - YMAX             = " << YMAX << std::endl;
222    std::cout << " - NB_PROCS_MAX     = " << NB_PROCS_MAX <<  std::endl;
223    std::cout << " - NB_TTY_CHANNELS  = " << NB_TTY_CHANNELS <<  std::endl;
224    std::cout << " - MEMC_WAYS        = " << MEMC_WAYS << std::endl;
225    std::cout << " - MEMC_SETS        = " << MEMC_SETS << std::endl;
226    std::cout << " - RAM_LATENCY      = " << XRAM_LATENCY << std::endl;
227    std::cout << " - MAX_FROZEN       = " << frozen_cycles << std::endl;
228    std::cout << " - MAX_CYCLES       = " << ncycles << std::endl;
229    std::cout << " - RESET_ADDRESS    = " << RESET_ADDRESS << std::endl;
230    std::cout << " - SOFT_FILENAME    = " << soft_name << std::endl;
231    std::cout << " - DISK_IMAGENAME   = " << disk_name << std::endl;
232    std::cout << std::endl;
233
234    // Internal and External VCI parameters definition
235    typedef soclib::caba::VciParams<vci_cell_width_int,
236            vci_plen_width,
237            vci_address_width,
238            vci_rerror_width,
239            vci_clen_width,
240            vci_rflag_width,
241            vci_srcid_width,
242            vci_pktid_width,
243            vci_trdid_width,
244            vci_wrplen_width> vci_param_int;
245
246    typedef soclib::caba::VciParams<vci_cell_width_ext,
247            vci_plen_width,
248            vci_address_width,
249            vci_rerror_width,
250            vci_clen_width,
251            vci_rflag_width,
252            vci_srcid_width,
253            vci_pktid_width,
254            vci_trdid_width,
255            vci_wrplen_width> vci_param_ext;
256
257#if USE_OPENMP
258    omp_set_dynamic(false);
259    omp_set_num_threads(threads);
260    std::cerr << "Built with openmp version " << _OPENMP << std::endl;
261    std::cout << " - OPENMP THREADS   = " << threads << std::endl;
262    std::cout << std::endl;
263#endif
264
265
266    ///////////////////////////////////////
267    //  Direct Network Mapping Table
268    ///////////////////////////////////////
269
270    MappingTable maptabd(vci_address_width,
271            IntTab(X_WIDTH + Y_WIDTH, 16 - X_WIDTH - Y_WIDTH),
272            IntTab(X_WIDTH + Y_WIDTH, vci_srcid_width - X_WIDTH - Y_WIDTH),
273            0x00FF000000ULL);
274
275    maptabd.add(Segment("seg_xicu", SEG_XCU_BASE, SEG_XCU_SIZE,
276                IntTab(cluster(0,0),XICU_TGTID), false));
277
278    maptabd.add(Segment("seg_mcfg", SEG_MMC_BASE, SEG_MMC_SIZE,
279                IntTab(cluster(0,0),MEMC_TGTID), false));
280
281    maptabd.add(Segment("seg_memc", SEG_RAM_BASE, SEG_RAM_SIZE,
282                IntTab(cluster(0,0),MEMC_TGTID), true));
283
284    maptabd.add(Segment("seg_mtty", SEG_TTY_BASE, SEG_TTY_SIZE,
285                IntTab(cluster(0,0),MTTY_TGTID), false));
286
287    maptabd.add(Segment("seg_bdev", SEG_IOC_BASE, SEG_IOC_SIZE,
288                IntTab(cluster(0,0),BDEV_TGTID), false));
289
290    maptabd.add(Segment("seg_brom", SEG_ROM_BASE, SEG_ROM_SIZE,
291                IntTab(cluster(0,0),XROM_TGTID), true));
292
293    maptabd.add(Segment("seg_fbuf", SEG_FBF_BASE, SEG_FBF_SIZE,
294                IntTab(cluster(0,0),FBUF_TGTID), false));
295
296    std::cout << maptabd << std::endl;
297
298    /////////////////////////////////////////////////
299    // Ram network mapping table
300    /////////////////////////////////////////////////
301
302    MappingTable maptabx(vci_address_width,
303                         IntTab(X_WIDTH+Y_WIDTH),
304                         IntTab(X_WIDTH+Y_WIDTH),
305                         0x00FF000000ULL);
306
307    maptabx.add(Segment("seg_xram", SEG_RAM_BASE, SEG_RAM_SIZE,
308                IntTab(cluster(0,0)), false));
309
310    std::cout << maptabx << std::endl;
311
312    ////////////////////
313    // Signals
314    ///////////////////
315
316    sc_clock signal_clk("clk");
317    sc_signal<bool> signal_resetn("resetn");
318
319    ////////////////////////////
320    //      Loader
321    ////////////////////////////
322
323#if USE_IOC_RDK
324    std::ostringstream ramdisk_name;
325    ramdisk_name << disk_name << "@" << std::hex << SEG_RDK_BASE << ":";
326    soclib::common::Loader loader( soft_name, ramdisk_name.str().c_str() );
327#else
328    soclib::common::Loader loader( soft_name );
329#endif
330
331    loader.memory_default(0x55);
332
333    typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;
334    proc_iss::set_loader( loader );
335
336    //////////////////////////////////////////////////////////////
337    // cluster construction
338    //////////////////////////////////////////////////////////////
339    TsarFpgaCluster<dspin_cmd_width, dspin_rsp_width,
340                    vci_param_int, vci_param_ext> fpga_cluster (
341                        "tsar_fpga_cluster",
342                        NB_PROCS_MAX,
343                        maptabd, maptabx,
344                        RESET_ADDRESS,
345                        X_WIDTH, Y_WIDTH,
346                        vci_srcid_width - X_WIDTH - Y_WIDTH,   // l_id width,
347                        MEMC_TGTID,
348                        XICU_TGTID,
349                        MTTY_TGTID,
350                        BDEV_TGTID,
351                        XROM_TGTID,
352                        disk_name,
353                        MEMC_WAYS, MEMC_SETS,
354                        L1_IWAYS, L1_ISETS, L1_DWAYS, L1_DSETS,
355                        XRAM_LATENCY,
356                        loader,
357                        frozen_cycles, trace_from,
358                        trace_proc_ok, trace_proc_id,
359                        trace_memc_ok );
360
361    DspinSignals<dspin_cmd_width> signal_dspin_bound_cmd_in;
362    DspinSignals<dspin_cmd_width> signal_dspin_bound_cmd_out;
363    DspinSignals<dspin_rsp_width> signal_dspin_bound_rsp_in;
364    DspinSignals<dspin_rsp_width> signal_dspin_bound_rsp_out;
365    DspinSignals<dspin_cmd_width> signal_dspin_bound_m2p_in;
366    DspinSignals<dspin_cmd_width> signal_dspin_bound_m2p_out;
367    DspinSignals<dspin_rsp_width> signal_dspin_bound_p2m_in;
368    DspinSignals<dspin_rsp_width> signal_dspin_bound_p2m_out;
369    DspinSignals<dspin_cmd_width> signal_dspin_bound_cla_in;
370    DspinSignals<dspin_cmd_width> signal_dspin_bound_cla_out;
371
372    // Cluster clock & reset
373    fpga_cluster.p_clk(signal_clk);
374    fpga_cluster.p_resetn(signal_resetn);
375    fpga_cluster.p_cmd_in(signal_dspin_bound_cmd_in);
376    fpga_cluster.p_cmd_out(signal_dspin_bound_cmd_out);
377    fpga_cluster.p_rsp_in(signal_dspin_bound_rsp_in);
378    fpga_cluster.p_rsp_out(signal_dspin_bound_rsp_out);
379    fpga_cluster.p_m2p_in(signal_dspin_bound_m2p_in);
380    fpga_cluster.p_m2p_out(signal_dspin_bound_m2p_out);
381    fpga_cluster.p_p2m_in(signal_dspin_bound_p2m_in);
382    fpga_cluster.p_p2m_out(signal_dspin_bound_p2m_out);
383    fpga_cluster.p_cla_in(signal_dspin_bound_cla_in);
384    fpga_cluster.p_cla_out(signal_dspin_bound_cla_out);
385
386    ////////////////////////////////////////////////////////
387    //   Simulation
388    ///////////////////////////////////////////////////////
389
390    sc_start(sc_core::sc_time(0, SC_NS));
391    signal_resetn = false;
392
393    // set cluster gateway signals default values
394    signal_dspin_bound_cmd_in.write = false;
395    signal_dspin_bound_cmd_in.read  = true;
396    signal_dspin_bound_cmd_out.write = false;
397    signal_dspin_bound_cmd_out.read  = true;
398
399    signal_dspin_bound_rsp_in.write = false;
400    signal_dspin_bound_rsp_in.read  = true;
401    signal_dspin_bound_rsp_out.write = false;
402    signal_dspin_bound_rsp_out.read  = true;
403
404    signal_dspin_bound_m2p_in.write = false;
405    signal_dspin_bound_m2p_in.read  = true;
406    signal_dspin_bound_m2p_out.write = false;
407    signal_dspin_bound_m2p_out.read  = true;
408
409    signal_dspin_bound_p2m_in.write = false;
410    signal_dspin_bound_p2m_in.read  = true;
411    signal_dspin_bound_p2m_out.write = false;
412    signal_dspin_bound_p2m_out.read  = true;
413
414    signal_dspin_bound_cla_in.write = false;
415    signal_dspin_bound_cla_in.read  = true;
416    signal_dspin_bound_cla_out.write = false;
417    signal_dspin_bound_cla_out.read  = true;
418
419    sc_start(sc_core::sc_time(1, SC_NS));
420    signal_resetn = true;
421
422    // simulation loop
423    for (uint64_t n = 0; n < ncycles && !stop_called; n += simulation_period)
424    {
425        // trace display
426        if ( trace_ok and (n > trace_from) )
427        {
428            std::cout << "****************** cycle " << std::dec << n ;
429            std::cout << " ********************************************" << std::endl;
430
431            if ( trace_proc_ok )
432            {
433                std::ostringstream proc_signame;
434                proc_signame << "[SIG]PROC_" << trace_proc_id ;
435                fpga_cluster.proc[trace_proc_id]->print_trace(1);
436                fpga_cluster.signal_vci_ini_proc[trace_proc_id].print_trace(proc_signame.str());
437
438                fpga_cluster.xicu->print_trace(0);
439                fpga_cluster.signal_vci_tgt_xicu.print_trace("[SIG]XICU");
440
441                for (int p = 0; p < NB_PROCS_MAX; p++)
442                {
443                    if ( fpga_cluster.signal_proc_irq[p*IRQ_PER_PROCESSOR].read() )
444                    {
445                        std::cout << "### IRQ_PROC_" << p << std::endl;
446                    }
447                }
448            }
449
450            if ( trace_memc_ok )
451            {
452                fpga_cluster.memc->print_trace();
453                fpga_cluster.signal_vci_tgt_memc.print_trace("[SEG]MEMC");
454                fpga_cluster.signal_vci_xram.print_trace("[SEG]XRAM");
455            }
456
457            fpga_cluster.bdev->print_trace();
458            fpga_cluster.signal_vci_tgt_bdev.print_trace("[SIG]BDEV_0_0");
459            fpga_cluster.signal_vci_ini_bdev.print_trace("[SIG]BDEV_0_0");
460        }  // end trace
461
462        struct timeval t1,t2;
463        if (gettimeofday(&t1, NULL) != 0) return EXIT_FAILURE;
464        sc_start(sc_core::sc_time(simulation_period, SC_NS));
465        if (gettimeofday(&t2, NULL) != 0) return EXIT_FAILURE;
466
467        // stats display
468        if (!trace_ok)
469        {
470            uint64_t ms1 = (uint64_t)t1.tv_sec * 1000ULL +
471                           (uint64_t)t1.tv_usec / 1000;
472            uint64_t ms2 = (uint64_t)t2.tv_sec * 1000ULL +
473                           (uint64_t)t2.tv_usec / 1000;
474            std::cerr << "platform clock frequency "
475                      << (double) simulation_period / (double) (ms2 - ms1)
476                      << "Khz" << std::endl;
477        }
478    }
479
480    return EXIT_SUCCESS;
481}
482
483void handler(int dummy = 0)
484{
485    stop_called = true;
486    sc_stop();
487}
488
489void voidhandler(int dummy = 0) {}
490
491int sc_main (int argc, char *argv[])
492{
493    signal(SIGINT, handler);
494    signal(SIGPIPE, voidhandler);
495
496    try {
497        return _main(argc, argv);
498    } catch (std::exception &e) {
499        std::cout << e.what() << std::endl;
500    } catch (...) {
501        std::cout << "Unknown exception occured" << std::endl;
502        throw;
503    }
504    return 1;
505}
506
507
508// Local Variables:
509// tab-width: 4
510// c-basic-offset: 4
511// c-file-offsets:((innamespace . 0)(inline-open . 0))
512// indent-tabs-mode: nil
513// End:
514
515// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.