package hardcaml_xilinx

  1. Overview
  2. Docs
Hardcaml wrappers for Xilinx memory primitives

Install

dune-project
 Dependency

Authors

Maintainers

Sources

v0.17.0.tar.gz
sha256=01df85cf275569447f3c8f1ad03bbae5f8751afbb886833be875aedda9ae3288

doc/src/hardcaml_xilinx/xpm_fifo_sync.ml.html

Source file xpm_fifo_sync.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
open Base
open Hardcaml
open Signal

module Xpm_2019_1 = struct
  let create
    ?(overflow_check = true)
    ?(showahead = false)
    ?(underflow_check = true)
    ?fifo_memory_type:arg_fifo_memory_type
    ?nearly_full
    ?(nearly_empty = 16)
    ?instance
    ?read_latency
    ()
    ~capacity
    ~clk
    ~clr
    ~wr
    ~d
    ~rd
    =
    (* Where is REMOVE_WR_RD_PROT_LOGIC? Its in the docs, but not on the component. *)
    ignore (overflow_check, underflow_check);
    let module XFifo =
      Xpm_2019_1.Xpm_fifo_sync.Make (struct
        include Xpm_2019_1.Xpm_fifo_sync.P

        let fifo_memory_type =
          Option.map ~f:Fifo_memory_type.to_xpm_args arg_fifo_memory_type
          |> Option.value ~default:fifo_memory_type
        ;;

        let read_mode = if showahead then "fwft" else "std"

        let fifo_read_latency =
          Option.value read_latency ~default:(if showahead then 0 else 1)
        ;;

        let write_data_width = width d
        let read_data_width = width d
        let fifo_write_depth = capacity
        let wr_data_count_width = num_bits_to_represent capacity
        let rd_data_count_width = num_bits_to_represent capacity
        let prog_full_thresh = Option.value nearly_full ~default:(capacity - 16)
        let prog_empty_thresh = nearly_empty

        (* There are limitations on the range for [prog_*_thresh], see docs for details.
           The checks are slightly simplified because write_data_width = read_data_width
           for our configuration. *)
        let () =
          let read_mode_val = if String.equal read_mode "std" then 0 else 1 in
          let min_thresh = 3 + (read_mode_val * 2) in
          let max_thresh = fifo_write_depth - 3 - (read_mode_val * 2) in
          let check_prog_thresh thresh =
            if thresh < min_thresh
            then raise_s [%message "threshold too low!" (thresh : int) (min_thresh : int)];
            if thresh > max_thresh
            then
              raise_s [%message "threshold too high!" (thresh : int) (max_thresh : int)]
          in
          check_prog_thresh prog_full_thresh;
          check_prog_thresh prog_empty_thresh
        ;;
      end)
    in
    let o : _ XFifo.O.t =
      XFifo.create
        ?instance
        { XFifo.I.wr_clk = clk
        ; rst = clr
        ; wr_en = wr
        ; rd_en = rd
        ; din = d
        ; sleep = gnd
        ; injectsbiterr = gnd
        ; injectdbiterr = gnd
        }
    in
    { Fifo.q = o.dout
    ; full = o.full
    ; empty = o.empty
    ; nearly_full = o.prog_full
    ; nearly_empty = o.prog_empty
    ; used = o.wr_data_count
    ; rd_rst_busy = o.rd_rst_busy
    ; wr_rst_busy = o.wr_rst_busy
    }
  ;;
end

module Xpm_2022_1 = struct
  let create
    ?(overflow_check = true)
    ?(showahead = false)
    ?(underflow_check = true)
    ?fifo_memory_type:arg_fifo_memory_type
    ?nearly_full
    ?(nearly_empty = 16)
    ?instance
    ?cascade_height:arg_cascade_height
    ?read_latency
    ()
    ~capacity
    ~clk
    ~clr
    ~wr
    ~d
    ~rd
    =
    ignore (overflow_check, underflow_check);
    let module XFifo =
      Xpm_2022_1.Xpm_fifo_sync.Make (struct
        include Xpm_2022_1.Xpm_fifo_sync.P

        let fifo_memory_type =
          Option.map ~f:Fifo_memory_type.to_xpm_args arg_fifo_memory_type
          |> Option.value ~default:fifo_memory_type
        ;;

        let read_mode = if showahead then "fwft" else "std"

        let fifo_read_latency =
          Option.value read_latency ~default:(if showahead then 0 else 1)
        ;;

        let write_data_width = width d
        let read_data_width = width d
        let fifo_write_depth = capacity
        let wr_data_count_width = num_bits_to_represent capacity
        let rd_data_count_width = num_bits_to_represent capacity
        let prog_full_thresh = Option.value nearly_full ~default:(capacity - 16)
        let prog_empty_thresh = nearly_empty
        let cascade_height = Option.value arg_cascade_height ~default:cascade_height

        (* There are limitations on the range for [prog_*_thresh], see docs for details.
           The checks are slightly simplified because write_data_width = read_data_width
           for our configuration. *)
        let () =
          let read_mode_val = if String.equal read_mode "std" then 0 else 1 in
          let check_prog_thresh thresh =
            assert (thresh >= 3 + (read_mode_val * 2));
            assert (thresh <= fifo_write_depth - 3 - (read_mode_val * 2))
          in
          check_prog_thresh prog_full_thresh;
          check_prog_thresh prog_empty_thresh
        ;;
      end)
    in
    let o : _ XFifo.O.t =
      XFifo.create
        ?instance
        { XFifo.I.wr_clk = clk
        ; rst = clr
        ; wr_en = wr
        ; rd_en = rd
        ; din = d
        ; sleep = gnd
        ; injectsbiterr = gnd
        ; injectdbiterr = gnd
        }
    in
    { Fifo.q = o.dout
    ; full = o.full
    ; empty = o.empty
    ; nearly_full = o.prog_full
    ; nearly_empty = o.prog_empty
    ; used = o.wr_data_count
    ; rd_rst_busy = o.rd_rst_busy
    ; wr_rst_busy = o.wr_rst_busy
    }
  ;;
end