Compare commits
No commits in common. "058191de55e38205b0b474995c546443e793376c" and "9939a226c8196a68058cfe99e6ed0e9f50e935d7" have entirely different histories.
058191de55
...
9939a226c8
@ -98,8 +98,7 @@
|
|||||||
<button onclick="save_code('%SAVECODEURI%')"><span class="text">Save (ctrl-s)</span></button>
|
<button onclick="save_code('%SAVECODEURI%')"><span class="text">Save (ctrl-s)</span></button>
|
||||||
<button onclick="save_code('%SAVEASURI%')"><span class="text">Save as new</span></button>
|
<button onclick="save_code('%SAVEASURI%')"><span class="text">Save as new</span></button>
|
||||||
Sim:
|
Sim:
|
||||||
<button onclick="send_to_sim('%IVERILOGPOSTURI%')"><span class="text">Icarus</span></button>
|
<button onclick="send_to_icarus()"><span class="text">Icarus</span></button>
|
||||||
<button onclick="send_to_sim('%VERILATORPOSTURI%')"><span class="text">Verilator</span></button>
|
|
||||||
<!-- button><span class="text">Verilator</span></button -->
|
<!-- button><span class="text">Verilator</span></button -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -124,9 +123,9 @@
|
|||||||
enableLiveAutocompletion : true
|
enableLiveAutocompletion : true
|
||||||
});
|
});
|
||||||
const log_area = document.getElementById('log');
|
const log_area = document.getElementById('log');
|
||||||
function send_to_sim(uri) {
|
function send_to_icarus() {
|
||||||
log_area.innerHTML = "Please wait...";
|
log_area.innerHTML = "Please wait...";
|
||||||
fetch(uri,
|
fetch('%IVERILOGPOSTURI%',
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
1
_web_server/server/iverilog
Symbolic link
1
_web_server/server/iverilog
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
run-restricted
|
||||||
@ -24,17 +24,22 @@
|
|||||||
(define INDEX-FILE "index.html")
|
(define INDEX-FILE "index.html")
|
||||||
(define DELETE-WORK-DIR #t)
|
(define DELETE-WORK-DIR #t)
|
||||||
|
|
||||||
(define TOP-MODULE "testbench")
|
(define DEFAULT-CODE
|
||||||
(define SNIPPET-FILE "code.sv")
|
(string-append
|
||||||
(define IVERILOG-METATOP-FILE "top_iverilog.sv")
|
"`timescale 10ps/10ps\n\n"
|
||||||
(define VERILATOR-CPP-FILE "top_verilator.cpp")
|
"module test;\n"
|
||||||
|
" initial begin\n"
|
||||||
|
" $display(\"Hello world!\");\n"
|
||||||
|
" $finish();\n"
|
||||||
|
" end\n"
|
||||||
|
"endmodule\n"))
|
||||||
|
|
||||||
(define IVERILOG-EXE "iverilog")
|
(define SIM-SV-FILE "testbench.sv")
|
||||||
(define VVP-EXE "vvp")
|
(define SIM-VC-FILE "testbench.vc")
|
||||||
(define VERILATR-EXE "verilator")
|
(define SIM-EXE-FILE "testbench.out")
|
||||||
|
(define SNIPPET-FILE "code.sv")
|
||||||
|
|
||||||
(define URI-IVERILOG "iverilog")
|
(define URI-IVERILOG "iverilog")
|
||||||
(define URI-VERILATOR "verilator")
|
|
||||||
(define URI-SAVE-CODE "save")
|
(define URI-SAVE-CODE "save")
|
||||||
(define URI-SAVEAS-CODE "saveas")
|
(define URI-SAVEAS-CODE "saveas")
|
||||||
|
|
||||||
@ -45,16 +50,6 @@
|
|||||||
|
|
||||||
(define LOG-LEVEL LOG-VERBOSE)
|
(define LOG-LEVEL LOG-VERBOSE)
|
||||||
|
|
||||||
(define DEFAULT-CODE
|
|
||||||
(string-append
|
|
||||||
"`timescale 1ps/1ps\n\n"
|
|
||||||
(format "module ~a (input clock);\n" TOP-MODULE)
|
|
||||||
" initial begin\n"
|
|
||||||
" $display(\"Hello world!\");\n"
|
|
||||||
" $finish();\n"
|
|
||||||
" end\n"
|
|
||||||
"endmodule\n"))
|
|
||||||
|
|
||||||
(define (multistring . strings)
|
(define (multistring . strings)
|
||||||
(apply string-append
|
(apply string-append
|
||||||
(insert-between strings "\n")))
|
(insert-between strings "\n")))
|
||||||
@ -240,6 +235,21 @@
|
|||||||
(code (regexp-substitute/global #f "\\$dump[a-z]*" code 'pre "$error" 'post)))
|
(code (regexp-substitute/global #f "\\$dump[a-z]*" code 'pre "$error" 'post)))
|
||||||
code))
|
code))
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Get module name
|
||||||
|
;;;
|
||||||
|
(define (module-name code)
|
||||||
|
(let ((rx (make-regexp
|
||||||
|
"(^|\\s)module\\s*(\\s|(#\\(.*\\)\\s*))[a-zA-Z0-9_]+")))
|
||||||
|
(let loop ((pos 0)
|
||||||
|
(modname #f))
|
||||||
|
(let ((m (regexp-exec rx code pos)))
|
||||||
|
(if m
|
||||||
|
(loop (match:end m) (match:substring m))
|
||||||
|
(if modname
|
||||||
|
(match:substring (string-match "[a-zA-Z0-9_]+$" modname))
|
||||||
|
#f))))))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Concatenate path elements and remove duplicate slashes
|
;;; Concatenate path elements and remove duplicate slashes
|
||||||
;;;
|
;;;
|
||||||
@ -257,86 +267,52 @@
|
|||||||
(map string-trim-both paths))
|
(map string-trim-both paths))
|
||||||
"/")))))
|
"/")))))
|
||||||
|
|
||||||
(define (wrap-exe exe wrapper)
|
;;;
|
||||||
(format "~a~a" (if wrapper (format "~a " wrapper) "") exe))
|
;;; Create dump module
|
||||||
|
;;;
|
||||||
|
(define (create-dump-module path modname top)
|
||||||
|
(define (-> . fmt) (display (apply format fmt)) (newline))
|
||||||
|
(let ((filename (path+ path (format "~a.v" modname))))
|
||||||
|
(with-output-to-file filename
|
||||||
|
(lambda ()
|
||||||
|
(-> "`timescale 1ps/1ps")
|
||||||
|
(-> "module ~a();" modname)
|
||||||
|
(-> " initial begin")
|
||||||
|
(-> " $dumpfile(\"~a/~a.vcd\");" path modname)
|
||||||
|
(-> " $dumpvars(0, ~a);" top)
|
||||||
|
(-> " end")
|
||||||
|
(-> "endmodule")))
|
||||||
|
filename))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Make workdir with sources and command file. Common part
|
;;; Make workdir with sources and command file
|
||||||
;;; Returns work directory path string, verilog file name
|
;;; Returns work directory path string
|
||||||
;;; and command file name.
|
|
||||||
;;;
|
;;;
|
||||||
(define* (make-sim-workdir code base top)
|
(define (make-sim-workdir simulator code top base)
|
||||||
(let* ((work-dir (mkdtemp (path+ base (format "work-~a-XXXXXX" (current-time)))))
|
(let* ((work-dir (mkdtemp (path+ base (format "work-~a-XXXXXX" (current-time)))))
|
||||||
(verilog-file (path+ work-dir (format "~a.sv" top)))
|
(verilog-file (path+ work-dir SIM-SV-FILE))
|
||||||
(command-file (path+ work-dir (format "~a.vc" top))))
|
(command-file (path+ work-dir SIM-VC-FILE))
|
||||||
|
(dump-file (create-dump-module work-dir "dump" top)))
|
||||||
(with-output-to-file verilog-file (cut display code))
|
(with-output-to-file verilog-file (cut display code))
|
||||||
(values work-dir verilog-file command-file)))
|
|
||||||
|
|
||||||
;;;
|
|
||||||
;;; Create workdir for Icarus Verilog
|
|
||||||
;;; Returns directory path
|
|
||||||
;;;
|
|
||||||
(define* (make-iverilog-workdir code metatop base top)
|
|
||||||
(let-values (((work-dir verilog-file command-file)
|
|
||||||
(make-sim-workdir code base top)))
|
|
||||||
(let ((metatop-file (path+ work-dir (format "__~a__.sv" top))))
|
|
||||||
(with-output-to-file metatop-file
|
|
||||||
(cut display (substitute metatop "@~a@"
|
|
||||||
`((WORKDIR ,work-dir)
|
|
||||||
(TOPMODULE ,top)))))
|
|
||||||
|
|
||||||
(with-output-to-file command-file
|
(with-output-to-file command-file
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
(cond
|
||||||
|
((eq? simulator 'iverilog)
|
||||||
(println "~a" verilog-file)
|
(println "~a" verilog-file)
|
||||||
(println "~a" metatop-file)
|
(println "~a" dump-file)
|
||||||
(println "+define+TESTBENCH")
|
(println "+define+TESTBENCH")
|
||||||
(println "+timescale+1ps/1ps"))))
|
(println "+timescale+1ps/1ps")))))
|
||||||
work-dir))
|
|
||||||
|
|
||||||
;;;
|
|
||||||
;;; Create workdir for Verilator
|
|
||||||
;;; Returns directory path
|
|
||||||
;;;
|
|
||||||
(define* (make-verilator-workdir code cpp base top)
|
|
||||||
(let-values (((work-dir verilog-file command-file)
|
|
||||||
(make-sim-workdir code base top)))
|
|
||||||
(let ((cpp-file (path+ work-dir (format "~a.cpp" top))))
|
|
||||||
(with-output-to-file cpp-file
|
|
||||||
(cut display (substitute cpp "@~a@" `((WORKDIR ,work-dir)
|
|
||||||
(TOPMODULE ,top)))))
|
|
||||||
|
|
||||||
(with-output-to-file command-file
|
|
||||||
(lambda ()
|
|
||||||
(println "+define+TESTBENCH")
|
|
||||||
(println "--timescale 1ps/1ps")
|
|
||||||
(println "--top-module ~a" top)
|
|
||||||
(println "--Mdir ~a" (path+ work-dir top))
|
|
||||||
(println "-cc")
|
|
||||||
(println "-O2")
|
|
||||||
(println "-o ~a" top)
|
|
||||||
(println "--exe")
|
|
||||||
(println "--build")
|
|
||||||
(println "-sv")
|
|
||||||
(println "-Wno-WIDTH")
|
|
||||||
(println "+1800-2017ext+sv")
|
|
||||||
(println "--timing")
|
|
||||||
(println "--trace")
|
|
||||||
(println "--quiet-exit")
|
|
||||||
(println "~a" verilog-file)
|
|
||||||
(println "~a.cpp" top))))
|
|
||||||
work-dir))
|
work-dir))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Compile sources and execute simulation with Icarus Verilog
|
;;; Compile sources and execute simulation with Icarus Verilog
|
||||||
;;; Returns (values status log)
|
;;; Returns (values status log)
|
||||||
;;;
|
;;;
|
||||||
(define (exec-sim-iverilog top work-dir iverilog-wrap vvp-wrap)
|
(define (exec-sim-iverilog work-dir vvp-exe iverilog-exe)
|
||||||
(let ((command-file (path+ work-dir (format "~a.vc" top)))
|
(let ((exe-file (path+ work-dir SIM-EXE-FILE))
|
||||||
(exe-file (path+ work-dir (format "~a.out" top))))
|
(command-file (path+ work-dir SIM-VC-FILE)))
|
||||||
;; Compile
|
;; Compile
|
||||||
(let ((cmdline (format "~a -g2012 -s __~a__ -o ~a -c~a"
|
(let ((cmdline (format "~a -g2012 -o ~a -c~a" iverilog-exe exe-file command-file)))
|
||||||
(wrap-exe IVERILOG-EXE iverilog-wrap)
|
|
||||||
top exe-file command-file)))
|
|
||||||
(let-values (((status out)
|
(let-values (((status out)
|
||||||
(system-to-string cmdline)))
|
(system-to-string cmdline)))
|
||||||
(let ((compile-log
|
(let ((compile-log
|
||||||
@ -345,7 +321,7 @@
|
|||||||
(values status compile-log)
|
(values status compile-log)
|
||||||
|
|
||||||
;; Execute
|
;; Execute
|
||||||
(let ((cmdline (format "~a -N ~a" (wrap-exe VVP-EXE vvp-wrap) exe-file)))
|
(let ((cmdline (format "~a -N ~a" vvp-exe exe-file)))
|
||||||
(let-values (((status out)
|
(let-values (((status out)
|
||||||
(system-to-string cmdline)))
|
(system-to-string cmdline)))
|
||||||
(let ((execution-log
|
(let ((execution-log
|
||||||
@ -353,61 +329,37 @@
|
|||||||
(values status (string-append compile-log execution-log)))))))))))
|
(values status (string-append compile-log execution-log)))))))))))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Compile sources and execute simulation with Verilator
|
;;; Get iverilog version
|
||||||
;;; Returns (values status log)
|
|
||||||
;;;
|
;;;
|
||||||
(define (exec-sim-verilator top work-dir verilator-wrap verilator-sim-wrap)
|
(define (iverilog-version iverilog-exe)
|
||||||
;; Compile
|
|
||||||
(let* ((command-file (path+ work-dir (format "~a.vc" top)))
|
|
||||||
(cmdline (format "~a -f ~a"
|
|
||||||
(wrap-exe VERILATR-EXE verilator-wrap)
|
|
||||||
command-file)))
|
|
||||||
(let-values (((status out)
|
(let-values (((status out)
|
||||||
(system-to-string cmdline)))
|
(system-to-string-list
|
||||||
(let ((compile-log
|
(format "~a -V" iverilog-exe))))
|
||||||
(exe-log-pretty cmdline status out)))
|
(if (and (zero? status)
|
||||||
(if (not (zero? status))
|
(not (null? out)))
|
||||||
(values status compile-log)
|
(car out)
|
||||||
|
"Unknown")))
|
||||||
;; Execute
|
|
||||||
(let ((cmdline (wrap-exe (path+ work-dir (format "~a/~a" top top))
|
|
||||||
verilator-sim-wrap)))
|
|
||||||
(let-values (((status out)
|
|
||||||
(system-to-string cmdline)))
|
|
||||||
(let ((execution-log
|
|
||||||
(exe-log-pretty cmdline status out)))
|
|
||||||
(values status (string-append compile-log execution-log))))))))))
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Execute simulation
|
;;; Execute simulation
|
||||||
;;;
|
;;;
|
||||||
(define* (exec-sim simulator code base top #:key
|
(define* (exec-sim simulator code base
|
||||||
(vvp-wrap "") (iverilog-wrap "") (metatop "")
|
#:key
|
||||||
(verilator-wrap "") (verilator-sim-wrap "") (verilator-cpp ""))
|
(vvp-exe "vvp")
|
||||||
|
(iverilog-exe "iverilog"))
|
||||||
|
(let ((top (module-name code)))
|
||||||
|
(if (not top)
|
||||||
|
"Error: No module declaration\n"
|
||||||
|
(let ((work-dir (make-sim-workdir simulator code top base)))
|
||||||
(let-values
|
(let-values
|
||||||
(((work-dir status log)
|
(((status log)
|
||||||
(cond
|
(cond
|
||||||
;; Run Icarus Verilog
|
|
||||||
((eq? simulator 'iverilog)
|
((eq? simulator 'iverilog)
|
||||||
(let ((work-dir (make-iverilog-workdir code metatop base top)))
|
(exec-sim-iverilog work-dir vvp-exe iverilog-exe))
|
||||||
(let-values (((status log)
|
|
||||||
(exec-sim-iverilog top work-dir iverilog-wrap vvp-wrap)))
|
|
||||||
(values work-dir status log))))
|
|
||||||
|
|
||||||
;; Run Verilator
|
|
||||||
((eq? simulator 'verilator)
|
|
||||||
(let ((work-dir (make-verilator-workdir code verilator-cpp base top)))
|
|
||||||
(let-values (((status log)
|
|
||||||
(exec-sim-verilator top work-dir verilator-wrap verilator-sim-wrap)))
|
|
||||||
(values work-dir status log))))
|
|
||||||
|
|
||||||
;; Inknown simulator
|
|
||||||
(else
|
(else
|
||||||
(values #f #f #f)))))
|
(values -1 "No simulator found!\n")))))
|
||||||
|
|
||||||
(if (not work-dir)
|
|
||||||
("ERROR: Unknown simulator")
|
|
||||||
(begin
|
|
||||||
;; Delete work dir
|
;; Delete work dir
|
||||||
(when DELETE-WORK-DIR
|
(when DELETE-WORK-DIR
|
||||||
(delete-recursive work-dir))
|
(delete-recursive work-dir))
|
||||||
@ -416,19 +368,9 @@
|
|||||||
(string-append
|
(string-append
|
||||||
log
|
log
|
||||||
(format "-----------------\nSimulation complete~a\n"
|
(format "-----------------\nSimulation complete~a\n"
|
||||||
(if (zero? status) " succesfully"" with errors")))))))
|
(if (zero? status)
|
||||||
|
" succesfully"
|
||||||
;;;
|
" with errors"))))))))
|
||||||
;;; Get app version
|
|
||||||
;;;
|
|
||||||
(define* (app-version exe #:optional (option "--version"))
|
|
||||||
(let-values (((status out)
|
|
||||||
(system-to-string-list
|
|
||||||
(format "~a ~a" exe option))))
|
|
||||||
(if (and (zero? status)
|
|
||||||
(not (null? out)))
|
|
||||||
(car out)
|
|
||||||
"Unknown")))
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Get storage dir from URI
|
;;; Get storage dir from URI
|
||||||
@ -486,43 +428,38 @@
|
|||||||
(define (make-page-handler host root index-file
|
(define (make-page-handler host root index-file
|
||||||
work-base stor-base
|
work-base stor-base
|
||||||
max-code-size
|
max-code-size
|
||||||
iverilog-wrap vvp-wrap
|
vvp-exe iverilog-exe)
|
||||||
verilator-wrap verilator-sim-wrap)
|
|
||||||
|
|
||||||
(let* ((root-path (split-and-decode-uri-path root))
|
(let* ((root-path (split-and-decode-uri-path root))
|
||||||
(root (encode-and-join-uri-path root-path))
|
(root (encode-and-join-uri-path root-path))
|
||||||
(iverilog-path (append root-path `(,URI-IVERILOG)))
|
(iverilog-path (append root-path `(,URI-IVERILOG)))
|
||||||
(verilator-path (append root-path `(,URI-VERILATOR)))
|
|
||||||
(savecode-path (append root-path `(,URI-SAVE-CODE)))
|
(savecode-path (append root-path `(,URI-SAVE-CODE)))
|
||||||
(saveas-path (append root-path `(,URI-SAVEAS-CODE)))
|
(saveas-path (append root-path `(,URI-SAVEAS-CODE)))
|
||||||
|
(iverilog-post-uri (encode-and-join-uri-path iverilog-path))
|
||||||
|
(savecode-post-uri (encode-and-join-uri-path savecode-path))
|
||||||
|
(saveas-post-uri (encode-and-join-uri-path saveas-path))
|
||||||
(index-html
|
(index-html
|
||||||
(read-template-text
|
(read-template-text
|
||||||
index-file
|
index-file
|
||||||
`(("IVERILOGPOSTURI" ,(encode-and-join-uri-path iverilog-path))
|
`(("IVERILOGPOSTURI" ,iverilog-post-uri)
|
||||||
("VERILATORPOSTURI" ,(encode-and-join-uri-path verilator-path))
|
("SAVECODEURI" ,savecode-post-uri)
|
||||||
("SAVECODEURI" ,(encode-and-join-uri-path savecode-path))
|
("SAVEASURI" ,saveas-post-uri)
|
||||||
("SAVEASURI" ,(encode-and-join-uri-path saveas-path))
|
|
||||||
("HELPSTRING",
|
("HELPSTRING",
|
||||||
(string-concatenate
|
(string-concatenate
|
||||||
(insert-between
|
(insert-between
|
||||||
`("Verilog Playground by Punzik (c) 2022"
|
`("Verilog Playground by Punzik (c) 2022"
|
||||||
""
|
""
|
||||||
,(format "Icarus: ~a"
|
,(format "Icarus: ~a"
|
||||||
(app-version (wrap-exe IVERILOG-EXE iverilog-wrap) "-V"))
|
(iverilog-version iverilog-exe))
|
||||||
,(format "Verilator: ~a"
|
,(format "Verilator: ~a" "TODO")
|
||||||
(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. (TODO) The top module must be named 'testbench'."
|
||||||
"2. The top module for the Verilator must have an input clock signal."
|
"2. (TODO) The top module for the Verilator must have an input clock signal."
|
||||||
"3. Code size should not exceed 10000 characters."
|
"3. Code size should not exceed 10000 characters."
|
||||||
"4. Code execution time no longer than 5 seconds.")
|
"4. Code execution time no longer than 5 seconds.")
|
||||||
"\\n"))))))
|
"\\n")))))))
|
||||||
(iverilog-metatop
|
|
||||||
(call-with-input-file IVERILOG-METATOP-FILE get-string-all))
|
|
||||||
(verilator-cpp
|
|
||||||
(call-with-input-file VERILATOR-CPP-FILE get-string-all)))
|
|
||||||
|
|
||||||
(lambda (request request-body)
|
(lambda (request request-body)
|
||||||
(let (;; Requested resource path
|
(let (;; Requested resource path
|
||||||
@ -612,27 +549,8 @@
|
|||||||
(exec-sim 'iverilog
|
(exec-sim 'iverilog
|
||||||
(sanitize-verilog code)
|
(sanitize-verilog code)
|
||||||
work-base
|
work-base
|
||||||
TOP-MODULE
|
#:vvp-exe vvp-exe
|
||||||
#:metatop iverilog-metatop
|
#:iverilog-exe iverilog-exe)
|
||||||
#:vvp-wrap vvp-wrap
|
|
||||||
#:iverilog-wrap iverilog-wrap)
|
|
||||||
#:content-type 'text/plain))
|
|
||||||
|
|
||||||
;; Run verilator simulation
|
|
||||||
((equal? path verilator-path)
|
|
||||||
(logger LOG-DBG "Request verilator simulation")
|
|
||||||
|
|
||||||
(when ref-stor-dir
|
|
||||||
(save-to-storage (path+ stor-base ref-stor-dir) code))
|
|
||||||
|
|
||||||
(make-response
|
|
||||||
(exec-sim 'verilator
|
|
||||||
(sanitize-verilog code)
|
|
||||||
work-base
|
|
||||||
TOP-MODULE
|
|
||||||
#:verilator-wrap verilator-wrap
|
|
||||||
#:verilator-sim-wrap verilator-sim-wrap
|
|
||||||
#:verilator-cpp verilator-cpp)
|
|
||||||
#:content-type 'text/plain))
|
#:content-type 'text/plain))
|
||||||
|
|
||||||
;; Save snippet
|
;; Save snippet
|
||||||
@ -690,10 +608,8 @@
|
|||||||
(-> " -p, --port PORT Listen on PORT port. Default: 8080")
|
(-> " -p, --port PORT Listen on PORT port. Default: 8080")
|
||||||
(-> " -s, --host URL Run on URL hostname. Default: http://127.0.0.1:8080")
|
(-> " -s, --host URL Run on URL hostname. Default: http://127.0.0.1:8080")
|
||||||
(-> " -r, --root URN Service location root. Default: ''")
|
(-> " -r, --root URN Service location root. Default: ''")
|
||||||
(-> " --iverilog-wrap PATH Icarus compiler wrapper.")
|
(-> " --ivverilog-exe PATH Set Icarus Verilog compiler executable. Default: iverilog")
|
||||||
(-> " --vvp-wrap PATH Icarus Verilog interpreter wrapper.")
|
(-> " --vvp-exe PATH Set Icarus Verilog interpreter executable. Default: vvp")
|
||||||
(-> " --verilator-wrap PATH Verilator compiler wrapper.")
|
|
||||||
(-> " --verilator-sim-wrap PATH Verilator simulation executable wrapper.")
|
|
||||||
(-> " --max-len LEN Set maximum code size in symbols. Default: 0 (infinite)")
|
(-> " --max-len LEN Set maximum code size in symbols. Default: 0 (infinite)")
|
||||||
(-> " --work-base PATH Set work base path. Default: ./")
|
(-> " --work-base PATH Set work base path. Default: ./")
|
||||||
(-> " --stor-base PATH Set snippets storage path. Default: ./")
|
(-> " --stor-base PATH Set snippets storage path. Default: ./")
|
||||||
@ -702,11 +618,6 @@
|
|||||||
(-> "")
|
(-> "")
|
||||||
(-> "Source code and issue tracker: <https://github.com/punzik/>")))))
|
(-> "Source code and issue tracker: <https://github.com/punzik/>")))))
|
||||||
|
|
||||||
(define (string-trim-if-string str)
|
|
||||||
(if (string? str)
|
|
||||||
(string-trim str)
|
|
||||||
str))
|
|
||||||
|
|
||||||
(define (main args)
|
(define (main args)
|
||||||
(debug-disable 'backtrace)
|
(debug-disable 'backtrace)
|
||||||
(let-values
|
(let-values
|
||||||
@ -716,10 +627,8 @@
|
|||||||
'(("port" #\p) required)
|
'(("port" #\p) required)
|
||||||
'(("host" #\s) required)
|
'(("host" #\s) required)
|
||||||
'(("root" #\r) required)
|
'(("root" #\r) required)
|
||||||
'(("vvp-wrap") required)
|
'(("vvp-exe") required)
|
||||||
'(("iverilog-wrap") required)
|
'(("iverilog-exe") required)
|
||||||
'(("verilator-wrap") required)
|
|
||||||
'(("verilator-sim-wrap") required)
|
|
||||||
'(("max-len") required)
|
'(("max-len") required)
|
||||||
'(("work-base") required)
|
'(("work-base") required)
|
||||||
'(("stor-base") required)
|
'(("stor-base") required)
|
||||||
@ -730,10 +639,8 @@
|
|||||||
(port (string->number (string-trim (or (option-get opts "port") "8080"))))
|
(port (string->number (string-trim (or (option-get opts "port") "8080"))))
|
||||||
(host (string-trim (or (option-get opts "host") "http://127.0.0.1:8080")))
|
(host (string-trim (or (option-get opts "host") "http://127.0.0.1:8080")))
|
||||||
(root (string-trim (or (option-get opts "root") "")))
|
(root (string-trim (or (option-get opts "root") "")))
|
||||||
(vvp-wrap (string-trim-if-string (option-get opts "vvp-wrap")))
|
(vvp (string-trim (or (option-get opts "vvp-exe") "vvp")))
|
||||||
(iverilog-wrap (string-trim-if-string (option-get opts "iverilog-wrap")))
|
(iverilog (string-trim (or (option-get opts "iverilog-exe") "iverilog")))
|
||||||
(verilator-wrap (string-trim-if-string (option-get opts "verilator-wrap")))
|
|
||||||
(verilator-sim-wrap (string-trim-if-string (option-get opts "verilator-sim-wrap")))
|
|
||||||
(max-code-size (string->number (string-trim (or (option-get opts "max-len") "0"))))
|
(max-code-size (string->number (string-trim (or (option-get opts "max-len") "0"))))
|
||||||
(work-base (string-trim (or (option-get opts "work-base") "./")))
|
(work-base (string-trim (or (option-get opts "work-base") "./")))
|
||||||
(stor-base (string-trim (or (option-get opts "stor-base") "./")))
|
(stor-base (string-trim (or (option-get opts "stor-base") "./")))
|
||||||
@ -753,10 +660,6 @@
|
|||||||
(set! LOG-LEVEL log-level)
|
(set! LOG-LEVEL log-level)
|
||||||
(logger LOG-INFO "Listen on '~a' port '~a'" addr port)
|
(logger LOG-INFO "Listen on '~a' port '~a'" addr port)
|
||||||
(logger LOG-INFO "Server URL: '~a/~a'" host root)
|
(logger LOG-INFO "Server URL: '~a/~a'" host root)
|
||||||
(logger LOG-INFO "iverilog wrapper: '~a'" iverilog-wrap)
|
|
||||||
(logger LOG-INFO "vvp wrapper: '~a'" vvp-wrap)
|
|
||||||
(logger LOG-INFO "verilator compiler wrapper: '~a'" verilator-wrap)
|
|
||||||
(logger LOG-INFO "verilator simulator wrapper: '~a'" verilator-sim-wrap)
|
|
||||||
(logger LOG-INFO "Max code size: ~a" max-code-size)
|
(logger LOG-INFO "Max code size: ~a" max-code-size)
|
||||||
(logger LOG-INFO "Work base path: '~a'" work-base)
|
(logger LOG-INFO "Work base path: '~a'" work-base)
|
||||||
(logger LOG-INFO "Storage base path: '~a'" stor-base)
|
(logger LOG-INFO "Storage base path: '~a'" stor-base)
|
||||||
@ -765,7 +668,5 @@
|
|||||||
(run-server
|
(run-server
|
||||||
(make-page-handler host root INDEX-FILE
|
(make-page-handler host root INDEX-FILE
|
||||||
work-base stor-base
|
work-base stor-base
|
||||||
max-code-size
|
max-code-size vvp iverilog)
|
||||||
iverilog-wrap vvp-wrap
|
|
||||||
verilator-wrap verilator-sim-wrap)
|
|
||||||
'http `(#:host ,addr #:port ,port)))))))
|
'http `(#:host ,addr #:port ,port)))))))
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
exe=$(basename $0)
|
||||||
|
|
||||||
if [ -z "$DONOTUSEFIREJAIL" ]; then
|
if [ -z "$DONOTUSEFIREJAIL" ]; then
|
||||||
exec firejail \
|
exec firejail \
|
||||||
--quiet --noprofile \
|
--quiet --noprofile \
|
||||||
--rlimit-cpu=5 \
|
--rlimit-cpu=5 \
|
||||||
--rlimit-as=250m \
|
--rlimit-as=250m \
|
||||||
--rlimit-fsize=250k \
|
--rlimit-fsize=250k \
|
||||||
"$@"
|
"$exe" "$@"
|
||||||
else
|
else
|
||||||
exec timeout -v -s KILL 5 "$@"
|
exec timeout -v -s INT 5 "$exe" "$@"
|
||||||
fi
|
fi
|
||||||
@ -1,11 +0,0 @@
|
|||||||
`timescale 1ps/1ps
|
|
||||||
|
|
||||||
module __@TOPMODULE@__;
|
|
||||||
logic clock = 1'b0;
|
|
||||||
initial forever #(5ns) clock = ~clock;
|
|
||||||
@TOPMODULE@ @TOPMODULE@ (clock);
|
|
||||||
initial begin
|
|
||||||
$dumpfile("@WORKDIR@/@TOPMODULE@.vcd");
|
|
||||||
$dumpvars(0, @TOPMODULE@);
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
#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);
|
|
||||||
|
|
||||||
/* Create model instance */
|
|
||||||
V@TOPMODULE@ *top = new V@TOPMODULE@(ctx);
|
|
||||||
|
|
||||||
#if (VM_TRACE == 1)
|
|
||||||
VerilatedVcdC *vcd = new VerilatedVcdC;
|
|
||||||
ctx->traceEverOn(true);
|
|
||||||
top->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
top->final();
|
|
||||||
printf("[%lu] Stop simulation\n", ctx->time());
|
|
||||||
|
|
||||||
#if (VM_TRACE == 1)
|
|
||||||
if (vcd) {
|
|
||||||
vcd->close();
|
|
||||||
delete vcd;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete top;
|
|
||||||
delete ctx;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
1
_web_server/server/vvp
Symbolic link
1
_web_server/server/vvp
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
run-restricted
|
||||||
Loading…
x
Reference in New Issue
Block a user