Compare commits
2 Commits
1e0bfb58cf
...
3aee2d2f38
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3aee2d2f38 | ||
|
|
b84ec9a1c5 |
@ -33,7 +33,7 @@
|
||||
|
||||
(define IVERILOG-EXE "iverilog")
|
||||
(define VVP-EXE "vvp")
|
||||
(define VERILATR-EXE "verilator")
|
||||
(define VERILATOR-EXE "verilator")
|
||||
|
||||
(define URI-IVERILOG "iverilog")
|
||||
(define URI-VERILATOR "verilator")
|
||||
@ -49,9 +49,14 @@
|
||||
(define DEFAULT-CODE
|
||||
(string-append
|
||||
"`timescale 1ps/1ps\n\n"
|
||||
(format "module ~a (input clock);\n" TOP-MODULE)
|
||||
;; (format "module ~a (input clock);\n" TOP-MODULE)
|
||||
(format "module ~a;\n" TOP-MODULE)
|
||||
" logic clock = 1'b0;\n"
|
||||
" initial forever #(5ns) clock = ~clock;\n"
|
||||
"\n"
|
||||
" initial begin\n"
|
||||
" $display(\"Hello world!\");\n"
|
||||
" repeat(10) @(posedge clock);\n"
|
||||
" $finish();\n"
|
||||
" end\n"
|
||||
"endmodule\n"))
|
||||
@ -566,8 +571,7 @@
|
||||
|
||||
(with-output-to-file command-file
|
||||
(lambda ()
|
||||
(println "+define+TESTBENCH")
|
||||
(println "-CFLAGS -fcoroutines")
|
||||
(println "-DTESTBENCH")
|
||||
(println "--timescale 1ps/1ps")
|
||||
(println "--top-module ~a" top)
|
||||
(println "--Mdir ~a" (path+ work-dir top))
|
||||
@ -580,7 +584,7 @@
|
||||
(println "--build")
|
||||
(println "-sv")
|
||||
(println "-Wno-WIDTH")
|
||||
(println "+1800-2017ext+sv")
|
||||
(println "+1800-2023ext+sv")
|
||||
(println "--timing")
|
||||
(println "--trace")
|
||||
(println "--trace-structs")
|
||||
@ -650,7 +654,7 @@
|
||||
(let* ((command-file (path+ work-dir (format "~a.vc" top)))
|
||||
(vcd-file (path+ work-dir (format "~a.vcd" top)))
|
||||
(cmds `(,(format "~a -f ~a"
|
||||
(wrap-exe VERILATR-EXE verilator-wrap)
|
||||
(wrap-exe VERILATOR-EXE verilator-wrap)
|
||||
command-file)
|
||||
,(wrap-exe (path+ work-dir (format "~a/~a" top top))
|
||||
verilator-sim-wrap))))
|
||||
@ -818,14 +822,13 @@
|
||||
,(format "Icarus: ~a"
|
||||
(app-version (wrap-exe IVERILOG-EXE iverilog-wrap) "-V"))
|
||||
,(format "Verilator: ~a"
|
||||
(app-version (wrap-exe VERILATR-EXE verilator-wrap)))
|
||||
(app-version (wrap-exe VERILATOR-EXE verilator-wrap)))
|
||||
""
|
||||
"Rules:"
|
||||
"0. Don't fool around ;)"
|
||||
"1. The top module must be named 'testbench'."
|
||||
"2. The top module must have an input clock signal."
|
||||
"3. Code size should not exceed 10000 characters."
|
||||
"4. Code execution time no longer than 5 seconds.")
|
||||
"2. Code size should not exceed 10000 characters."
|
||||
"3. Code execution time no longer than 5 seconds.")
|
||||
"\\n"))))))
|
||||
(iverilog-metatop
|
||||
(call-with-input-file IVERILOG-METATOP-FILE get-string-all))
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module __@TOPMODULE@__;
|
||||
logic clock = 1'b0;
|
||||
initial forever #(5ns) clock = ~clock;
|
||||
@TOPMODULE@ @TOPMODULE@ (clock);
|
||||
@TOPMODULE@ @TOPMODULE@ ();
|
||||
|
||||
initial begin
|
||||
$dumpfile("@WORKDIR@/@TOPMODULE@.vcd");
|
||||
$dumpvars(1, @TOPMODULE@);
|
||||
|
||||
@ -1,58 +1,43 @@
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
#include "V@TOPMODULE@.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_c.h>
|
||||
|
||||
#define DUMPFILE "@WORKDIR@/@TOPMODULE@.vcd"
|
||||
#define CLOCK_HALF_PERIOD 5000
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
VerilatedContext *ctx = new VerilatedContext;
|
||||
ctx->commandArgs(argc, argv);
|
||||
int main(int argc, char** argv, char**) {
|
||||
// Setup context, defaults, and parse command line
|
||||
Verilated::debug(0);
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
contextp->traceEverOn(true);
|
||||
contextp->commandArgs(argc, argv);
|
||||
|
||||
/* Create model instance */
|
||||
V@TOPMODULE@ *top = new V@TOPMODULE@(ctx);
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating
|
||||
const std::unique_ptr<V@TOPMODULE@> topp{new V@TOPMODULE@{contextp.get()}};
|
||||
|
||||
#if (VM_TRACE == 1)
|
||||
VerilatedVcdC *vcd = new VerilatedVcdC;
|
||||
ctx->traceEverOn(true);
|
||||
top->trace(vcd, 99);
|
||||
topp->trace(vcd, 99);
|
||||
vcd->open(DUMPFILE);
|
||||
#endif
|
||||
|
||||
top->clock = 0;
|
||||
|
||||
/* ---- Evaluation loop ---- */
|
||||
for (;;) {
|
||||
/* Eval */
|
||||
top->eval();
|
||||
|
||||
/* Trace steady-state values */
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd) vcd->dump(ctx->time());
|
||||
#endif
|
||||
|
||||
/* Break exactly after calling $finish */
|
||||
if (ctx->gotFinish()) break;
|
||||
|
||||
/* Clock event */
|
||||
ctx->timeInc(CLOCK_HALF_PERIOD);
|
||||
top->clock = top->clock ? 0 : 1;
|
||||
// Simulate until $finish
|
||||
while (!contextp->gotFinish()) {
|
||||
// Evaluate model
|
||||
topp->eval();
|
||||
vcd->dump(contextp->time());
|
||||
// Advance time
|
||||
if (!topp->eventsPending()) break;
|
||||
contextp->time(topp->nextTimeSlot());
|
||||
}
|
||||
|
||||
top->final();
|
||||
printf("[%lu] Stop simulation\n", ctx->time());
|
||||
if (!contextp->gotFinish()) {
|
||||
VL_DEBUG_IF(VL_PRINTF("+ Exiting without $finish; no events left\n"););
|
||||
}
|
||||
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd) {
|
||||
// Execute 'final' processes
|
||||
topp->final();
|
||||
|
||||
// Print statistical summary report
|
||||
contextp->statsPrintSummary();
|
||||
vcd->close();
|
||||
delete vcd;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete top;
|
||||
delete ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user