OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_trng.vhd] - Blame information for rev 23

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zero_gravi
-- #################################################################################################
2
-- # << NEORV32 - True Random Number Generator (TRNG) >>                                           #
3
-- # ********************************************************************************************* #
4 23 zero_gravi
-- # This unit implements a true random number generator which uses several GARO chain as entropy  #
5
-- # source. The outputs of all chains are XORed and de-biased using a John von Neumann randomness #
6
-- # extractor. The de-biased signal is further processed by a simple LFSR for improved whitening. #
7 2 zero_gravi
-- #                                                                                               #
8
-- # Sources:                                                                                      #
9
-- #  - Von Neumann De-Biasing: "Iterating Von Neumann's Post-Processing under Hardware            #
10
-- #    Constraints" by Vladimir Rozic, Bohan Yang, Wim Dehaene and Ingrid Verbauwhede, 2016       #
11
-- # ********************************************************************************************* #
12
-- # BSD 3-Clause License                                                                          #
13
-- #                                                                                               #
14
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
15
-- #                                                                                               #
16
-- # Redistribution and use in source and binary forms, with or without modification, are          #
17
-- # permitted provided that the following conditions are met:                                     #
18
-- #                                                                                               #
19
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
20
-- #    conditions and the following disclaimer.                                                   #
21
-- #                                                                                               #
22
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
23
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
24
-- #    provided with the distribution.                                                            #
25
-- #                                                                                               #
26
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
27
-- #    endorse or promote products derived from this software without specific prior written      #
28
-- #    permission.                                                                                #
29
-- #                                                                                               #
30
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
31
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
32
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
33
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
34
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
35
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
36
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
37
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
38
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
39
-- # ********************************************************************************************* #
40
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
41
-- #################################################################################################
42
 
43
library ieee;
44
use ieee.std_logic_1164.all;
45
use ieee.numeric_std.all;
46
 
47
library neorv32;
48
use neorv32.neorv32_package.all;
49
 
50
entity neorv32_trng is
51
  port (
52
    -- host access --
53
    clk_i  : in  std_ulogic; -- global clock line
54
    addr_i : in  std_ulogic_vector(31 downto 0); -- address
55
    rden_i : in  std_ulogic; -- read enable
56
    wren_i : in  std_ulogic; -- write enable
57
    data_i : in  std_ulogic_vector(31 downto 0); -- data in
58
    data_o : out std_ulogic_vector(31 downto 0); -- data out
59
    ack_o  : out std_ulogic  -- transfer acknowledge
60
  );
61
end neorv32_trng;
62
 
63
architecture neorv32_trng_rtl of neorv32_trng is
64
 
65
  -- advanced configuration --------------------------------------------------------------------------------
66 23 zero_gravi
  constant num_inv_c   : natural := 15; -- length of GARO inverter chain (default=15, has to be odd)
67
  constant num_garos_c : natural := 2; -- number of GARO elements (default=2)
68
  constant lfsr_taps_c : std_ulogic_vector(7 downto 0) := "10111000"; -- Fibonacci post-processing LFSR feedback taps
69
  constant lfsr_en_c   : boolean := true; -- use LFSR-based post-processing
70
  type tap_mask_t is array (0 to num_garos_c-1) of std_ulogic_vector(num_inv_c-2 downto 0);
71
  constant tap_mask : tap_mask_t := ( -- GARO tap masks, sum of set bits has to be even
72
    "11110000000000",
73
    "00000011000000"
74
  );
75 2 zero_gravi
  -- -------------------------------------------------------------------------------------------------------
76
 
77
  -- control register bits --
78 23 zero_gravi
  constant ctrl_data_lsb_c   : natural :=  0; -- r/-: Random data bit LSB
79
  constant ctrl_data_msb_c   : natural :=  7; -- r/-: Random data bit MSB
80
  constant ctrl_data_valid_c : natural := 15; -- r/-: Output data valid
81
  constant ctrl_err_zero_c   : natural := 16; -- r/-: stuck at 0 error
82
  constant ctrl_err_one_c    : natural := 17; -- r/-: stuck at 1 error
83
  constant ctrl_en_c         : natural := 31; -- r/w: TRNG enable
84 2 zero_gravi
 
85
  -- IO space: module base address --
86
  constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
87
  constant lo_abb_c : natural := index_size_f(trng_size_c); -- low address boundary bit
88
 
89 23 zero_gravi
  -- Component: GARO Element --
90
  component neorv32_trng_garo_element
91
    generic (
92
      NUM_INV : natural := 16 -- number of inverters in chain
93
    );
94
    port (
95
      clk_i    : in  std_ulogic;
96
      enable_i : in  std_ulogic;
97
      enable_o : out std_ulogic;
98
      mask_i   : in  std_ulogic_vector(NUM_INV-2 downto 0);
99
      data_o   : out std_ulogic;
100
      error0_o : out std_ulogic;
101
      error1_o : out std_ulogic
102
    );
103
  end component;
104
 
105 2 zero_gravi
  -- access control --
106
  signal acc_en : std_ulogic; -- module access enable
107
  signal addr   : std_ulogic_vector(31 downto 0); -- access address
108
  signal wren   : std_ulogic; -- full word write enable
109
  signal rden   : std_ulogic; -- read enable
110
 
111 23 zero_gravi
  -- garo array --
112
  signal garo_en_in    : std_ulogic_vector(num_garos_c-1 downto 0);
113
  signal garo_en_out   : std_ulogic_vector(num_garos_c-1 downto 0);
114
  signal garo_data     : std_ulogic_vector(num_garos_c-1 downto 0);
115
  signal garo_err_zero : std_ulogic_vector(num_garos_c-1 downto 0);
116
  signal garo_err_one  : std_ulogic_vector(num_garos_c-1 downto 0);
117
  signal garo_res      : std_ulogic;
118
  signal garo_err0     : std_ulogic;
119
  signal garo_err1     : std_ulogic;
120 2 zero_gravi
 
121 23 zero_gravi
  -- de-biasing --
122
  signal db_data     : std_ulogic_vector(2 downto 0);
123
  signal db_state    : std_ulogic; -- process de-biasing every second cycle
124
  signal rnd_valid   : std_ulogic;
125
  signal rnd_data    : std_ulogic;
126 2 zero_gravi
 
127 23 zero_gravi
  -- processing core --
128
  signal rnd_enable : std_ulogic;
129
  signal rnd_cnt    : std_ulogic_vector(3 downto 0);
130
  signal rnd_sreg   : std_ulogic_vector(7 downto 0);
131
  signal rnd_output : std_ulogic_vector(7 downto 0);
132
  signal rnd_ready  : std_ulogic;
133
 
134
  -- health check --
135
  signal rnd_error_zero : std_ulogic; -- stuck at zero
136
  signal rnd_error_one  : std_ulogic; -- stuck at one
137
 
138 2 zero_gravi
begin
139
 
140
  -- Access Control -------------------------------------------------------------------------
141
  -- -------------------------------------------------------------------------------------------
142
  acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = trng_base_c(hi_abb_c downto lo_abb_c)) else '0';
143
  addr   <= trng_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
144
  wren   <= acc_en and wren_i;
145
  rden   <= acc_en and rden_i;
146
 
147
 
148
  -- Read/Write Access ----------------------------------------------------------------------
149
  -- -------------------------------------------------------------------------------------------
150
  rw_access: process(clk_i)
151
  begin
152
    if rising_edge(clk_i) then
153
      ack_o <= acc_en and (rden_i or wren_i);
154
      -- write access --
155
      if (wren = '1') then
156 23 zero_gravi
        rnd_enable <= data_i(ctrl_en_c);
157 2 zero_gravi
      end if;
158
      -- read access --
159
      data_o <= (others => '0');
160
      if (rden = '1') then
161 23 zero_gravi
        data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= rnd_output;
162
        data_o(ctrl_data_valid_c) <= rnd_ready;
163
        data_o(ctrl_err_zero_c)   <= rnd_error_zero;
164
        data_o(ctrl_err_one_c)    <= rnd_error_one;
165
        data_o(ctrl_en_c)         <= rnd_enable;
166 2 zero_gravi
      end if;
167
    end if;
168
  end process rw_access;
169
 
170
 
171 23 zero_gravi
  -- Entropy Source -------------------------------------------------------------------------
172 2 zero_gravi
  -- -------------------------------------------------------------------------------------------
173 23 zero_gravi
  neorv32_trng_garo_element_inst:
174
  for i in 0 to num_garos_c-1 generate
175
    neorv32_trng_garo_element_inst_i: neorv32_trng_garo_element
176
    generic map (
177
      NUM_INV => num_inv_c -- number of inverters in chain
178
    )
179
    port map (
180
      clk_i    => clk_i,
181
      enable_i => garo_en_in(i),
182
      enable_o => garo_en_out(i),
183
      mask_i   => tap_mask(i),
184
      data_o   => garo_data(i),
185
      error0_o => garo_err_zero(i),
186
      error1_o => garo_err_one(i)
187
    );
188
  end generate;
189
 
190
  -- GARO element connection --
191
  garo_intercon: process(rnd_enable, garo_en_out, garo_data, garo_err_zero, garo_err_one)
192
    variable data_v : std_ulogic;
193
    variable err0_v : std_ulogic;
194
    variable err1_v : std_ulogic;
195 2 zero_gravi
  begin
196 23 zero_gravi
    -- enable chain --
197
    for i in 0 to num_garos_c-1 loop
198
      if (i = 0) then
199
        garo_en_in(i) <= rnd_enable;
200
      else
201
        garo_en_in(i) <= garo_en_out(i-1);
202 2 zero_gravi
      end if;
203
    end loop; -- i
204 23 zero_gravi
    -- data & status --
205
    data_v := garo_data(0);
206
    err0_v := garo_err_zero(0);
207
    err1_v := garo_err_one(0);
208
    for i in 1 to num_garos_c-1 loop
209
      data_v := data_v xor garo_data(i);
210
      err0_v := err0_v or garo_err_zero(i);
211
      err1_v := err1_v or garo_err_one(i);
212
    end loop; -- i
213
    garo_res  <= data_v;
214
    garo_err0 <= err0_v;
215
    garo_err1 <= err1_v;
216
  end process garo_intercon;
217 2 zero_gravi
 
218 23 zero_gravi
 
219
  -- De-Biasing -----------------------------------------------------------------------------
220
  -- -------------------------------------------------------------------------------------------
221
  jvn_debiasing_sync: process(clk_i)
222 2 zero_gravi
  begin
223
    if rising_edge(clk_i) then
224 23 zero_gravi
      db_data  <= db_data(db_data'left-1 downto 0) & garo_res;
225
      db_state <= (not db_state) and rnd_enable; -- just toggle when enabled -> process in every second cycle
226 2 zero_gravi
    end if;
227 23 zero_gravi
  end process jvn_debiasing_sync;
228 2 zero_gravi
 
229
 
230 23 zero_gravi
  -- John von Neumann De-Biasing --
231
  jvn_debiasing: process(db_state, db_data)
232
    variable tmp_v : std_ulogic_vector(2 downto 0);
233
  begin
234
    -- check groups of two non-overlapping bits from the input stream
235
    tmp_v := db_state & db_data(db_data'left downto db_data'left-1);
236
    case tmp_v is
237
      when "101"  => rnd_valid <= '1'; rnd_data <= '1'; -- rising edge -> '1'
238
      when "110"  => rnd_valid <= '1'; rnd_data <= '0'; -- falling edge -> '0'
239
      when others => rnd_valid <= '0'; rnd_data <= '-'; -- invalid
240
    end case;
241
  end process jvn_debiasing;
242
 
243
 
244 2 zero_gravi
  -- Processing Core ------------------------------------------------------------------------
245
  -- -------------------------------------------------------------------------------------------
246
  processing_core: process(clk_i)
247
  begin
248
    if rising_edge(clk_i) then
249 23 zero_gravi
      -- sample random data and apply post-processing --
250 2 zero_gravi
      if (rnd_enable = '0') then
251
        rnd_cnt  <= (others => '0');
252
        rnd_sreg <= (others => '0');
253 23 zero_gravi
      elsif (rnd_valid = '1') and (garo_en_out(garo_en_out'left) = '1') then -- valid random sample and GAROs ready?
254
        if (rnd_cnt = "1000") then
255 2 zero_gravi
          rnd_cnt <= (others => '0');
256
        else
257
          rnd_cnt <= std_ulogic_vector(unsigned(rnd_cnt) + 1);
258
        end if;
259 23 zero_gravi
        if (lfsr_en_c = true) then -- LFSR post-processing
260
          rnd_sreg <= rnd_sreg(rnd_sreg'left-1 downto 0) & (xnor_all_f(rnd_sreg and lfsr_taps_c) xnor rnd_data);
261
        else -- NO post-processing
262
          rnd_sreg <= rnd_sreg(rnd_sreg'left-1 downto 0) & rnd_data;
263
        end if;
264 2 zero_gravi
      end if;
265
 
266
      -- data output register --
267 23 zero_gravi
      if (rnd_cnt = "1000") then
268
        rnd_output <= rnd_sreg;
269 2 zero_gravi
      end if;
270
 
271 23 zero_gravi
      -- health check error --
272
      if (rnd_enable = '0') then
273
        rnd_error_zero <= '0';
274
        rnd_error_one  <= '0';
275
      else
276
        rnd_error_zero <= rnd_error_zero or garo_err0;
277
        rnd_error_one  <= rnd_error_one  or garo_err1;
278
      end if;
279
 
280 2 zero_gravi
      -- data ready flag --
281 23 zero_gravi
      if (rnd_cnt = "1000") then -- new sample ready?
282
        rnd_ready <= '1';
283
      elsif (rnd_enable = '0') or (rden = '1') then -- clear when deactivated or on data read
284
        rnd_ready <= '0';
285 2 zero_gravi
      end if;
286
    end if;
287
  end process processing_core;
288
 
289 23 zero_gravi
 
290
end neorv32_trng_rtl;
291
 
292
 
293
-- ############################################################################################################################
294
-- ############################################################################################################################
295
 
296
 
297
-- #################################################################################################
298
-- # << NEORV32 - True Random Number Generator (TRNG) - GARO Chain-Based Entropy Source >>         #
299
-- # ********************************************************************************************* #
300
-- # An inverter chain (ring oscillator) is used as entropy source. The inverter chain is          #
301
-- # constructed as GARO (Galois Ring Oscillator) TRNG, which is an "asynchronous" LFSR. The       #
302
-- # single inverters are connected via latches that are used to enbale/disable the TRNG. Also,    #
303
-- # these latches are used as additional delay element. By using unique enable signals for each   #
304
-- # latch, the synthesis tool cannot "optimize" (=remove) any of the inverters out of the design. #
305
-- # Furthermore, the latches prevent the synthesis tool from detecting combinatorial loops.       #
306
-- #                                                                                               #
307
-- # Sources:                                                                                      #
308
-- #  - GARO: "Experimental Assessment of FIRO- and GARO-based Noise Sources for Digital TRNG      #
309
-- #    Designs on FPGAs" by Martin Schramm, Reiner Dojen and Michael Heigly, 2017                 #
310
-- #  - Latches for platform independence: "Extended Abstract: The Butterfly PUF Protecting IP     #
311
-- #    on every FPGA" by Sandeep S. Kumar, Jorge Guajardo, Roel Maesyz, Geert-Jan Schrijen and    #
312
-- #    Pim Tuyls, Philips Research Europe, 2008                                                   #
313
-- # ********************************************************************************************* #
314
-- # BSD 3-Clause License                                                                          #
315
-- #                                                                                               #
316
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
317
-- #                                                                                               #
318
-- # Redistribution and use in source and binary forms, with or without modification, are          #
319
-- # permitted provided that the following conditions are met:                                     #
320
-- #                                                                                               #
321
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
322
-- #    conditions and the following disclaimer.                                                   #
323
-- #                                                                                               #
324
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
325
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
326
-- #    provided with the distribution.                                                            #
327
-- #                                                                                               #
328
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
329
-- #    endorse or promote products derived from this software without specific prior written      #
330
-- #    permission.                                                                                #
331
-- #                                                                                               #
332
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
333
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
334
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
335
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
336
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
337
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
338
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
339
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
340
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
341
-- # ********************************************************************************************* #
342
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
343
-- #################################################################################################
344
 
345
library ieee;
346
use ieee.std_logic_1164.all;
347
use ieee.numeric_std.all;
348
 
349
library neorv32;
350
use neorv32.neorv32_package.all;
351
 
352
entity neorv32_trng_garo_element is
353
  generic (
354
    NUM_INV : natural := 15 -- number of inverters in chain
355
  );
356
  port (
357
    clk_i    : in  std_ulogic;
358
    enable_i : in  std_ulogic;
359
    enable_o : out std_ulogic;
360
    mask_i   : in  std_ulogic_vector(NUM_INV-2 downto 0);
361
    data_o   : out std_ulogic;
362
    error0_o : out std_ulogic;
363
    error1_o : out std_ulogic
364
  );
365
end neorv32_trng_garo_element;
366
 
367
architecture neorv32_trng_garo_element_rtl of neorv32_trng_garo_element is
368
 
369
  -- debugging --
370
  constant is_sim_c : boolean := false;
371
 
372
  signal inv_chain   : std_ulogic_vector(NUM_INV-1 downto 0); -- oscillator chain
373
  signal enable_sreg : std_ulogic_vector(NUM_INV-1 downto 0); -- enable shift register
374
  signal sync_ff     : std_ulogic_vector(2 downto 0); -- synchronizer
375
 
376
  signal cnt_zero, cnt_one : std_ulogic_vector(5 downto 0); -- stuck-at-0/1 counters
377
 
378
begin
379
 
380
  -- Sanity Check ---------------------------------------------------------------------------
381
  -- -------------------------------------------------------------------------------------------
382
  assert ((NUM_INV mod 2) /= 0) report "NEORV32 TRNG.GARO_element: NUM_INV has to be odd." severity error;
383
 
384
 
385
  -- Entropy Source -------------------------------------------------------------------------
386
  -- -------------------------------------------------------------------------------------------
387
  garo_chain: process(clk_i, enable_i, enable_sreg, mask_i, inv_chain)
388 2 zero_gravi
  begin
389 23 zero_gravi
    if (is_sim_c = false) then
390
      for i in 0 to NUM_INV-1 loop -- inverters in chain
391
        if (enable_i = '0') then -- start with a defined state (latch reset)
392
          inv_chain(i) <= '0';
393
        -- Using individual enable signals for each inverter - derived from a shift register - to prevent the synthesis tool
394
        -- from removing all but one inverter (since they implement "logical identical functions").
395
        -- This also allows to make the TRNG platform independent.
396
        elsif (enable_sreg(i) = '1') then
397
          -- here we have the inverter chain --
398
          if (i = NUM_INV-1) then -- left-most inverter?
399
            inv_chain(i) <= not inv_chain(0); -- direct input of right most inverter (= output signal)
400
          else
401
            -- if tap switch is ON:  use final output XORed with previous inverter's output
402
            -- if tap switch is OFF: just use previous inverter's output
403
            inv_chain(i) <= not (inv_chain(i+1) xor (inv_chain(0) and mask_i(i)));
404
          end if;
405
        end if;
406
      end loop; -- i
407
    else -- simulate as simple LFSR
408
      if rising_edge(clk_i) then
409
        if (enable_i = '0') then
410
          inv_chain <= (others => '0');
411
        else
412
          inv_chain(NUM_INV-1 downto 0) <= inv_chain(inv_chain'left-1 downto 0) & xnor_all_f(inv_chain(NUM_INV-2 downto 0) and mask_i);
413
        end if;
414
      end if;
415
    end if;
416
  end process garo_chain;
417 2 zero_gravi
 
418
 
419 23 zero_gravi
  -- Control --------------------------------------------------------------------------------
420
  -- -------------------------------------------------------------------------------------------
421
  ctrl_unit: process(clk_i)
422
  begin
423
    if rising_edge(clk_i) then
424
      enable_sreg <= enable_sreg(enable_sreg'left-1 downto 0) & enable_i; -- activate right-most inverter first
425
      sync_ff     <= sync_ff(sync_ff'left-1 downto 0) & inv_chain(0); -- synchronize to prevent metastability 
426
    end if;
427
  end process ctrl_unit;
428 2 zero_gravi
 
429 23 zero_gravi
  -- output for "enable chain" --
430
  enable_o <= enable_sreg(enable_sreg'left);
431
 
432
  -- rnd output --
433
  data_o <= sync_ff(sync_ff'left);
434
 
435
 
436
  -- Health Check ---------------------------------------------------------------------------
437
  -- -------------------------------------------------------------------------------------------
438
  health_check: process(clk_i)
439
  begin
440
    if rising_edge(clk_i) then
441
      if (enable_sreg(enable_sreg'left) = '0') then
442
        cnt_zero <= (others => '0');
443
        cnt_one  <= (others => '0');
444
      else
445
        -- stuck-at-zero --
446
        if (and_all_f(cnt_zero) = '0') then -- max not reached yet
447
          error0_o <= '0';
448
          if (sync_ff(sync_ff'left) = '0') then
449
            cnt_zero <= std_ulogic_vector(unsigned(cnt_zero) + 1);
450
          else
451
            cnt_zero <= (others => '0');
452
          end if;
453
        else
454
          error0_o <= '1';
455
        end if;
456
        -- stuck-at-one --
457
        if (and_all_f(cnt_one) = '0') then -- max not reached yet
458
          error1_o <= '0';
459
          if (sync_ff(sync_ff'left) = '1') then
460
            cnt_one <= std_ulogic_vector(unsigned(cnt_one) + 1);
461
          else
462
            cnt_one <= (others => '0');
463
          end if;
464
        else
465
          error1_o <= '1';
466
        end if;
467
      end if;
468
    end if;
469
  end process health_check;
470
 
471
 
472
end neorv32_trng_garo_element_rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.