loadMemHex method
- String hexMemContents
Reads a verilog-compliant hex file and preloads memory with it.
Example input format:
@80000000
B3 02 00 00 33 05 00 00 B3 05 00 00 13 05 F5 1F
6F 00 40 00 93 02 10 00 17 03 00 00 13 03 83 02
23 20 53 00 6F 00 00 00
@80000040
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Implementation
void loadMemHex(String hexMemContents) {
/// The number of bytes per cacheline.
const lineBytes = 4;
var address = 0;
var bytes = <String>[];
void addByte(String byte) {
bytes.add(byte);
if (bytes.length == lineBytes) {
final lvData = LogicValue.ofBigInt(
BigInt.parse(bytes.reversed.join(), radix: 16), lineBytes * 8);
final addr = LogicValue.ofInt(address - address % lineBytes, addrWidth);
setData(addr, lvData);
bytes = [];
}
}
List<String> reconstruct(LogicValue data) {
final out = <String>[];
for (var counter = 0; counter < lineBytes; counter++) {
out.add(data
.getRange(counter * 8, (counter + 1) * 8)
.toInt()
.toRadixString(16)
.padLeft(2, '0'));
}
return out;
}
for (var line in hexMemContents.split('\n')) {
line = line.trim();
if (line.startsWith('@')) {
// pad out remaining bytes as 0
// add that many to address
if (bytes.isNotEmpty) {
final thres = lineBytes - bytes.length;
for (var i = 0; i < thres; i++) {
addByte('00');
address++;
}
}
// check to see if this block already exists in memory
final lineAddr = int.parse(line.substring(1), radix: 16);
final lineAddrLv =
LogicValue.ofInt(lineAddr - lineAddr % lineBytes, addrWidth);
if (getData(lineAddrLv) != null) {
// must reconstruct the bytes array ending at the provided address
final endOff = lineAddr % lineBytes;
final origData = getData(lineAddrLv);
final newData = reconstruct(origData!).sublist(0, endOff);
bytes = newData;
}
address = lineAddr;
} else {
for (final byte in line.split(RegExp(r'\s'))) {
addByte(byte);
address++;
}
}
}
// pad out remaining bytes as 0
// add that many to address
final thres = lineBytes - bytes.length;
if (bytes.isNotEmpty) {
for (var i = 0; i < thres; i++) {
addByte('00');
address++;
}
}
}