From 013c186459f800082b98ae2684544a245adf8d91 Mon Sep 17 00:00:00 2001 From: Donggyu Kim Date: Sun, 19 Oct 2014 19:17:12 -0700 Subject: [PATCH] [MIDAS] add tests for other designs --- .gitignore | 1 + Makefile | 14 +++++---- csrc/EnableShiftRegister.cc | 31 ++++++++++++++++++ csrc/GCD.cc | 2 -- csrc/MemorySearch.cc | 40 ++++++++++++++++++++++++ csrc/Parity.cc | 24 ++++++++++++++ csrc/ResetShiftRegister.cc | 32 +++++++++++++++++++ csrc/Risc.cc | 52 +++++++++++++++++++++++++++++++ csrc/RiscSRAM.cc | 52 +++++++++++++++++++++++++++++++ csrc/ShiftRegister.cc | 27 ++++++++++++++++ csrc/Stack.cc | 45 ++++++++++++++++++++++++++ csrc/debug_api.cc | 34 +++++++++++++++++--- csrc/debug_api.h | 3 ++ src/main/scala/DaisyBackend.scala | 14 ++++----- 14 files changed, 352 insertions(+), 19 deletions(-) create mode 100644 csrc/EnableShiftRegister.cc create mode 100644 csrc/MemorySearch.cc create mode 100644 csrc/Parity.cc create mode 100644 csrc/ResetShiftRegister.cc create mode 100644 csrc/Risc.cc create mode 100644 csrc/RiscSRAM.cc create mode 100644 csrc/ShiftRegister.cc create mode 100644 csrc/Stack.cc diff --git a/.gitignore b/.gitignore index 397a57f1..421ab87f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ generated +logs results target project/target diff --git a/Makefile b/Makefile index 6a729a54..6e831c0f 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ srcdir := $(basedir)/src/main/scala csrcdir := $(basedir)/csrc tutdir := $(basedir)/tutorial/examples gendir := $(basedir)/generated +logdir := $(basedir)/logs resdir := $(basedir)/results zeddir := $(basedir)/fpga-zynq/zedboard bitstream := fpga-images-zedboard/boot.bin @@ -25,23 +26,24 @@ driver := $(addsuffix -zedborad, $(designs)) $(designs): %: %Shim.v %-fpga %-zedborad $(cpp): %Shim.cpp: %.scala - mkdir -p $(resdir) - sbt "run $(basename $@) $(C_FLAGS)" | tee $(resdir)/$@.out + mkdir -p $(logdir) + sbt "run $(basename $@) $(C_FLAGS)" | tee $(logdir)/$@.out $(v) : %Shim.v: %.scala - mkdir -p $(resdir) - sbt "run $(basename $@) $(V_FLAGS)" | tee $(resdir)/$@.out + mkdir -p $(logdir) $(resdir) + sbt "run $(basename $@) $(V_FLAGS)" | tee $(logdir)/$@.out cd $(gendir); cp $*.io.map $*.chain.map $(resdir) $(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 mkdir -p $(resdir) cd $(resdir); $(CXX) $(CXXFLAGS) $^ -o $@ clean: - rm -rf $(gendir) $(resdir) + rm -rf $(gendir) $(logdir) $(resdir) cleanall: rm -rf project/target target diff --git a/csrc/EnableShiftRegister.cc b/csrc/EnableShiftRegister.cc new file mode 100644 index 00000000..627cb819 --- /dev/null +++ b/csrc/EnableShiftRegister.cc @@ -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 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; +} diff --git a/csrc/GCD.cc b/csrc/GCD.cc index 5cf947b2..168caf58 100644 --- a/csrc/GCD.cc +++ b/csrc/GCD.cc @@ -1,6 +1,4 @@ #include "debug_api.h" -#include -#include class GCD_t: debug_api_t { diff --git a/csrc/MemorySearch.cc b/csrc/MemorySearch.cc new file mode 100644 index 00000000..89f54f2b --- /dev/null +++ b/csrc/MemorySearch.cc @@ -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 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; +} diff --git a/csrc/Parity.cc b/csrc/Parity.cc new file mode 100644 index 00000000..49c2312b --- /dev/null +++ b/csrc/Parity.cc @@ -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; +} diff --git a/csrc/ResetShiftRegister.cc b/csrc/ResetShiftRegister.cc new file mode 100644 index 00000000..85d9e6b6 --- /dev/null +++ b/csrc/ResetShiftRegister.cc @@ -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 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; +} diff --git a/csrc/Risc.cc b/csrc/Risc.cc new file mode 100644 index 00000000..cf7218c0 --- /dev/null +++ b/csrc/Risc.cc @@ -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 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; +} diff --git a/csrc/RiscSRAM.cc b/csrc/RiscSRAM.cc new file mode 100644 index 00000000..a3adef47 --- /dev/null +++ b/csrc/RiscSRAM.cc @@ -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 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; +} diff --git a/csrc/ShiftRegister.cc b/csrc/ShiftRegister.cc new file mode 100644 index 00000000..2e75ac73 --- /dev/null +++ b/csrc/ShiftRegister.cc @@ -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 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; +} diff --git a/csrc/Stack.cc b/csrc/Stack.cc new file mode 100644 index 00000000..2d9ad0fa --- /dev/null +++ b/csrc/Stack.cc @@ -0,0 +1,45 @@ +#include "debug_api.h" +#include +class Stack_t: debug_api_t +{ +public: + Stack_t(int size_): debug_api_t("Stack"), size(size_) {} + void run() { + std::stack 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; +} diff --git a/csrc/debug_api.cc b/csrc/debug_api.cc index affc3692..1aef5e3a 100644 --- a/csrc/debug_api.cc +++ b/csrc/debug_api.cc @@ -6,6 +6,7 @@ #include #include #include +#include #define read_reg(r) (dev_vaddr[r]) #define write_reg(r, v) (dev_vaddr[r] = v) @@ -18,7 +19,7 @@ #define SNAP 3 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); assert(fd != -1); @@ -42,6 +43,8 @@ debug_api_t::debug_api_t(std::string design_) // Read mapping files read_io_map_file(design + ".io.map"); read_chain_map_file(design + ".chain.map"); + + srand(time(NULL)); } debug_api_t::~debug_api_t() { @@ -49,7 +52,7 @@ debug_api_t::~debug_api_t() { if (pass) std::cout << " Passed" << std::endl; else - std::cout << " Failed" << std::endl; + std::cout << " Failed, first at cycle " << fail_t << std::endl; write_replay_file(design + ".replay"); } @@ -159,6 +162,7 @@ void debug_api_t::snapshot(std::string &snap) { std::bitset bin_value(value); snap += bin_value.to_string(); i++; + if (i >= limit) break; } } } @@ -205,7 +209,7 @@ void debug_api_t::step(uint32_t n) { if (t > 0) poke_snap(); poke_steps(n); if (t > 0) snapshot(snap); - std::cout << "* STEP " << n << " -> " << t << " * " << std::endl; + std::cout << "* STEP " << n << " -> " << (t + n) << " * " << std::endl; peek_all(); 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) { int value = peek(path); 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; - std::cout << "* EXPECT " << path << " -> " << value << " == " << expected << " * " << std::endl; 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; +} diff --git a/csrc/debug_api.h b/csrc/debug_api.h index 93bba4e7..6332c566 100644 --- a/csrc/debug_api.h +++ b/csrc/debug_api.h @@ -36,6 +36,7 @@ class debug_api_t std::ostringstream replay; bool pass; + int32_t fail_t; uint32_t snap_size; volatile uintptr_t* dev_vaddr; const static uintptr_t dev_paddr = 0x43C00000; @@ -45,6 +46,8 @@ class debug_api_t void poke(std::string path, uint32_t value); uint32_t peek(std::string path); bool expect(std::string path, uint32_t expected); + bool expect(bool ok, std::string s); + uint32_t rand_next(int limit); uint64_t t; }; diff --git a/src/main/scala/DaisyBackend.scala b/src/main/scala/DaisyBackend.scala index 7a96cfdd..b7df42ad 100644 --- a/src/main/scala/DaisyBackend.scala +++ b/src/main/scala/DaisyBackend.scala @@ -89,8 +89,8 @@ object DaisyBackend { for (i <- (0 until chain.daisylen).reverse) { val wires = ArrayBuffer[UInt]() var totalWidth = 0 - while (totalWidth < top.daisywidth) { - val totalMargin = top.daisywidth - totalWidth + while (totalWidth < daisywidth) { + val totalMargin = daisywidth - totalWidth if (stateIdx < states(m).size) { val state = states(m)(stateIdx) val stateWidth = state.needWidth @@ -168,7 +168,7 @@ object DaisyBackend { chain.io.stall := daisyPins(m).stall var high = datawidth-1 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 data = UInt(read)(high, low) if (widthMargin == 0) { @@ -176,7 +176,7 @@ object DaisyBackend { } else { chain.io.dataIo.data(i) := Cat(data, UInt(0, widthMargin)) } - high -= chain.daisywidth + high -= daisywidth } if (lastChain == null) { connectSRAMRestarts(m) @@ -269,7 +269,7 @@ object DaisyBackend { stateWidth += width thisWidth += width while (totalWidth < stateWidth) totalWidth += top.hostwidth - while (daisyWidth < thisWidth) daisyWidth += top.daisywidth + while (daisyWidth < thisWidth) daisyWidth += daisywidth } case _ => { val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + state.name @@ -277,7 +277,7 @@ object DaisyBackend { res append "%s %d\n".format(path, width) stateWidth += width 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) else res append "null %d\n".format(width) - while (daisyWidth < width) daisyWidth += top.daisywidth + while (daisyWidth < width) daisyWidth += daisywidth val daisyPadWidth = daisyWidth - width if (daisyPadWidth > 0) { res append "null %d\n".format(daisyPadWidth)