Project

General

Profile

Download (4.44 KB) Statistics
| Branch: | Tag: | Revision:
1
open Vhdl_ast
2
open Mini_vhdl_ast
3
open Vhdl_2_mini_vhdl_map
4
open Mini_vhdl_utils
5

    
6
(*
7
type db_tuple_t =
8
  {
9
    mutable entity: vhdl_entity_t;
10
    mutable architecture: vhdl_architecture_t;
11
    mutable architecture_signals: mini_vhdl_declaration_t list;
12
    mutable architecture_ports: vhdl_port_t list;
13
    mutable architecture_generics: vhdl_port_t list;
14
    mutable assigned_signals_names: vhdl_name_t list;
15
    mutable contexts: vhdl_load_t list;
16
  }
17
*)
18

    
19
type level = INFO | WARNING | ERROR
20

    
21
let print ?(level = INFO) ?(code = "") s =
22
  match s with
23
  | "" -> ()
24
  | _ -> match level with
25
    | INFO -> Printf.printf    "<INFO> %s" s
26
    | WARNING -> Printf.printf "<WARNING =%s=> %s" code s
27
    | ERROR -> Printf.printf   "<ERROR =%s=> %s" code s
28

    
29
let filter_display s l to_string_name = match l with
30
  | [] -> ""
31
  | _ -> Printf.sprintf "%s [%s]\n" s (String.concat ", " (List.map to_string_name l))
32

    
33
(**
34
 * Display
35
 *)
36
let display_struct_content : (vhdl_name_t -> string) -> db_tuple_t -> unit =
37
  fun to_string_name ->
38
    fun {entity; architecture; architecture_signals; architecture_ports; architecture_generics; assigned_signals_names; contexts} ->
39
      let arch_name = to_string_name architecture.name in
40
      let ent_name = to_string_name entity.name in
41
      let sigs_names = List.flatten (List.map mini_vhdl_declaration_t_names architecture_signals) in
42
      let in_ports_names = List.flatten (List.map get_names (get_ports architecture_ports InPort)) in
43
      let out_ports_names = List.flatten (List.map get_names (get_ports architecture_ports OutPort)) in
44
      let inout_ports_names = List.flatten (List.map get_names (get_ports architecture_ports InoutPort)) in
45
      let generics_names = List.flatten (List.map get_names architecture_generics) in
46
      print (Printf.sprintf "Details for architecture [%s] of entity [%s]\n" arch_name ent_name);
47
      print (filter_display "  Inner signals" sigs_names to_string_name);
48
      print (filter_display "  In ports" in_ports_names to_string_name);
49
      print (filter_display "  InOut ports" inout_ports_names to_string_name);
50
      print (filter_display "  Out ports" out_ports_names to_string_name);
51
      print (filter_display "  Generics" generics_names to_string_name);
52
      print (filter_display "  Assigned names" (List.sort_uniq compare assigned_signals_names) to_string_name)
53

    
54
(**
55
 * Checks
56
 * All checks should have the same signature:
57
 *  (vhdl_name_t -> string) -> string -> level -> db_tuple_t -> unit
58
 *)
59
let check_error_duplicate_signal_assignment : (vhdl_name_t -> string) -> string -> level -> db_tuple_t -> unit=
60
  fun to_string_name -> fun code -> fun level ->
61
      fun {entity; architecture; architecture_signals; architecture_ports; architecture_generics; assigned_signals_names; contexts} ->
62
        let dupl = duplicates assigned_signals_names in
63
        if List.length dupl > 0
64
          then print ~level:level ~code:code (Printf.sprintf " Duplicate concurrent assignment of %s" (filter_display "signal" dupl to_string_name))
65
          else ()
66

    
67
let check_missing_signal_assignment : (vhdl_name_t -> string) -> string -> level -> db_tuple_t -> unit=
68
  fun to_string_name -> fun code -> fun level ->
69
      fun {entity; architecture; architecture_signals; architecture_ports; architecture_generics; assigned_signals_names; contexts} ->
70
        let out_ports_names = List.flatten (List.map get_names (get_ports architecture_ports OutPort)) in
71
        let inout_ports_names = List.flatten (List.map get_names (get_ports architecture_ports InoutPort)) in
72
        let sigs_names = List.flatten (List.map mini_vhdl_declaration_t_names architecture_signals) in
73
        let declared_signals = inout_ports_names@sigs_names@out_ports_names in
74
        let uniq_assigned_signals = List.sort_uniq compare assigned_signals_names in
75
        let missing = diff declared_signals uniq_assigned_signals to_string_name in
76
        if List.length missing > 0
77
          then print ~level:level ~code:code (Printf.sprintf " Missing assignment of %s" (filter_display "signal" missing to_string_name))
78
          else ()
79

    
80
let checks = [("#E001",ERROR,check_error_duplicate_signal_assignment); ("#W001",WARNING,check_missing_signal_assignment)] 
81

    
82
(**
83
 * Main
84
 *)
85
let check_mini_vhdl db to_string_name =
86
  let rec iter_checks checks x = match checks with
87
    | [] -> ()
88
    | (code,level,check)::tl -> check to_string_name code level x; iter_checks tl x in
89
  let disp_and_check x =
90
    display_struct_content to_string_name x;
91
    iter_checks checks x in
92
  List.iter disp_and_check db;
(2-2/3)