Pass verilator simple literal, add, jump
This commit is contained in:
parent
ec4837a744
commit
9fc82c9736
|
@ -34,4 +34,5 @@ bin/
|
|||
*.json
|
||||
*.vcd
|
||||
!tester/src/test/resources/*.vhd
|
||||
obj_dir
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include "VVexRiscv.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
int i;
|
||||
int clk;
|
||||
printf("start\n");
|
||||
Verilated::commandArgs(argc, argv);
|
||||
// init top verilog instance
|
||||
VVexRiscv* top = new VVexRiscv;
|
||||
|
@ -34,5 +35,6 @@ int main(int argc, char **argv, char **env) {
|
|||
if (Verilated::gotFinish()) exit(0);
|
||||
}
|
||||
tfp->close();
|
||||
printf("done\n");
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -107,8 +107,11 @@ trait Pipeline {
|
|||
val stageBefore = stages(stageIndex - 1)
|
||||
val stage = stages(stageIndex)
|
||||
|
||||
when(!stageBefore.arbitration.isStuck) {
|
||||
stage.arbitration.isValid := stage.arbitration.isValid && !stage.arbitration.removeIt
|
||||
when(!stage.arbitration.isStuck) {
|
||||
stage.arbitration.isValid := False
|
||||
}
|
||||
when(!stageBefore.arbitration.isStuck && !stageBefore.arbitration.removeIt) {
|
||||
stage.arbitration.isValid := stageBefore.arbitration.isValid
|
||||
}
|
||||
when(stage.arbitration.removeIt){
|
||||
stage.arbitration.isValid := False
|
||||
|
|
|
@ -44,7 +44,7 @@ class Stage() extends Area{
|
|||
// def apply[T <: Data](key : Stageable[T]) : T = ???
|
||||
|
||||
|
||||
val arbitration = new Bundle{
|
||||
val arbitration = new Area{
|
||||
val haltIt = False
|
||||
val removeIt = False
|
||||
val isValid = RegInit(False)
|
||||
|
|
|
@ -322,7 +322,7 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo
|
|||
}
|
||||
|
||||
//FetchService hardware implementation
|
||||
val jump = if(jumpInfos.length != 0) {
|
||||
val jump = if(jumpInfos.length != 0) new Area {
|
||||
val sortedByStage = jumpInfos.sortWith((a, b) => pipeline.indexOf(a.stage) > pipeline.indexOf(b.stage))
|
||||
val valids = sortedByStage.map(_.interface.valid)
|
||||
val pcs = sortedByStage.map(_.interface.payload)
|
||||
|
@ -360,11 +360,11 @@ class IBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
iCmd = master(Stream(IBusSimpleCmd()))
|
||||
iCmd = master(Stream(IBusSimpleCmd())).setName("iCmd")
|
||||
iCmd.valid := prefetch.arbitration.isFiring
|
||||
iCmd.pc := prefetch.output(PC)
|
||||
|
||||
iRsp = in(IBusSimpleRsp())
|
||||
iRsp = in(IBusSimpleRsp()).setName("iRsp")
|
||||
fetch.insert(INSTRUCTION) := iRsp.inst
|
||||
}
|
||||
}
|
||||
|
@ -431,7 +431,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
execute plug new Area{
|
||||
import execute._
|
||||
|
||||
dCmd = master Stream(DBusSimpleCmd())
|
||||
dCmd = master(Stream(DBusSimpleCmd())).setName("dCmd")
|
||||
dCmd.valid := input(MEMORY_ENABLE) && arbitration.isFiring
|
||||
dCmd.wr := input(INSTRUCTION)(5)
|
||||
dCmd.address := input(SRC_ADD_SUB).asUInt
|
||||
|
@ -440,12 +440,14 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
when(input(MEMORY_ENABLE) && !dCmd.ready){
|
||||
arbitration.haltIt := True
|
||||
}
|
||||
|
||||
dCmd.elements
|
||||
}
|
||||
|
||||
memory plug new Area {
|
||||
import memory._
|
||||
|
||||
dRsp = in(DBusSimpleRsp())
|
||||
dRsp = in(DBusSimpleRsp()).setName("dRsp")
|
||||
insert(MEMORY_READ_DATA) := dRsp.data
|
||||
assert(!(input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
|
||||
}
|
||||
|
@ -453,7 +455,6 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
writeBack plug new Area {
|
||||
import memory._
|
||||
|
||||
dRsp = in(DBusSimpleRsp())
|
||||
val rspFormated = input(INSTRUCTION)(13 downto 12).mux(
|
||||
default -> input(MEMORY_READ_DATA), //W
|
||||
1 -> B((31 downto 8) -> (input(MEMORY_READ_DATA)(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> input(MEMORY_READ_DATA)(7 downto 0)),
|
||||
|
@ -593,7 +594,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
|
|||
writeBack plug new Area {
|
||||
import writeBack._
|
||||
|
||||
val regFileWrite = global.regFile.writePort
|
||||
val regFileWrite = global.regFile.writePort.addAttribute("verilator public")
|
||||
regFileWrite.valid := input(REGFILE_WRITE_VALID) && arbitration.isFiring
|
||||
regFileWrite.address := input(INSTRUCTION)(rdRange).asUInt
|
||||
regFileWrite.data := input(REGFILE_WRITE_DATA)
|
||||
|
@ -686,6 +687,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
|||
|
||||
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
decoderService.addDefault(REGFILE_WRITE_VALID,False)
|
||||
decoderService.add(List(
|
||||
ADD -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
|
||||
SUB -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> True)),
|
||||
|
@ -806,11 +808,11 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
|
|||
}
|
||||
}
|
||||
|
||||
class OutputAluResult extends Plugin[VexRiscv]{
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
out(pipeline.writeBack.input(pipeline.config.REGFILE_WRITE_DATA))
|
||||
}
|
||||
}
|
||||
//class OutputAluResult extends Plugin[VexRiscv]{
|
||||
// override def build(pipeline: VexRiscv): Unit = {
|
||||
// out(pipeline.writeBack.input(pipeline.config.REGFILE_WRITE_DATA))
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
object TopLevel {
|
||||
|
@ -829,13 +831,19 @@ object TopLevel {
|
|||
new SrcPlugin,
|
||||
new FullBarrielShifterPlugin,
|
||||
new DBusSimplePlugin,
|
||||
new HazardSimplePlugin(true,true,true,true),
|
||||
// new HazardSimplePlugin(false,false,false,false),
|
||||
new NoPredictionBranchPlugin,
|
||||
new OutputAluResult
|
||||
// new HazardSimplePlugin(true,true,true,true),
|
||||
new HazardSimplePlugin(false,false,false,false),
|
||||
new NoPredictionBranchPlugin
|
||||
// new OutputAluResult
|
||||
)
|
||||
|
||||
new VexRiscv(config)
|
||||
val toplevel = new VexRiscv(config)
|
||||
|
||||
// val iBus = toplevel.service(classOf[IBusSimplePlugin])
|
||||
// val dBus = toplevel.service(classOf[DBusSimplePlugin])
|
||||
|
||||
|
||||
toplevel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
#include "VVexRiscv.h"
|
||||
#include "VVexRiscv_VexRiscv.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t memory[1024 * 1024];
|
||||
|
||||
uint32_t hti(char c) {
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return c - '0';
|
||||
}
|
||||
|
||||
uint32_t hToI(char *c, uint32_t size) {
|
||||
uint32_t value = 0;
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
value += hti(c[i]) << ((size - i - 1) * 4);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void loadHex(const char* path) {
|
||||
FILE *fp = fopen(path, "r");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* content = new char[size];
|
||||
fread(content, 1, size, fp);
|
||||
|
||||
int offset = 0;
|
||||
char* line = content;
|
||||
while (1) {
|
||||
if (line[0] == ':') {
|
||||
uint32_t byteCount = hToI(line + 1, 2);
|
||||
uint32_t nextAddr = hToI(line + 3, 4) + offset;
|
||||
uint32_t key = hToI(line + 7, 2);
|
||||
//printf("%d %d %d\n", byteCount, nextAddr,key);
|
||||
switch (key) {
|
||||
case 0:
|
||||
for (uint32_t i = 0; i < byteCount; i++) {
|
||||
memory[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;
|
||||
case 2:
|
||||
offset = hToI(line + 9, 4) << 4;
|
||||
break;
|
||||
case 4:
|
||||
offset = hToI(line + 9, 4) << 16;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
while (*line != '\n' && size != 0) {
|
||||
line++;
|
||||
size--;
|
||||
}
|
||||
if (size <= 1)
|
||||
break;
|
||||
line++;
|
||||
size--;
|
||||
}
|
||||
|
||||
delete content;
|
||||
}
|
||||
|
||||
|
||||
#define testA1ReagFileWriteRef {1,10},{2,20},{3,40},{4,60}
|
||||
#define testA2ReagFileWriteRef {5,1},{7,3}
|
||||
uint32_t regFileWriteRefIndex = 0;
|
||||
uint32_t regFileWriteRefArray[][2] = {
|
||||
testA1ReagFileWriteRef,
|
||||
testA1ReagFileWriteRef,
|
||||
testA2ReagFileWriteRef,
|
||||
testA2ReagFileWriteRef
|
||||
};
|
||||
|
||||
#define TEXTIFY(A) #A
|
||||
|
||||
#define assertEq(x,ref) if(x != ref) {\
|
||||
printf("\n*** %s is %d but should be %d ***\n\n",TEXTIFY(x),x,ref);\
|
||||
error = 1;\
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
int i;
|
||||
int clk;
|
||||
int error = 0;
|
||||
printf("start\n");
|
||||
loadHex("testA.hex");
|
||||
Verilated::commandArgs(argc, argv);
|
||||
// init top verilog instance
|
||||
VVexRiscv* top = new VVexRiscv;
|
||||
// init trace dump
|
||||
Verilated::traceEverOn(true);
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp, 99);
|
||||
tfp->open("sim.vcd");
|
||||
|
||||
// Reset
|
||||
top->clk = 1;
|
||||
top->reset = 1;
|
||||
top->iCmd_ready = 1;
|
||||
top->dCmd_ready = 1;
|
||||
for (uint32_t i = 0; i < 16; i++) {
|
||||
tfp->dump(i);
|
||||
top->eval();
|
||||
}
|
||||
top->reset = 0;
|
||||
|
||||
// run simulation for 100 clock periods
|
||||
for (i = 16; i < 600; i+=2) {
|
||||
|
||||
uint32_t iRsp_inst_next = top->iRsp_inst;
|
||||
if (top->iCmd_valid) {
|
||||
assert((top->iCmd_payload_pc & 3) == 0);
|
||||
uint8_t* ptr = memory + top->iCmd_payload_pc;
|
||||
iRsp_inst_next = (ptr[0] << 0) | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
|
||||
}
|
||||
|
||||
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
|
||||
assertEq(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address, regFileWriteRefArray[regFileWriteRefIndex][0]);
|
||||
assertEq(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data, regFileWriteRefArray[regFileWriteRefIndex][1]);
|
||||
printf("%d\n",i);
|
||||
|
||||
regFileWriteRefIndex++;
|
||||
if(regFileWriteRefIndex == sizeof(regFileWriteRefArray)/sizeof(regFileWriteRefArray[0])){
|
||||
tfp->dump(i);
|
||||
tfp->dump(i+1);
|
||||
printf("SUCCESS\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(error) {
|
||||
tfp->dump(i);
|
||||
tfp->dump(i+1);
|
||||
break;
|
||||
}
|
||||
// dump variables into VCD file and toggle clock
|
||||
for (clk = 0; clk < 2; clk++) {
|
||||
tfp->dump(i+ clk);
|
||||
top->clk = !top->clk;
|
||||
|
||||
top->eval();
|
||||
}
|
||||
|
||||
top->iRsp_inst = iRsp_inst_next;
|
||||
|
||||
if (Verilated::gotFinish())
|
||||
exit(0);
|
||||
}
|
||||
|
||||
tfp->close();
|
||||
printf("done\n");
|
||||
exit(0);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
run: compile
|
||||
./obj_dir/VVexRiscv
|
||||
|
||||
verilate:
|
||||
verilator -cc ../../../../VexRiscv.v --trace -Wno-WIDTH --exe main.cpp
|
||||
|
||||
compile: verilate
|
||||
make -j -C obj_dir/ -f VVexRiscv.mk VVexRiscv
|
||||
|
||||
clean:
|
||||
rm -rf obj_dir
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
:1000000013000000130000001300000013000000A4
|
||||
:100010001300000013000000130000009300A00074
|
||||
:100020001300000013000000130000001300000084
|
||||
:100030001300000013000000130000001301400132
|
||||
:100040001300000013000000130000001300000064
|
||||
:100050001300000013000000130000009381E00172
|
||||
:100060001300000013000000130000001300000044
|
||||
:100070001300000013000000130000003382210071
|
||||
:100080001300000013000000130000001300000024
|
||||
:100090001300000013000000130000009300A000F4
|
||||
:1000A000130140019381E00133822100130000001D
|
||||
:1000B00013000000130000001300000013000000F4
|
||||
:1000C00013000000130000001300000013000000E4
|
||||
:1000D00013000000130000001300000013000000D4
|
||||
:1000E00013000000130000001300000013000000C4
|
||||
:1000F00013000000130000001300000013000000B4
|
||||
:1001000013000000130000001300000013000000A3
|
||||
:100110001300000013000000130000009302100001
|
||||
:100120001300000013000000130000001300000083
|
||||
:100130001300000013000000130000006F00000413
|
||||
:100140001300000013000000130000001300000063
|
||||
:100150001300000013000000130000001303200030
|
||||
:100160001300000013000000130000001300000043
|
||||
:100170001300000013000000130000009303300080
|
||||
:100180001300000013000000130000001300000023
|
||||
:100190001300000013000000130000009302100081
|
||||
:0C01A0006F008000130320009303300068
|
||||
:0400000540000000B7
|
||||
:00000001FF
|
|
@ -0,0 +1,57 @@
|
|||
[*]
|
||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||
[*] Sun Mar 12 18:21:04 2017
|
||||
[*]
|
||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/sim.vcd"
|
||||
[dumpfile_mtime] "Sun Mar 12 18:18:56 2017"
|
||||
[dumpfile_size] 105148
|
||||
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/yolo.gtkw"
|
||||
[timestart] 156
|
||||
[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
|
||||
[treeopen] TOP.
|
||||
[sst_width] 487
|
||||
[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
|
||||
@22
|
||||
TOP.VexRiscv.decode_input_INSTRUCTION[31:0]
|
||||
TOP.VexRiscv.decode_input_PC[31:0]
|
||||
TOP.VexRiscv.iCmd_payload_pc[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.iCmd_ready
|
||||
TOP.VexRiscv.iCmd_valid
|
||||
@22
|
||||
TOP.VexRiscv.iRsp_inst[31:0]
|
||||
TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[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
|
||||
@29
|
||||
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
|
Loading…
Reference in New Issue