// -*- SystemC -*- // DESCRIPTION: Verilator Example: Top level main for invoking SystemC model // // Copyright 2003-2013 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. //==================================================================== #include #include #include #include #ifdef SYSTEMPERL # include "systemperl.h" // SystemC + SystemPerl global header # include "sp_log.h" // Logging cout to files # include "SpTraceVcd.h" # include "SpCoverage.h" #else # include "systemc.h" // SystemC global header # include "verilated_vcd_sc.h" // Tracing #endif #include "Vtop.h" // Top level header, generated from verilog Vtop *top; int sc_main(int argc, char* argv[]) { Verilated::commandArgs(argc, argv); Verilated::randReset(2); Verilated::debug(0); // We compiled with it on for testing, turn it back off // General logfile ios::sync_with_stdio(); #ifdef SYSTEMPERL sp_log_file simlog ("sim.log"); simlog.redirect_cout(); #endif // Defaults #if (SYSTEMC_VERSION>20011000) #else sc_time dut(1.0, sc_ns); sc_set_default_time_unit(dut); #endif //========== // Define the Clocks cout << "Defining Clocks\n"; #if (SYSTEMC_VERSION>=20070314) sc_clock clk ("clk", 10,SC_NS, 0.5, 3,SC_NS, true); sc_clock fastclk ("fastclk", 2,SC_NS, 0.5, 2,SC_NS, true); #else sc_clock clk ("clk", 10, 0.5, 3, true); sc_clock fastclk ("fastclk", 2, 0.5, 2, true); #endif cout << "Defining Interconnect\n"; sc_signal reset_l; sc_signal passed; sc_signal in_small; sc_signal in_quad; sc_signal > in_wide; sc_signal out_small; sc_signal out_quad; sc_signal > out_wide; //========== // Part under test #ifdef SYSTEMPERL SP_CELL (top, Vtop); SP_PIN (top, clk, clk); SP_PIN (top, fastclk, fastclk); SP_PIN (top, reset_l, reset_l); SP_PIN (top, passed, passed); SP_PIN (top, in_small, in_small); SP_PIN (top, in_quad, in_quad); SP_PIN (top, in_wide, in_wide); SP_PIN (top, out_small, out_small); SP_PIN (top, out_quad, out_quad); SP_PIN (top, out_wide, out_wide); #else Vtop* top = new Vtop("top"); top->clk (clk); top->fastclk (fastclk); top->reset_l (reset_l); top->passed (passed); top->in_small (in_small); top->in_quad (in_quad); top->in_wide (in_wide); top->out_small (out_small); top->out_quad (out_quad); top->out_wide (out_wide); #endif //========== // Waves #if VM_TRACE // Before any evaluation, need to know to calculate those signals only used for tracing Verilated::traceEverOn(true); #endif // You must do one evaluation before enabling waves, in order to allow // SystemC to interconnect everything for testing. cout <<("Test initialization...\n"); reset_l = 1; #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif //========== // Waves #if VM_TRACE cout << "Enabling waves...\n"; # ifdef SYSTEMPERL SpTraceFile* tfp = new SpTraceFile; # else VerilatedVcdSc* tfp = new VerilatedVcdSc; # endif top->trace (tfp, 99); tfp->open ("vlt_dump.vcd"); #endif //========== // Start of Test cout <<("Test beginning...\n"); reset_l = 1; while (VL_TIME_Q() < 60 && !passed && !Verilated::gotFinish()) { #if VM_TRACE // Flush the wave files each cycle so we can immediately see the output // Don't do this in "real" programs, do it in a abort() handler instead if (tfp) tfp->flush(); #endif if (VL_TIME_Q() > 10) { reset_l = 1; // Deassert reset } else if (VL_TIME_Q() > 1) { reset_l = 0; // Assert reset } #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif } top->final(); //========== // Close Waves #if VM_TRACE if (tfp) tfp->close(); #endif if (!passed) { VL_PRINTF ("A Test failed!!\n"); abort(); } //========== // Coverage analysis (since test passed) mkdir("logs", 0777); #if VM_COVERAGE SpCoverage::write(); // Writes logs/coverage.pl #endif //========== // Close LogFiles cout << "*-* All Finished *-*\n"; // Magic if using perl's Log::Detect return(0); }