Skip to content

Commit

Permalink
sim: Update memory-map for atombones
Browse files Browse the repository at this point in the history
- atomsim:
    - util: add function to resolve environment variables in file path
    - memory: add initializtion functions using bin, hex
    - update memory map for atomsim
    - use hex to initialize bootrom at start
  • Loading branch information
saursin committed Oct 14, 2023
1 parent f177abd commit 84d3141
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 35 deletions.
4 changes: 4 additions & 0 deletions sim/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ LDLIBS := -L include/CppLinuxSerial/
INCLUDES := -I . -I include/
INCLUDES += -I $(VERILATED_DIR) -I $(VERILATOR_INCLUDE_PATH) -I $(VERILATOR_INCLUDE_PATH)/vltstd

ifeq ($(DEBUG), 1)
CFLAGS += -g -O0
endif

EXE := $(BIN_DIR)/atomsim
SRCS := main.cpp atomsim.cpp simstate.cpp vuart.cpp interactive.cpp
SRCS += memory.cpp util.cpp
Expand Down
38 changes: 16 additions & 22 deletions sim/backend_atombones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "memory.hpp"
#include "vuart.hpp"
#include "except.hpp"
// #include "util.hpp"
#include "util.hpp"

#include "build/verilated/VAtomBones_headers.h"

Expand All @@ -28,8 +28,8 @@ Backend_atomsim::Backend_atomsim(Atomsim * sim, Backend_config config):
// Constuct Memory objects
try
{
mem_["imem"] = std::shared_ptr<Memory> (new Memory(config_.imem_size_kb * 1024, config_.imem_offset, true));
mem_["dmem"] = std::shared_ptr<Memory> (new Memory(config_.dmem_size_kb * 1024, config_.dmem_offset, false));
mem_["bootrom"] = std::shared_ptr<Memory> (new Memory(config_.bootrom_size_kb * 1024, config_.bootrom_offset, true));
mem_["ram"] = std::shared_ptr<Memory> (new Memory(config_.ram_size_kb * 1024, config_.ram_offset, false));
}
catch(const std::exception& e)
{
Expand All @@ -39,23 +39,17 @@ Backend_atomsim::Backend_atomsim(Atomsim * sim, Backend_config config):

// ====== Initialize ========
// Initialize memory
// load text section
try
{
if(sim_->sim_config_.verbose_flag)
std::cout << "Initializing imem:" << std::endl;
mem_["imem"]->set_write_protect(false);
init_from_elf(mem_["imem"].get(), sim_->sim_config_.ifile, std::vector<int>{5, 6});
mem_["imem"]->set_write_protect(true);

if(sim_->sim_config_.verbose_flag)
std::cout << "Initializing dmem:" << std::endl;
init_from_elf(mem_["dmem"].get(), sim_->sim_config_.ifile, std::vector<int>{5, 6});
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}

if(sim_->sim_config_.verbose_flag)
std::cout << "Initializing bootrom" << std::endl;

mem_["bootrom"]->set_write_protect(false);
init_from_imgfile(mem_["bootrom"].get(), resolve_envvar_in_path(config_.bootrom_img));
mem_["bootrom"]->set_write_protect(true);

if(sim_->sim_config_.verbose_flag)
std::cout << "Initializing ram:" << std::endl;
init_from_elf(mem_["ram"].get(), sim_->sim_config_.ifile, std::vector<int>{5, 6});


// Initialize CPU state by resetting
Expand Down Expand Up @@ -109,7 +103,7 @@ void Backend_atomsim::service_mem_req()
if(tb->m_core->iport_valid_o == 1)
{
Word_alias i_w;
mem_["imem"]->fetch(iaddr, i_w.byte, 4);
this->fetch(iaddr, i_w.byte, 4);
tb->m_core->iport_data_i = i_w.word;
tb->m_core->iport_ack_i = 1;
}
Expand Down Expand Up @@ -359,7 +353,7 @@ int Backend_atomsim::tick()
for(uint32_t addr=begin_signature_at; addr<end_signature_at; addr+=4)
{
Word_alias w;
mem_["dmem"]->fetch(addr, w.byte, 4);
this->fetch(addr, w.byte, 4);

char temp [50];
sprintf(temp, "%08x", w.word);
Expand Down
11 changes: 7 additions & 4 deletions sim/backend_atombones.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
#define ATOMSIM_TARGETNAME "atombones"
#define TARGET_ATOMBONES

#define DEFAULT_BOOTROM_IMAGE "${RVATOM}/sw/bootloader/bootloader.hex"

class Memory;
class Vuart;

struct Backend_config
{
uint32_t imem_offset = 0x00010000;
uint32_t imem_size_kb = (64*1024); // default: 64 MB
uint32_t bootrom_offset = 0x00010000;
uint32_t bootrom_size_kb = 8; // default: 8 KB
std::string bootrom_img = DEFAULT_BOOTROM_IMAGE;

uint32_t dmem_offset = 0x20000000;
uint32_t dmem_size_kb = (64*1024); // default: 64 MB
uint32_t ram_offset = 0x20000000;
uint32_t ram_size_kb = (80*1024); // default: 80 MB

std::string vuart_portname = "";
uint32_t vuart_baudrate = 115200;
Expand Down
5 changes: 3 additions & 2 deletions sim/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ void parse_commandline_args(int argc, char**argv, Atomsim_config &sim_config, Ba
("u,enable-uart-dump", "Enable dumping UART data (from soc) to stdout", cxxopts::value<bool>(backend_config.enable_uart_dump)->default_value(default_backend_config.enable_uart_dump?"true":"false"))

#ifdef TARGET_ATOMBONES
("imemsize", "Specify size of instruction memory to simulate (in KB)", cxxopts::value<uint32_t>(backend_config.imem_size_kb)->default_value(std::to_string(default_backend_config.imem_size_kb)))
("dmemsize", "Specify size of data memory to simulate (in KB)", cxxopts::value<uint32_t>(backend_config.dmem_size_kb)->default_value(std::to_string(default_backend_config.dmem_size_kb)))
("bootrom-size", "Specify size of bootrom to simulate (in KB)", cxxopts::value<uint32_t>(backend_config.bootrom_size_kb)->default_value(std::to_string(default_backend_config.bootrom_size_kb)))
("bootrom-image", "Specify bootrom hex image", cxxopts::value<std::string>(backend_config.bootrom_img)->default_value(default_backend_config.bootrom_img))
("ram-size", "Specify size of RAM memory to simulate (in KB)", cxxopts::value<uint32_t>(backend_config.ram_size_kb)->default_value(std::to_string(default_backend_config.ram_size_kb)))
#endif
;

Expand Down
47 changes: 47 additions & 0 deletions sim/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,51 @@ unsigned init_from_elf(Memory * m, std::string filepath, std::vector<int> flag_s
i++;
}
return (unsigned int) reader.get_entry();
}


void init_from_bin(Memory * m, std::string filepath) {
if(!m) {
throw Atomsim_exception("Can't initialize memory; mem pointer == null");
}

std::vector<char> fcontents = fReadBin(filepath);

printf("Loading %ld bytes at 0x%08x from %s\n", fcontents.size(), m->get_base_addr(), filepath.c_str());
m->store(m->get_base_addr(), (uint8_t*)fcontents.data(), fcontents.size());
}


void init_from_hex(Memory * m, std::string filepath) {
if(!m) {
throw Atomsim_exception("Can't initialize memory; mem pointer == null");
}

std::vector<std::string> fcontents = fRead(filepath);
uint32_t addr = m->get_base_addr();

printf("Loading %ld bytes at 0x%08x from %s\n", fcontents.size(), addr, filepath.c_str());

// parse
for(unsigned l=0; l<fcontents.size(); l++) {
std::string line = strip(fcontents[l]);
if (line.length() != 8)
throw Atomsim_exception("file:"+filepath+":"+std::to_string(l+1)+" Invalid hex format");

Word_alias wa;
wa.word = std::stoul(line, nullptr, 16);
m->store(addr, wa.byte, 4);
addr += 4;
}
}


void init_from_imgfile(Memory * m, std::string filepath) {
std::string ext = filepath.substr(filepath.length()-4, 4);
if(ext == ".hex")
init_from_hex(m, filepath);
else if (ext == ".bin")
init_from_bin(m, filepath);
else
throw Atomsim_exception("invalid image-file format: "+filepath);
}
29 changes: 28 additions & 1 deletion sim/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,31 @@ class Memory
* @param flag_signatures section signatures to load
* @return unsigned entry point
*/
unsigned init_from_elf(Memory * m, std::string filepath, std::vector<int> flag_signatures);
unsigned init_from_elf(Memory * m, std::string filepath, std::vector<int> flag_signatures);


/**
* @brief Initialize a memory from an bin file
*
* @param m memory ptr
* @param filepath elf file path
*/
void init_from_bin(Memory * m, std::string filepath);


/**
* @brief Initialize a memory from an hex file
*
* @param m memory ptr
* @param filepath elf file path
*/
void init_from_hex(Memory * m, std::string filepath);


/**
* @brief Initialize a memory from bin/hex file
*
* @param m memory ptr
* @param filepath bin/hex filepath
*/
void init_from_imgfile(Memory * m, std::string filepath);
36 changes: 30 additions & 6 deletions sim/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include "except.hpp"

// declared in main.cpp
extern bool NO_COLOR_OUTPUT;
Expand Down Expand Up @@ -80,15 +82,37 @@ size_t tokenize(const std::string &txt, std::vector<std::string> &strs, char ch)
return strs.size();
}

std::string resolve_envvar_in_path(std::string path) {
std::string resolvedpath = path;
size_t startpos = resolvedpath.find("${");

std::vector<char> fReadBin(std::string memfile)
while(startpos != std::string::npos) {
size_t endpos = resolvedpath.find("}", startpos);
if (endpos == std::string::npos) {
throw Atomsim_exception("Malformed Path, can't resolve environment vars");
}

std::string var = resolvedpath.substr(startpos+2, endpos-startpos-2);
const char * varval = getenv(var.c_str());

if (varval == nullptr) {
throw Atomsim_exception("Can't resolve envvar: " + var);
}

resolvedpath.replace(startpos, endpos-startpos+1, varval);
startpos = resolvedpath.find("${", startpos + 1);
}
return resolvedpath;
}

std::vector<char> fReadBin(std::string filepath)
{
std::vector<char> fcontents;
std::ifstream f (memfile, std::ios::out | std::ios::binary);
std::ifstream f (filepath, std::ios::out | std::ios::binary);

if(!f)
{
throw "file access failed";
throw Atomsim_exception("file access failed: "+filepath);
}
try
{
Expand All @@ -101,7 +125,7 @@ std::vector<char> fReadBin(std::string memfile)
}
catch(...)
{
throw "file reading failed!";
throw Atomsim_exception("file reading failed: "+filepath);
}
f.close();
return fcontents;
Expand All @@ -116,7 +140,7 @@ std::vector<std::string> fRead (std::string filepath)
// input file stream
std::ifstream fin(filepath.c_str());
if(!fin){
throw "file access failed";
throw Atomsim_exception("file access failed: "+filepath);
}

// reading file line by line and appending into the vector of strings
Expand All @@ -137,7 +161,7 @@ void fWrite (std::vector<std::string> data, std::string filepath)
std::ofstream File(filepath);
if(!File)
{
throw "file writing failed";
throw Atomsim_exception("file writing failed: " + filepath);
}
for(unsigned int i=0; i<data.size(); i++)
{
Expand Down
9 changes: 9 additions & 0 deletions sim/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ size_t tokenize(const std::string &txt, std::vector<std::string> &strs, char ch)
//////////////////////////////////////////////////////////////////////////////
// File I/O

/**
* @brief Resolves environment variable in path specified using ${VAR} syntax
*
* @param path input path
* @return std::string resolved oath
*/
std::string resolve_envvar_in_path(std::string path);


/**
* @brief reads a binary file
*
Expand Down

0 comments on commit 84d3141

Please sign in to comment.