All base instruction pass Riscv-Test (load/store not tested)

This commit is contained in:
Charles Papon 2017-03-14 20:13:35 +01:00
parent ad6964f0bb
commit 7065ed5d93
3 changed files with 145 additions and 111 deletions

View File

@ -114,8 +114,6 @@ case class VexRiscvConfig(pcWidth : Int){
object REGFILE_WRITE_VALID extends Stageable(Bool)
object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
val SRC1_USE = REG1_USE
val SRC2_USE = REG2_USE
object SRC1 extends Stageable(Bits(32 bits))
object SRC2 extends Stageable(Bits(32 bits))
object SRC_ADD_SUB extends Stageable(Bits(32 bits))
@ -144,6 +142,11 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
stages ++= List.fill(6)(new Stage())
val prefetch :: fetch :: decode :: execute :: memory :: writeBack :: Nil = stages.toList
plugins ++= config.plugins
//regression usage
writeBack.input(config.INSTRUCTION) keep() addAttribute("verilator public")
writeBack.input(config.PC) keep() addAttribute("verilator public")
writeBack.arbitration.isValid keep() addAttribute("verilator public")
}
@ -232,9 +235,9 @@ class DecoderSimplePlugin extends Plugin[VexRiscv] with DecoderService {
val decodedBits = Bits(stageables.foldLeft(0)(_ + _.dataType.getBitsWidth) bits)
val defaultBits = cloneOf(decodedBits)
assert(defaultValue == 0)
defaultBits := defaultValue
for(i <- decodedBits.range)
defaultBits(i) := Bool(defaultValue.testBit(i))
val logicOr = for((key, mapping) <- spec) yield Mux[Bits](((input(INSTRUCTION) & key.care) === (key.value & key.care)), B(mapping.value & mapping.care, decodedBits.getWidth bits) , B(0, decodedBits.getWidth bits))
decodedBits := logicOr.foldLeft(defaultBits)(_ | _)
@ -291,8 +294,8 @@ class NoPredictionBranchPlugin extends Plugin[VexRiscv]{
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
SRC_USE_SUB_LESS -> True,
SRC1_USE -> True,
SRC2_USE -> True
REG1_USE -> True,
REG2_USE -> True
)
val jActions = List[(Stageable[_ <: BaseType],Any)](
@ -300,14 +303,13 @@ class NoPredictionBranchPlugin extends Plugin[VexRiscv]{
SRC1_CTRL -> Src1CtrlEnum.FOUR,
SRC2_CTRL -> Src2CtrlEnum.PC,
SRC_USE_SUB_LESS -> False,
REGFILE_WRITE_VALID -> True,
SRC2_USE -> True
REGFILE_WRITE_VALID -> True
)
decoderService.addDefault(BRANCH_CTRL, BranchCtrlEnum.INC)
decoderService.add(List(
JAL -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL)),
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR)),
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR, REG1_USE -> True)),
BEQ -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
BNE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
BLT -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
@ -388,7 +390,7 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo
arbitration.isValid := True
//PC calculation without Jump
val pc = Reg(UInt(pcWidth bits)) init(resetVector)
val pc = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public")
when(arbitration.isValid && !arbitration.isStuck){
val pcPlus4 = pc + 4
if(fastFetchCmdPcCalculation) pcPlus4.addAttribute("keep") //Disallow to use the carry in as enable
@ -480,7 +482,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
MEMORY_ENABLE -> True,
SRC1_USE -> True
REG1_USE -> True
)
decoderService.addDefault(MEMORY_ENABLE, False)
@ -491,9 +493,9 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
LBU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LHU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LWU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
SB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)),
SH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)),
SW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True))
SB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)),
SH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)),
SW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True))
))
}
@ -646,7 +648,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
import pipeline.config._
val global = pipeline plug new Area{
val regFile = Mem(Bits(32 bits),32)
val regFile = Mem(Bits(32 bits),32) addAttribute("verilator public")
}
decode plug new Area{
@ -745,7 +747,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
SRC1_USE -> True
REG1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
@ -755,11 +757,11 @@ class IntAluPlugin extends Plugin[VexRiscv]{
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
SRC1_USE -> True,
SRC2_USE -> True
REG1_USE -> True,
REG2_USE -> True
)
val otherAction = List(
val otherAction = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
@ -790,7 +792,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
))
decoderService.add(List(
LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.SRC1)),
LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.SRC1, SRC1_CTRL -> Src1CtrlEnum.IMU)),
AUIPC -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC2_CTRL -> Src2CtrlEnum.PC))
))
}
@ -837,7 +839,8 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
@ -846,7 +849,9 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True,
REG2_USE -> True
)
val decoderService = pipeline.service(classOf[DecoderService])
@ -900,7 +905,7 @@ object TopLevel {
)
config.plugins ++= List(
new PcManagerSimplePlugin(0, true),
new PcManagerSimplePlugin(0, false),
new IBusSimplePlugin,
new DecoderSimplePlugin,
new RegFilePlugin(SYNC),
@ -915,6 +920,8 @@ object TopLevel {
val toplevel = new VexRiscv(config)
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)

View File

@ -9,7 +9,32 @@
#include <cstring>
#include <string.h>
uint8_t memory[1024 * 1024];
class Memory{
public:
uint8_t* mem[1 << 12];
Memory(){
for(uint32_t i = 0;i < (1 << 12);i++) mem[i] = NULL;
}
~Memory(){
for(uint32_t i = 0;i < (1 << 12);i++) if(mem[i]) delete mem[i];
}
uint8_t* get(uint32_t address){
if(mem[address >> 20] == NULL) mem[address >> 20] = new uint8_t[1024*1024];
return &mem[address >> 20][address & 0xFFFFF];
}
uint8_t& operator [](uint32_t address) {
return *get(address);
}
/*T operator [](uint32_t address) const {
return get(address);
}*/
};
//uint8_t memory[1024 * 1024];
uint32_t hti(char c) {
if (c >= 'A' && c <= 'F')
@ -27,7 +52,7 @@ uint32_t hToI(char *c, uint32_t size) {
return value;
}
void loadHexImpl(string path) {
void loadHexImpl(string path,Memory* mem) {
FILE *fp = fopen(&path[0], "r");
fseek(fp, 0, SEEK_END);
uint32_t size = ftell(fp);
@ -46,7 +71,7 @@ void loadHexImpl(string path) {
switch (key) {
case 0:
for (uint32_t i = 0; i < byteCount; i++) {
memory[nextAddr + i] = hToI(line + 9 + i * 2, 2);
*(mem->get(nextAddr + i)) = hToI(line + 9 + i * 2, 2);
//printf("%x %x %c%c\n",nextAddr + i,hToI(line + 9 + i*2,2),line[9 + i * 2],line[9 + i * 2+1]);
}
break;
@ -88,7 +113,6 @@ uint32_t regFileWriteRefArray[][2] = {
#define assertEq(x,ref) if(x != ref) {\
printf("\n*** %s is %d but should be %d ***\n\n",TEXTIFY(x),x,ref);\
error = 1; \
throw std::exception();\
}
@ -97,14 +121,12 @@ class success : public std::exception { };
class Workspace{
public:
Memory mem;
string name;
VVexRiscv* top;
int i;
int error;
Workspace(string name){
error = 0;
this->name = name;
top = new VVexRiscv;
}
@ -114,15 +136,17 @@ public:
}
Workspace* loadHex(string path){
loadHexImpl(path);
loadHexImpl(path,&mem);
return this;
}
virtual void postReset() {}
virtual void checks(){}
void pass(){ throw success();}
void fail(){ throw std::exception();}
Workspace* run(uint32_t timeout = 1000){
cout << "Start " << name << endl;
Workspace* run(uint32_t timeout = 5000){
// cout << "Start " << name << endl;
// init trace dump
Verilated::traceEverOn(true);
@ -142,6 +166,7 @@ public:
top->reset = 0;
top->eval();
postReset();
try {
// run simulation for 100 clock periods
@ -151,8 +176,11 @@ public:
if (top->iCmd_valid) {
assertEq(top->iCmd_payload_pc & 3,0);
//printf("%d\n",top->iCmd_payload_pc);
uint8_t* ptr = memory + top->iCmd_payload_pc;
iRsp_inst_next = (ptr[0] << 0) | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
iRsp_inst_next = (mem[top->iCmd_payload_pc + 0] << 0)
| (mem[top->iCmd_payload_pc + 1] << 8)
| (mem[top->iCmd_payload_pc + 2] << 16)
| (mem[top->iCmd_payload_pc + 3] << 24);
}
checks();
@ -172,10 +200,12 @@ public:
if (Verilated::gotFinish())
exit(0);
}
cout << "timeout" << endl;
fail();
} catch (const success e) {
printf("SUCCESS\n");
cout <<"SUCCESS " << name << endl;
} catch (const std::exception& e) {
std::cout << e.what();
cout << "FAIL " << name << endl;
}
@ -213,53 +243,68 @@ public:
loadHex("../../resources/hex/" + name + ".hex");
}
virtual void checks(){
virtual void postReset() {
top->VexRiscv->prefetch_PcManagerSimplePlugin_pc = 0x800000bcu;
}
virtual void checks(){
if(top->VexRiscv->writeBack_arbitration_isValid == 1 && top->VexRiscv->writeBack_input_INSTRUCTION == 0x00000073){
uint32_t code = top->VexRiscv->RegFilePlugin_regFile[28];
if((code & 1) == 0){
cout << "Wrong error code"<< endl;
fail();
}
if(code == 1){
pass();
}else{
cout << "Error code " << code/2 << endl;
fail();
}
}
}
};
string riscvTestMain[] = {
"rv32ui-p-add.hex",
"rv32ui-p-addi.hex",
"rv32ui-p-and.hex",
"rv32ui-p-andi.hex",
"rv32ui-p-auipc.hex",
"rv32ui-p-beq.hex",
"rv32ui-p-bge.hex",
"rv32ui-p-bgeu.hex",
"rv32ui-p-blt.hex",
"rv32ui-p-bltu.hex",
"rv32ui-p-bne.hex",
"rv32ui-p-j.hex",
"rv32ui-p-jal.hex",
"rv32ui-p-jalr.hex",
"rv32ui-p-or.hex",
"rv32ui-p-ori.hex",
"rv32ui-p-simple.hex",
"rv32ui-p-sll.hex",
"rv32ui-p-slli.hex",
"rv32ui-p-slt.hex",
"rv32ui-p-slti.hex",
"rv32ui-p-sra.hex",
"rv32ui-p-srai.hex",
"rv32ui-p-srl.hex",
"rv32ui-p-srli.hex",
"rv32ui-p-sub.hex",
"rv32ui-p-xor.hex",
"rv32ui-p-xori.hex"
"rv32ui-p-simple",
"rv32ui-p-lui",
"rv32ui-p-auipc",
"rv32ui-p-jal",
"rv32ui-p-jalr",
"rv32ui-p-beq",
"rv32ui-p-bge",
"rv32ui-p-bgeu",
"rv32ui-p-blt",
"rv32ui-p-bltu",
"rv32ui-p-bne",
"rv32ui-p-add",
"rv32ui-p-addi",
"rv32ui-p-and",
"rv32ui-p-andi",
"rv32ui-p-or",
"rv32ui-p-ori",
"rv32ui-p-sll",
"rv32ui-p-slli",
"rv32ui-p-slt",
"rv32ui-p-slti",
"rv32ui-p-sra",
"rv32ui-p-srai",
"rv32ui-p-srl",
"rv32ui-p-srli",
"rv32ui-p-sub",
"rv32ui-p-xor",
"rv32ui-p-xori"
};
string riscvTestMemory[] = {
"rv32ui-p-lb.hex",
"rv32ui-p-lbu.hex",
"rv32ui-p-lh.hex",
"rv32ui-p-lhu.hex",
"rv32ui-p-lui.hex",
"rv32ui-p-lw.hex",
"rv32ui-p-sb.hex",
"rv32ui-p-sh.hex",
"rv32ui-p-sw.hex"
"rv32ui-p-lb",
"rv32ui-p-lbu",
"rv32ui-p-lh",
"rv32ui-p-lhu",
"rv32ui-p-lw",
"rv32ui-p-sb",
"rv32ui-p-sh",
"rv32ui-p-sw"
};

View File

@ -1,57 +1,39 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Sun Mar 12 18:21:04 2017
[*] Tue Mar 14 18:15:03 2017
[*]
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/sim.vcd"
[dumpfile_mtime] "Sun Mar 12 18:18:56 2017"
[dumpfile_size] 105148
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-jalr.vcd"
[dumpfile_mtime] "Tue Mar 14 18:13:30 2017"
[dumpfile_size] 7129488
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/yolo.gtkw"
[timestart] 156
[timestart] 0
[size] 1776 953
[pos] -1 -1
*-4.022038 200 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[pos] -1 -353
*-4.722985 26 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] TOP.
[sst_width] 487
[sst_width] 418
[signals_width] 559
[sst_expanded] 1
[sst_vpaned_height] 279
@28
TOP.VexRiscv.decode_BRANCH_CTRL[1:0]
TOP.VexRiscv.execute_BRANCH_SOLVED[1:0]
TOP.VexRiscv.execute_input_BRANCH_CTRL[1:0]
TOP.VexRiscv.execute_input_BRANCH_SOLVED[1:0]
TOP.VexRiscv.decode_arbitration_isValid
TOP.VexRiscv.decode_arbitration_isStuck
TOP.clk
TOP.iCmd_valid
@22
TOP.VexRiscv.decode_input_INSTRUCTION[31:0]
TOP.VexRiscv.decode_input_PC[31:0]
TOP.VexRiscv.iCmd_payload_pc[31:0]
TOP.iCmd_payload_pc[31:0]
@28
TOP.VexRiscv.iCmd_ready
TOP.VexRiscv.iCmd_valid
TOP.iCmd_ready
@22
TOP.VexRiscv.iRsp_inst[31:0]
TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[31:0]
TOP.iRsp_inst[31:0]
@28
TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid
TOP.VexRiscv.prefetch_arbitration_isValid
TOP.VexRiscv.fetch_arbitration_isValid
TOP.VexRiscv.decode_arbitration_isValid
TOP.VexRiscv.execute_arbitration_isValid
TOP.VexRiscv.memory_arbitration_isValid
TOP.VexRiscv.writeBack_arbitration_isValid
TOP.VexRiscv.prefetch_arbitration_removeIt
TOP.VexRiscv.fetch_arbitration_removeIt
TOP.VexRiscv.decode_arbitration_removeIt
TOP.VexRiscv.execute_arbitration_removeIt
TOP.VexRiscv.memory_arbitration_removeIt
TOP.VexRiscv.writeBack_arbitration_removeIt
TOP.reset
@29
TOP.VexRiscv.writeBack_arbitration_isValid
@22
TOP.VexRiscv.writeBack_input_PC[31:0]
@28
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid
@22
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0]
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0]
@28
TOP.VexRiscv.clk
[pattern_trace] 1
[pattern_trace] 0