@@ -59,7 +59,8 @@ std::shared_ptr<MmioPort> mmio_port(Port::Dir dir, const MmioReg ®, const std
59
59
}
60
60
61
61
std::shared_ptr<Component> mmio (const std::vector<fletcher::RecordBatchDescription> &batches,
62
- const std::vector<MmioReg> ®s) {
62
+ const std::vector<MmioReg> ®s,
63
+ Axi4LiteSpec axi_spec) {
63
64
// Clock/reset port.
64
65
// TODO(johanpel): Everything is on the kernel clock domain now until vhdmmio gets CDC support.
65
66
auto kcd = port (" kcd" , cr (), Port::Dir::IN, kernel_cd ());
@@ -74,7 +75,7 @@ std::shared_ptr<Component> mmio(const std::vector<fletcher::RecordBatchDescripti
74
75
comp->Add (port);
75
76
}
76
77
// Add the bus interface.
77
- auto bus = axi4_lite (Port::Dir::IN, bus_cd ());
78
+ auto bus = axi4_lite (Port::Dir::IN, bus_cd (), axi_spec );
78
79
comp->Add (bus);
79
80
80
81
// This will be a primitive component generated by vhdmmio.
@@ -85,14 +86,21 @@ std::shared_ptr<Component> mmio(const std::vector<fletcher::RecordBatchDescripti
85
86
return comp;
86
87
}
87
88
88
- static size_t AddrSpaceUsed (uint32_t width) {
89
- return 4 * (width / 32 + (width % 32 != 0 ));
89
+ // Calculate how much address space is used by this register, given a width and an alignment.
90
+ static size_t AddrSpaceUsed (uint32_t width, uint32_t alignment) {
91
+ return (alignment / 8 ) * (width / alignment + (width % alignment != 0 ));
90
92
}
91
93
92
- std::string GenerateVhdmmioYaml (const std::vector<std::vector<MmioReg> *>& regs, std::optional<size_t *> next_addr) {
94
+ static size_t Offset (uint32_t address, uint32_t alignment) {
95
+ return 8 * (address % (alignment / 8 ));
96
+ }
97
+
98
+ std::string GenerateVhdmmioYaml (const std::vector<std::vector<MmioReg> *> ®s,
99
+ Axi4LiteSpec axi_spec,
100
+ std::optional<size_t *> next_addr) {
93
101
std::stringstream ss;
94
102
// The next free byte address.
95
- size_t next_free_addr = 0 ;
103
+ size_t next_free_addr = axi_spec. offset ;
96
104
// Header:
97
105
ss << " metadata:\n "
98
106
" name: mmio\n "
@@ -105,40 +113,41 @@ std::string GenerateVhdmmioYaml(const std::vector<std::vector<MmioReg> *>& regs,
105
113
" reset-name: kcd_reset\n "
106
114
" \n "
107
115
" features:\n "
108
- " bus-width: 32 \n "
109
- " optimize: yes\n "
116
+ " bus-width: " << std::to_string (axi_spec. data_width ) << " \n " ;
117
+ ss << " optimize: yes\n "
110
118
" \n "
111
119
" interface:\n "
112
120
" flatten: yes\n "
113
121
" \n "
114
122
" fields: \n " ;
115
123
116
124
// Iterate over the registers and generate the appropriate YAML lines.
117
- for (auto &sub : regs) {
125
+ for (const auto &sub : regs) {
118
126
for (auto &r : *sub) {
119
127
// Determine the address.
120
128
if (r.addr ) {
121
129
// There is a fixed address.
122
- ss << " - address: " << *r.addr << " \n " ;
130
+ ss << " - address: " << axi_spec. offset + *r.addr << " \n " ;
123
131
// Just take this address plus its space as the next address. This limits how the vector of MmioRegs can be
124
132
// supplied (fixed addr. must be at the start of the vector and ordered), but we don't currently use this in
125
133
// any other way.
126
- next_free_addr = *r.addr + AddrSpaceUsed (r.width );
134
+ next_free_addr = axi_spec. offset + *r.addr + AddrSpaceUsed (r.width , 32 );
127
135
} else {
128
136
// There is not a fixed address.
129
137
ss << " - address: " << next_free_addr << " \n " ;
130
138
r.addr = next_free_addr;
131
- next_free_addr += AddrSpaceUsed (r.width );
139
+ next_free_addr += AddrSpaceUsed (r.width , 32 );
132
140
}
133
141
// Set doc, name and other stuff.
134
142
ss << " name: " << r.name << " \n " ;
135
143
if (!r.desc .empty ()) {
136
144
ss << " doc: " << r.desc << " \n " ;
137
145
}
146
+ auto offset = Offset (r.addr .value (), axi_spec.data_width );
138
147
if (r.width > 1 ) {
139
- ss << " bitrange: " << r.index + r.width - 1 << " .." << r.index << " \n " ;
148
+ ss << " bitrange: " << offset + r.index + r.width - 1 << " .." << offset + r.index << " \n " ;
140
149
} else {
141
- ss << " bitrange: " << r.index << " \n " ;
150
+ ss << " bitrange: " << offset + r.index << " \n " ;
142
151
}
143
152
ss << " behavior: " << ToString (r.behavior ) << " \n " ;
144
153
ss << " \n " ;
@@ -154,8 +163,8 @@ std::string GenerateVhdmmioYaml(const std::vector<std::vector<MmioReg> *>& regs,
154
163
155
164
bool ExposeToKernel (MmioFunction fun) {
156
165
switch (fun) {
157
- case MmioFunction::DEFAULT: return true ;
158
- case MmioFunction::KERNEL: return true ;
166
+ case MmioFunction::DEFAULT:
167
+ case MmioFunction::KERNEL:
159
168
case MmioFunction::BATCH: return true ;
160
169
default :return false ;
161
170
}
0 commit comments