[MIDAS] add tests for other designs

This commit is contained in:
Donggyu Kim 2014-10-19 19:17:12 -07:00
parent 7c25216fd3
commit 013c186459
14 changed files with 352 additions and 19 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
generated generated
logs
results results
target target
project/target project/target

View File

@ -3,6 +3,7 @@ srcdir := $(basedir)/src/main/scala
csrcdir := $(basedir)/csrc csrcdir := $(basedir)/csrc
tutdir := $(basedir)/tutorial/examples tutdir := $(basedir)/tutorial/examples
gendir := $(basedir)/generated gendir := $(basedir)/generated
logdir := $(basedir)/logs
resdir := $(basedir)/results resdir := $(basedir)/results
zeddir := $(basedir)/fpga-zynq/zedboard zeddir := $(basedir)/fpga-zynq/zedboard
bitstream := fpga-images-zedboard/boot.bin bitstream := fpga-images-zedboard/boot.bin
@ -25,23 +26,24 @@ driver := $(addsuffix -zedborad, $(designs))
$(designs): %: %Shim.v %-fpga %-zedborad $(designs): %: %Shim.v %-fpga %-zedborad
$(cpp): %Shim.cpp: %.scala $(cpp): %Shim.cpp: %.scala
mkdir -p $(resdir) mkdir -p $(logdir)
sbt "run $(basename $@) $(C_FLAGS)" | tee $(resdir)/$@.out sbt "run $(basename $@) $(C_FLAGS)" | tee $(logdir)/$@.out
$(v) : %Shim.v: %.scala $(v) : %Shim.v: %.scala
mkdir -p $(resdir) mkdir -p $(logdir) $(resdir)
sbt "run $(basename $@) $(V_FLAGS)" | tee $(resdir)/$@.out sbt "run $(basename $@) $(V_FLAGS)" | tee $(logdir)/$@.out
cd $(gendir); cp $*.io.map $*.chain.map $(resdir) cd $(gendir); cp $*.io.map $*.chain.map $(resdir)
$(fpga): %-fpga: %Shim.v $(fpga): %-fpga: %Shim.v
cd $(zeddir); make $(bitstream) DESIGN=$*; cp $(bitstream) $(resdir) mkdir -p $(resdir)
cd $(zeddir); make clean; make $(bitstream) DESIGN=$*; cp $(bitstream) $(resdir)
$(driver): %-zedborad: $(csrcdir)/%.cc $(csrcdir)/debug_api.cc $(csrcdir)/debug_api.h $(driver): %-zedborad: $(csrcdir)/%.cc $(csrcdir)/debug_api.cc $(csrcdir)/debug_api.h
mkdir -p $(resdir) mkdir -p $(resdir)
cd $(resdir); $(CXX) $(CXXFLAGS) $^ -o $@ cd $(resdir); $(CXX) $(CXXFLAGS) $^ -o $@
clean: clean:
rm -rf $(gendir) $(resdir) rm -rf $(gendir) $(logdir) $(resdir)
cleanall: cleanall:
rm -rf project/target target rm -rf project/target target

View File

@ -0,0 +1,31 @@
#include "debug_api.h"
class EnableShiftRegister_t: debug_api_t
{
public:
EnableShiftRegister_t(): debug_api_t("EnableShiftRegister") {}
void run() {
std::vector<uint32_t> reg(4, 0);
for (int i = 0 ; i < 16 ; i++) {
uint32_t in = rand_next(2);
uint32_t shift = rand_next(2);
poke("EnableShiftRegister.io_in", in);
poke("EnableShiftRegister.io_shift", shift);
step(1);
if (shift) {
for (int j = 3 ; j > 0 ; j--) {
reg[j] = reg[j-1];
}
reg[0] = in;
}
expect("EnableShiftRegister.io_out", reg[3]);
}
}
};
int main()
{
EnableShiftRegister_t EnableShiftRegister;
EnableShiftRegister.run();
return 0;
}

View File

@ -1,6 +1,4 @@
#include "debug_api.h" #include "debug_api.h"
#include <assert.h>
#include <iostream>
class GCD_t: debug_api_t class GCD_t: debug_api_t
{ {

40
csrc/MemorySearch.cc Normal file
View File

@ -0,0 +1,40 @@
#include "debug_api.h"
class MemorySearch_t: debug_api_t
{
public:
MemorySearch_t(): debug_api_t("MemorySearch") {}
void run() {
std::vector<uint32_t> list;
list.push_back(0);
list.push_back(4);
list.push_back(15);
list.push_back(14);
list.push_back(2);
list.push_back(5);
list.push_back(13);
int n = 8;
int maxT = n * (list.size() + 3);
for (int i = 0 ; i < n ; i++) {
uint32_t target = rand_next(16);
poke("MemorySearch.io_en", 1);
poke("MemorySearch.io_target", target);
step(1);
poke("MemorySearch.io_en", 0);
do {
step(1);
} while(peek("MemorySearch.io_done") == 0 && t < maxT);
uint32_t addr = peek("MemorySearch.io_address");
std::ostringstream oss;
oss << "LOOKING FOR " << target << " FOUND " << addr;
expect(addr == list.size() | list[addr] == target, oss.str());
}
}
};
int main()
{
MemorySearch_t MemorySearch;
MemorySearch.run();
return 0;
}

24
csrc/Parity.cc Normal file
View File

@ -0,0 +1,24 @@
#include "debug_api.h"
class Parity_t: debug_api_t
{
public:
Parity_t(): debug_api_t("Parity") {}
void run() {
uint32_t isOdd = 0;
for (int i = 0 ; i < 10 ; i++) {
uint32_t bit = rand_next(2);
poke("Parity.io_in", bit);
step(1);
isOdd = (isOdd + bit) % 2;
expect("Parity.io_out", isOdd);
}
}
};
int main()
{
Parity_t Parity;
Parity.run();
return 0;
}

View File

@ -0,0 +1,32 @@
#include "debug_api.h"
class ResetShiftRegister_t: debug_api_t
{
public:
ResetShiftRegister_t(): debug_api_t("ResetShiftRegister") {}
void run() {
std::vector<uint32_t> ins(4, 0);
int k = 0;
for (int i = 0 ; i < 16 ; i++) {
uint32_t in = rand_next(2);
uint32_t shift = rand_next(2);
if (shift == 1)
ins[k % 5] = in;
poke("ResetShiftRegister.io_in", in);
poke("ResetShiftRegister.io_shift", shift);
step(1);
if (shift)
k++;
int expected = 0;
if (t > 4) expected = ins[(k + 1) % 4];
expect("ResetShiftRegister.io_out", expected);
}
}
};
int main()
{
ResetShiftRegister_t ResetShiftRegister;
ResetShiftRegister.run();
return 0;
}

52
csrc/Risc.cc Normal file
View File

@ -0,0 +1,52 @@
#include "debug_api.h"
class Risc_t: debug_api_t
{
public:
Risc_t(): debug_api_t("Risc") {}
void run() {
std::vector<uint32_t> app;
app.push_back(I(1, 1, 0, 1));
app.push_back(I(0, 1, 1, 1));
app.push_back(I(0, 1, 1, 1));
app.push_back(I(0, 255, 1, 0));
wr(0, 0);
for (int addr = 0 ; addr < app.size() ; addr++) {
wr(addr, app[addr]);
}
boot();
int k = 0;
do {
tick(); k += 1;
} while (peek("Risc.io_valid") == 0 && k < 10);
expect(k < 10, "TIME LIMIT");
expect("Risc.io_out", 4);
}
private:
void wr(uint32_t addr, uint32_t data) {
poke("Risc.io_isWr", 1);
poke("Risc.io_wrAddr", addr);
poke("Risc.io_wrData", data);
step(1);
}
void boot() {
poke("Risc.io_isWr", 0);
poke("Risc.io_boot", 1);
step(1);
}
void tick() {
poke("Risc.io_isWr", 0);
poke("Risc.io_boot", 0);
step(1);
}
uint32_t I(uint32_t op, uint32_t rc, uint32_t ra, uint32_t rb) {
return (op << 24 | rc << 16 | ra << 8 | rb);
}
};
int main()
{
Risc_t Risc;
Risc.run();
return 0;
}

52
csrc/RiscSRAM.cc Normal file
View File

@ -0,0 +1,52 @@
#include "debug_api.h"
class RiscSRAM_t: debug_api_t
{
public:
RiscSRAM_t(): debug_api_t("RiscSRAM") {}
void run() {
std::vector<uint32_t> app;
app.push_back(I(1, 1, 0, 1));
app.push_back(I(0, 1, 1, 1));
app.push_back(I(0, 1, 1, 1));
app.push_back(I(0, 255, 1, 0));
wr(0, 0);
for (int addr = 0 ; addr < app.size() ; addr++) {
wr(addr, app[addr]);
}
boot();
int k = 0;
do {
tick(); k += 1;
} while (peek("RiscSRAM.io_valid") == 0 && k < 40);
expect(k < 40, "TIME LIMIT");
expect("RiscSRAM.io_out", 4);
}
private:
void wr(uint32_t addr, uint32_t data) {
poke("RiscSRAM.io_isWr", 1);
poke("RiscSRAM.io_wrAddr", addr);
poke("RiscSRAM.io_wrData", data);
step(1);
}
void boot() {
poke("RiscSRAM.io_isWr", 0);
poke("RiscSRAM.io_boot", 1);
step(1);
}
void tick() {
poke("RiscSRAM.io_isWr", 0);
poke("RiscSRAM.io_boot", 0);
step(1);
}
uint32_t I(uint32_t op, uint32_t rc, uint32_t ra, uint32_t rb) {
return op << 24 | rc << 16 | ra << 8 | rb;
}
};
int main()
{
RiscSRAM_t RiscSRAM;
RiscSRAM.run();
return 0;
}

27
csrc/ShiftRegister.cc Normal file
View File

@ -0,0 +1,27 @@
#include "debug_api.h"
class ShiftRegister_t: debug_api_t
{
public:
ShiftRegister_t(): debug_api_t("ShiftRegister") {}
void run() {
std::vector<uint32_t> reg(4, 0);
for (int i = 0 ; i < 64 ; i++) {
uint32_t in = rand_next(2);
poke("ShiftRegister.io_in", in);
step(1);
for (int j = 3 ; j > 0 ; j--) {
reg[j] = reg[j-1];
}
reg[0] = in;
if (t >= 4) expect("ShiftRegister.io_out", reg[3]);
}
}
};
int main()
{
ShiftRegister_t ShiftRegister;
ShiftRegister.run();
return 0;
}

45
csrc/Stack.cc Normal file
View File

@ -0,0 +1,45 @@
#include "debug_api.h"
#include <stack>
class Stack_t: debug_api_t
{
public:
Stack_t(int size_): debug_api_t("Stack"), size(size_) {}
void run() {
std::stack<uint32_t> stack;
uint32_t nextDataOut = 0;
uint32_t dataOut = 0;
for (int i = 0 ; i < 16 ; i++) {
uint32_t enable = rand_next(2);
uint32_t push = rand_next(2);
uint32_t pop = rand_next(2);
uint32_t dataIn = rand_next(256);
if (enable) {
dataOut = nextDataOut;
if (push && stack.size() < size) {
stack.push(dataIn);
} else if (pop && stack.size() > 0) {
stack.pop();
}
if (stack.size()) {
nextDataOut = stack.top();
}
}
poke("Stack.io_pop", pop);
poke("Stack.io_push", push);
poke("Stack.io_en", enable);
poke("Stack.io_dataIn", dataIn);
step(1);
expect("Stack.io_dataOut", dataOut);
}
}
private:
int size;
};
int main()
{
Stack_t Stack(8);
Stack.run();
return 0;
}

View File

@ -6,6 +6,7 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <bitset> #include <bitset>
#include <stdlib.h>
#define read_reg(r) (dev_vaddr[r]) #define read_reg(r) (dev_vaddr[r])
#define write_reg(r, v) (dev_vaddr[r] = v) #define write_reg(r, v) (dev_vaddr[r] = v)
@ -18,7 +19,7 @@
#define SNAP 3 #define SNAP 3
debug_api_t::debug_api_t(std::string design_) debug_api_t::debug_api_t(std::string design_)
: t(0), snap_size(0), pass(true), design(design_) : t(0), snap_size(0), pass(true), fail_t(-1), design(design_)
{ {
int fd = open("/dev/mem", O_RDWR|O_SYNC); int fd = open("/dev/mem", O_RDWR|O_SYNC);
assert(fd != -1); assert(fd != -1);
@ -42,6 +43,8 @@ debug_api_t::debug_api_t(std::string design_)
// Read mapping files // Read mapping files
read_io_map_file(design + ".io.map"); read_io_map_file(design + ".io.map");
read_chain_map_file(design + ".chain.map"); read_chain_map_file(design + ".chain.map");
srand(time(NULL));
} }
debug_api_t::~debug_api_t() { debug_api_t::~debug_api_t() {
@ -49,7 +52,7 @@ debug_api_t::~debug_api_t() {
if (pass) if (pass)
std::cout << " Passed" << std::endl; std::cout << " Passed" << std::endl;
else else
std::cout << " Failed" << std::endl; std::cout << " Failed, first at cycle " << fail_t << std::endl;
write_replay_file(design + ".replay"); write_replay_file(design + ".replay");
} }
@ -159,6 +162,7 @@ void debug_api_t::snapshot(std::string &snap) {
std::bitset<sizeof(uint32_t) * 8> bin_value(value); std::bitset<sizeof(uint32_t) * 8> bin_value(value);
snap += bin_value.to_string(); snap += bin_value.to_string();
i++; i++;
if (i >= limit) break;
} }
} }
} }
@ -205,7 +209,7 @@ void debug_api_t::step(uint32_t n) {
if (t > 0) poke_snap(); if (t > 0) poke_snap();
poke_steps(n); poke_steps(n);
if (t > 0) snapshot(snap); if (t > 0) snapshot(snap);
std::cout << "* STEP " << n << " -> " << t << " * " << std::endl; std::cout << "* STEP " << n << " -> " << (t + n) << " * " << std::endl;
peek_all(); peek_all();
if (t > 0) write_snap(snap, n); if (t > 0) write_snap(snap, n);
@ -229,7 +233,29 @@ uint32_t debug_api_t::peek(std::string path) {
bool debug_api_t::expect(std::string path, uint32_t expected) { bool debug_api_t::expect(std::string path, uint32_t expected) {
int value = peek(path); int value = peek(path);
bool ok = value == expected; bool ok = value == expected;
std::cout << "* EXPECT " << path << " -> " << value << " == " << expected;
if (ok) {
std::cout << " PASS * " << std::endl;
} else {
if (fail_t < 0) fail_t = t;
std::cout << " FAIL * " << std::endl;
}
pass &= ok; pass &= ok;
std::cout << "* EXPECT " << path << " -> " << value << " == " << expected << " * " << std::endl;
return ok; return ok;
} }
bool debug_api_t::expect(bool ok, std::string s) {
std::cout << "* " << s;
if (ok) {
std::cout << " PASS * " << std::endl;
} else {
if (fail_t < 0) fail_t = t;
std::cout << " FAIL * " << std::endl;
}
pass &= ok;
return ok;
}
uint32_t debug_api_t::rand_next(int limit) {
return rand() % limit;
}

View File

@ -36,6 +36,7 @@ class debug_api_t
std::ostringstream replay; std::ostringstream replay;
bool pass; bool pass;
int32_t fail_t;
uint32_t snap_size; uint32_t snap_size;
volatile uintptr_t* dev_vaddr; volatile uintptr_t* dev_vaddr;
const static uintptr_t dev_paddr = 0x43C00000; const static uintptr_t dev_paddr = 0x43C00000;
@ -45,6 +46,8 @@ class debug_api_t
void poke(std::string path, uint32_t value); void poke(std::string path, uint32_t value);
uint32_t peek(std::string path); uint32_t peek(std::string path);
bool expect(std::string path, uint32_t expected); bool expect(std::string path, uint32_t expected);
bool expect(bool ok, std::string s);
uint32_t rand_next(int limit);
uint64_t t; uint64_t t;
}; };

View File

@ -89,8 +89,8 @@ object DaisyBackend {
for (i <- (0 until chain.daisylen).reverse) { for (i <- (0 until chain.daisylen).reverse) {
val wires = ArrayBuffer[UInt]() val wires = ArrayBuffer[UInt]()
var totalWidth = 0 var totalWidth = 0
while (totalWidth < top.daisywidth) { while (totalWidth < daisywidth) {
val totalMargin = top.daisywidth - totalWidth val totalMargin = daisywidth - totalWidth
if (stateIdx < states(m).size) { if (stateIdx < states(m).size) {
val state = states(m)(stateIdx) val state = states(m)(stateIdx)
val stateWidth = state.needWidth val stateWidth = state.needWidth
@ -168,7 +168,7 @@ object DaisyBackend {
chain.io.stall := daisyPins(m).stall chain.io.stall := daisyPins(m).stall
var high = datawidth-1 var high = datawidth-1
for (i <- (0 until chain.daisylen).reverse) { for (i <- (0 until chain.daisylen).reverse) {
val low = math.max(high-chain.daisywidth+1, 0) val low = math.max(high-daisywidth+1, 0)
val widthMargin = daisywidth-(high-low+1) val widthMargin = daisywidth-(high-low+1)
val data = UInt(read)(high, low) val data = UInt(read)(high, low)
if (widthMargin == 0) { if (widthMargin == 0) {
@ -176,7 +176,7 @@ object DaisyBackend {
} else { } else {
chain.io.dataIo.data(i) := Cat(data, UInt(0, widthMargin)) chain.io.dataIo.data(i) := Cat(data, UInt(0, widthMargin))
} }
high -= chain.daisywidth high -= daisywidth
} }
if (lastChain == null) { if (lastChain == null) {
connectSRAMRestarts(m) connectSRAMRestarts(m)
@ -269,7 +269,7 @@ object DaisyBackend {
stateWidth += width stateWidth += width
thisWidth += width thisWidth += width
while (totalWidth < stateWidth) totalWidth += top.hostwidth while (totalWidth < stateWidth) totalWidth += top.hostwidth
while (daisyWidth < thisWidth) daisyWidth += top.daisywidth while (daisyWidth < thisWidth) daisyWidth += daisywidth
} }
case _ => { case _ => {
val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + state.name val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + state.name
@ -277,7 +277,7 @@ object DaisyBackend {
res append "%s %d\n".format(path, width) res append "%s %d\n".format(path, width)
stateWidth += width stateWidth += width
while (totalWidth < stateWidth) totalWidth += top.hostwidth while (totalWidth < stateWidth) totalWidth += top.hostwidth
while (daisyWidth < thisWidth) daisyWidth += top.daisywidth while (daisyWidth < thisWidth) daisyWidth += daisywidth
} }
} }
} }
@ -300,7 +300,7 @@ object DaisyBackend {
res append "%s[%d] %d\n".format(path, i, width) res append "%s[%d] %d\n".format(path, i, width)
else else
res append "null %d\n".format(width) res append "null %d\n".format(width)
while (daisyWidth < width) daisyWidth += top.daisywidth while (daisyWidth < width) daisyWidth += daisywidth
val daisyPadWidth = daisyWidth - width val daisyPadWidth = daisyWidth - width
if (daisyPadWidth > 0) { if (daisyPadWidth > 0) {
res append "null %d\n".format(daisyPadWidth) res append "null %d\n".format(daisyPadWidth)