39 |
39 |
let std_logic_cst = ["U"; "X"; "0"; "1"; "Z"; "W"; "L"; "H"; "-" ]
|
40 |
40 |
|
41 |
41 |
(* TODO: do we need more constructors ? *)
|
42 |
|
type cst_val_t = CstInt of int | CstStdLogic of string
|
|
42 |
type cst_val_t = CstInt of int | CstStdLogic of string | CstBV of string * string
|
43 |
43 |
|
44 |
44 |
let pp_cst_val fmt c =
|
45 |
45 |
match c with
|
46 |
46 |
| CstInt i -> Format.fprintf fmt "%i" i
|
47 |
47 |
| CstStdLogic s -> if List.mem s std_logic_cst then Format.fprintf fmt "%s" s else assert false
|
|
48 |
| CstBV (pref,suff) -> Format.fprintf fmt "%s\"%s\"" pref suff
|
48 |
49 |
|
49 |
50 |
(************************************************************************************)
|
50 |
51 |
(* Declarations *)
|
51 |
52 |
(************************************************************************************)
|
52 |
53 |
|
53 |
54 |
|
54 |
|
(* TODO ? Shall we merge definition / declaration *)
|
|
55 |
(* TODO ? Shall we merge definition / declaration ? Do they appear at the same
|
|
56 |
place or at different ones ? *)
|
55 |
57 |
type vhdl_definition_t =
|
56 |
58 |
| Type of {name : string ; definition: vhdl_type_t}
|
57 |
59 |
| Subtype of {name : string ; definition: vhdl_type_t}
|
... | ... | |
123 |
125 |
let signal_att = [ "event"; "stable"; "last_value" ]
|
124 |
126 |
|
125 |
127 |
type vhdl_string_attributes_t = StringAtt of string
|
126 |
|
let pp_signal_attribute fmt sa = match sa with
|
|
128 |
let pp_string_attribute fmt sa = match sa with
|
127 |
129 |
| StringAtt s -> Format.fprintf fmt "'%s" s
|
128 |
130 |
let signal_att = [ "simple_name"; "path_name"; "instance_name" ]
|
129 |
131 |
|
... | ... | |
132 |
134 |
(************************************************************************************)
|
133 |
135 |
|
134 |
136 |
|
135 |
|
(* TODO: call to functions? procedures? *)
|
|
137 |
(* TODO: call to functions? procedures? component instanciations ? *)
|
|
138 |
|
|
139 |
type suffix_selection_t = Idx of int | Range of int * int
|
|
140 |
let pp_suffix_selection fmt sel =
|
|
141 |
match sel with
|
|
142 |
| Idx n -> Format.fprintf fmt "(%i)" n
|
|
143 |
| Range(n,m) -> Format.fprintf fmt "(%i downto %i)" n m
|
|
144 |
|
136 |
145 |
type vhdl_expr_t =
|
|
146 |
| Cst of cst_val_t
|
137 |
147 |
| Var of string (* a signal or a variable *)
|
|
148 |
| Sig of { name: string; att: vhdl_signal_attributes_t option }
|
|
149 |
| SuffixMod of { expr : vhdl_expr_t; selection : suffix_selection_t }
|
138 |
150 |
| Op of { id: string; args: vhdl_expr_t list }
|
139 |
151 |
|
140 |
152 |
let rec pp_vhdl_expr fmt e =
|
141 |
153 |
match e with
|
|
154 |
| Cst c -> pp_cst_val fmt c
|
142 |
155 |
| Var s -> Format.fprintf fmt "%s" s
|
|
156 |
| Sig s -> Format.fprintf
|
|
157 |
fmt
|
|
158 |
"%s%t"
|
|
159 |
s.name
|
|
160 |
(fun fmt -> match s.att with None -> () | Some att -> pp_signal_attribute fmt att)
|
|
161 |
| SuffixMod s ->
|
|
162 |
Format.fprintf fmt "%a %a"
|
|
163 |
pp_vhdl_expr s.expr
|
|
164 |
pp_suffix_selection s.selection
|
143 |
165 |
| Op op -> (
|
144 |
166 |
match op.args with
|
145 |
167 |
| [] -> assert false
|
146 |
|
| _ -> Format.fprintf fmt "%s (%a)" op.id (Utils.fprintf_list ~sep:",@ " pp_vhdl_expr) op.args
|
|
168 |
| [ e1; e2] -> Format.fprintf fmt "@[<hov 3>%a %s %a@]" pp_vhdl_expr e1 op.id pp_vhdl_expr e2
|
|
169 |
| _ -> assert false (* all ops are binary up to now *)
|
|
170 |
(* | _ -> Format.fprintf fmt "@[<hov 3>%s (%a)@]" op.id (Utils.fprintf_list ~sep:",@ " pp_vhdl_expr) op.args *)
|
147 |
171 |
)
|
148 |
172 |
|
|
173 |
(* Available operators in the standard library. There are some restrictions on
|
|
174 |
types. See reference doc. *)
|
149 |
175 |
let arith_funs = ["+";"-";"*";"/";"mod"; "rem";"abs";"**"]
|
150 |
176 |
let bool_funs = ["and"; "or"; "nand"; "nor"; "xor"; "not"]
|
151 |
177 |
let rel_funs = ["<";">";"<=";">=";"/=";"="]
|
152 |
|
|
153 |
|
|
154 |
178 |
|
|
179 |
|
|
180 |
type vhdl_if_case_t = {
|
|
181 |
if_cond: vhdl_expr_t;
|
|
182 |
if_block: vhdl_sequential_stmt_t list;
|
|
183 |
}
|
|
184 |
and vhdl_sequential_stmt_t =
|
|
185 |
| VarAssign of { lhs: string; rhs: vhdl_expr_t }
|
|
186 |
| SigSeqAssign of { lhs: string; rhs: vhdl_expr_t }
|
|
187 |
| If of { if_cases: vhdl_if_case_t list;
|
|
188 |
default: (vhdl_sequential_stmt_t list) option; }
|
|
189 |
| Case of { guard: vhdl_expr_t; branches: vhdl_case_item_t list }
|
|
190 |
and vhdl_case_item_t = {
|
|
191 |
when_cond: vhdl_expr_t;
|
|
192 |
when_stmt: vhdl_sequential_stmt_t;
|
|
193 |
}
|
155 |
194 |
|
156 |
|
type vhdl_sequential_stmt_t =
|
157 |
|
| VarAssign of { lhs: string; rhs: vhdl_expr_t }
|
158 |
|
(* | Case of { guard: vhdl_expr_t; branches: { case: }
|
159 |
|
| Case of { guard: vhdl_expr_t; branches
|
160 |
|
*)
|
161 |
|
|
162 |
|
let pp_vhdl_sequential_stmt fmt stmt =
|
|
195 |
|
|
196 |
|
|
197 |
let rec pp_vhdl_sequential_stmt fmt stmt =
|
163 |
198 |
match stmt with
|
164 |
199 |
| VarAssign va -> Format.fprintf fmt "%s := %a;" va.lhs pp_vhdl_expr va.rhs
|
165 |
|
|
|
200 |
| SigSeqAssign va -> Format.fprintf fmt "%s <= %a;" va.lhs pp_vhdl_expr va.rhs
|
|
201 |
| If ifva -> (
|
|
202 |
List.iteri (fun idx ifcase ->
|
|
203 |
if idx = 0 then
|
|
204 |
Format.fprintf fmt "@[<v 3>if"
|
|
205 |
else
|
|
206 |
Format.fprintf fmt "@ @[<v 3>elsif";
|
|
207 |
Format.fprintf fmt " %a then@ %a@]"
|
|
208 |
pp_vhdl_expr ifcase.if_cond
|
|
209 |
pp_vhdl_sequential_stmts ifcase.if_block
|
|
210 |
) ifva.if_cases;
|
|
211 |
let _ =
|
|
212 |
match ifva.default with
|
|
213 |
| None -> ()
|
|
214 |
| Some bl -> Format.fprintf fmt "@ @[<v 3>else@ %a@]" pp_vhdl_sequential_stmts bl
|
|
215 |
in
|
|
216 |
Format.fprintf fmt "@ end if;"
|
|
217 |
)
|
|
218 |
| Case caseva -> (
|
|
219 |
Format.fprintf fmt "@[<v 3>case %a is@ %a@]@ end case;"
|
|
220 |
pp_vhdl_expr caseva.guard
|
|
221 |
(Utils.fprintf_list ~sep:"@ " pp_vhdl_case) caseva.branches
|
|
222 |
)
|
|
223 |
|
|
224 |
|
|
225 |
and pp_vhdl_sequential_stmts fmt l = Utils.fprintf_list ~sep:"@ " pp_vhdl_sequential_stmt fmt l
|
|
226 |
and pp_vhdl_case fmt case =
|
|
227 |
Format.fprintf fmt "when %a => %a"
|
|
228 |
pp_vhdl_expr case.when_cond
|
|
229 |
pp_vhdl_sequential_stmt case.when_stmt
|
|
230 |
|
166 |
231 |
type signal_condition_t =
|
167 |
232 |
{
|
168 |
233 |
expr: vhdl_expr_t; (* when expression *)
|
... | ... | |
362 |
427 |
let pp_vhdl_architecture fmt a =
|
363 |
428 |
Format.fprintf
|
364 |
429 |
fmt
|
365 |
|
"@[<v 3>architecture %s of %s is@ %a@]@ @[<v 3>begin@ %a@]@ end %s"
|
|
430 |
"@[<v 3>architecture %s of %s is@ %a@]@ @[<v 3>begin@ %a@]@ end %s;"
|
366 |
431 |
a.name
|
367 |
432 |
a.entity
|
368 |
433 |
(Utils.fprintf_list ~sep:"@ " pp_vhdl_declaration) a.declarations
|
Working example!