mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 04:57:25 -04:00
[memutils] Add support for > 32b memories
Pack > 32bit memory loads into wider RAM instances. Fixes #790 Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
parent
b4e5d91842
commit
dc8ba83de4
3 changed files with 46 additions and 16 deletions
|
@ -31,12 +31,22 @@ extern void simutil_verilator_memload(const char *file);
|
|||
*
|
||||
* @return 1 if successful, 0 otherwise
|
||||
*/
|
||||
extern int simutil_verilator_set_mem(int index, const svLogicVecVal *val);
|
||||
extern int simutil_verilator_set_mem(int index, const svBitVecVal *val);
|
||||
}
|
||||
|
||||
bool VerilatorMemUtil::RegisterMemoryArea(const std::string name,
|
||||
const std::string location) {
|
||||
MemArea mem = {.name = name, .location = location};
|
||||
// Default to 32bit width
|
||||
return RegisterMemoryArea(name, location, 32);
|
||||
}
|
||||
|
||||
bool VerilatorMemUtil::RegisterMemoryArea(const std::string name,
|
||||
const std::string location,
|
||||
size_t width_bit) {
|
||||
MemArea mem = {.name = name, .location = location, .width_bit = width_bit};
|
||||
|
||||
assert((width_bit == 32 || width_bit == 64) &&
|
||||
"TODO: Check if width other than 32 and 64 works as expected.");
|
||||
|
||||
auto ret = mem_register_.emplace(name, mem);
|
||||
if (ret.second == false) {
|
||||
|
@ -130,8 +140,9 @@ bool VerilatorMemUtil::ParseCLIArguments(int argc, char **argv,
|
|||
void VerilatorMemUtil::PrintMemRegions() const {
|
||||
std::cout << "Registered memory regions:" << std::endl;
|
||||
for (const auto &m : mem_register_) {
|
||||
std::cout << "\t'" << m.second.name << "' at location: '"
|
||||
<< m.second.location << "'" << std::endl;
|
||||
std::cout << "\t'" << m.second.name << "' (" << m.second.width_bit
|
||||
<< "bits) at location: '" << m.second.location << "'"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,9 +397,17 @@ bool VerilatorMemUtil::MemWrite(const MemArea &m, const std::string &filepath,
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((m.width_bit % 32) != 0) {
|
||||
std::cerr << "ERROR: width for: " << m.name
|
||||
<< "must be a multiple of 32 (was : " << m.width_bit << ")"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
size_t size_byte = m.width_bit / 8;
|
||||
|
||||
switch (type) {
|
||||
case kMemImageElf:
|
||||
if (!WriteElfToMem(scope, filepath)) {
|
||||
if (!WriteElfToMem(scope, filepath, size_byte)) {
|
||||
std::cerr << "ERROR: Writing ELF file to memory \"" << m.name << "\" ("
|
||||
<< m.location << ") failed." << std::endl;
|
||||
return false;
|
||||
|
@ -410,7 +429,8 @@ bool VerilatorMemUtil::MemWrite(const MemArea &m, const std::string &filepath,
|
|||
}
|
||||
|
||||
bool VerilatorMemUtil::WriteElfToMem(const svScope &scope,
|
||||
const std::string &filepath) {
|
||||
const std::string &filepath,
|
||||
size_t size_byte) {
|
||||
bool retcode;
|
||||
svScope prev_scope = svSetScope(scope);
|
||||
|
||||
|
@ -422,9 +442,9 @@ bool VerilatorMemUtil::WriteElfToMem(const svScope &scope,
|
|||
retcode = false;
|
||||
goto ret;
|
||||
}
|
||||
for (int i = 0; i < (len_bytes + 3) / 4; ++i) {
|
||||
if (!simutil_verilator_set_mem(i, (svLogicVecVal *)&buf[4 * i])) {
|
||||
std::cerr << "ERROR: Could not set memory byte: " << i * 4 << "/"
|
||||
for (int i = 0; i < (len_bytes + size_byte - 1) / size_byte; ++i) {
|
||||
if (!simutil_verilator_set_mem(i, (svBitVecVal *)&buf[size_byte * i])) {
|
||||
std::cerr << "ERROR: Could not set memory byte: " << i * size_byte << "/"
|
||||
<< len_bytes << "" << std::endl;
|
||||
|
||||
retcode = false;
|
||||
|
|
|
@ -21,6 +21,7 @@ enum MemImageType {
|
|||
struct MemArea {
|
||||
std::string name; // Unique identifier
|
||||
std::string location; // Design scope location
|
||||
size_t width_bit; // Memory width
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,10 +42,18 @@ class VerilatorMemUtil : public SimCtrlExtension {
|
|||
* instantiated memory, which needs to support the DPI-C interfaces
|
||||
* 'simutil_verilator_memload' and 'simutil_verilator_set_mem' used for
|
||||
* 'vmem' and 'elf' files, respectively.
|
||||
* The |width_bit| argument specifies the with in bits of the target memory
|
||||
* instance (used for packing data).
|
||||
*
|
||||
* Memories must be registered before command arguments are parsed by
|
||||
* ParseCommandArgs() in order for them to be known.
|
||||
*/
|
||||
bool RegisterMemoryArea(const std::string name, const std::string location,
|
||||
size_t width_bit);
|
||||
|
||||
/**
|
||||
* Register a memory with default width (32bits)
|
||||
*/
|
||||
bool RegisterMemoryArea(const std::string name, const std::string location);
|
||||
|
||||
/**
|
||||
|
@ -98,7 +107,8 @@ class VerilatorMemUtil : public SimCtrlExtension {
|
|||
MemImageType type);
|
||||
bool MemWrite(const MemArea &m, const std::string &filepath,
|
||||
MemImageType type);
|
||||
bool WriteElfToMem(const svScope &scope, const std::string &filepath);
|
||||
bool WriteElfToMem(const svScope &scope, const std::string &filepath,
|
||||
size_t size_byte);
|
||||
bool WriteVmemToMem(const svScope &scope, const std::string &filepath);
|
||||
};
|
||||
|
||||
|
|
|
@ -71,16 +71,16 @@ module prim_generic_ram_1p #(
|
|||
$readmemh(file, mem);
|
||||
endtask
|
||||
|
||||
// TODO: Allow 'val' to have other widths than 32 bit
|
||||
// Width must be a multiple of 32bit for this function to work
|
||||
// Note that the DPI export and function definition must both be in the same generate
|
||||
// context to get the correct name.
|
||||
if (Width == 32) begin : gen_32bit
|
||||
// Function for setting a specific 32 bit element in |mem|
|
||||
if ((Width % 32) == 0) begin : gen_set_mem
|
||||
// Function for setting a specific element in |mem|
|
||||
// Returns 1 (true) for success, 0 (false) for errors.
|
||||
export "DPI-C" function simutil_verilator_set_mem;
|
||||
|
||||
function int simutil_verilator_set_mem(input int index,
|
||||
input logic[31:0] val);
|
||||
input bit [Width-1:0] val);
|
||||
if (index >= Depth) begin
|
||||
return 0;
|
||||
end
|
||||
|
@ -89,11 +89,11 @@ module prim_generic_ram_1p #(
|
|||
return 1;
|
||||
endfunction
|
||||
end else begin : gen_other
|
||||
// Function doesn't work for Width != 32 so just return 0
|
||||
// Function doesn't work unless Width % 32 so just return 0
|
||||
export "DPI-C" function simutil_verilator_set_mem;
|
||||
|
||||
function int simutil_verilator_set_mem(input int index,
|
||||
input logic[31:0] val);
|
||||
input bit [Width-1:0] val);
|
||||
return 0;
|
||||
endfunction
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue