1 //
2 // Copyright (c) 2010-2019 Antmicro
3 //
4 //  This file is licensed under the MIT License.
5 //  Full license text is available in 'licenses/MIT.txt'.
6 //
7 using Antmicro.Renode.Core;
8 using Antmicro.Renode.Peripherals.Bus;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Time;
11 using System;
12 using static Antmicro.Renode.Utilities.BitHelper;
13 using Antmicro.Renode.Utilities;
14 using System.Collections.Generic;
15 using Antmicro.Renode.Logging;
16 
17 namespace Antmicro.Renode.Peripherals.Miscellaneous
18 {
19     public class STM32F4_RNG : IDoubleWordPeripheral, IKnownSize
20     {
STM32F4_RNG(IMachine machine)21         public STM32F4_RNG(IMachine machine)
22         {
23             IRQ = new GPIO();
24 
25             var registerMap = new Dictionary<long, DoubleWordRegister>
26             {
27                 {(long)Registers.Control, new DoubleWordRegister(this)
28                     .WithReservedBits(0, 2)
29                     .WithFlag(2, out enable, changeCallback: (_, value) => Update(), name: "RNGEN")
30                     .WithFlag(3, out interruptEnable, changeCallback: (_, value) => Update(), name: "IE")
31                     .WithReservedBits(4, 28)
32                 },
33                 {(long)Registers.Status, new DoubleWordRegister(this)
34                     .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => enable.Value, name: "DRDY")
35                     .WithTag("CECS", 1, 1)
36                     .WithTag("SECS", 2, 1)
37                     .WithReservedBits(3, 2)
38                     .WithTag("CEIS", 5, 1)
39                     .WithTag("SEIS", 6, 1)
40                     .WithReservedBits(7, 25)
41                 },
42                 {(long)Registers.Data, new DoubleWordRegister(this)
43                     .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ =>
44                 {
45                     if(enable.Value)
46                     {
47                         return unchecked((uint)rng.Next());
48                     }
49                     else
50                     {
51                         return 0;
52                     }
53                 }, name: "RNDATA")
54                 },
55             };
56             registers = new DoubleWordRegisterCollection(this, registerMap);
57         }
58 
Reset()59         public void Reset()
60         {
61             registers.Reset();
62         }
63 
ReadDoubleWord(long offset)64         public uint ReadDoubleWord(long offset)
65         {
66             return registers.Read(offset);
67         }
68 
WriteDoubleWord(long offset, uint value)69         public void WriteDoubleWord(long offset, uint value)
70         {
71             registers.Write(offset, value);
72         }
73 
Update()74         private void Update()
75         {
76             IRQ.Set(enable.Value && interruptEnable.Value);
77         }
78 
79         public long Size => 0x400;
80         public GPIO IRQ { get; private set; }
81 
82         private DoubleWordRegisterCollection registers;
83         private PseudorandomNumberGenerator rng = EmulationManager.Instance.CurrentEmulation.RandomGenerator;
84         private IFlagRegisterField enable;
85         private IFlagRegisterField interruptEnable;
86 
87         private enum Registers
88         {
89             Control = 0x0,
90             Status = 0x4,
91             Data = 0x8,
92         }
93     }
94 }
95