1 //
2 // Copyright (c) 2010-2021 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 Antmicro.Renode.Core;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Logging;
11 using Antmicro.Renode.Peripherals;
12 using Antmicro.Renode.Peripherals.Timers;
13 using Antmicro.Renode.Time;
14 
15 namespace Antmicro.Renode.Peripherals.Miscellaneous
16 {
17     public class DWT: BasicDoubleWordPeripheral, IKnownSize
18     {
DWT(IMachine machine, uint frequency)19         public DWT(IMachine machine, uint frequency): base(machine)
20         {
21             CreateRegisters();
22             cycleCounter = new LimitTimer(machine.ClockSource, frequency, this, "CycleCounter", direction: Direction.Ascending);
23         }
24 
Reset()25         public override void Reset()
26         {
27             base.Reset();
28             cycleCounter.Reset();
29         }
30 
CreateRegisters()31         private void CreateRegisters()
32         {
33             Registers.Control.Define(this)
34                 .WithFlag(0, writeCallback: (_, val) =>
35                     {
36                         cycleCounter.Enabled = val;
37                         this.Log(LogLevel.Debug, "{0}", val ? "Enabled" : "Disabled");
38                     }, valueProviderCallback: _ => cycleCounter.Enabled, name: "CYCCNTENA")
39                 .WithTag("POSTPRESET", 1, 4)
40                 .WithTag("POSTCNT", 5, 4)
41                 .WithTag("CYCTAP", 9, 1)
42                 .WithTag("SYNCTAP", 10, 2)
43                 .WithTag("PCSAMPLEENA", 12, 1)
44                 .WithReservedBits(13, 3)
45                 .WithTag("EXCTRCENA", 16, 1)
46                 .WithTag("CPIEVTENA", 17, 1)
47                 .WithTag("EXCEVTENA", 18, 1)
48                 .WithTag("SLEEPEVTENA", 19, 1)
49                 .WithTag("LSUEVTENA", 20, 1)
50                 .WithTag("FOLDEVTENA", 21, 1)
51                 .WithTag("CYCEVTEN", 22, 1)
52                 .WithReservedBits(23, 5)
53                 .WithTag("NUMCOMP", 28, 4);
54             Registers.CycleCounter.Define(this)
55                 .WithValueField(0, 32, writeCallback: (_, val) => { cycleCounter.Value = val; },
56                     valueProviderCallback: _ => (uint)cycleCounter.Value, name: "CYCCNT");
57             Registers.Count.Define(this)
58                 .WithTag("CPICNT", 0, 8)
59                 .WithReservedBits(8, 24);
60             Registers.ExceptionOverheadCounter.Define(this)
61                 .WithTag("EXCCNT", 0, 8)
62                 .WithReservedBits(8, 24);
63             Registers.SleepCounter.Define(this)
64                 .WithTag("SLEEPCNT", 0, 8)
65                 .WithReservedBits(8, 24);
66             Registers.LoadStoreUnitCounter.Define(this)
67                 .WithTag("LSUCNT", 0, 8)
68                 .WithReservedBits(8, 24);
69             Registers.FoldCounter.Define(this)
70                 .WithTag("FOLDCNT", 0, 8)
71                 .WithReservedBits(8, 24);
72             Registers.ProgramCounterSample.Define(this)
73                 .WithTag("EIASAMPLE", 0, 32);
74             Registers.Comparator0.Define(this)
75                 .WithTag("COMP", 0, 32);
76             Registers.Mask0.Define(this)
77                 .WithTag("MASK", 0, 4)
78                 .WithReservedBits(4, 28);
79             Registers.Function0.Define(this)
80                 .WithTaggedFlag("FUNCTION", 0)
81                 .WithReservedBits(4, 1)
82                 .WithTaggedFlag("EMITRANGE", 5)
83                 .WithReservedBits(6, 1)
84                 .WithTaggedFlag("CYCMATCH", 7)
85                 .WithTaggedFlag("DATAVMATCH", 8)
86                 .WithTaggedFlag("LNK1ENA", 9)
87                 .WithTag("DATAVSIZE", 10, 2)
88                 .WithTag("DATAVADDR0", 12, 4)
89                 .WithTag("DATAVADDR1", 16, 4)
90                 .WithReservedBits(20, 4)
91                 .WithTaggedFlag("MATCHED", 24)
92                 .WithReservedBits(25, 7);
93             Registers.Comparator1.Define(this)
94                 .WithTag("COMP", 0, 32);
95             Registers.Mask1.Define(this)
96                 .WithTag("MASK", 0, 4)
97                 .WithReservedBits(4, 28);
98             Registers.Function1.Define(this)
99                 .WithTaggedFlag("FUNCTION", 0)
100                 .WithReservedBits(4, 1)
101                 .WithTaggedFlag("EMITRANGE", 5)
102                 .WithReservedBits(6, 1)
103                 .WithTaggedFlag("CYCMATCH", 7)
104                 .WithTaggedFlag("DATAVMATCH", 8)
105                 .WithTaggedFlag("LNK1ENA", 9)
106                 .WithTag("DATAVSIZE", 10, 2)
107                 .WithTag("DATAVADDR0", 12, 4)
108                 .WithTag("DATAVADDR1", 16, 4)
109                 .WithReservedBits(20, 4)
110                 .WithTaggedFlag("MATCHED", 24)
111                 .WithReservedBits(25, 7);
112             Registers.Comparator2.Define(this)
113                 .WithTag("COMP", 0, 32);
114             Registers.Mask2.Define(this)
115                 .WithTag("MASK", 0, 4)
116                 .WithReservedBits(4, 28);
117             Registers.Function2.Define(this)
118                 .WithTaggedFlag("FUNCTION", 0)
119                 .WithReservedBits(4, 1)
120                 .WithTaggedFlag("EMITRANGE", 5)
121                 .WithReservedBits(6, 1)
122                 .WithTaggedFlag("CYCMATCH", 7)
123                 .WithTaggedFlag("DATAVMATCH", 8)
124                 .WithTaggedFlag("LNK1ENA", 9)
125                 .WithTag("DATAVSIZE", 10, 2)
126                 .WithTag("DATAVADDR0", 12, 4)
127                 .WithTag("DATAVADDR1", 16, 4)
128                 .WithReservedBits(20, 4)
129                 .WithTaggedFlag("MATCHED", 24)
130                 .WithReservedBits(25, 7);
131             Registers.Comparator3.Define(this)
132                 .WithTag("COMP", 0, 32);
133             Registers.Mask3.Define(this)
134                 .WithTag("MASK", 0, 4)
135                 .WithReservedBits(4, 28);
136             Registers.Function3.Define(this)
137                 .WithTaggedFlag("FUNCTION", 0)
138                 .WithReservedBits(4, 1)
139                 .WithTaggedFlag("EMITRANGE", 5)
140                 .WithReservedBits(6, 1)
141                 .WithTaggedFlag("CYCMATCH", 7)
142                 .WithTaggedFlag("DATAVMATCH", 8)
143                 .WithTaggedFlag("LNK1ENA", 9)
144                 .WithTag("DATAVSIZE", 10, 2)
145                 .WithTag("DATAVADDR0", 12, 4)
146                 .WithTag("DATAVADDR1", 16, 4)
147                 .WithReservedBits(20, 4)
148                 .WithTaggedFlag("MATCHED", 24)
149                 .WithReservedBits(25, 7);
150             Registers.PeripheralID4.Define(this, 0x04)
151                 .WithTag("PID", 0, 32);
152             Registers.PeripheralID5.Define(this, 0x00)
153                 .WithTag("PID", 0, 32);
154             Registers.PeripheralID6.Define(this, 0x00)
155                 .WithTag("PID", 0, 32);
156             Registers.PeripheralID7.Define(this, 0x00)
157                 .WithTag("PID", 0, 32);
158             Registers.PeripheralID0.Define(this, 0x02)
159                 .WithTag("PID", 0, 32);
160             Registers.PeripheralID1.Define(this, 0xB0)
161                 .WithTag("PID", 0, 32);
162             Registers.PeripheralID2.Define(this, 0x1B)
163                 .WithTag("PID", 0, 32);
164             Registers.PeripheralID3.Define(this, 0x00)
165                 .WithTag("PID", 0, 32);
166             Registers.ComponentID0.Define(this, 0x0D)
167                 .WithTag("CID", 0, 32);
168             Registers.ComponentID1.Define(this, 0xE0)
169                 .WithTag("CID", 0, 32);
170             Registers.ComponentID2.Define(this, 0x05)
171                 .WithTag("CID", 0, 32);
172             Registers.ComponentID3.Define(this, 0xB1)
173                 .WithTag("CID", 0, 32);
174         }
175 
176         public long Size => 0x1000;
177 
178         private readonly LimitTimer cycleCounter;
179 
180         private enum Registers
181         {
182             Control                  = 0x000, // Control Register
183             CycleCounter             = 0x004, // Cycle Count Register
184             Count                    = 0x008, // Count Register
185             ExceptionOverheadCounter = 0x00C, // Exception OverheadCount Register
186             SleepCounter             = 0x010, // Sleep Counter Register
187             LoadStoreUnitCounter     = 0x014, // Load-Store-UnitCounter Register
188             FoldCounter              = 0x018, // Fold Counter Register
189             ProgramCounterSample     = 0x01C, // Program CounterSample Register
190             Comparator0              = 0x020, // ComparatorRegister #0
191             Mask0                    = 0x024, // Mask Register #0
192             Function0                = 0x028, // Function Register#0
193             Comparator1              = 0x030, // ComparatorRegister #1
194             Mask1                    = 0x034, // Mask Register #1
195             Function1                = 0x038, // Function Register#1
196             Comparator2              = 0x040, // ComparatorRegister #2
197             Mask2                    = 0x044, // Mask Register #2
198             Function2                = 0x048, // Function Register#2
199             Comparator3              = 0x050, // ComparatorRegister #3
200             Mask3                    = 0x054, // Mask Register #3
201             Function3                = 0x058, // Function Register#3
202             PeripheralID4            = 0xFD0, // Peripheral ID4
203             PeripheralID5            = 0xFD4, // Peripheral ID5
204             PeripheralID6            = 0xFD8, // Peripheral ID6
205             PeripheralID7            = 0xFDC, // Peripheral ID7
206             PeripheralID0            = 0xFE0, // Peripheral ID0
207             PeripheralID1            = 0xFE4, // Peripheral ID1
208             PeripheralID2            = 0xFE8, // Peripheral ID2
209             PeripheralID3            = 0xFEC, // Peripheral ID3
210             ComponentID0             = 0xFF0, // Component ID0
211             ComponentID1             = 0xFF4, // Component ID1
212             ComponentID2             = 0xFF8, // Component ID2
213             ComponentID3             = 0xFFC, // Component ID3
214         }
215     }
216 }
217 
218