Fix debug reset.
[riscv-isa-sim.git] / riscv / cachesim.h
1 // See LICENSE for license details.
2
3 #ifndef _RISCV_CACHE_SIM_H
4 #define _RISCV_CACHE_SIM_H
5
6 #include "memtracer.h"
7 #include <cstring>
8 #include <string>
9 #include <map>
10 #include <cstdint>
11
12 class lfsr_t
13 {
14 public:
15 lfsr_t() : reg(1) {}
16 lfsr_t(const lfsr_t& lfsr) : reg(lfsr.reg) {}
17 uint32_t next() { return reg = (reg>>1)^(-(reg&1) & 0xd0000001); }
18 private:
19 uint32_t reg;
20 };
21
22 class cache_sim_t
23 {
24 public:
25 cache_sim_t(size_t sets, size_t ways, size_t linesz, const char* name);
26 cache_sim_t(const cache_sim_t& rhs);
27 virtual ~cache_sim_t();
28
29 void access(uint64_t addr, size_t bytes, bool store);
30 void print_stats();
31 void set_miss_handler(cache_sim_t* mh) { miss_handler = mh; }
32
33 static cache_sim_t* construct(const char* config, const char* name);
34
35 protected:
36 static const uint64_t VALID = 1ULL << 63;
37 static const uint64_t DIRTY = 1ULL << 62;
38
39 virtual uint64_t* check_tag(uint64_t addr);
40 virtual uint64_t victimize(uint64_t addr);
41
42 lfsr_t lfsr;
43 cache_sim_t* miss_handler;
44
45 size_t sets;
46 size_t ways;
47 size_t linesz;
48 size_t idx_shift;
49
50 uint64_t* tags;
51
52 uint64_t read_accesses;
53 uint64_t read_misses;
54 uint64_t bytes_read;
55 uint64_t write_accesses;
56 uint64_t write_misses;
57 uint64_t bytes_written;
58 uint64_t writebacks;
59
60 std::string name;
61
62 void init();
63 };
64
65 class fa_cache_sim_t : public cache_sim_t
66 {
67 public:
68 fa_cache_sim_t(size_t ways, size_t linesz, const char* name);
69 uint64_t* check_tag(uint64_t addr);
70 uint64_t victimize(uint64_t addr);
71 private:
72 static bool cmp(uint64_t a, uint64_t b);
73 std::map<uint64_t, uint64_t> tags;
74 };
75
76 class cache_memtracer_t : public memtracer_t
77 {
78 public:
79 cache_memtracer_t(const char* config, const char* name)
80 {
81 cache = cache_sim_t::construct(config, name);
82 }
83 ~cache_memtracer_t()
84 {
85 delete cache;
86 }
87 void set_miss_handler(cache_sim_t* mh)
88 {
89 cache->set_miss_handler(mh);
90 }
91
92 protected:
93 cache_sim_t* cache;
94 };
95
96 class icache_sim_t : public cache_memtracer_t
97 {
98 public:
99 icache_sim_t(const char* config) : cache_memtracer_t(config, "I$") {}
100 bool interested_in_range(uint64_t begin, uint64_t end, access_type type)
101 {
102 return type == FETCH;
103 }
104 void trace(uint64_t addr, size_t bytes, access_type type)
105 {
106 if (type == FETCH) cache->access(addr, bytes, false);
107 }
108 };
109
110 class dcache_sim_t : public cache_memtracer_t
111 {
112 public:
113 dcache_sim_t(const char* config) : cache_memtracer_t(config, "D$") {}
114 bool interested_in_range(uint64_t begin, uint64_t end, access_type type)
115 {
116 return type == LOAD || type == STORE;
117 }
118 void trace(uint64_t addr, size_t bytes, access_type type)
119 {
120 if (type == LOAD || type == STORE) cache->access(addr, bytes, type == STORE);
121 }
122 };
123
124 #endif