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