aboutsummaryrefslogtreecommitdiffstats
path: root/src/verilog
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2020-04-02 14:54:14 +0100
committerYann Herklotz <git@yannherklotz.com>2020-04-02 14:54:20 +0100
commit8659e1b672a9b28a78c5b026312e7f3c0cb87c36 (patch)
tree7208310bcfa2cbae6dc8d244ee3693718df4a20b /src/verilog
parent5398b08ec6d445f91ed74c8434150cfbf99cc373 (diff)
downloadvericert-kvx-8659e1b672a9b28a78c5b026312e7f3c0cb87c36.tar.gz
vericert-kvx-8659e1b672a9b28a78c5b026312e7f3c0cb87c36.zip
Handle loops and conditionals correctly
Diffstat (limited to 'src/verilog')
-rw-r--r--src/verilog/PrintVerilog.ml50
-rw-r--r--src/verilog/Verilog.v15
2 files changed, 53 insertions, 12 deletions
diff --git a/src/verilog/PrintVerilog.ml b/src/verilog/PrintVerilog.ml
index 5199872..292fcf2 100644
--- a/src/verilog/PrintVerilog.ml
+++ b/src/verilog/PrintVerilog.ml
@@ -92,9 +92,13 @@ let pprint_edge_top i = function
| Valledge -> "@*"
| Voredge (e1, e2) -> concat ["@("; pprint_edge e1; " or "; pprint_edge e2; ")"]
+let declare i t =
+ function (r, sz) ->
+ concat [ indent i; t; " ["; sprintf "%d" (Nat.to_int sz - 1); ":0] ";
+ register r; ";\n" ]
+
let pprint_module_item i = function
- | Vdecl (r, n, e) ->
- concat [indent i; "reg ["; sprintf "%d" (Nat.to_int n - 1); ":0] "; register r; " = "; pprint_expr e; ";\n"]
+ | Vdecl (r, sz) -> declare i "reg" (r, sz)
| Valways (e, s) ->
concat [indent i; "always "; pprint_edge_top i e; "\n"; pprint_stmnt (i+1) s]
@@ -105,12 +109,48 @@ let rec intersperse c = function
let make_io i io r = concat [indent i; io; " "; register r; ";\n"]
+let compose f g x = g x |> f
+
+let init_inputs i r = declare i "input" r
+
+let init_outputs i r = declare i "output reg" r
+
+let testbench = "module testbench;
+ reg start, reset, clk;
+ wire finish;
+ wire [31:0] return_val;
+
+ main m(start, reset, clk, finish, return_val);
+
+ initial begin
+ clk = 0;
+ start = 0;
+ reset = 0;
+ @(posedge clk) reset = 1;
+ @(posedge clk) reset = 0;
+ end
+
+ always #5 clk = ~clk;
+
+ always @(posedge clk) begin
+ if (finish == 1) begin
+ $display(\"finished: %d\", return_val);
+ $finish;
+ end
+ end
+endmodule
+"
+
let pprint_module i n m =
let inputs = m.mod_start :: m.mod_reset :: m.mod_clk :: m.mod_args in
let outputs = [m.mod_finish; m.mod_return] in
- concat [ indent i; "module "; n; "("; concat (intersperse ", " (List.map register (inputs @ outputs))); ");\n";
- fold_map (make_io (i+1) "input") inputs; fold_map (make_io (i+1) "output") outputs;
- fold_map (pprint_module_item (i+1)) m.mod_body; indent i; "endmodule\n"
+ concat [ indent i; "module "; n;
+ "("; concat (intersperse ", " (List.map (compose register fst) (inputs @ outputs))); ");\n";
+ fold_map (init_inputs (i+1)) inputs;
+ fold_map (init_outputs (i+1)) outputs;
+ fold_map (pprint_module_item (i+1)) m.mod_body;
+ indent i; "endmodule\n\n";
+ testbench
]
let print_program pp v = pstr pp (pprint_module 0 "main" v)
diff --git a/src/verilog/Verilog.v b/src/verilog/Verilog.v
index 212dbc0..b9200b7 100644
--- a/src/verilog/Verilog.v
+++ b/src/verilog/Verilog.v
@@ -32,6 +32,7 @@ From compcert Require Integers.
Import ListNotations.
Definition reg : Type := positive.
+Definition szreg : Type := reg * nat.
Record value : Type := mkvalue {
vsize : nat;
@@ -108,7 +109,7 @@ Inductive edge : Type :=
| Voredge : edge -> edge -> edge.
Inductive module_item : Type :=
-| Vdecl : reg -> nat -> expr -> module_item
+| Vdecl : reg -> nat -> module_item
| Valways : edge -> stmnt -> module_item.
(** [mod_start] If set, starts the computations in the module. *)
@@ -119,12 +120,12 @@ Inductive module_item : Type :=
(** [mod_return] The return value that was computed. *)
(** [mod_body] The body of the module, including the state machine. *)
Record module : Type := mkmodule {
- mod_start : reg;
- mod_reset : reg;
- mod_clk : reg;
- mod_finish : reg;
- mod_return : reg;
- mod_args : list reg;
+ mod_start : szreg;
+ mod_reset : szreg;
+ mod_clk : szreg;
+ mod_finish : szreg;
+ mod_return : szreg;
+ mod_args : list szreg;
mod_body : list module_item;
}.