Skip to content

Commit

Permalink
support verilator
Browse files Browse the repository at this point in the history
  • Loading branch information
donggyukim committed May 11, 2018
1 parent bf7c35a commit 98235b5
Show file tree
Hide file tree
Showing 5 changed files with 403 additions and 4 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ generated-src
test_run_dir
target
project/target
logs
*.key
*.log
*.swp
*.out
.ivy2
VTile
dump.vcd*
DVEfiles
22 changes: 19 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
default: compile

base_dir = $(abspath .)
src_dir = $(base_dir)/src/main/scala/
src_dir = $(base_dir)/src/main
gen_dir = $(base_dir)/generated-src

SBT = sbt
Expand All @@ -12,9 +12,25 @@ sbt:

compile: $(gen_dir)/Tile.v

$(gen_dir)/Tile.v: $(wildcard $(src_dir)/*.scala)
$(gen_dir)/Tile.v: $(wildcard $(src_dir)/scala/*.scala)
$(SBT) $(SBT_FLAGS) "run $(gen_dir)"

CXXFLAGS += -std=c++11 -Wall -Wno-unused-variable

VERILATOR = verilator --cc --exe
VERILATOR_FLAGS = --assert -Wno-STMTDLY -O3 --trace \
--top-module Tile -Mdir $(gen_dir)/VTile.csrc \
-CFLAGS "$(CXXFLAGS) -include $(gen_dir)/VTile.csrc/VTile.h"

$(base_dir)/VTile: $(gen_dir)/Tile.v $(src_dir)/cc/top.cc $(src_dir)/cc/mm.cc $(src_dir)/cc/mm.h
$(VERILATOR) $(VERILATOR_FLAGS) -o $@ $< $(word 2, $^) $(word 3, $^)
$(MAKE) -C $(gen_dir)/VTile.csrc -f VTile.mk

verilator: $(base_dir)/VTile

%.out: $(base_dir)/VTile $(base_dir)/src/test/resources/%.hex
$^ 2> $@

test:
$(SBT) $(SBT_FLAGS) test

Expand All @@ -24,4 +40,4 @@ clean:
cleanall: clean
rm -rf target project/target

.PHONY: clean cleanall
.PHONY: sbt compile test verilator clean cleanall
142 changes: 142 additions & 0 deletions src/main/cc/mm.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// See LICENSE for license details.

#include "mm.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cassert>

mm_magic_t::mm_magic_t(size_t size, size_t word_size):
data(new char[size]),
size(size),
word_size(word_size),
store_inflight(false)
{
dummy_data.resize(word_size);
}

mm_magic_t::~mm_magic_t()
{
delete [] data;
}

void mm_magic_t::write(uint64_t addr, char *data) {
addr %= this->size;

char* base = this->data + addr;
memcpy(base, data, word_size);
}

void mm_magic_t::write(uint64_t addr, char *data, uint64_t strb, uint64_t size)
{
strb &= ((1L << size) - 1) << (addr % word_size);
addr %= this->size;

char *base = this->data + addr;
for (int i = 0; i < word_size; i++) {
if (strb & 1) base[i] = data[i];
strb >>= 1;
}
}

std::vector<char> mm_magic_t::read(uint64_t addr)
{
addr %= this->size;

char *base = this->data + addr;
return std::vector<char>(base, base + word_size);
}

void mm_magic_t::tick(
bool reset,
bool ar_valid,
uint64_t ar_addr,
uint64_t ar_id,
uint64_t ar_size,
uint64_t ar_len,

bool aw_valid,
uint64_t aw_addr,
uint64_t aw_id,
uint64_t aw_size,
uint64_t aw_len,

bool w_valid,
uint64_t w_strb,
void *w_data,
bool w_last,

bool r_ready,
bool b_ready)
{
bool ar_fire = !reset && ar_valid && ar_ready();
bool aw_fire = !reset && aw_valid && aw_ready();
bool w_fire = !reset && w_valid && w_ready();
bool r_fire = !reset && r_valid() && r_ready;
bool b_fire = !reset && b_valid() && b_ready;

if (ar_fire) {
uint64_t start_addr = (ar_addr / word_size) * word_size;
for (size_t i = 0; i <= ar_len; i++) {
auto dat = read(start_addr + i * word_size);
rresp.push(mm_rresp_t(ar_id, dat, i == ar_len));
}
}

if (aw_fire) {
store_addr = aw_addr;
store_id = aw_id;
store_count = aw_len + 1;
store_size = 1 << aw_size;
store_inflight = true;
}

if (w_fire) {
write(store_addr, (char*)w_data, w_strb, store_size);
store_addr += store_size;
store_count--;

if (store_count == 0) {
store_inflight = false;
bresp.push(store_id);
assert(w_last);
}
}

if (b_fire)
bresp.pop();

if (r_fire)
rresp.pop();

cycle++;

if (reset) {
while (!bresp.empty()) bresp.pop();
while (!rresp.empty()) rresp.pop();
cycle = 0;
}
}

void load_mem(char* mem, const char* fn)
{
int start = 0;
std::ifstream in(fn);
if (!in)
{
std::cerr << "could not open " << fn << std::endl;
exit(EXIT_FAILURE);
}

std::string line;
while (std::getline(in, line))
{
#define parse_nibble(c) ((c) >= 'a' ? (c)-'a'+10 : (c)-'0')
for (int i = line.length()-2, j = 0; i >= 0; i -= 2, j++) {
mem[start + j] = (parse_nibble(line[i]) << 4) | parse_nibble(line[i+1]);
}
start += line.length()/2;
}
}
99 changes: 99 additions & 0 deletions src/main/cc/mm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// See LICENSE for license details.

#ifndef MM_EMULATOR_H
#define MM_EMULATOR_H

#include <stdint.h>
#include <cstring>
#include <queue>

struct mm_rresp_t
{
uint64_t id;
std::vector<char> data;
bool last;

mm_rresp_t(uint64_t id, std::vector<char> data, bool last)
{
this->id = id;
this->data = data;
this->last = last;
}

mm_rresp_t()
{
this->id = 0;
this->last = false;
}
};

class mm_magic_t
{
public:
mm_magic_t(size_t size, size_t word_size);
~mm_magic_t();
void init(size_t sz, int word_size);
char* get_data() { return data; }
size_t get_size() { return size; }

bool ar_ready() { return true; }
bool aw_ready() { return !store_inflight; }
bool w_ready() { return store_inflight; }
bool b_valid() { return !bresp.empty(); }
uint64_t b_resp() { return 0; }
uint64_t b_id() { return b_valid() ? bresp.front() : 0; }
bool r_valid() { return !rresp.empty(); }
uint64_t r_resp() { return 0; }
uint64_t r_id() { return r_valid() ? rresp.front().id: 0; }
void *r_data() { return r_valid() ? &rresp.front().data[0] : &dummy_data[0]; }
bool r_last() { return r_valid() ? rresp.front().last : false; }

void tick
(
bool reset,

bool ar_valid,
uint64_t ar_addr,
uint64_t ar_id,
uint64_t ar_size,
uint64_t ar_len,

bool aw_valid,
uint64_t aw_addr,
uint64_t aw_id,
uint64_t aw_size,
uint64_t aw_len,

bool w_valid,
uint64_t w_strb,
void *w_data,
bool w_last,

bool r_ready,
bool b_ready
);

void write(uint64_t addr, char *data);
void write(uint64_t addr, char *data, uint64_t strb, uint64_t size);
std::vector<char> read(uint64_t addr);

private:
char* data;
size_t size;
size_t word_size;

bool store_inflight;
uint64_t store_addr;
uint64_t store_id;
uint64_t store_size;
uint64_t store_count;
std::vector<char> dummy_data;
std::queue<uint64_t> bresp;

std::queue<mm_rresp_t> rresp;

uint64_t cycle;
};

void load_mem(char* mem, const char* fn);
#endif
Loading

0 comments on commit 98235b5

Please sign in to comment.