npc,fix: bugs of new arch in cpu-tests
All checks were successful
Build npc tests / npc-build (flow) (push) Successful in 3m7s
Build npc tests / npc-build (flow-simlib) (push) Successful in 3m13s
Build abstract machine with nix / build-packages (nemu) (pull_request) Successful in 25s
Build abstract machine with nix / build-packages (nemu-lib) (pull_request) Successful in 19s
Build abstract machine with nix / build-packages (rv32Cross.abstract-machine) (pull_request) Successful in 7s
Build abstract machine with nix / build-packages (abstract-machine) (pull_request) Successful in 1m23s
All checks were successful
Build npc tests / npc-build (flow) (push) Successful in 3m7s
Build npc tests / npc-build (flow-simlib) (push) Successful in 3m13s
Build abstract machine with nix / build-packages (nemu) (pull_request) Successful in 25s
Build abstract machine with nix / build-packages (nemu-lib) (pull_request) Successful in 19s
Build abstract machine with nix / build-packages (rv32Cross.abstract-machine) (pull_request) Successful in 7s
Build abstract machine with nix / build-packages (abstract-machine) (pull_request) Successful in 1m23s
This commit is contained in:
parent
fd1aae7c33
commit
24aeabee4f
29 changed files with 1317 additions and 544 deletions
|
@ -5,7 +5,7 @@ jobs:
|
||||||
npc-build:
|
npc-build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
package: [ "flow", "flow-simlib"]
|
package: [ "flow", "flow-simlib" ]
|
||||||
runs-on: nix
|
runs-on: nix
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -6,3 +6,7 @@ difftest/
|
||||||
**/result
|
**/result
|
||||||
/.pre-commit-config.yaml
|
/.pre-commit-config.yaml
|
||||||
**/.vscode/
|
**/.vscode/
|
||||||
|
*.sock
|
||||||
|
logs/
|
||||||
|
**/.envrc
|
||||||
|
**/.gdbinit
|
||||||
|
|
16
flake.nix
16
flake.nix
|
@ -163,20 +163,22 @@
|
||||||
++ self.checks.${system}.pre-commit-check.enabledPackages;
|
++ self.checks.${system}.pre-commit-check.enabledPackages;
|
||||||
};
|
};
|
||||||
|
|
||||||
devShells.difftest = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
|
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
||||||
|
buildInputs = self.checks.${system}.pre-commit-check.enabledPackages;
|
||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
diffu.packages.${system}.default
|
diffu.packages.${system}.default
|
||||||
am-kernels.packages.${system}.rv32Cross.am-kernels-npc
|
am-kernels.packages.${system}.rv32Cross.am-kernels-npc
|
||||||
self.packages.${system}.nemu-lib
|
self.packages.${system}.nemu-lib
|
||||||
spike-diff.packages.${system}.default
|
spike-diff.packages.${system}.default
|
||||||
|
pkgs.gef
|
||||||
|
pkgs.gtkwave
|
||||||
];
|
];
|
||||||
|
|
||||||
DIFFU_IMAGES_PATH = "${am-kernels.packages.${system}.rv32Cross.am-kernels-npc}/share";
|
DIFFU_IMAGES_PATH = "${am-kernels.packages.${system}.rv32Cross.am-kernels-npc}";
|
||||||
};
|
NEMU_SO = "${self.packages.${system}.nemu-lib}/lib/riscv32-nemu-interpreter-so";
|
||||||
|
NPC_SO = "/home/xin/repo/ysyx-workbench/npc/build/csrc/Flow/libFlow.so";
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
|
||||||
buildInputs = self.checks.${system}.pre-commit-check.enabledPackages;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
2
npc/.gitignore
vendored
2
npc/.gitignore
vendored
|
@ -17,3 +17,5 @@ hs_err_pid*
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
||||||
*.vcd
|
*.vcd
|
||||||
|
*.gtkw
|
||||||
|
*.sock
|
||||||
|
|
29
npc/CMakePresets.json
Normal file
29
npc/CMakePresets.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"cmakeMinimumRequired": {
|
||||||
|
"major": 3,
|
||||||
|
"minor": 19,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"ENABLE_YSYX_GIT_TRACKER": "ON",
|
||||||
|
"BUILD_CHISEL_EMIT_TARGET": "ON",
|
||||||
|
"TOPMODULE": "Flow",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||||
|
"BUILD_USE_BLOOP": "ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"configurePreset": "default"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
ThisBuild / scalaVersion := "2.13.12"
|
ThisBuild / scalaVersion := "2.13.12"
|
||||||
ThisBuild / version := "0.1.0"
|
ThisBuild / version := "0.1.1"
|
||||||
|
|
||||||
val chiselVersion = "6.2.0"
|
val chiselVersion = "6.5.0"
|
||||||
val circeVersion = "0.14.1"
|
val circeVersion = "0.14.1"
|
||||||
|
|
||||||
lazy val root = (project in file("."))
|
lazy val root = (project in file("."))
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
sbt.version=1.9.9
|
sbt.version=1.10.1
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import "DPI-C" function int pmem_read(input int addr);
|
import "DPI-C" function int pmem_read(input int addr, input byte rmask);
|
||||||
import "DPI-C" function void pmem_write(input int waddr, input int wdata, input byte wmask);
|
import "DPI-C" function void pmem_write(input int waddr, input int wdata, input byte wmask);
|
||||||
|
|
||||||
module RamDpi (
|
module RamDpi (
|
||||||
|
@ -9,6 +9,7 @@ module RamDpi (
|
||||||
input [31:0] writeAddr,
|
input [31:0] writeAddr,
|
||||||
input [31:0] writeData,
|
input [31:0] writeData,
|
||||||
input [3:0] writeMask,
|
input [3:0] writeMask,
|
||||||
|
input [3:0] readMask,
|
||||||
input reg [31:0] readAddr,
|
input reg [31:0] readAddr,
|
||||||
output reg [31:0] readData,
|
output reg [31:0] readData,
|
||||||
input reg [31:0] pc,
|
input reg [31:0] pc,
|
||||||
|
@ -16,7 +17,7 @@ module RamDpi (
|
||||||
);
|
);
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
if (valid) begin // 有读写请求时
|
if (valid) begin // 有读写请求时
|
||||||
readData = pmem_read(readAddr);
|
readData = pmem_read(readAddr, { 4'h0, readMask });
|
||||||
if (writeEnable) begin // 有写请求时
|
if (writeEnable) begin // 有写请求时
|
||||||
pmem_write(writeAddr, writeData, { 4'h0, writeMask });
|
pmem_write(writeAddr, writeData, { 4'h0, writeMask });
|
||||||
end
|
end
|
||||||
|
@ -25,5 +26,5 @@ module RamDpi (
|
||||||
readData = 32'h80000000;
|
readData = 32'h80000000;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assign inst = pmem_read(pc);
|
assign inst = pmem_read(pc, 8'hF);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -94,7 +94,7 @@ class newALU(implicit p: Params) extends Module {
|
||||||
val b = Input(Vec(SrcBSelect.all.length, UInt(p.XLEN)))
|
val b = Input(Vec(SrcBSelect.all.length, UInt(p.XLEN)))
|
||||||
})
|
})
|
||||||
val out = IO(new Bundle {
|
val out = IO(new Bundle {
|
||||||
val eq = Output(Bool())
|
val isEqual = Output(Bool())
|
||||||
val result = Output(UInt(p.XLEN))
|
val result = Output(UInt(p.XLEN))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ class newALU(implicit p: Params) extends Module {
|
||||||
val sll = a << b(5, 0)
|
val sll = a << b(5, 0)
|
||||||
val srl = a >> b(5, 0)
|
val srl = a >> b(5, 0)
|
||||||
val sra = a.asSInt >> b(5, 0)
|
val sra = a.asSInt >> b(5, 0)
|
||||||
out.eq := a === b
|
out.isEqual := a === b
|
||||||
|
|
||||||
import OpSelect._
|
import OpSelect._
|
||||||
|
|
||||||
|
|
|
@ -16,38 +16,14 @@ import chisel3.util.experimental.decode.{decoder, TruthTable}
|
||||||
import flow.components.util._
|
import flow.components.util._
|
||||||
import flow.components.RV32Inst._
|
import flow.components.RV32Inst._
|
||||||
|
|
||||||
class RamControlInterface(addrWidth: Int) extends Bundle {
|
class RamDpi(implicit p: Params) extends BlackBox with HasBlackBoxResource {
|
||||||
val valid = Input(Bool())
|
val io = IO(new DpiRamInterface)
|
||||||
val writeMask = Input(UInt((addrWidth / 8).W))
|
|
||||||
val writeEnable = Input(Bool())
|
|
||||||
def ctrlBindPorts = {
|
|
||||||
valid :: writeMask :: writeEnable :: HNil
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Extends here might not be the best solution.
|
|
||||||
* We need a way to merge two bundles together
|
|
||||||
*/
|
|
||||||
class RamInterface[T <: Data](tpe: T, addrWidth: Int)
|
|
||||||
extends RamControlInterface(addrWidth) {
|
|
||||||
val clock = Input(Clock())
|
|
||||||
val reset = Input(Reset())
|
|
||||||
val writeAddr = Input(UInt(addrWidth.W))
|
|
||||||
val writeData = Input(tpe)
|
|
||||||
val readAddr = Input(UInt(addrWidth.W))
|
|
||||||
val readData = Output(tpe)
|
|
||||||
val pc = Input(UInt(addrWidth.W))
|
|
||||||
val inst = Output(tpe)
|
|
||||||
}
|
|
||||||
|
|
||||||
class RamDpi extends BlackBox with HasBlackBoxResource {
|
|
||||||
val io = IO((new RamInterface(UInt(32.W), 32)))
|
|
||||||
addResource("/RamDpi.v")
|
addResource("/RamDpi.v")
|
||||||
}
|
}
|
||||||
|
|
||||||
class DpiRamControlInterface(implicit p: Params) extends Bundle {
|
class DpiRamControlInterface(implicit p: Params) extends Bundle {
|
||||||
val valid = Input(Bool())
|
val valid = Input(Bool())
|
||||||
|
val readMask = Input(UInt((p.XLEN.get / 8).W))
|
||||||
val writeMask = Input(UInt((p.XLEN.get / 8).W))
|
val writeMask = Input(UInt((p.XLEN.get / 8).W))
|
||||||
val writeEnable = Input(Bool())
|
val writeEnable = Input(Bool())
|
||||||
}
|
}
|
||||||
|
@ -84,6 +60,15 @@ class RamController(implicit p: Params) extends Module {
|
||||||
BitPat.dontCare(out.writeMask.getWidth)
|
BitPat.dontCare(out.writeMask.getWidth)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val readMaskMapping = TruthTable(
|
||||||
|
Array(
|
||||||
|
lb -> BitPat("b0001"),
|
||||||
|
lh -> BitPat("b0011"),
|
||||||
|
lw -> BitPat("b1111")
|
||||||
|
),
|
||||||
|
BitPat.dontCare(out.readMask.getWidth)
|
||||||
|
)
|
||||||
|
|
||||||
private val writeEnableMapping = TruthTable(
|
private val writeEnableMapping = TruthTable(
|
||||||
Array(
|
Array(
|
||||||
sb -> BitPat("b1"),
|
sb -> BitPat("b1"),
|
||||||
|
@ -94,6 +79,7 @@ class RamController(implicit p: Params) extends Module {
|
||||||
)
|
)
|
||||||
|
|
||||||
out.valid := decoder(in.inst, validMapping)
|
out.valid := decoder(in.inst, validMapping)
|
||||||
out.writeEnable := decoder(in.inst, writeMaskMapping)
|
out.writeEnable := decoder(in.inst, writeEnableMapping)
|
||||||
out.writeMask := decoder(in.inst, writeMaskMapping)
|
out.writeMask := decoder(in.inst, writeMaskMapping)
|
||||||
|
out.readMask := decoder(in.inst, readMaskMapping)
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class newProgramCounter(implicit p: Params) extends Module {
|
||||||
val control = IO(newPcControlInterface())
|
val control = IO(newPcControlInterface())
|
||||||
import newPcControlInterface.SrcSelect._
|
import newPcControlInterface.SrcSelect._
|
||||||
val in = IO(new Bundle {
|
val in = IO(new Bundle {
|
||||||
val brAddr = Input(UInt(p.XLEN))
|
val brOffset = Input(UInt(p.XLEN))
|
||||||
val jAddr = Input(UInt(p.XLEN))
|
val jAddr = Input(UInt(p.XLEN))
|
||||||
})
|
})
|
||||||
val out = IO(Output(UInt(p.XLEN)))
|
val out = IO(Output(UInt(p.XLEN)))
|
||||||
|
@ -83,8 +83,8 @@ class newProgramCounter(implicit p: Params) extends Module {
|
||||||
private val npc = MuxLookup(control.srcSelect, 4.U)(
|
private val npc = MuxLookup(control.srcSelect, 4.U)(
|
||||||
Seq(
|
Seq(
|
||||||
pStatic -> (pcReg + 4.U),
|
pStatic -> (pcReg + 4.U),
|
||||||
pJmp -> in.brAddr,
|
pJmp -> in.jAddr,
|
||||||
pBR -> in.jAddr
|
pBR -> (pcReg + in.brOffset)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,6 @@ class RegisterFile[T <: Data](tpe: T, regCount: Int, numReadPorts: Int)
|
||||||
for (port <- 0 until numReadPorts) {
|
for (port <- 0 until numReadPorts) {
|
||||||
out.src(port) := regFile(in.rs(port).asUInt)
|
out.src(port) := regFile(in.rs(port).asUInt)
|
||||||
}
|
}
|
||||||
traceName(regFile)
|
|
||||||
dontTouch(regFile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class newRegisterFile(implicit p: Params) extends Module {
|
class newRegisterFile(implicit p: Params) extends Module {
|
||||||
|
@ -94,6 +92,8 @@ class newRegisterFile(implicit p: Params) extends Module {
|
||||||
|
|
||||||
out.src1 := regFile(in.rs1)
|
out.src1 := regFile(in.rs1)
|
||||||
out.src2 := regFile(in.rs2)
|
out.src2 := regFile(in.rs2)
|
||||||
|
traceName(regFile)
|
||||||
|
dontTouch(regFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegisterFileController(implicit p: Params) extends Module {
|
class RegisterFileController(implicit p: Params) extends Module {
|
||||||
|
@ -124,18 +124,20 @@ class RegisterFileController(implicit p: Params) extends Module {
|
||||||
// format: on
|
// format: on
|
||||||
|
|
||||||
private val writeSelectMapping = TruthTable(
|
private val writeSelectMapping = TruthTable(
|
||||||
memOutMapping ++ npcMapping,
|
aluOutMapping ++ memOutMapping ++ npcMapping,
|
||||||
BitPat.dontCare(out.writeSelect.getWidth)
|
BitPat.dontCare(out.writeSelect.getWidth)
|
||||||
)
|
)
|
||||||
|
|
||||||
// enable write if instruction belongs to any mapping above
|
// enable write if instruction belongs to any mapping above
|
||||||
private val writeEnableMapping = TruthTable(
|
private val writeEnableMapping = TruthTable(
|
||||||
(aluOutMapping ++ memOutMapping ++ npcMapping).map(x =>
|
(aluOutMapping ++ memOutMapping ++ npcMapping).map(x =>
|
||||||
(x._1 -> BitPat(true.B))
|
(x._1 -> BitPat("b1"))
|
||||||
),
|
),
|
||||||
BitPat(false.B)
|
BitPat("b0")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
println(writeEnableMapping)
|
||||||
|
|
||||||
out.writeSelect := RegControl.WriteSelect
|
out.writeSelect := RegControl.WriteSelect
|
||||||
.safe(
|
.safe(
|
||||||
decoder(in.inst, writeSelectMapping)
|
decoder(in.inst, writeSelectMapping)
|
||||||
|
|
|
@ -34,31 +34,34 @@ class EX(implicit val p: Params) extends Module {
|
||||||
{
|
{
|
||||||
import flow.components.ALUControlInterface.SrcASelect._
|
import flow.components.ALUControlInterface.SrcASelect._
|
||||||
import flow.components.util.chiselEnumAsInt
|
import flow.components.util.chiselEnumAsInt
|
||||||
alu.in.a(aSrcARs1) := _in.inst.rs1
|
alu.in.a(aSrcARs1) := _in.src1
|
||||||
alu.in.a(aSrcAPc) := _in.pc
|
alu.in.a(aSrcAPc) := _in.pc
|
||||||
alu.in.a(aSrcAZero) := 0.U
|
alu.in.a(aSrcAZero) := 0.U
|
||||||
|
|
||||||
import flow.components.ALUControlInterface.SrcBSelect._
|
import flow.components.ALUControlInterface.SrcBSelect._
|
||||||
alu.in.b(aSrcBRs2) := _in.inst.rs2
|
alu.in.b(aSrcBRs2) := _in.src2
|
||||||
alu.in.b(aSrcBImmI) := _in.inst.immI
|
alu.in.b(aSrcBImmI) := _in.inst.immI
|
||||||
alu.in.b(aSrcBImmJ) := _in.inst.immJ
|
alu.in.b(aSrcBImmJ) := _in.inst.immJ
|
||||||
alu.in.b(aSrcBImmU) := _in.inst.immU
|
alu.in.b(aSrcBImmU) := _in.inst.immU
|
||||||
alu.in.b(aSrcBImmS) := _in.inst.immS
|
alu.in.b(aSrcBImmS) := _in.inst.immS
|
||||||
}
|
}
|
||||||
|
|
||||||
_out.exeEq := alu.out.result
|
_out.exeOut := alu.out.result
|
||||||
_out.exeOut := alu.out.eq
|
|
||||||
|
|
||||||
_toIF.jAddr := alu.out.result
|
_toIF.jAddr := alu.out.result
|
||||||
_toIF.brAddr := _in.inst.immB
|
_toIF.brOffset := _in.inst.immB
|
||||||
|
_toIF.pc := _in.pc
|
||||||
|
|
||||||
import flow.components.newPcControlInterface.SrcSelect._
|
import flow.components.newPcControlInterface.SrcSelect._
|
||||||
|
val regSrcEq = Wire(Bool());
|
||||||
|
regSrcEq := (_in.src1 === _in.src2);
|
||||||
when(_in.pcCtrl.srcSelect === pBR) {
|
when(_in.pcCtrl.srcSelect === pBR) {
|
||||||
val branchUseSlt = _in.inst(14)
|
val branchUseSlt = _in.inst(14)
|
||||||
val branchInvertResult = _in.inst(12)
|
val branchInvertResult = _in.inst(12)
|
||||||
val _branchResult = Mux(branchUseSlt, alu.out.result(0), alu.out.eq)
|
val _branchResult =
|
||||||
|
Mux(branchUseSlt, alu.out.result(0), regSrcEq)
|
||||||
val branchResult = Mux(branchInvertResult, !_branchResult, _branchResult)
|
val branchResult = Mux(branchInvertResult, !_branchResult, _branchResult)
|
||||||
_toIF.pcCtrl.srcSelect := Mux(branchInvertResult, pBR, pStatic)
|
_toIF.pcCtrl.srcSelect := Mux(branchResult, pBR, pStatic)
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
_toIF.pcCtrl.srcSelect := _in.pcCtrl.srcSelect
|
_toIF.pcCtrl.srcSelect := _in.pcCtrl.srcSelect
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import flow.stages.messages._
|
||||||
import flow.components._
|
import flow.components._
|
||||||
import flow.components.RV32InstSubfields._
|
import flow.components.RV32InstSubfields._
|
||||||
import chisel3.util.DecoupledIO
|
import chisel3.util.DecoupledIO
|
||||||
|
import chisel3.experimental.Trace._
|
||||||
|
import chisel3.util.experimental.InlineInstance
|
||||||
|
|
||||||
class ID(implicit val p: Params) extends Module {
|
class ID(implicit val p: Params) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
|
@ -25,7 +27,7 @@ class ID(implicit val p: Params) extends Module {
|
||||||
val _out = msgio.out.bits
|
val _out = msgio.out.bits
|
||||||
val _fromWB = io.fromWB
|
val _fromWB = io.fromWB
|
||||||
|
|
||||||
val regs = Module(new newRegisterFile)
|
val regs = Module(new newRegisterFile with InlineInstance)
|
||||||
|
|
||||||
// Controllers
|
// Controllers
|
||||||
val pcController = Module(new PcController)
|
val pcController = Module(new PcController)
|
||||||
|
|
|
@ -34,7 +34,7 @@ class IF(implicit val p: Params) extends Module {
|
||||||
private val pc = Module(new newProgramCounter)
|
private val pc = Module(new newProgramCounter)
|
||||||
|
|
||||||
// PC update
|
// PC update
|
||||||
pc.in.brAddr := _fromEx.brAddr
|
pc.in.brOffset := _fromEx.brOffset
|
||||||
pc.in.jAddr := _fromEx.jAddr
|
pc.in.jAddr := _fromEx.jAddr
|
||||||
|
|
||||||
pc.control := _fromEx.pcCtrl
|
pc.control := _fromEx.pcCtrl
|
||||||
|
|
|
@ -30,8 +30,10 @@ class LS(implicit val p: Params) extends Module {
|
||||||
ram.io.clock := clock
|
ram.io.clock := clock
|
||||||
ram.io.reset := reset
|
ram.io.reset := reset
|
||||||
ram.io.writeAddr := _in.exeOut
|
ram.io.writeAddr := _in.exeOut
|
||||||
ram.io.writeData := _in.src1
|
ram.io.writeData := _in.src2
|
||||||
ram.io.writeMask := _in.ramCtrl.writeMask
|
ram.io.writeMask := _in.ramCtrl.writeMask
|
||||||
|
ram.io.readMask := _in.ramCtrl.readMask
|
||||||
|
|
||||||
ram.io.writeEnable := _in.ramCtrl.writeEnable
|
ram.io.writeEnable := _in.ramCtrl.writeEnable
|
||||||
ram.io.valid := _in.ramCtrl.valid // TODO: change to a better name
|
ram.io.valid := _in.ramCtrl.valid // TODO: change to a better name
|
||||||
ram.io.readAddr := _in.exeOut
|
ram.io.readAddr := _in.exeOut
|
||||||
|
@ -39,7 +41,7 @@ class LS(implicit val p: Params) extends Module {
|
||||||
// TODO: Change to icache, and move to IF stage.
|
// TODO: Change to icache, and move to IF stage.
|
||||||
// Change to arbitor here
|
// Change to arbitor here
|
||||||
ram.io.pc := _fromIF.pc
|
ram.io.pc := _fromIF.pc
|
||||||
_toIF.inst := ram.io.pc
|
_toIF.inst := ram.io.inst
|
||||||
|
|
||||||
_out.memOut := ram.io.readData
|
_out.memOut := ram.io.readData
|
||||||
_out.exeOut := _in.exeOut
|
_out.exeOut := _in.exeOut
|
||||||
|
|
|
@ -30,7 +30,6 @@ class EX2LS(implicit p: Params) extends Bundle {
|
||||||
val src2 = UInt(p.XLEN)
|
val src2 = UInt(p.XLEN)
|
||||||
|
|
||||||
val exeOut = UInt(p.XLEN)
|
val exeOut = UInt(p.XLEN)
|
||||||
val exeEq = Bool()
|
|
||||||
|
|
||||||
// Control
|
// Control
|
||||||
val ramCtrl = Flipped(new DpiRamControlInterface)
|
val ramCtrl = Flipped(new DpiRamControlInterface)
|
||||||
|
@ -47,7 +46,8 @@ class LS2WB(implicit p: Params) extends Bundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
class EX2IF(implicit p: Params) extends Bundle {
|
class EX2IF(implicit p: Params) extends Bundle {
|
||||||
val brAddr = UInt(p.XLEN)
|
val pc = UInt(p.XLEN)
|
||||||
|
val brOffset = UInt(p.XLEN)
|
||||||
val jAddr = UInt(p.XLEN)
|
val jAddr = UInt(p.XLEN)
|
||||||
|
|
||||||
// Control
|
// Control
|
||||||
|
|
|
@ -6,6 +6,7 @@ import chisel3.util.DecoupledIO
|
||||||
import flow.Params
|
import flow.Params
|
||||||
import flow.stages.utils._
|
import flow.stages.utils._
|
||||||
import flow.stages.messages._
|
import flow.stages.messages._
|
||||||
|
import chisel3.experimental.Trace._
|
||||||
|
|
||||||
class WB(implicit val p: Params) extends Module {
|
class WB(implicit val p: Params) extends Module {
|
||||||
// val msgio = IO(DecoupledMsgIO(in = (new LS2WB).S))
|
// val msgio = IO(DecoupledMsgIO(in = (new LS2WB).S))
|
||||||
|
@ -25,4 +26,7 @@ class WB(implicit val p: Params) extends Module {
|
||||||
_toID.regCtrl := _in.regCtrl;
|
_toID.regCtrl := _in.regCtrl;
|
||||||
_toID.rd := _in.rd
|
_toID.rd := _in.rd
|
||||||
_toID.npc := _in.pc + 4.U
|
_toID.npc := _in.pc + 4.U
|
||||||
|
|
||||||
|
traceName(_in.pc)
|
||||||
|
traceName(_in.rd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import chisel3.util.{BinaryMemoryFile, HexMemoryFile}
|
||||||
import chisel3.experimental.Trace
|
import chisel3.experimental.Trace
|
||||||
import scala.collection.IndexedSeqView
|
import scala.collection.IndexedSeqView
|
||||||
import shapeless.Poly1
|
import shapeless.Poly1
|
||||||
import flow.components.RamControlInterface
|
import flow.components.DpiRamControlInterface
|
||||||
import flow.components.RV32Inst
|
import flow.components.RV32Inst
|
||||||
import flow.components.RV32InstSubfields._
|
import flow.components.RV32InstSubfields._
|
||||||
import flow.components.util._
|
import flow.components.util._
|
||||||
|
@ -21,6 +21,11 @@ import flow.components.util._
|
||||||
import flow.components.{RegControl, PcControlInterface, ALUControlInterface}
|
import flow.components.{RegControl, PcControlInterface, ALUControlInterface}
|
||||||
|
|
||||||
import flow.stages._
|
import flow.stages._
|
||||||
|
import chisel3.experimental.annotate
|
||||||
|
import chisel3.experimental.ChiselAnnotation
|
||||||
|
|
||||||
|
import chisel3.Data
|
||||||
|
import chisel3.experimental.{annotate, requireIsAnnotatable, ChiselAnnotation}
|
||||||
|
|
||||||
class Flow extends Module {
|
class Flow extends Module {
|
||||||
implicit val p: Params = new Params(XLEN = 32.W, arch = "single")
|
implicit val p: Params = new Params(XLEN = 32.W, arch = "single")
|
||||||
|
@ -40,448 +45,3 @@ class Flow extends Module {
|
||||||
LS.io.fromIF := IF.io.toRam
|
LS.io.fromIF := IF.io.toRam
|
||||||
ID.io.fromWB := WB.io.toID
|
ID.io.fromWB := WB.io.toID
|
||||||
}
|
}
|
||||||
|
|
||||||
// class Control(width: Int) extends RawModule {
|
|
||||||
// // Helpers
|
|
||||||
// class WrapList[T](vl: T) { type Type = T; val v = vl }
|
|
||||||
// object wrap extends Poly1 {
|
|
||||||
// implicit def default[A] = at[A](Right(_).withLeft[Int])
|
|
||||||
// }
|
|
||||||
// def lit(x: Element) = { x.litValue.toInt }
|
|
||||||
// def toBits(t: dst.Type): BitPat = {
|
|
||||||
// val list = t.toList
|
|
||||||
// list
|
|
||||||
// .map(e =>
|
|
||||||
// e match {
|
|
||||||
// case Right(x) => BitPat(lit(x).U(x.getWidth.W))
|
|
||||||
// case Left(x) => BitPat.dontCare(x)
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// .reduceLeft(_ ## _)
|
|
||||||
// }
|
|
||||||
// val r = Right
|
|
||||||
// def l[T <: Any](x: T) = x match {
|
|
||||||
// case x: ChiselEnum => Left(log2Ceil(x.all.length))
|
|
||||||
// case x: Data => Left(x.getWidth)
|
|
||||||
// case _ => throw new IllegalArgumentException
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// val inst = IO(Input(UInt(width.W)))
|
|
||||||
//
|
|
||||||
// val reg = IO(Flipped(RegControl()))
|
|
||||||
// val pc = IO(Flipped(PcControlInterface()))
|
|
||||||
// val alu = IO(Flipped(ALUControlInterface()))
|
|
||||||
// val ram = IO(Flipped(RamControlInterface(32)))
|
|
||||||
//
|
|
||||||
// val dst = new WrapList(
|
|
||||||
// (reg.ctrlBindPorts ++
|
|
||||||
// pc.ctrlBindPorts ++
|
|
||||||
// alu.ctrlBindPorts ++
|
|
||||||
// ram.ctrlBindPorts).map(wrap)
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val dstList = dst.v.toList
|
|
||||||
// val controlWidth = dstList.map(_.toOption.get.getWidth).reduce(_ + _)
|
|
||||||
// val reversePrefixSum = dstList.scanLeft(0)(_ + _.toOption.get.getWidth)
|
|
||||||
// val sliceIndex = reversePrefixSum.map(controlWidth - _)
|
|
||||||
// val slices = sliceIndex.map(_ - 1).zip(sliceIndex.tail)
|
|
||||||
//
|
|
||||||
// import reg.WriteSelect._
|
|
||||||
// import reg._
|
|
||||||
// import pc.SrcSelect._
|
|
||||||
// import pc._
|
|
||||||
// import alu.OpSelect._
|
|
||||||
// import alu.SrcASelect._
|
|
||||||
// import alu.SrcBSelect._
|
|
||||||
// import pc._
|
|
||||||
// import RV32Inst._
|
|
||||||
// // format: off
|
|
||||||
// val ControlMapping: Array[(BitPat, dst.Type)] = Array(
|
|
||||||
// // Regs | writeEnable :: writeSelect :: HNil
|
|
||||||
// // PC | useImmB :: srcSelect :: HNil
|
|
||||||
// // Exe | op :: srcASelect :: srcBSelect :: signExt :: HNil
|
|
||||||
// // Mem | valid :: writeMask :: writeEnable :: HNil
|
|
||||||
//
|
|
||||||
// (lui , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc)::
|
|
||||||
// r(aOpAdd) :: r(aSrcAZero) :: r(aSrcBImmU) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (auipc , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc)::
|
|
||||||
// r(aOpAdd) :: r(aSrcAPc) :: r(aSrcBImmU) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// // ---- Control Transfer Instructions ----
|
|
||||||
// (jal , (
|
|
||||||
// r(true.B) :: r(rNpc) ::
|
|
||||||
// r(false.B) :: r(pExeOut) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcAPc) :: r(aSrcBImmJ) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (jalr , (
|
|
||||||
// r(true.B) :: r(rNpc) ::
|
|
||||||
// r(false.B) :: r(pExeOut) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (beq , (
|
|
||||||
// r(false.B) :: l(WriteSelect) ::
|
|
||||||
// r(true.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (bne , (
|
|
||||||
// r(false.B) :: l(WriteSelect) ::
|
|
||||||
// r(true.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (blt , (
|
|
||||||
// r(false.B) :: l(WriteSelect) ::
|
|
||||||
// r(true.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(true.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (bge , (
|
|
||||||
// r(false.B) :: l(WriteSelect) ::
|
|
||||||
// r(true.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(true.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (bltu , (
|
|
||||||
// r(false.B) :: l(WriteSelect)::
|
|
||||||
// r(true.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (bgeu , (
|
|
||||||
// r(false.B) :: l(WriteSelect)::
|
|
||||||
// r(true.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// // ---- Memory Access Instructions ----
|
|
||||||
//
|
|
||||||
// (lb , (
|
|
||||||
// r(true.B) :: r(rMemOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(1.U(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (lbu , (
|
|
||||||
// r(true.B) :: r(rMemOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(0.U(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (lh , (
|
|
||||||
// r(true.B) :: r(rMemOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(3.U(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (lhu , (
|
|
||||||
// r(true.B) :: r(rMemOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(2.U(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (lw , (
|
|
||||||
// r(true.B) :: r(rMemOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(14.U(4.W)) :: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sb , (
|
|
||||||
// r(false.B) :: l(WriteSelect)::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmS) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(1.U(4.W)) :: r(true.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sh , (
|
|
||||||
// r(false.B) :: l(WriteSelect)::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmS) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(3.U(4.W)) :: r(true.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sw , (
|
|
||||||
// r(false.B) :: l(WriteSelect)::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmS) :: l(Bool()) ::
|
|
||||||
// r(true.B) :: r(15.U(4.W)) :: r(true.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// // ---- Integer Computational Instructions ---
|
|
||||||
//
|
|
||||||
// (addi , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (slti , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(true.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sltiu , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (xori , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpXor) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (ori , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpOr) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (andi , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAnd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (slli , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSll) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (srli , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSrl) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (srai , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSra) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (add , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sub , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSub) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sll , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSll) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (slt , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(true.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sltu , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (xor , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpXor) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (srl , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSrl) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (sra , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpSra) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (or , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpOr) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
//
|
|
||||||
// (and , (
|
|
||||||
// r(true.B) :: r(rAluOut) ::
|
|
||||||
// r(false.B) :: r(pStaticNpc) ::
|
|
||||||
// r(aOpAnd) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) ::
|
|
||||||
// r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil
|
|
||||||
// )),
|
|
||||||
// )
|
|
||||||
// // format: on
|
|
||||||
//
|
|
||||||
// val default = BitPat(0.U(controWidth.W))
|
|
||||||
//
|
|
||||||
// // println(s"ControlMapping = ${ControlMapping.map(it => (it._1 -> toBits(it._2))).foreach(x => println(x._2))}\n")
|
|
||||||
// val out = decoder(
|
|
||||||
// inst,
|
|
||||||
// TruthTable(ControlMapping.map(it => (it._1 -> toBits(it._2))), default)
|
|
||||||
// )
|
|
||||||
// val srcList = slices.map(s => out(s._1, s._2))
|
|
||||||
//
|
|
||||||
// assert(out != default)
|
|
||||||
// println(s"out = $out, default = $default\n")
|
|
||||||
// println(s"dstList = ${dstList}\n")
|
|
||||||
// println(s"srcList = ${srcList}\n")
|
|
||||||
// srcList
|
|
||||||
// .zip(dstList)
|
|
||||||
// .foreach({ case (src, dst) =>
|
|
||||||
// dst.toOption.get := src.asTypeOf(dst.toOption.get)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class Flow extends Module {
|
|
||||||
// def lit(x: Data) = { x.litValue.toInt }
|
|
||||||
//
|
|
||||||
// val dataType = UInt(32.W)
|
|
||||||
// val ram = Module(new RamDpi)
|
|
||||||
// val control = Module(new Control(32))
|
|
||||||
// val reg = Module(new RegisterFile(dataType, 32, 2))
|
|
||||||
// val pc = Module(new ProgramCounter(dataType))
|
|
||||||
// val alu = Module(new ALU(dataType))
|
|
||||||
//
|
|
||||||
// // TODO: Switch to Decoupled and Arbiter later
|
|
||||||
// ram.io.pc := pc.out
|
|
||||||
// val inst = ram.io.inst
|
|
||||||
//
|
|
||||||
// dontTouch(reg.control.writeEnable)
|
|
||||||
//
|
|
||||||
// import control.pc.SrcSelect._
|
|
||||||
//
|
|
||||||
// val npc = Wire(dataType)
|
|
||||||
// npc := pc.out + 4.U
|
|
||||||
// pc.in.exeOut := alu.out.result
|
|
||||||
// pc.in.immB := inst.immB
|
|
||||||
//
|
|
||||||
// control.inst := inst
|
|
||||||
// reg.control <> control.reg
|
|
||||||
// // FIXME: Probably optimizable with bulk connection
|
|
||||||
// pc.control <> control.pc
|
|
||||||
// pc.control.useImmB := control.pc.useImmB
|
|
||||||
// alu.control <> control.alu
|
|
||||||
// val branchUseSlt = Wire(Bool())
|
|
||||||
// val branchInvertResult = Wire(Bool())
|
|
||||||
// branchUseSlt := inst(14)
|
|
||||||
// branchInvertResult := inst(12)
|
|
||||||
// val _branchResult = Mux(branchUseSlt, alu.out.result(0), alu.out.eq)
|
|
||||||
// val branchResult = Mux(branchInvertResult, !_branchResult, _branchResult)
|
|
||||||
// pc.control.useImmB := control.pc.useImmB && branchResult
|
|
||||||
// // printf(cf"_branchResult = ${_branchResult}, branchResult = ${branchResult}\n")
|
|
||||||
// // printf(cf"pcin.useImmB = ${pc.control.useImmB}, control.out.useImmB = ${control.pc.useImmB} \n")
|
|
||||||
//
|
|
||||||
// import control.reg.WriteSelect._
|
|
||||||
// reg.in.writeData(rAluOut) := alu.out.result
|
|
||||||
// val maskedData = ram.io.readData & Cat(
|
|
||||||
// Fill(8, ram.io.writeMask(3)),
|
|
||||||
// Fill(8, ram.io.writeMask(2)),
|
|
||||||
// Fill(8, ram.io.writeMask(1)),
|
|
||||||
// "b11111111".U
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val doSignExt = control.ram.writeMask(0)
|
|
||||||
// val signExt16 = control.ram.writeMask(1)
|
|
||||||
// when(!doSignExt) {
|
|
||||||
// reg.in.writeData(rMemOut) := maskedData
|
|
||||||
// // printf(cf"!doSignExt\n")
|
|
||||||
// }.elsewhen(signExt16) {
|
|
||||||
// reg.in.writeData(rMemOut) := Cat(
|
|
||||||
// Fill(16, maskedData(15)),
|
|
||||||
// maskedData(15, 0)
|
|
||||||
// )
|
|
||||||
// // printf(cf"elsewhen\n")
|
|
||||||
// }.otherwise {
|
|
||||||
// reg.in
|
|
||||||
// .writeData(rMemOut) := Cat(Fill(24, maskedData(7)), maskedData(7, 0))
|
|
||||||
// // printf(cf"otherwise\n")
|
|
||||||
// }
|
|
||||||
// // printf(cf"maskedData = ${maskedData}, writeData = ${reg.in.writeData(lit(rMemOut))}\n")
|
|
||||||
// reg.in.writeData(rNpc) := npc
|
|
||||||
//
|
|
||||||
// reg.in.writeAddr := inst.rd
|
|
||||||
// reg.in.rs(0) := inst.rs1
|
|
||||||
// reg.in.rs(1) := inst.rs2
|
|
||||||
//
|
|
||||||
// // TODO: Bulk connection here
|
|
||||||
// ram.io.clock := clock
|
|
||||||
// ram.io.reset := reset
|
|
||||||
// ram.io.writeAddr := alu.out.result
|
|
||||||
// ram.io.writeData := reg.out.src(1)
|
|
||||||
// ram.io.writeMask := control.ram.writeMask
|
|
||||||
// ram.io.writeEnable := control.ram.writeEnable
|
|
||||||
// ram.io.valid := control.ram.valid
|
|
||||||
// ram.io.readAddr := alu.out.result
|
|
||||||
//
|
|
||||||
// import control.alu.SrcASelect._
|
|
||||||
// import control.alu.SrcBSelect._
|
|
||||||
// alu.in.a(aSrcARs1) := reg.out.src(0)
|
|
||||||
// alu.in.a(aSrcAPc) := pc.out
|
|
||||||
// alu.in.a(aSrcAZero) := 0.U
|
|
||||||
//
|
|
||||||
// alu.in.b(aSrcBRs2) := reg.out.src(1)
|
|
||||||
// // alu.in.b(lit(aSrcBImmI)) := inst(31, 20).pad(aSrcBImmI.getWidth)
|
|
||||||
// alu.in.b(aSrcBImmI) := inst.immI
|
|
||||||
// alu.in.b(aSrcBImmJ) := inst.immJ
|
|
||||||
// alu.in.b(aSrcBImmS) := inst.immS
|
|
||||||
// alu.in.b(aSrcBImmU) := inst.immU
|
|
||||||
//
|
|
||||||
// Trace.traceName(pc.out)
|
|
||||||
// dontTouch(control.out)
|
|
||||||
// }
|
|
||||||
|
|
|
@ -7,10 +7,10 @@ import chisel3.experimental.Trace._
|
||||||
import chisel3.stage.{ChiselGeneratorAnnotation, DesignAnnotation}
|
import chisel3.stage.{ChiselGeneratorAnnotation, DesignAnnotation}
|
||||||
import chisel3.util.experimental.InlineInstance
|
import chisel3.util.experimental.InlineInstance
|
||||||
import circt.stage.ChiselStage
|
import circt.stage.ChiselStage
|
||||||
import firrtl.annotations.TargetToken.{Instance, OfModule, Ref}
|
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import scala.io.Source
|
import scala.io.Source
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import firrtl.annotations.TargetToken.{OfModule, Instance, Ref}
|
||||||
|
|
||||||
// TODO: Generate verilator config file
|
// TODO: Generate verilator config file
|
||||||
|
|
||||||
|
|
|
@ -19,4 +19,4 @@ void Config::cli_parse(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Config config;
|
Config config{.wavefile = "flowwave.vcd"};
|
||||||
|
|
|
@ -7,6 +7,7 @@ extern "C" {
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <devices.hpp>
|
#include <devices.hpp>
|
||||||
|
#include <string>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <vl_wrapper.hpp>
|
#include <vl_wrapper.hpp>
|
||||||
#include <vpi_user.h>
|
#include <vpi_user.h>
|
||||||
|
@ -39,21 +40,19 @@ void *pmem_get() {
|
||||||
return pmem;
|
return pmem;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pmem_read(int raddr) {
|
int pmem_read(int raddr, int rmask) {
|
||||||
void *pmem = pmem_get();
|
void *pmem = pmem_get();
|
||||||
auto mem = static_cast<MMap *>(pmem);
|
auto mem = static_cast<MMap *>(pmem);
|
||||||
// TODO: Do memory difftest at memory read and write to diagnose at a finer
|
// TODO: Do memory difftest at memory read and write to diagnose at a finer
|
||||||
// granularity
|
// granularity
|
||||||
mem->trace(raddr, true, regs->get_pc());
|
|
||||||
if (g_skip_memcheck)
|
if (g_skip_memcheck)
|
||||||
return mem->read(PMEM_START);
|
return mem->read(PMEM_START, rmask);
|
||||||
return mem->read(raddr);
|
return mem->read(raddr, rmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pmem_write(int waddr, int wdata, char wmask) {
|
void pmem_write(int waddr, int wdata, char wmask) {
|
||||||
void *pmem = pmem_get();
|
void *pmem = pmem_get();
|
||||||
auto mem = static_cast<MMap *>(pmem);
|
auto mem = static_cast<MMap *>(pmem);
|
||||||
mem->trace((std::size_t)waddr, false, regs->get_pc(), wdata);
|
|
||||||
return mem->write((std::size_t)waddr, wdata, wmask);
|
return mem->write((std::size_t)waddr, wdata, wmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,13 +145,37 @@ void npc_init(void *args) {
|
||||||
DbgState *dbg = (DbgState *)args;
|
DbgState *dbg = (DbgState *)args;
|
||||||
void *mem = pmem_get();
|
void *mem = pmem_get();
|
||||||
dbg->bp = new std::vector<Breakpoint>;
|
dbg->bp = new std::vector<Breakpoint>;
|
||||||
|
dbg->cmd_return_buf = new std::string;
|
||||||
|
|
||||||
top = new VlModule;
|
top = new VlModule;
|
||||||
regs = new Registers("TOP.Flow.reg_0.regFile_", "TOP.Flow.pc.out");
|
regs = new Registers("TOP.Flow.ID.regs_regFile_",
|
||||||
|
"TOP.Flow.WB.msgio_in_bits_pc");
|
||||||
top->setup(config.wavefile, regs);
|
top->setup(config.wavefile, regs);
|
||||||
top->reset_eval(10);
|
top->reset_eval(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *npc_monitor(void *args, char **argv, int argc) {
|
||||||
|
DbgState *dbg = (DbgState *)args;
|
||||||
|
std::string *cmd_return_buf = dbg->cmd_return_buf;
|
||||||
|
|
||||||
|
if (strncmp(argv[0], "trace", 5) == 0) {
|
||||||
|
if (strncmp(argv[1], "on", 2) == 0) {
|
||||||
|
*cmd_return_buf = "Tracing turned on\n";
|
||||||
|
if (!top->start_trace())
|
||||||
|
*cmd_return_buf = "Failed to turn on tracing\n";
|
||||||
|
return cmd_return_buf->data();
|
||||||
|
} else if (strncmp(argv[1], "off", 3) == 0) {
|
||||||
|
*cmd_return_buf = "Tracing turned off\n";
|
||||||
|
if (!top->end_trace())
|
||||||
|
*cmd_return_buf = "Failed to turn on tracing\n";
|
||||||
|
return cmd_return_buf->data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*cmd_return_buf = "Command not found\n";
|
||||||
|
return cmd_return_buf->data();
|
||||||
|
}
|
||||||
|
|
||||||
bool npc_do_difftest = true;
|
bool npc_do_difftest = true;
|
||||||
|
|
||||||
static gdbstub_t gdbstub_priv;
|
static gdbstub_t gdbstub_priv;
|
||||||
|
|
1045
npc/flake.lock
1045
npc/flake.lock
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||||
nixpkgs-circt162.url = "github:NixOS/nixpkgs/7995cae3ad60e3d6931283d650d7f43d31aaa5c7";
|
nixpkgs-circt162.url = "github:NixOS/nixpkgs/7995cae3ad60e3d6931283d650d7f43d31aaa5c7";
|
||||||
nur-xin = {
|
nur-xin = {
|
||||||
url = "git+https://git.xinyang.life/xin/nur.git";
|
url = "git+https://git.xinyang.life/xin/nur.git";
|
||||||
|
@ -11,11 +12,18 @@
|
||||||
url = "github:zaninime/sbt-derivation";
|
url = "github:zaninime/sbt-derivation";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
am-kernels.url = "git+https://git.xinyang.life/xin/am-kernels.git?ref=dev";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, nur-xin, nixpkgs-circt162, sbt-derivation }:
|
outputs = { self, nixpkgs, nixpkgs-stable, flake-utils, nur-xin, nixpkgs-circt162, sbt-derivation, am-kernels }:
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
|
stablePkgs = import nixpkgs-stable {
|
||||||
|
inherit system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
overlays = [
|
||||||
|
];
|
||||||
|
};
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
|
@ -45,14 +53,15 @@
|
||||||
flex
|
flex
|
||||||
bison
|
bison
|
||||||
nvboard
|
nvboard
|
||||||
verilator
|
|
||||||
flow
|
flow
|
||||||
espresso
|
espresso
|
||||||
bloop
|
bloop
|
||||||
coursier
|
coursier
|
||||||
sbt
|
sbt
|
||||||
];
|
gef
|
||||||
|
] ++ [stablePkgs.verilator];
|
||||||
CHISEL_FIRTOOL_PATH = "${nixpkgs-circt162.legacyPackages.${system}.circt}/bin";
|
CHISEL_FIRTOOL_PATH = "${nixpkgs-circt162.legacyPackages.${system}.circt}/bin";
|
||||||
|
NPC_IMAGES_PATH = "${am-kernels.packages.${system}.rv32Cross.am-kernels-npc}/share";
|
||||||
|
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
cli11
|
cli11
|
||||||
|
|
|
@ -88,14 +88,18 @@ public:
|
||||||
ram->transfer(waddr, (uint8_t *)&wdata, len, true);
|
ram->transfer(waddr, (uint8_t *)&wdata, len, true);
|
||||||
} else if (devices->handle(waddr, (uint8_t *)&wdata, len, true)) {
|
} else if (devices->handle(waddr, (uint8_t *)&wdata, len, true)) {
|
||||||
}
|
}
|
||||||
|
logger->trace("[W] 0x{:x}: 0x{:x}", waddr, wdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
word_t read(paddr_t raddr) const {
|
word_t read(paddr_t raddr, int rmask) const {
|
||||||
word_t res = 0;
|
word_t res = 0;
|
||||||
|
size_t len = (rmask & 1) + ((rmask & 2) >> 1) + ((rmask & 4) >> 2) +
|
||||||
|
((rmask & 8) >> 3);
|
||||||
if (ram->in_pmem(raddr)) {
|
if (ram->in_pmem(raddr)) {
|
||||||
ram->transfer(raddr, (uint8_t *)&res, 4, false);
|
ram->transfer(raddr, (uint8_t *)&res, len, false);
|
||||||
} else if (devices->handle(raddr, (uint8_t *)&res, 4, false)) {
|
} else if (devices->handle(raddr, (uint8_t *)&res, 4, false)) {
|
||||||
}
|
}
|
||||||
|
logger->trace("[R] 0x{:x}: 0x{:x}", raddr, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +124,7 @@ public:
|
||||||
void *get_pmem() { return ram->mem.data(); }
|
void *get_pmem() { return ram->mem.data(); }
|
||||||
|
|
||||||
void trace(paddr_t addr, bool is_read, word_t pc = 0, word_t value = 0) {
|
void trace(paddr_t addr, bool is_read, word_t pc = 0, word_t value = 0) {
|
||||||
logger->trace("[{}] 0x{:x}", is_read ? 'R' : 'W', this->read(addr));
|
logger->trace("[{}] 0x{:x}", is_read ? 'R' : 'W', this->read(addr, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef _NPC_TYPES_H__
|
#ifndef _NPC_TYPES_H__
|
||||||
#define _NPC_TYPES_H__
|
#define _NPC_TYPES_H__
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include <gdbstub.h>
|
#include <gdbstub.h>
|
||||||
|
@ -32,6 +33,7 @@ struct Breakpoint {
|
||||||
|
|
||||||
struct DbgState {
|
struct DbgState {
|
||||||
std::vector<Breakpoint> *bp;
|
std::vector<Breakpoint> *bp;
|
||||||
|
std::string *cmd_return_buf;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ template <typename T, typename R> class VlModuleInterfaceCommon : public T {
|
||||||
uint64_t sim_time = 0;
|
uint64_t sim_time = 0;
|
||||||
uint64_t posedge_cnt = 0;
|
uint64_t posedge_cnt = 0;
|
||||||
std::unique_ptr<Tracer<T>> tracer;
|
std::unique_ptr<Tracer<T>> tracer;
|
||||||
|
std::filesystem::path wavefile;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const R *registers;
|
const R *registers;
|
||||||
|
@ -43,8 +44,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(std::filesystem::path wavefile, const R *r) {
|
void setup(std::filesystem::path wavefile, const R *r) {
|
||||||
if (!wavefile.empty())
|
wavefile = "wave.vcd";
|
||||||
tracer = std::make_unique<Tracer<T>>(this, wavefile);
|
|
||||||
registers = r;
|
registers = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +89,30 @@ public:
|
||||||
this->reset = 0;
|
this->reset = 0;
|
||||||
g_skip_memcheck = false;
|
g_skip_memcheck = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_posedge() {
|
bool is_posedge() {
|
||||||
// Will be posedge when eval is called
|
// Will be posedge when eval is called
|
||||||
return T::clock == 0;
|
return T::clock == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool start_trace() { return init_tracer(wavefile); }
|
||||||
|
|
||||||
|
bool end_trace() {
|
||||||
|
tracer.reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool init_tracer(std::filesystem::path wavefile) {
|
||||||
|
fmt::print("wavefile: {}", wavefile.string());
|
||||||
|
std::filesystem::path wav = "wave.vcd";
|
||||||
|
if (!wav.empty()) {
|
||||||
|
// Creating of tracer must happen after this class fully initialized
|
||||||
|
tracer = std::make_unique<Tracer<T>>(this, wav);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,18 +27,23 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static vpiHandle get_handle(const std::string name) {
|
||||||
|
vpiHandle hdl = vpi_handle_by_name((PLI_BYTE8 *)name.c_str(), nullptr);
|
||||||
|
if (hdl == nullptr) {
|
||||||
|
SPDLOG_ERROR("VPI Handle {} not found", name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
SPDLOG_INFO("Found VPI handle {} at {}", name, (void *)hdl);
|
||||||
|
}
|
||||||
|
return hdl;
|
||||||
|
}
|
||||||
|
|
||||||
void init_handlers(const std::string regs_prefix, const std::string pcname) {
|
void init_handlers(const std::string regs_prefix, const std::string pcname) {
|
||||||
|
pc_handle = get_handle(pcname);
|
||||||
for (int i = 0; i < nr; i++) {
|
for (int i = 0; i < nr; i++) {
|
||||||
std::string regname = regs_prefix + std::to_string(i);
|
std::string regname = regs_prefix + std::to_string(i);
|
||||||
vpiHandle vh = vpi_handle_by_name((PLI_BYTE8 *)regname.c_str(), nullptr);
|
reg_handles[i] = get_handle(regname);
|
||||||
if (vh == nullptr) {
|
|
||||||
std::cerr << "vpiHandle " << regname.c_str() << " not found"
|
|
||||||
<< std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
reg_handles[i] = vh;
|
|
||||||
}
|
}
|
||||||
pc_handle = vpi_handle_by_name((PLI_BYTE8 *)pcname.c_str(), nullptr);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
86
scripts/difftests.py
Normal file
86
scripts/difftests.py
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
This script is used to provide a wrapper to difftest, so that they can be easily
|
||||||
|
deployed on ci environment.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import os.path as osp
|
||||||
|
import sys
|
||||||
|
from multiprocessing import Pool, Process
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
def find_all_test_images(path):
|
||||||
|
tests = []
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for file in files:
|
||||||
|
# Get file extensions and select files with .bin
|
||||||
|
ext = osp.splitext(file)[1]
|
||||||
|
if ext == ".bin":
|
||||||
|
tests.append(osp.join(root, file))
|
||||||
|
return tests
|
||||||
|
|
||||||
|
def run_test(test_image, ref, ref_prefix, dut, dut_prefix):
|
||||||
|
diffu = "diffu"
|
||||||
|
args = [
|
||||||
|
"--images-path", "/",
|
||||||
|
"-m", test_image,
|
||||||
|
"--ref", ref,
|
||||||
|
"--ref-prefix", ref_prefix,
|
||||||
|
"--dut", dut,
|
||||||
|
"--dut-prefix", dut_prefix,
|
||||||
|
"> logs/" + osp.basename(test_image) + ".log",
|
||||||
|
"2>&1"
|
||||||
|
]
|
||||||
|
|
||||||
|
status = os.system(diffu + " " + " ".join(args))
|
||||||
|
exitcode = os.waitstatus_to_exitcode(status)
|
||||||
|
|
||||||
|
image_shortname = osp.basename(test_image)
|
||||||
|
print(f"{ 'FAILED' if exitcode else 'PASSED' } {image_shortname}")
|
||||||
|
if exitcode:
|
||||||
|
print(f"cmd: {diffu + ' ' + ' '.join(args)}")
|
||||||
|
print(f"exitcode: {exitcode}")
|
||||||
|
sys.exit(exitcode)
|
||||||
|
|
||||||
|
def print_statistics(results):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main():
|
||||||
|
DIFFU_IMAGES_PATH = os.environ["DIFFU_IMAGES_PATH"]
|
||||||
|
print(DIFFU_IMAGES_PATH)
|
||||||
|
assert(osp.isdir(DIFFU_IMAGES_PATH))
|
||||||
|
os.makedirs("logs", exist_ok = True)
|
||||||
|
# Run tests in a multiprocess pool
|
||||||
|
tests = find_all_test_images(DIFFU_IMAGES_PATH)
|
||||||
|
ref, ref_prefix, dut, dut_prefix = sys.argv[1:]
|
||||||
|
ref_shortname = osp.basename(ref)
|
||||||
|
dut_shortname = osp.basename(dut)
|
||||||
|
print(f"[{ref_shortname}, {dut_shortname}]")
|
||||||
|
procs = []
|
||||||
|
for test in tests:
|
||||||
|
image_shortname = osp.basename(test)
|
||||||
|
p = Process(target=run_test, args=(test, ref, ref_prefix, dut, dut_prefix), name=image_shortname, daemon=True)
|
||||||
|
procs.append(p)
|
||||||
|
p.start()
|
||||||
|
|
||||||
|
timeout = 0
|
||||||
|
for p in procs:
|
||||||
|
p.join(5)
|
||||||
|
if p.exitcode is None:
|
||||||
|
print(f"{ 'TIMEOUT' } {p.name}")
|
||||||
|
p.terminate()
|
||||||
|
p.join()
|
||||||
|
timeout += 1
|
||||||
|
|
||||||
|
not_success = sum((1 for p in procs if p.exitcode != 0))
|
||||||
|
failed = not_success - timeout
|
||||||
|
|
||||||
|
print("==========")
|
||||||
|
print(f"TOTAL {len(procs)}\tFAILED: {failed}\tTIMEOUT: {timeout}")
|
||||||
|
|
||||||
|
return not_success
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
Loading…
Reference in a new issue