Fix halt arbitrations
This commit is contained in:
parent
11797fbb6e
commit
c6610ea454
|
@ -99,7 +99,8 @@ trait Pipeline {
|
||||||
|
|
||||||
//Arbitration
|
//Arbitration
|
||||||
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){
|
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){
|
||||||
stage.arbitration.isStuck := stages.takeRight(stages.length - stageIndex).map(_.arbitration.haltIt).reduce(_ || _)
|
stage.arbitration.isStuckByOthers := stages.takeRight(stages.length - stageIndex - 1).map(_.arbitration.haltIt).foldLeft(False)(_ || _)
|
||||||
|
stage.arbitration.isStuck := stage.arbitration.haltIt || stage.arbitration.isStuckByOthers
|
||||||
stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt
|
stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ class Stage() extends Area{
|
||||||
val removeIt = False
|
val removeIt = False
|
||||||
val isValid = RegInit(False)
|
val isValid = RegInit(False)
|
||||||
val isStuck = Bool
|
val isStuck = Bool
|
||||||
|
val isStuckByOthers = Bool
|
||||||
val isFiring = Bool
|
val isFiring = Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,7 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo
|
||||||
|
|
||||||
//PC calculation without Jump
|
//PC calculation without Jump
|
||||||
val pc = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public")
|
val pc = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public")
|
||||||
when(arbitration.isValid && !arbitration.isStuck){
|
when(arbitration.isFiring){
|
||||||
val pcPlus4 = pc + 4
|
val pcPlus4 = pc + 4
|
||||||
if(fastFetchCmdPcCalculation) pcPlus4.addAttribute("keep") //Disallow to use the carry in as enable
|
if(fastFetchCmdPcCalculation) pcPlus4.addAttribute("keep") //Disallow to use the carry in as enable
|
||||||
pc := pcPlus4
|
pc := pcPlus4
|
||||||
|
@ -410,7 +410,6 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo
|
||||||
//Register managments
|
//Register managments
|
||||||
when(pcLoad.valid) {
|
when(pcLoad.valid) {
|
||||||
pc := pcLoad.payload
|
pc := pcLoad.payload
|
||||||
arbitration.removeIt := True
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,8 +437,9 @@ class IBusSimplePlugin(interfaceKeepData : Boolean) extends Plugin[VexRiscv]{
|
||||||
|
|
||||||
require(interfaceKeepData)
|
require(interfaceKeepData)
|
||||||
iCmd = master(Stream(IBusSimpleCmd())).setName("iCmd")
|
iCmd = master(Stream(IBusSimpleCmd())).setName("iCmd")
|
||||||
iCmd.valid := prefetch.arbitration.isFiring
|
iCmd.valid := prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers
|
||||||
iCmd.pc := prefetch.output(PC)
|
iCmd.pc := prefetch.output(PC)
|
||||||
|
prefetch.arbitration.haltIt setWhen(!iCmd.ready)
|
||||||
|
|
||||||
iRsp = in(IBusSimpleRsp()).setName("iRsp")
|
iRsp = in(IBusSimpleRsp()).setName("iRsp")
|
||||||
fetch.insert(INSTRUCTION) := iRsp.inst
|
fetch.insert(INSTRUCTION) := iRsp.inst
|
||||||
|
@ -520,7 +520,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
||||||
import execute._
|
import execute._
|
||||||
|
|
||||||
dCmd = master(Stream(DBusSimpleCmd())).setName("dCmd")
|
dCmd = master(Stream(DBusSimpleCmd())).setName("dCmd")
|
||||||
dCmd.valid := input(MEMORY_ENABLE) && arbitration.isFiring
|
dCmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers
|
||||||
dCmd.wr := input(INSTRUCTION)(5)
|
dCmd.wr := input(INSTRUCTION)(5)
|
||||||
dCmd.address := input(SRC_ADD_SUB).asUInt
|
dCmd.address := input(SRC_ADD_SUB).asUInt
|
||||||
dCmd.size := input(INSTRUCTION)(13 downto 12).asUInt
|
dCmd.size := input(INSTRUCTION)(13 downto 12).asUInt
|
||||||
|
@ -529,7 +529,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
||||||
U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0),
|
U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0),
|
||||||
default -> input(REG2)(31 downto 0)
|
default -> input(REG2)(31 downto 0)
|
||||||
)
|
)
|
||||||
when(input(MEMORY_ENABLE) && !dCmd.ready){
|
when(arbitration.isValid && input(MEMORY_ENABLE) && !dCmd.ready){
|
||||||
arbitration.haltIt := True
|
arbitration.haltIt := True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
||||||
writeBack plug new Area {
|
writeBack plug new Area {
|
||||||
import writeBack._
|
import writeBack._
|
||||||
|
|
||||||
// val rspShifted = input(MEMORY_READ_DATA) //TODO uncoment it (combloop)
|
|
||||||
val rspShifted = MEMORY_READ_DATA()
|
val rspShifted = MEMORY_READ_DATA()
|
||||||
rspShifted := input(MEMORY_READ_DATA)
|
rspShifted := input(MEMORY_READ_DATA)
|
||||||
switch(input(MEMORY_ADDRESS_LOW)){
|
switch(input(MEMORY_ADDRESS_LOW)){
|
||||||
|
|
|
@ -99,15 +99,6 @@ void loadHexImpl(string path,Memory* mem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#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 TEXTIFY(A) #A
|
||||||
|
|
||||||
|
@ -118,6 +109,8 @@ uint32_t regFileWriteRefArray[][2] = {
|
||||||
|
|
||||||
class success : public std::exception { };
|
class success : public std::exception { };
|
||||||
|
|
||||||
|
uint32_t testsCounter = 0, successCounter = 0;
|
||||||
|
|
||||||
class Workspace{
|
class Workspace{
|
||||||
public:
|
public:
|
||||||
static uint32_t cycles;
|
static uint32_t cycles;
|
||||||
|
@ -127,6 +120,7 @@ public:
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Workspace(string name){
|
Workspace(string name){
|
||||||
|
testsCounter++;
|
||||||
this->name = name;
|
this->name = name;
|
||||||
top = new VVexRiscv;
|
top = new VVexRiscv;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +169,8 @@ public:
|
||||||
uint32_t iRsp_inst_next = top->iRsp_inst;
|
uint32_t iRsp_inst_next = top->iRsp_inst;
|
||||||
uint32_t dRsp_inst_next = VL_RANDOM_I(32);
|
uint32_t dRsp_inst_next = VL_RANDOM_I(32);
|
||||||
|
|
||||||
if (top->iCmd_valid) {
|
|
||||||
|
if (top->iCmd_valid && top->iCmd_ready) {
|
||||||
assertEq(top->iCmd_payload_pc & 3,0);
|
assertEq(top->iCmd_payload_pc & 3,0);
|
||||||
//printf("%d\n",top->iCmd_payload_pc);
|
//printf("%d\n",top->iCmd_payload_pc);
|
||||||
|
|
||||||
|
@ -185,7 +180,7 @@ public:
|
||||||
| (mem[top->iCmd_payload_pc + 3] << 24);
|
| (mem[top->iCmd_payload_pc + 3] << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top->dCmd_valid) {
|
if (top->dCmd_valid && top->dCmd_ready) {
|
||||||
// assertEq(top->iCmd_payload_pc & 3,0);
|
// assertEq(top->iCmd_payload_pc & 3,0);
|
||||||
//printf("%d\n",top->iCmd_payload_pc);
|
//printf("%d\n",top->iCmd_payload_pc);
|
||||||
|
|
||||||
|
@ -214,9 +209,14 @@ public:
|
||||||
top->clk = !top->clk;
|
top->clk = !top->clk;
|
||||||
|
|
||||||
top->eval();
|
top->eval();
|
||||||
|
if(top->clk == 0){
|
||||||
|
top->iCmd_ready = VL_RANDOM_I(1);
|
||||||
|
top->dCmd_ready = VL_RANDOM_I(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cycles += 1;
|
cycles += 1;
|
||||||
|
|
||||||
|
|
||||||
top->iRsp_inst = iRsp_inst_next;
|
top->iRsp_inst = iRsp_inst_next;
|
||||||
top->dRsp_data = dRsp_inst_next;
|
top->dRsp_data = dRsp_inst_next;
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ public:
|
||||||
fail();
|
fail();
|
||||||
} catch (const success e) {
|
} catch (const success e) {
|
||||||
cout <<"SUCCESS " << name << endl;
|
cout <<"SUCCESS " << name << endl;
|
||||||
|
successCounter++;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
cout << "FAIL " << name << endl;
|
cout << "FAIL " << name << endl;
|
||||||
}
|
}
|
||||||
|
@ -241,8 +242,21 @@ public:
|
||||||
};
|
};
|
||||||
uint32_t Workspace::cycles = 0;
|
uint32_t Workspace::cycles = 0;
|
||||||
|
|
||||||
|
#define testA1ReagFileWriteRef {1,10},{2,20},{3,40},{4,60}
|
||||||
|
#define testA2ReagFileWriteRef {5,1},{7,3}
|
||||||
|
uint32_t regFileWriteRefArray[][2] = {
|
||||||
|
testA1ReagFileWriteRef,
|
||||||
|
testA1ReagFileWriteRef,
|
||||||
|
testA2ReagFileWriteRef,
|
||||||
|
testA2ReagFileWriteRef
|
||||||
|
};
|
||||||
|
|
||||||
class TestA : public Workspace{
|
class TestA : public Workspace{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t regFileWriteRefIndex = 0;
|
||||||
|
|
||||||
TestA() : Workspace("testA") {
|
TestA() : Workspace("testA") {
|
||||||
loadHex("../../resources/hex/testA.hex");
|
loadHex("../../resources/hex/testA.hex");
|
||||||
}
|
}
|
||||||
|
@ -354,7 +368,7 @@ struct timespec timer_start(){
|
||||||
long timer_end(struct timespec start_time){
|
long timer_end(struct timespec start_time){
|
||||||
struct timespec end_time;
|
struct timespec end_time;
|
||||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);
|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);
|
||||||
long diffInNanos = end_time.tv_nsec - start_time.tv_nsec;
|
uint64_t diffInNanos = end_time.tv_sec*1e9 + end_time.tv_nsec - start_time.tv_sec*1e9 - start_time.tv_nsec;
|
||||||
return diffInNanos;
|
return diffInNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,17 +378,23 @@ int main(int argc, char **argv, char **env) {
|
||||||
printf("BOOT\n");
|
printf("BOOT\n");
|
||||||
timespec startedAt = timer_start();
|
timespec startedAt = timer_start();
|
||||||
|
|
||||||
TestA().run();
|
for(int idx = 0;idx < 2;idx++){
|
||||||
|
TestA().run();
|
||||||
for(const string &name : riscvTestMain){
|
for(const string &name : riscvTestMain){
|
||||||
RiscvTest(name).run();
|
RiscvTest(name).run();
|
||||||
}
|
}
|
||||||
for(const string &name : riscvTestMemory){
|
for(const string &name : riscvTestMemory){
|
||||||
RiscvTest(name).run();
|
RiscvTest(name).run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long duration = timer_end(startedAt);
|
uint64_t duration = timer_end(startedAt);
|
||||||
cout << "Had simulate " << Workspace::cycles << " clock cycles in " << duration*1e-9 << " s (" << Workspace::cycles / (duration*1e-9) << " Khz)" << endl;
|
cout << "Had simulate " << Workspace::cycles << " clock cycles in " << duration*1e-9 << " s (" << Workspace::cycles / (duration*1e-9) << " Khz)" << endl;
|
||||||
printf("exit\n");
|
if(successCounter == testsCounter)
|
||||||
|
cout << "Success " << successCounter << "/" << testsCounter << endl;
|
||||||
|
else
|
||||||
|
cout << "Failure " << testsCounter - successCounter << "/" << testsCounter << endl;
|
||||||
|
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ run: compile
|
||||||
./obj_dir/VVexRiscv
|
./obj_dir/VVexRiscv
|
||||||
|
|
||||||
verilate:
|
verilate:
|
||||||
verilator -cc ../../../../VexRiscv.v -O3 -CFLAGS -std=c++11 --gdbbt --trace -Wno-WIDTH --x-assign unique --exe main.cpp
|
verilator -cc ../../../../VexRiscv.v -O3 -CFLAGS -std=c++11 --gdbbt --trace -Wno-WIDTH --x-assign unique --exe main.cpp
|
||||||
|
|
||||||
compile: verilate
|
compile: verilate
|
||||||
make -j -C obj_dir/ -f VVexRiscv.mk VVexRiscv
|
make -j -C obj_dir/ -f VVexRiscv.mk VVexRiscv
|
||||||
|
|
Loading…
Reference in New Issue