package hardcaml_waveterm

  1. Overview
  2. Docs

Source file sim.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
open Base
open Hardcaml

let wrap ?cfg sim =
  let cycle = ref 0 in
  let compare =
    match cfg with
    | None -> String.compare
    | Some s ->
      let f =
        let s = List.mapi ~f:(fun i (n, _) -> n, i) s in
        fun x -> List.Assoc.find s x ~equal:String.equal
      in
      fun a b ->
        (match f a, f b with
         | None, None -> String.compare a b
         | Some _, None -> -1
         | None, Some _ -> 1
         | Some a, Some b -> Int.compare a b)
  in
  let get_type = function
    | None -> fun _ -> Wave_format.Binary
    | Some l ->
      fun n ->
        (try List.Assoc.find_exn l n ~equal:String.equal with
         | _ -> Wave_format.Binary)
  in
  let port (n, v) =
    match n with
    | "clock" | "clk" -> Wave.Clock n, fun _ -> ()
    | "reset" | "rst" ->
      let d = Data.create 1 in
      Wave.Binary (n, d), fun v -> Data.set d !cycle (if v then Bits.vdd else Bits.gnd)
    | _ ->
      let t = get_type cfg n in
      let width = Bits.width !v in
      let d = Data.create width in
      let wave =
        if width = 1 && Poly.equal t Binary
        then Wave.Binary (n, d)
        else Wave.Data (n, d, t, Left)
      in
      wave, fun _ -> Data.set d !cycle !v
  in
  let ports =
    List.concat
      [ List.map (Cyclesim.in_ports sim) ~f:port
      ; List.map (Cyclesim.out_ports ~clock_edge:Before sim) ~f:port
      ; List.map (Cyclesim.internal_ports sim) ~f:port
      ]
  in
  let ports =
    List.sort
      ~compare:(fun (w0, _) (w1, _) -> compare (Wave.get_name w0) (Wave.get_name w1))
      ports
  in
  let waves = Array.of_list (List.map ~f:fst ports) in
  let updates = Array.of_list (List.map ~f:snd ports) in
  let tasks rst () =
    Array.iter ~f:(fun f -> f rst) updates;
    Int.incr cycle
  in
  let sim =
    Cyclesim.Private.modify
      sim
      [ After, Reset, tasks true; After, At_clock_edge, tasks false ]
  in
  sim, waves
;;
OCaml

Innovation. Community. Security.