1 //
2 // Copyright (c) 2010-2020 Antmicro
3 //
4 //  This file is licensed under the MIT License.
5 //  Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using System.Collections.Generic;
9 using Antmicro.Renode.Core;
10 using Antmicro.Renode.Core.Structure.Registers;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.Peripherals.Bus;
13 
14 namespace Antmicro.Renode.Peripherals.Miscellaneous
15 {
16     public class K6xF_RNG : IDoubleWordPeripheral, IKnownSize
17     {
K6xF_RNG(IMachine machine)18         public K6xF_RNG(IMachine machine)
19         {
20             IRQ = new GPIO();
21 
22             var registerMap = new Dictionary<long, DoubleWordRegister>
23             {
24                 {(long)Registers.Control, new DoubleWordRegister(this)
25                     .WithReservedBits(5, 26)
26                     .WithFlag(4, out sleep, name: "SLP")
27                     .WithTaggedFlag("CLRI", 3)
28                     .WithTaggedFlag("INTM", 2)
29                     .WithTaggedFlag("HA", 1)
30                     .WithFlag(0, out enable, name: "GO")
31                 },
32                 {(long)Registers.Status, new DoubleWordRegister(this)
33                     .WithReservedBits(24, 8)
34                     .WithValueField(16, 8, name: "OREG_SIZE")
35                     .WithValueField(8, 8, FieldMode.Read, valueProviderCallback: _ => (enable.Value) ? 1u : 0u, name: "OREG_LVL")
36                     .WithReservedBits(5, 3)
37                     .WithTaggedFlag("SLP", 4)
38                     .WithTaggedFlag("ERRI", 3)
39                     .WithTaggedFlag("ORU", 2)
40                     .WithTaggedFlag("LRS", 1)
41                     .WithTaggedFlag("SECV", 0)
42                 },
43                 {(long)Registers.Entropy, new DoubleWordRegister(this)
44                     .WithValueField(0, 32, name:"EXT_ENT")
45                 },
46                 {(long)Registers.Output, new DoubleWordRegister(this)
47                     .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ => (enable.Value) ? unchecked((uint)rng.Next()) : 0u, name: "RNDOUT")
48                 }
49             };
50 
51             registers = new DoubleWordRegisterCollection(this, registerMap);
52 
53             rng = EmulationManager.Instance.CurrentEmulation.RandomGenerator;
54         }
55 
ReadDoubleWord(long offset)56         public uint ReadDoubleWord(long offset)
57         {
58             return registers.Read(offset);
59         }
60 
Reset()61         public void Reset()
62         {
63             registers.Reset();
64         }
65 
WriteDoubleWord(long offset, uint value)66         public void WriteDoubleWord(long offset, uint value)
67         {
68             registers.Write(offset, value);
69         }
70 
71         public long Size => 0x1000;
72 
73         public GPIO IRQ { get; private set; }
74 
75         private readonly DoubleWordRegisterCollection registers;
76         private readonly PseudorandomNumberGenerator rng;
77         private readonly IFlagRegisterField enable;
78         private readonly IFlagRegisterField sleep;
79 
80         private enum Registers
81         {
82             Control = 0x0,
83             Status  = 0x4,
84             Entropy = 0x8,
85             Output  = 0xC
86         }
87     }
88 }
89