simulavr  1.1.0
traceval.h
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
5  * Copyright (C) 2009 Onno Kortmann
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  ****************************************************************************
22  *
23  * $Id$
24  */
25 #ifndef traceval_h
26 #define traceval_h
27 
28 #include <stdint.h>
29 #include <iostream>
30 #include <sstream>
31 #include <map>
32 #include <vector>
33 
34 /* TODO, notes:
35 
36  ===========================================================
37  Goals for tracing functionality for values in the simulator
38  ===========================================================
39 
40  - being dumped into a file every time they changed (classical hardware
41  register change use)
42 
43  - being dumped into a file every time they have been write-accessed
44  (register with 'write-will-cause-something' functionality
45 
46  - enable statistics counters for accesses (such as EEPROM)
47 
48  - for eeproms, it should also be possible in particular to have an easy
49  tracing for whole blocks of memory
50 
51  - statistics on the number of accesses on the FLASH can then be used for
52  profiling and on the RAM for stack size checking etc.
53 
54  ... this leads to ...
55  ============================
56  List of tracers to implement
57  ============================
58  - VCD dumping on changing a value. VCD dumping of the writes AND the READS
59  itself as some kind of visible strobes may also be of interest!
60 
61  - Human-readable dumping of a simulavrxx trace, with register changes in a
62  column next to the current opcode line etc. (much like the current tracing,
63  but much cleaner in the code). Human-readable dumping should also say
64  whether there has been a read-access or a write-access and whether the
65  value changed during write!
66 
67  Also the interface should be able to warn when there is a read-access
68  before a write access (e.g. read access of SRAM in unknown state).
69 
70  =====================
71  Ideas for further use
72  =====================
73 
74  - memory array access profiling
75 
76  - 'wear map' for eeproms
77 
78  - For RAM, map with addresses that have been written at all
79 
80  - For flash, give out a map of read access counters (write-acesses later on
81  for boot loaders??) for each flash address. A separate tool could then be
82  used to merge the output of avr-objdump -S and this to produce nice
83  per-line profiling statistics. */
84 
85 class Dumper;
86 
102 class TraceValue {
103 
104  public:
106  TraceValue(size_t bits,
107  const std::string &_name,
108  const int __index = -1,
109  const void* shadow = NULL);
110  virtual ~TraceValue() { shadow = NULL; }
111 
113  size_t bits() const;
114 
116 
119  unsigned value() const;
120 
122  std::string name() const;
123 
125  std::string barename() const;
126 
128  int index() const;
129 
131  enum Atype {
132  READ=1, // true if a READ access has been logged
133  WRITE=2,
135  };
136 
139  bool enabled() const;
140 
142  void enable();
143 
144 
146  void change(unsigned val);
147  void change(unsigned val, unsigned mask);
149  void write(unsigned val);
151  void read();
152 
153 
156  bool written() const;
157 
160  void set_written();
161 
167  void set_written(unsigned val);
168 
170  Atype flags() const;
171 
173 
175  virtual void cycle();
176 
179  virtual void dump(Dumper &d);
180 
182  virtual char VcdBit(int bitNo) const;
183 
184  protected:
186  void clear_flags();
187  friend class TraceKeeper;
188 
189  private:
190  std::string _name;
191 
192  int _index;
193 
195  const unsigned b;
196 
198  const void *shadow;
199 
201  unsigned v;
203  int f;
206  bool _written;
207 
209 
211  bool _enabled;
212 };
213 
215 
216  public:
218  TraceValueOutput(const std::string &_name): TraceValue(1, _name) {}
219 
221  virtual char VcdBit(int bitNo) const;
222 
223 };
224 
225 class AvrDevice;
227 
228 typedef std::vector<TraceValue*> TraceSet;
229 
231 class Dumper {
232 
233  public:
236  virtual void setActiveSignals(const TraceSet &act) {}
237 
239  virtual void start() {}
241  virtual void stop() {}
242 
244  virtual void cycle() {}
245 
248  virtual void markRead(const TraceValue *t) {}
250  virtual void markReadUnknown(const TraceValue *t) {}
251 
254  virtual void markWrite(const TraceValue *t) {}
258  virtual void markChange(const TraceValue *t) {}
259 
261 
262  virtual ~Dumper() {}
263 
265 
268  virtual bool enabled(const TraceValue *t) const=0;
269 };
270 
273 class WarnUnknown : public Dumper {
274 
275  public:
276  WarnUnknown(AvrDevice *core);
277  void markReadUnknown(const TraceValue *t);
278  bool enabled(const TraceValue *t) const;
279 
280  private:
282 };
283 
285 class DumpVCD : public Dumper {
286 
287  public:
289  DumpVCD(std::ostream *os, const std::string &tscale = "ns",
290  const bool rstrobes = false, const bool wstrobes = false);
291 
293  DumpVCD(const std::string &name, const std::string &tscale = "ns",
294  const bool rstrobes = false, const bool wstrobes = false);
295 
296  void setActiveSignals(const TraceSet &act);
297 
299  void start();
300 
302  void stop();
303 
305  void cycle();
306 
309  void markRead(const TraceValue *t);
310 
313  void markWrite(const TraceValue *t);
314 
316  void markChange(const TraceValue *t);
317 
318  bool enabled(const TraceValue *t) const;
319  ~DumpVCD();
320 
321  private:
323  std::map<const TraceValue*, size_t> id2num;
324  const std::string tscale;
325  const bool rs, ws;
327 
328  // list of signals marked last cycle
329  std::vector<int> marked;
330  std::ostream *os;
331 
332  // buffer for change data
333  std::stringstream osbuffer;
334 
335  void valout(const TraceValue *v);
336 
338  void flushbuffer(void);
339 };
340 
344 class DumpManager {
345 
346  public:
348  static DumpManager* Instance(void);
349 
351  static void Reset(void);
352 
354 
361  void SetSingleDeviceApp(void);
362 
365  void addDumper(Dumper *dump, const TraceSet &vals);
366 
369  void start();
370 
372  void stopApplication(void);
373 
376  void cycle();
377 
379  ~DumpManager() { stopApplication(); }
380 
383  void save(std::ostream &os) const;
384 
389  TraceSet load(std::istream &is);
390 
395  TraceSet load(const std::string &istr);
396 
398  const TraceSet& all();
399 
400  private:
401  friend class TraceValueRegister;
402  friend class AvrDevice;
403 
405  DumpManager();
406 
408  void appendDeviceName(std::string &s);
409 
411  void registerAvrDevice(AvrDevice* dev);
412 
414  void unregisterAvrDevice(AvrDevice* dev);
415 
417  void detachAvrDevices();
418 
420  TraceValue* seekValueByName(const std::string &name);
421 
424 
429 
431  std::vector<Dumper*> dumps;
432 
434  std::vector<AvrDevice*> devices;
435 
436  static int _devidx;
438 };
439 
441 
443 
444  private:
445  typedef std::map<std::string*, TraceValue*> valmap_t;
446  typedef std::map<std::string*, TraceValueRegister*> regmap_t;
447 
448  std::string _tvr_scopename;
449  std::string _tvr_scopeprefix;
450  valmap_t _tvr_values;
451  regmap_t _tvr_registers;
452 
455  void _tvr_registerTraceValues(TraceValueRegister *r);
456  void _tvr_unregisterTraceValues(TraceValueRegister *r);
457 
458  protected:
460  virtual size_t _tvr_getValuesCount(void);
461 
463  virtual void _tvr_insertTraceValuesToSet(TraceSet &t);
464 
465  public:
467  TraceValueRegister(TraceValueRegister *parent, const std::string &name):
468  _tvr_scopename(name),
469  _tvr_scopeprefix(parent->GetTraceValuePrefix() + name + "."),
470  _tvr_parent(parent)
471  {
472  _tvr_parent->_tvr_registerTraceValues(this);
473  }
476  _tvr_scopename(""),
477  _tvr_scopeprefix(""),
478  _tvr_parent(NULL)
479  {
480  DumpManager::Instance()->appendDeviceName(_tvr_scopename);
481  if(_tvr_scopename.length() > 0)
482  _tvr_scopeprefix += _tvr_scopename + ".";
483  }
484  virtual ~TraceValueRegister();
485 
487  const std::string GetTraceValuePrefix(void) { return _tvr_scopeprefix; }
489  const std::string GetScopeName(void) { return _tvr_scopename; }
491  void RegisterTraceValue(TraceValue *t);
493  void UnregisterTraceValue(TraceValue *t);
495  TraceValueRegister* GetScopeGroupByName(const std::string &name);
497  virtual TraceValue* GetTraceValueByName(const std::string &name);
499  TraceValueRegister* FindScopeGroupByName(const std::string &name);
501  TraceValue* FindTraceValueByName(const std::string &name);
503  TraceSet* GetAllTraceValues(void);
505  TraceSet* GetAllTraceValuesRecursive(void);
506 };
507 
510 
511  private:
512  typedef std::map<std::string*, TraceSet*> setmap_t;
513 
514  setmap_t _tvr_valset;
515 
517  int _tvr_numberindex(const std::string &str);
518 
519  protected:
521 
522  virtual size_t _tvr_getValuesCount(void);
523 
525 
526  virtual void _tvr_insertTraceValuesToSet(TraceSet &t);
527 
528  public:
531 
533 
535  void RegisterTraceSetValue(TraceValue *t, const std::string &name, const size_t size);
537  virtual TraceValue* GetTraceValueByName(const std::string &name);
538 };
539 
541 
542 TraceValue *trace_direct(TraceValueRegister *t, const std::string &name, const bool *val);
543 
545 
546 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, const uint8_t *val);
547 
549 
550 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, const uint16_t *val);
551 
553 
554 TraceValue* trace_direct(TraceValueRegister *t, const std::string &name, const uint32_t *val);
555 
556 #endif
std::vector< AvrDevice * > devices
Device list.
Definition: traceval.h:434
TraceValue * trace_direct(TraceValueRegister *t, const std::string &name, const bool *val)
Register a directly traced bool value.
Definition: traceval.cpp:788
virtual char VcdBit(int bitNo) const
Definition: traceval.cpp:149
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
void read()
Log a read access.
Definition: traceval.cpp:93
setmap_t _tvr_valset
the registered TraceValue&#39;s
Definition: traceval.h:514
bool changesWritten
Definition: traceval.h:326
std::string _tvr_scopename
the scope name itself
Definition: traceval.h:448
friend class DumpManager
Definition: avrdevice.h:78
std::map< std::string *, TraceSet * > setmap_t
type of TraceSet map
Definition: traceval.h:512
int index() const
Gives the index of this member in a memory field (or -1)
Definition: traceval.cpp:60
std::ostream * os
Definition: traceval.h:330
regmap_t _tvr_registers
the sub-registers
Definition: traceval.h:451
virtual void cycle()
Called for each cycle before dumping the values.
Definition: traceval.h:244
unsigned value() const
Gives the saved shadow value for this trace value.
Definition: traceval.cpp:62
TraceSet active
Set of active tracing values.
Definition: traceval.h:426
std::string barename() const
Gives the name without the index.
Definition: traceval.cpp:58
virtual ~Dumper()
Destructor, called for all dumpers at the very end of the run.
Definition: traceval.h:262
int _index
Definition: traceval.h:192
std::stringstream osbuffer
Definition: traceval.h:333
virtual void markRead(const TraceValue *t)
Definition: traceval.h:248
static DumpManager * _instance
Definition: traceval.h:437
Atype flags() const
Gives the current set of flag readings.
Definition: traceval.cpp:108
void set_written()
Definition: traceval.cpp:99
TraceValueOutput(const std::string &_name)
Definition: traceval.h:218
static int _devidx
Definition: traceval.h:436
size_t bits() const
Give number of bits for this value. Max 32.
Definition: traceval.cpp:50
const unsigned b
number of bits
Definition: traceval.h:195
Build a register for TraceValue&#39;s.
Definition: traceval.h:442
std::map< const TraceValue *, size_t > id2num
Definition: traceval.h:323
void clear_flags()
Clear all access flags.
virtual void markWrite(const TraceValue *t)
Definition: traceval.h:254
TraceValue(size_t bits, const std::string &_name, const int __index=-1, const void *shadow=NULL)
Generate a new unitialized trace value of width bits.
Definition: traceval.cpp:37
std::string name() const
Give name (fully qualified), including the index appended if it is >=0.
Definition: traceval.cpp:52
bool written() const
Definition: traceval.cpp:97
void write(unsigned val)
Log a write access on this value.
Definition: traceval.cpp:84
bool enabled() const
Definition: traceval.cpp:64
const void * shadow
shadow reg, if used
Definition: traceval.h:198
std::map< std::string *, TraceValue * > valmap_t
type of values map
Definition: traceval.h:445
std::map< std::string *, TraceValueRegister * > regmap_t
type of subregisters map
Definition: traceval.h:446
~DumpManager()
Destroys the DumpManager instance and shut down all dumpers.
Definition: traceval.h:379
virtual void start()
Called before start of tracing.
Definition: traceval.h:239
virtual void setActiveSignals(const TraceSet &act)
Definition: traceval.h:236
std::string _tvr_scopeprefix
the prefix scope for a TraceValue name
Definition: traceval.h:449
TraceValueRegister()
Create a TraceValueRegister, with a empty scope name, single device application.
Definition: traceval.h:475
unsigned v
The value itself.
Definition: traceval.h:201
const std::string GetTraceValuePrefix(void)
Returns the scope prefix.
Definition: traceval.h:487
TraceSet _all
Set of all traceable values (placeholder instance for all() method)
Definition: traceval.h:428
std::vector< Dumper * > dumps
All dumpers, which we want to use.
Definition: traceval.h:431
virtual void markChange(const TraceValue *t)
Definition: traceval.h:258
bool _written
Definition: traceval.h:206
TraceSet tv
Definition: traceval.h:322
bool _enabled
Tracing of this value enabled at all?
Definition: traceval.h:211
friend class TraceKeeper
Definition: traceval.h:187
valmap_t _tvr_values
the registered TraceValue&#39;s
Definition: traceval.h:450
TraceValueRegister * _tvr_parent
Registers a TraceValueRegister for this register, build a hierarchy.
Definition: traceval.h:454
void _tvr_registerTraceValues(TraceValueRegister *r)
Definition: traceval.cpp:182
std::vector< int > marked
Definition: traceval.h:329
void enable()
Enable tracing.
Definition: traceval.cpp:66
static DumpManager * Instance(void)
Singleton class access.
Definition: traceval.cpp:567
void change(unsigned val)
Log a change on this value.
Definition: traceval.cpp:68
std::vector< TraceValue * > TraceSet
Definition: traceval.h:226
const std::string tscale
Definition: traceval.h:324
virtual void stop()
Called after stopping tracing.
Definition: traceval.h:241
const bool ws
Definition: traceval.h:325
TraceValueRegister(TraceValueRegister *parent, const std::string &name)
Create a TraceValueRegister, with a scope prefix built on parent scope + name.
Definition: traceval.h:467
bool singleDeviceApp
Flag, if we use only one device, e.g. assign no device name.
Definition: traceval.h:423
void appendDeviceName(std::string &s)
append a unique device name to a string
Definition: traceval.cpp:586
AvrDevice * core
Definition: traceval.h:281
virtual void markReadUnknown(const TraceValue *t)
Definition: traceval.h:250
virtual ~TraceValue()
Definition: traceval.h:110
const std::string GetScopeName(void)
Returns the scope name.
Definition: traceval.h:489
int f
accesses since last dump/clearflagsd
Definition: traceval.h:203
virtual void cycle()
Called at least once for each cycle if this trace value is activated.
Definition: traceval.cpp:110
virtual void dump(Dumper &d)
Definition: traceval.cpp:134
std::string _name
Definition: traceval.h:190
Atype
Possible access types for a trace value.
Definition: traceval.h:131