fpu fix arbitration/lock bugs
add getVexRiscvRegressionArgs
This commit is contained in:
parent
a6e89fe05c
commit
b1f4c06d4e
|
@ -8,7 +8,7 @@ import spinal.lib._
|
||||||
import scala.beans.BeanProperty
|
import scala.beans.BeanProperty
|
||||||
|
|
||||||
trait JumpService{
|
trait JumpService{
|
||||||
def createJumpInterface(stage : Stage, priority : Int = 0) : Flow[UInt]
|
def createJumpInterface(stage : Stage, priority : Int = 0) : Flow[UInt] //High priority win
|
||||||
}
|
}
|
||||||
|
|
||||||
trait IBusFetcher{
|
trait IBusFetcher{
|
||||||
|
|
|
@ -25,95 +25,128 @@ import spinal.lib._
|
||||||
import vexriscv.ip._
|
import vexriscv.ip._
|
||||||
import spinal.lib.bus.avalon.AvalonMM
|
import spinal.lib.bus.avalon.AvalonMM
|
||||||
import spinal.lib.eda.altera.{InterruptReceiverTag, ResetEmitterTag}
|
import spinal.lib.eda.altera.{InterruptReceiverTag, ResetEmitterTag}
|
||||||
|
import vexriscv.demo.smp.VexRiscvSmpClusterGen
|
||||||
import vexriscv.ip.fpu.FpuParameter
|
import vexriscv.ip.fpu.FpuParameter
|
||||||
|
|
||||||
|
|
||||||
// make clean all SEED=42 MMU=no STOP_ON_ERROR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes SUPERVISOR=yes REDO=1 DHRYSTONE=yes LRSC=yes AMO=yes LINUX_REGRESSION=yes TRACE=yes TRACE_START=1000000000 FLOW_INFO=ye IBUS_DATA_WIDTH=128 DBUS_DATA_WIDTH=128
|
// make clean all SEED=42 MMU=no STOP_ON_ERROR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes SUPERVISOR=yes REDO=1 DHRYSTONE=yes LRSC=yes AMO=yes LINUX_REGRESSION=yes TRACE=yes TRACE_START=1000000000 FLOW_INFO=ye IBUS_DATA_WIDTH=128 DBUS_DATA_WIDTH=128
|
||||||
//make clean all SEED=42 MMU=no STOP_ON_ERROR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes SUPERVISOR=yes REDO=1 DHRYSTONE=yes LRSC=yes AMO=yes TRACE=yes TRACE_START=1000000000 FLOW_INFO=ye IBUS_DATA_WIDTH=128 DBUS_DATA_WIDTH=128 LINUX_SOC_SMP=yes VMLINUX=../../../../../buildroot/output/images/Image RAMDISK=../../../../../buildroot/output/images/rootfs.cpio DTB=../../../../../buildroot/output/images/dtb EMULATOR=../../../../../opensbi/build/platform/spinal/vexriscv/sim/smp/firmware/fw_jump.bin
|
// make clean all IBUS=CACHED IBUS_DATA_WIDTH=64 COMPRESSED=no DBUS=CACHED DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 LRSC=yes AMO=yes SUPERVISOR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes MUL=yes DIV=yes RVF=yes RVD=yes DEBUG_PLUGIN=no LINUX_SOC_SMP=yes EMULATOR=$IMAGES/fw_jump.bin VMLINUX=$IMAGES/Image DTB=$IMAGES/linux.dtb RAMDISK=$IMAGES/rootfs.cpio TRACE=ye REDO=1 DEBUG=ye WITH_USER_IO=yes SEED=42
|
||||||
object TestsWorkspace {
|
object TestsWorkspace {
|
||||||
def main(args: Array[String]) {
|
def main(args: Array[String]) {
|
||||||
SpinalConfig().generateVerilog {
|
SpinalConfig().generateVerilog {
|
||||||
|
|
||||||
// make clean all REDO=10 CSR=no MMU=no COREMARK=no RVF=yes RVD=yes REDO=1 DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 DEBUG=ye TRACE=ye
|
// make clean all REDO=10 CSR=no MMU=no COREMARK=no RVF=yes RVD=yes REDO=1 DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 DEBUG=ye TRACE=ye
|
||||||
val config = VexRiscvConfig(
|
// val config = VexRiscvConfig(
|
||||||
plugins = List(
|
// plugins = List(
|
||||||
new IBusCachedPlugin(
|
// new IBusCachedPlugin(
|
||||||
prediction = DYNAMIC,
|
// prediction = DYNAMIC,
|
||||||
config = InstructionCacheConfig(
|
// config = InstructionCacheConfig(
|
||||||
cacheSize = 4096,
|
// cacheSize = 4096,
|
||||||
bytePerLine =32,
|
// bytePerLine =32,
|
||||||
wayCount = 1,
|
// wayCount = 1,
|
||||||
addressWidth = 32,
|
// addressWidth = 32,
|
||||||
cpuDataWidth = 32,
|
// cpuDataWidth = 32,
|
||||||
memDataWidth = 32,
|
// memDataWidth = 32,
|
||||||
catchIllegalAccess = true,
|
// catchIllegalAccess = true,
|
||||||
catchAccessFault = true,
|
// catchAccessFault = true,
|
||||||
asyncTagMemory = false,
|
// asyncTagMemory = false,
|
||||||
twoCycleRam = true,
|
// twoCycleRam = true,
|
||||||
twoCycleCache = true
|
// twoCycleCache = true
|
||||||
),
|
// ),
|
||||||
memoryTranslatorPortConfig = MmuPortConfig(
|
// memoryTranslatorPortConfig = MmuPortConfig(
|
||||||
portTlbSize = 4
|
// portTlbSize = 4
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
new DBusCachedPlugin(
|
// new DBusCachedPlugin(
|
||||||
config = new DataCacheConfig(
|
// config = new DataCacheConfig(
|
||||||
cacheSize = 4096,
|
// cacheSize = 4096,
|
||||||
bytePerLine = 32,
|
// bytePerLine = 32,
|
||||||
wayCount = 1,
|
// wayCount = 1,
|
||||||
addressWidth = 32,
|
// addressWidth = 32,
|
||||||
cpuDataWidth = 64,
|
// cpuDataWidth = 64,
|
||||||
memDataWidth = 64,
|
// memDataWidth = 64,
|
||||||
catchAccessError = true,
|
// catchAccessError = true,
|
||||||
catchIllegal = true,
|
// catchIllegal = true,
|
||||||
catchUnaligned = true
|
// catchUnaligned = true
|
||||||
),
|
// ),
|
||||||
memoryTranslatorPortConfig = MmuPortConfig(
|
// memoryTranslatorPortConfig = MmuPortConfig(
|
||||||
portTlbSize = 6
|
// portTlbSize = 6
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
new MmuPlugin(
|
// new MmuPlugin(
|
||||||
virtualRange = _(31 downto 28) === 0xC,
|
// virtualRange = _(31 downto 28) === 0xC,
|
||||||
ioRange = _(31 downto 28) === 0xF
|
// ioRange = _(31 downto 28) === 0xF
|
||||||
),
|
// ),
|
||||||
new DecoderSimplePlugin(
|
// new DecoderSimplePlugin(
|
||||||
catchIllegalInstruction = true
|
// catchIllegalInstruction = true
|
||||||
),
|
// ),
|
||||||
new RegFilePlugin(
|
// new RegFilePlugin(
|
||||||
regFileReadyKind = plugin.SYNC,
|
// regFileReadyKind = plugin.SYNC,
|
||||||
zeroBoot = false
|
// zeroBoot = false
|
||||||
),
|
// ),
|
||||||
new IntAluPlugin,
|
// new IntAluPlugin,
|
||||||
new SrcPlugin(
|
// new SrcPlugin(
|
||||||
separatedAddSub = false,
|
// separatedAddSub = false,
|
||||||
executeInsertion = true
|
// executeInsertion = true
|
||||||
),
|
// ),
|
||||||
new FullBarrelShifterPlugin,
|
// new FullBarrelShifterPlugin,
|
||||||
new HazardSimplePlugin(
|
// new HazardSimplePlugin(
|
||||||
bypassExecute = true,
|
// bypassExecute = true,
|
||||||
bypassMemory = true,
|
// bypassMemory = true,
|
||||||
bypassWriteBack = true,
|
// bypassWriteBack = true,
|
||||||
bypassWriteBackBuffer = true,
|
// bypassWriteBackBuffer = true,
|
||||||
pessimisticUseSrc = false,
|
// pessimisticUseSrc = false,
|
||||||
pessimisticWriteRegFile = false,
|
// pessimisticWriteRegFile = false,
|
||||||
pessimisticAddressMatch = false
|
// pessimisticAddressMatch = false
|
||||||
),
|
// ),
|
||||||
new MulPlugin,
|
// new MulPlugin,
|
||||||
new DivPlugin,
|
// new DivPlugin,
|
||||||
new CsrPlugin(CsrPluginConfig.small(0x80000020l)),
|
// new CsrPlugin(CsrPluginConfig.small(0x80000020l)),
|
||||||
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||||
new BranchPlugin(
|
// new BranchPlugin(
|
||||||
earlyBranch = false,
|
// earlyBranch = false,
|
||||||
catchAddressMisaligned = true
|
// catchAddressMisaligned = true
|
||||||
),
|
// ),
|
||||||
new YamlPlugin("cpu0.yaml")
|
// new YamlPlugin("cpu0.yaml")
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
config.plugins += new FpuPlugin(
|
// config.plugins += new FpuPlugin(
|
||||||
externalFpu = false,
|
// externalFpu = false,
|
||||||
p = FpuParameter(
|
// p = FpuParameter(
|
||||||
withDouble = true
|
// withDouble = true
|
||||||
)
|
// )
|
||||||
|
// )
|
||||||
|
|
||||||
|
// mkdir buildroot-build
|
||||||
|
// cd buildroot-build/
|
||||||
|
// make O=$PWD BR2_EXTERNAL=../buildroot-spinal-saxon -C ../buildroot saxon_regression_defconfig
|
||||||
|
|
||||||
|
// export IMAGES=/media/data/open/SaxonSoc/artyA7SmpUpdate/buildroot-regression/buildroot-build/images
|
||||||
|
// make clean all IBUS=CACHED IBUS_DATA_WIDTH=64 COMPRESSED=no DBUS=CACHED DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 LRSC=yes AMO=yes SUPERVISOR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes MUL=yes DIV=yes RVF=yes RVD=yes DEBUG_PLUGIN=no LINUX_SOC_SMP=yes EMULATOR=$IMAGES/fw_jump.bin VMLINUX=$IMAGES/Image DTB=$IMAGES/linux.dtb RAMDISK=$IMAGES/rootfs.cpio TRACE=ye REDO=1 DEBUG=ye WITH_USER_IO=no
|
||||||
|
// make clean all IBUS=CACHED IBUS_DATA_WIDTH=64 COMPRESSED=no DBUS=CACHED DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 LRSC=yes AMO=yes SUPERVISOR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes MUL=yes DIV=yes RVF=yes RVD=yes DEBUG_PLUGIN=no LINUX_SOC_SMP=yes EMULATOR=$IMAGES/fw_jump.bin VMLINUX=$IMAGES/Image DTB=$IMAGES/linux.dtb RAMDISK=$IMAGES/rootfs.cpio TRACE=yes REDO=1 DEBUG=ye WITH_USER_IO=no FLOW_INFO=yes TRACE_START=47000000000ll SEED=43
|
||||||
|
// make clean all IBUS=CACHED IBUS_DATA_WIDTH=64 COMPRESSED=no DBUS=CACHED DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 LRSC=yes AMO=yes SUPERVISOR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes MUL=yes DIV=yes RVF=yes RVD=yes DEBUG_PLUGIN=no LINUX_SOC_SMP=yes EMULATOR=$IMAGES/fw_jump.bin VMLINUX=$IMAGES/Image DTB=$IMAGES/linux.dtb RAMDISK=$IMAGES/rootfs.cpio TRACE=yes REDO=1 DEBUG=ye WITH_USER_IO=no FLOW_INFO=yes TRACE_START=47000000000ll SEED=45
|
||||||
|
//make clean all IBUS=CACHED IBUS_DATA_WIDTH=64 COMPRESSED=no DBUS=CACHED DBUS_LOAD_DATA_WIDTH=64 DBUS_STORE_DATA_WIDTH=64 LRSC=yes AMO=yes SUPERVISOR=yes DBUS_EXCLUSIVE=yes DBUS_INVALIDATE=yes MUL=yes DIV=yes RVF=yes RVD=yes DEBUG_PLUGIN=no LINUX_SOC_SMP=yes EMULATOR=$IMAGES/fw_jump.bin VMLINUX=$IMAGES/Image DTB=$IMAGES/linux.dtb RAMDISK=$IMAGES/rootfs.cpio TRACE=yes REDO=1 DEBUG=ye WITH_USER_IO=no FLOW_INFO=yes TRACE_START=565000000ll SEED=45
|
||||||
|
val config = VexRiscvSmpClusterGen.vexRiscvConfig(
|
||||||
|
hartId = 0,
|
||||||
|
ioRange = _ (31 downto 28) === 0xF,
|
||||||
|
resetVector = 0x80000000l,
|
||||||
|
iBusWidth = 64,
|
||||||
|
dBusWidth = 64,
|
||||||
|
loadStoreWidth = 64,
|
||||||
|
iCacheSize = 4096*2,
|
||||||
|
dCacheSize = 4096*2,
|
||||||
|
iCacheWays = 2,
|
||||||
|
dCacheWays = 2,
|
||||||
|
withFloat = true,
|
||||||
|
withDouble = true,
|
||||||
|
externalFpu = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
println("Args :")
|
||||||
|
println(config.getRegressionArgs().mkString(" "))
|
||||||
|
|
||||||
|
|
||||||
val toplevel = new VexRiscv(config)
|
val toplevel = new VexRiscv(config)
|
||||||
// val toplevel = new VexRiscv(configLight)
|
// val toplevel = new VexRiscv(configLight)
|
||||||
// val toplevel = new VexRiscv(configTest)
|
// val toplevel = new VexRiscv(configTest)
|
||||||
|
|
|
@ -16,7 +16,9 @@ object VexRiscvConfig{
|
||||||
|
|
||||||
def apply(plugins : Seq[Plugin[VexRiscv]] = ArrayBuffer()) : VexRiscvConfig = apply(true,true,plugins)
|
def apply(plugins : Seq[Plugin[VexRiscv]] = ArrayBuffer()) : VexRiscvConfig = apply(true,true,plugins)
|
||||||
}
|
}
|
||||||
|
trait VexRiscvRegressionArg{
|
||||||
|
def getVexRiscvRegressionArgs() : Seq[String]
|
||||||
|
}
|
||||||
case class VexRiscvConfig(){
|
case class VexRiscvConfig(){
|
||||||
var withMemoryStage = true
|
var withMemoryStage = true
|
||||||
var withWriteBackStage = true
|
var withWriteBackStage = true
|
||||||
|
@ -83,6 +85,15 @@ case class VexRiscvConfig(){
|
||||||
}
|
}
|
||||||
object SRC1_CTRL extends Stageable(Src1CtrlEnum())
|
object SRC1_CTRL extends Stageable(Src1CtrlEnum())
|
||||||
object SRC2_CTRL extends Stageable(Src2CtrlEnum())
|
object SRC2_CTRL extends Stageable(Src2CtrlEnum())
|
||||||
|
|
||||||
|
def getRegressionArgs() : Seq[String] = {
|
||||||
|
val str = ArrayBuffer[String]()
|
||||||
|
plugins.foreach{
|
||||||
|
case e : VexRiscvRegressionArg => str ++= e.getVexRiscvRegressionArgs()
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
str
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ object VexRiscvSmpClusterGen {
|
||||||
)
|
)
|
||||||
|
|
||||||
if(withFloat) config.plugins += new FpuPlugin(
|
if(withFloat) config.plugins += new FpuPlugin(
|
||||||
externalFpu = true,
|
externalFpu = externalFpu,
|
||||||
p = FpuParameter(withDouble = withDouble)
|
p = FpuParameter(withDouble = withDouble)
|
||||||
)
|
)
|
||||||
config
|
config
|
||||||
|
|
|
@ -184,7 +184,8 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
|
|
||||||
val commitLogic = for(source <- 0 until portCount) yield new Area{
|
val commitLogic = for(source <- 0 until portCount) yield new Area{
|
||||||
val fire = False
|
val fire = False
|
||||||
val target, hit = Reg(UInt(log2Up(rfLockCount) bits)) init(0)
|
val target, hit = Reg(UInt(log2Up(rfLockCount+1) bits)) init(0)
|
||||||
|
val full = target + 1 === hit
|
||||||
when(fire){
|
when(fire){
|
||||||
hit := hit + 1
|
hit := hit + 1
|
||||||
}
|
}
|
||||||
|
@ -192,7 +193,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
commitFork.commit(source).ready := False
|
commitFork.commit(source).ready := False
|
||||||
when(commitFork.commit(source).valid) {
|
when(commitFork.commit(source).valid) {
|
||||||
for (lock <- rf.lock) {
|
for (lock <- rf.lock) {
|
||||||
when(lock.valid && lock.source === source && lock.id === hit) {
|
when(lock.valid && lock.source === source && lock.id === hit && !lock.commited) {
|
||||||
fire := True
|
fire := True
|
||||||
lock.commited := True
|
lock.commited := True
|
||||||
lock.write := commitFork.commit(source).write
|
lock.write := commitFork.commit(source).write
|
||||||
|
@ -233,7 +234,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
val hits = List((useRs1, s0.rs1), (useRs2, s0.rs2), (useRs3, s0.rs3), (useRd, s0.rd)).map{case (use, reg) => use && rf.lock.map(l => l.valid && l.source === s0.source && l.address === reg).orR}
|
val hits = List((useRs1, s0.rs1), (useRs2, s0.rs2), (useRs3, s0.rs3), (useRd, s0.rd)).map{case (use, reg) => use && rf.lock.map(l => l.valid && l.source === s0.source && l.address === reg).orR}
|
||||||
val hazard = hits.orR
|
val hazard = hits.orR || commitLogic.map(_.full).read(s0.source)
|
||||||
when(s0.fire && useRd){
|
when(s0.fire && useRd){
|
||||||
for(i <- 0 until portCount){
|
for(i <- 0 until portCount){
|
||||||
when(s0.source === i){
|
when(s0.source === i){
|
||||||
|
@ -938,7 +939,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
output.roundMode := input.roundMode
|
output.roundMode := input.roundMode
|
||||||
output.scrap := norm.scrap
|
output.scrap := norm.scrap
|
||||||
output.value := norm.output
|
output.value := norm.output
|
||||||
output.NV := NV
|
output.NV := NV //TODO isn't propagated in FMA
|
||||||
output.DZ := False
|
output.DZ := False
|
||||||
|
|
||||||
decode.mulToAdd.valid := input.valid && input.add
|
decode.mulToAdd.valid := input.valid && input.add
|
||||||
|
@ -946,7 +947,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
decode.mulToAdd.rs1.mantissa := norm.output.mantissa >> 1 //FMA Precision lost
|
decode.mulToAdd.rs1.mantissa := norm.output.mantissa >> 1 //FMA Precision lost
|
||||||
decode.mulToAdd.rs1.exponent := norm.output.exponent
|
decode.mulToAdd.rs1.exponent := norm.output.exponent
|
||||||
decode.mulToAdd.rs1.sign := norm.output.sign
|
decode.mulToAdd.rs1.sign := norm.output.sign
|
||||||
decode.mulToAdd.rs1.special := False //TODO
|
decode.mulToAdd.rs1.special := norm.output.special
|
||||||
decode.mulToAdd.rs2 := input.rs3
|
decode.mulToAdd.rs2 := input.rs3
|
||||||
decode.mulToAdd.rd := input.rd
|
decode.mulToAdd.rd := input.rd
|
||||||
decode.mulToAdd.lockId := input.lockId
|
decode.mulToAdd.lockId := input.lockId
|
||||||
|
@ -1289,6 +1290,8 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
if(p.withMul) (inputs += mul.result.output)
|
if(p.withMul) (inputs += mul.result.output)
|
||||||
if(p.withShortPipMisc) (inputs += shortPip.rfOutput.pipelined(m2s = true))
|
if(p.withShortPipMisc) (inputs += shortPip.rfOutput.pipelined(m2s = true))
|
||||||
val arbitrated = StreamArbiterFactory.lowerFirst.noLock.on(inputs)
|
val arbitrated = StreamArbiterFactory.lowerFirst.noLock.on(inputs)
|
||||||
|
val isCommited = rf.lock.map(_.commited).read(arbitrated.lockId)
|
||||||
|
val commited = arbitrated.haltWhen(!isCommited).toFlow
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoundFront extends MergeInput{
|
class RoundFront extends MergeInput{
|
||||||
|
@ -1298,7 +1301,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
val roundFront = new Area {
|
val roundFront = new Area {
|
||||||
val input = merge.arbitrated.stage()
|
val input = merge.commited.stage()
|
||||||
val output = input.swapPayload(new RoundFront())
|
val output = input.swapPayload(new RoundFront())
|
||||||
output.payload.assignSomeByName(input.payload)
|
output.payload.assignSomeByName(input.payload)
|
||||||
|
|
||||||
|
@ -1328,8 +1331,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
|
||||||
|
|
||||||
val roundBack = new Area{
|
val roundBack = new Area{
|
||||||
val input = roundFront.output.stage()
|
val input = roundFront.output.stage()
|
||||||
val isCommited = rf.lock.map(_.commited).read(input.lockId)
|
val output = input.swapPayload(RoundOutput())
|
||||||
val output = input.haltWhen(!isCommited).toFlow.swapPayload(RoundOutput())
|
|
||||||
import input.payload._
|
import input.payload._
|
||||||
|
|
||||||
val math = p.internalFloating()
|
val math = p.internalFloating()
|
||||||
|
|
|
@ -92,8 +92,15 @@ object FpuFormat extends SpinalEnum{
|
||||||
val FLOAT, DOUBLE = newElement()
|
val FLOAT, DOUBLE = newElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
object FpuRoundMode extends SpinalEnum(defaultEncoding = binarySequential){
|
object FpuRoundMode extends SpinalEnum(){
|
||||||
val RNE, RTZ, RDN, RUP, RMM = newElement()
|
val RNE, RTZ, RDN, RUP, RMM = newElement()
|
||||||
|
defaultEncoding = SpinalEnumEncoding("opt")(
|
||||||
|
RNE -> 0,
|
||||||
|
RTZ -> 1,
|
||||||
|
RDN -> 2,
|
||||||
|
RUP -> 3,
|
||||||
|
RMM -> 4
|
||||||
|
)
|
||||||
}
|
}
|
||||||
object FpuRoundModeInstr extends SpinalEnum(){
|
object FpuRoundModeInstr extends SpinalEnum(){
|
||||||
val RNE, RTZ, RDN, RUP, RMM, DYN = newElement()
|
val RNE, RTZ, RDN, RUP, RMM, DYN = newElement()
|
||||||
|
|
|
@ -66,7 +66,6 @@ class BranchPlugin(earlyBranch : Boolean,
|
||||||
object IS_FENCEI extends Stageable(Bool)
|
object IS_FENCEI extends Stageable(Bool)
|
||||||
|
|
||||||
var jumpInterface : Flow[UInt] = null
|
var jumpInterface : Flow[UInt] = null
|
||||||
var predictionJumpInterface : Flow[UInt] = null
|
|
||||||
var predictionExceptionPort : Flow[ExceptionCause] = null
|
var predictionExceptionPort : Flow[ExceptionCause] = null
|
||||||
var branchExceptionPort : Flow[ExceptionCause] = null
|
var branchExceptionPort : Flow[ExceptionCause] = null
|
||||||
|
|
||||||
|
|
|
@ -544,7 +544,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
||||||
|
|
||||||
|
|
||||||
if(supervisorGen) {
|
if(supervisorGen) {
|
||||||
redoInterface = pcManagerService.createJumpInterface(pipeline.execute, -1)
|
redoInterface = pcManagerService.createJumpInterface(pipeline.execute, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
exceptionPendings = Vec(Bool, pipeline.stages.length)
|
exceptionPendings = Vec(Bool, pipeline.stages.length)
|
||||||
|
@ -749,12 +749,13 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
||||||
satpAccess(CSR.SATP, 31 -> satp.MODE, 22 -> satp.ASID, 0 -> satp.PPN)
|
satpAccess(CSR.SATP, 31 -> satp.MODE, 22 -> satp.ASID, 0 -> satp.PPN)
|
||||||
|
|
||||||
|
|
||||||
if(supervisorGen) {
|
val satpLogic = supervisorGen generate new Area {
|
||||||
redoInterface.valid := False
|
redoInterface.valid := False
|
||||||
redoInterface.payload := decode.input(PC)
|
redoInterface.payload := decode.input(PC)
|
||||||
duringWrite(CSR.SATP){
|
duringWrite(CSR.SATP) {
|
||||||
execute.arbitration.flushNext := True
|
|
||||||
redoInterface.valid := True
|
redoInterface.valid := True
|
||||||
|
execute.arbitration.flushNext := True
|
||||||
|
decode.arbitration.haltByOther := True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
||||||
dBusCmdSlavePipe : Boolean = false,
|
dBusCmdSlavePipe : Boolean = false,
|
||||||
dBusRspSlavePipe : Boolean = false,
|
dBusRspSlavePipe : Boolean = false,
|
||||||
relaxedMemoryTranslationRegister : Boolean = false,
|
relaxedMemoryTranslationRegister : Boolean = false,
|
||||||
csrInfo : Boolean = false) extends Plugin[VexRiscv] with DBusAccessService with DBusEncodingService {
|
csrInfo : Boolean = false) extends Plugin[VexRiscv] with DBusAccessService with DBusEncodingService with VexRiscvRegressionArg {
|
||||||
import config._
|
import config._
|
||||||
assert(!(config.withExternalAmo && !dBusRspSlavePipe))
|
assert(!(config.withExternalAmo && !dBusRspSlavePipe))
|
||||||
assert(isPow2(cacheSize))
|
assert(isPow2(cacheSize))
|
||||||
|
@ -52,6 +52,18 @@ class DBusCachedPlugin(val config : DataCacheConfig,
|
||||||
dBusAccess
|
dBusAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def getVexRiscvRegressionArgs(): Seq[String] = {
|
||||||
|
var args = List[String]()
|
||||||
|
args :+= "DBUS=CACHED"
|
||||||
|
args :+= s"DBUS_LOAD_DATA_WIDTH=$memDataWidth"
|
||||||
|
args :+= s"DBUS_STORE_DATA_WIDTH=$cpuDataWidth"
|
||||||
|
if(withLrSc) args :+= "LRSC=yes"
|
||||||
|
if(withAmo) args :+= "AMO=yes"
|
||||||
|
if(config.withExclusive && config.withInvalidate) args ++= List("DBUS_EXCLUSIVE=yes", "DBUS_INVALIDATE=yes")
|
||||||
|
args
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override def addLoadWordEncoding(key : MaskedLiteral): Unit = {
|
override def addLoadWordEncoding(key : MaskedLiteral): Unit = {
|
||||||
val decoderService = pipeline.service(classOf[DecoderService])
|
val decoderService = pipeline.service(classOf[DecoderService])
|
||||||
val cfg = pipeline.config
|
val cfg = pipeline.config
|
||||||
|
|
|
@ -10,7 +10,7 @@ import vexriscv.ip.fpu._
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
|
|
||||||
class FpuPlugin(externalFpu : Boolean = false,
|
class FpuPlugin(externalFpu : Boolean = false,
|
||||||
p : FpuParameter) extends Plugin[VexRiscv]{
|
p : FpuParameter) extends Plugin[VexRiscv] with VexRiscvRegressionArg {
|
||||||
|
|
||||||
object FPU_ENABLE extends Stageable(Bool())
|
object FPU_ENABLE extends Stageable(Bool())
|
||||||
object FPU_COMMIT extends Stageable(Bool())
|
object FPU_COMMIT extends Stageable(Bool())
|
||||||
|
@ -24,6 +24,13 @@ class FpuPlugin(externalFpu : Boolean = false,
|
||||||
|
|
||||||
var port : FpuPort = null
|
var port : FpuPort = null
|
||||||
|
|
||||||
|
override def getVexRiscvRegressionArgs(): Seq[String] = {
|
||||||
|
var args = List[String]()
|
||||||
|
args :+= "RVF=yes"
|
||||||
|
if(p.withDouble) args :+= "RVD=yes"
|
||||||
|
args
|
||||||
|
}
|
||||||
|
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
||||||
|
@ -154,7 +161,7 @@ class FpuPlugin(externalFpu : Boolean = false,
|
||||||
dBusEncoding.addStoreWordEncoding(FSD)
|
dBusEncoding.addStoreWordEncoding(FSD)
|
||||||
}
|
}
|
||||||
|
|
||||||
exposeEncoding()
|
// exposeEncoding()
|
||||||
}
|
}
|
||||||
|
|
||||||
def exposeEncoding(): Unit ={
|
def exposeEncoding(): Unit ={
|
||||||
|
@ -171,15 +178,6 @@ class FpuPlugin(externalFpu : Boolean = false,
|
||||||
if(s == pipeline.config.RS1_USE) (if(isSet)rs1 += key else rs1N += key)
|
if(s == pipeline.config.RS1_USE) (if(isSet)rs1 += key else rs1N += key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// println("COMMIT => ")
|
|
||||||
// filter(0x53, commits).foreach(println)
|
|
||||||
// println("COMMITN => ")
|
|
||||||
// filter(0x53, commitsN).foreach(println)
|
|
||||||
// println("RSP => ")
|
|
||||||
// filter(0x53, rsps).foreach(println)
|
|
||||||
// println("RSPN => ")
|
|
||||||
// filter(0x53, rspsN).foreach(println)
|
|
||||||
|
|
||||||
val commitLut, rspLut, rs1Lut = Array.fill(32)(false)
|
val commitLut, rspLut, rs1Lut = Array.fill(32)(false)
|
||||||
filter(0x53,commits).foreach{m =>
|
filter(0x53,commits).foreach{m =>
|
||||||
val idx = (m.value >> 27).toInt
|
val idx = (m.value >> 27).toInt
|
||||||
|
@ -256,11 +254,17 @@ class FpuPlugin(externalFpu : Boolean = false,
|
||||||
execute.arbitration.haltByOther setWhen(csrActive && hasPending) // pessimistic
|
execute.arbitration.haltByOther setWhen(csrActive && hasPending) // pessimistic
|
||||||
|
|
||||||
val fs = Reg(Bits(2 bits)) init(1)
|
val fs = Reg(Bits(2 bits)) init(1)
|
||||||
when(hasPending){
|
val sd = fs === 3
|
||||||
|
|
||||||
|
when(stages.last.arbitration.isFiring && stages.last.input(FPU_ENABLE)){
|
||||||
fs := 3 //DIRTY
|
fs := 3 //DIRTY
|
||||||
}
|
}
|
||||||
|
|
||||||
service.rw(CSR.SSTATUS, 13, fs)
|
service.rw(CSR.SSTATUS, 13, fs)
|
||||||
service.rw(CSR.MSTATUS, 13, fs)
|
service.rw(CSR.MSTATUS, 13, fs)
|
||||||
|
|
||||||
|
service.r(CSR.SSTATUS, 31, sd)
|
||||||
|
service.r(CSR.MSTATUS, 31, sd)
|
||||||
}
|
}
|
||||||
|
|
||||||
decode plug new Area{
|
decode plug new Area{
|
||||||
|
|
|
@ -49,15 +49,26 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
injectorStage = (!config.twoCycleCache && !withoutInjectorStage) || injectorStage,
|
injectorStage = (!config.twoCycleCache && !withoutInjectorStage) || injectorStage,
|
||||||
relaxPredictorAddress = relaxPredictorAddress,
|
relaxPredictorAddress = relaxPredictorAddress,
|
||||||
fetchRedoGen = true,
|
fetchRedoGen = true,
|
||||||
predictionBuffer = predictionBuffer){
|
predictionBuffer = predictionBuffer) with VexRiscvRegressionArg{
|
||||||
import config._
|
import config._
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assert(isPow2(cacheSize))
|
assert(isPow2(cacheSize))
|
||||||
assert(!(memoryTranslatorPortConfig != null && config.cacheSize/config.wayCount > 4096), "When the I$ is used with MMU, each way can't be bigger than a page (4096 bytes)")
|
assert(!(memoryTranslatorPortConfig != null && config.cacheSize/config.wayCount > 4096), "When the I$ is used with MMU, each way can't be bigger than a page (4096 bytes)")
|
||||||
|
|
||||||
|
|
||||||
assert(!(withoutInjectorStage && injectorStage))
|
assert(!(withoutInjectorStage && injectorStage))
|
||||||
|
|
||||||
|
|
||||||
|
override def getVexRiscvRegressionArgs(): Seq[String] = {
|
||||||
|
var args = List[String]()
|
||||||
|
args :+= "IBUS=CACHED"
|
||||||
|
args :+= s"IBUS_DATA_WIDTH=$memDataWidth"
|
||||||
|
args :+= s"COMPRESSED=${if(compressedGen) "yes" else "no"}"
|
||||||
|
args
|
||||||
|
}
|
||||||
|
|
||||||
var iBus : InstructionCacheMemBus = null
|
var iBus : InstructionCacheMemBus = null
|
||||||
var mmuBus : MemoryTranslatorBus = null
|
var mmuBus : MemoryTranslatorBus = null
|
||||||
var privilegeService : PrivilegeService = null
|
var privilegeService : PrivilegeService = null
|
||||||
|
|
|
@ -19,9 +19,16 @@ class MulDivIterativePlugin(genMul : Boolean = true,
|
||||||
mulUnrollFactor : Int = 1,
|
mulUnrollFactor : Int = 1,
|
||||||
divUnrollFactor : Int = 1,
|
divUnrollFactor : Int = 1,
|
||||||
dhrystoneOpt : Boolean = false,
|
dhrystoneOpt : Boolean = false,
|
||||||
customMul : (UInt, UInt, Stage, VexRiscv) => Area = null) extends Plugin[VexRiscv]{
|
customMul : (UInt, UInt, Stage, VexRiscv) => Area = null) extends Plugin[VexRiscv] with VexRiscvRegressionArg {
|
||||||
import MulDivIterativePlugin._
|
import MulDivIterativePlugin._
|
||||||
|
|
||||||
|
override def getVexRiscvRegressionArgs(): Seq[String] = {
|
||||||
|
var args = List[String]()
|
||||||
|
if(genMul) args :+= "MUL=yes"
|
||||||
|
if(genDiv) args :+= "DIV=yes"
|
||||||
|
args
|
||||||
|
}
|
||||||
|
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
import Riscv._
|
import Riscv._
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
|
@ -5,7 +5,7 @@ import spinal.core._
|
||||||
import spinal.lib.KeepAttribute
|
import spinal.lib.KeepAttribute
|
||||||
|
|
||||||
//Input buffer generaly avoid the FPGA synthesis to duplicate reg inside the DSP cell, which could stress timings quite much.
|
//Input buffer generaly avoid the FPGA synthesis to duplicate reg inside the DSP cell, which could stress timings quite much.
|
||||||
class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{
|
class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv] with VexRiscvRegressionArg {
|
||||||
object MUL_LL extends Stageable(UInt(32 bits))
|
object MUL_LL extends Stageable(UInt(32 bits))
|
||||||
object MUL_LH extends Stageable(SInt(34 bits))
|
object MUL_LH extends Stageable(SInt(34 bits))
|
||||||
object MUL_HL extends Stageable(SInt(34 bits))
|
object MUL_HL extends Stageable(SInt(34 bits))
|
||||||
|
@ -15,6 +15,11 @@ class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{
|
||||||
|
|
||||||
object IS_MUL extends Stageable(Bool)
|
object IS_MUL extends Stageable(Bool)
|
||||||
|
|
||||||
|
override def getVexRiscvRegressionArgs(): Seq[String] = {
|
||||||
|
List("MUL=yes")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
import Riscv._
|
import Riscv._
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
|
@ -227,7 +227,8 @@ class success : public std::exception { };
|
||||||
#define SIP 0x144
|
#define SIP 0x144
|
||||||
#define SATP 0x180
|
#define SATP 0x180
|
||||||
|
|
||||||
|
#define UTIME 0xC01 // rdtime
|
||||||
|
#define UTIMEH 0xC81
|
||||||
|
|
||||||
#define SSTATUS_SIE 0x00000002
|
#define SSTATUS_SIE 0x00000002
|
||||||
#define SSTATUS_SPIE 0x00000020
|
#define SSTATUS_SPIE 0x00000020
|
||||||
|
@ -426,6 +427,7 @@ public:
|
||||||
bool lrscReserved;
|
bool lrscReserved;
|
||||||
uint32_t lrscReservedAddress;
|
uint32_t lrscReservedAddress;
|
||||||
u32 fpuCompletionTockens;
|
u32 fpuCompletionTockens;
|
||||||
|
u32 dutRfWriteValue;
|
||||||
|
|
||||||
RiscvGolden() {
|
RiscvGolden() {
|
||||||
pc = 0x80000000;
|
pc = 0x80000000;
|
||||||
|
@ -444,6 +446,10 @@ public:
|
||||||
status.spp = 1;
|
status.spp = 1;
|
||||||
#ifdef RVF
|
#ifdef RVF
|
||||||
status.fs = 1;
|
status.fs = 1;
|
||||||
|
misa |= 1 << 5;
|
||||||
|
#endif
|
||||||
|
#ifdef RVD
|
||||||
|
misa |= 1 << 3;
|
||||||
#endif
|
#endif
|
||||||
fcsr.flags = 0;
|
fcsr.flags = 0;
|
||||||
fcsr.frm = 0;
|
fcsr.frm = 0;
|
||||||
|
@ -515,10 +521,10 @@ public:
|
||||||
}
|
}
|
||||||
void trap(bool interrupt,int32_t cause, bool valueWrite, uint32_t value) {
|
void trap(bool interrupt,int32_t cause, bool valueWrite, uint32_t value) {
|
||||||
#ifdef FLOW_INFO
|
#ifdef FLOW_INFO
|
||||||
cout << "TRAP " << (interrupt ? "interrupt" : "exception") << " cause=" << cause << " PC=0x" << hex << pc << " val=0x" << hex << value << dec << endl;
|
// cout << "TRAP " << (interrupt ? "interrupt" : "exception") << " cause=" << cause << " PC=0x" << hex << pc << " val=0x" << hex << value << dec << endl;
|
||||||
if(cause == 9){
|
// if(cause == 9){
|
||||||
cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl;
|
// cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl;
|
||||||
}
|
// }
|
||||||
#endif
|
#endif
|
||||||
//Check leguality of the interrupt
|
//Check leguality of the interrupt
|
||||||
if(interrupt) {
|
if(interrupt) {
|
||||||
|
@ -584,7 +590,7 @@ public:
|
||||||
virtual bool csrRead(int32_t csr, uint32_t *value){
|
virtual bool csrRead(int32_t csr, uint32_t *value){
|
||||||
if(((csr >> 8) & 0x3) > privilege) return true;
|
if(((csr >> 8) & 0x3) > privilege) return true;
|
||||||
switch(csr){
|
switch(csr){
|
||||||
case MSTATUS: *value = status.raw & MSTATUS_READ_MASK; break;
|
case MSTATUS: *value = (status.raw | (((status.raw & 0x6000) == 0x6000) ? 0x80000000 : 0)) & MSTATUS_READ_MASK; break;
|
||||||
case MIP: *value = getIp().raw; break;
|
case MIP: *value = getIp().raw; break;
|
||||||
case MIE: *value = ie.raw; break;
|
case MIE: *value = ie.raw; break;
|
||||||
case MTVEC: *value = mtvec.raw; break;
|
case MTVEC: *value = mtvec.raw; break;
|
||||||
|
@ -597,7 +603,7 @@ public:
|
||||||
case MIDELEG: *value = mideleg; break;
|
case MIDELEG: *value = mideleg; break;
|
||||||
case MHARTID: *value = 0; break;
|
case MHARTID: *value = 0; break;
|
||||||
|
|
||||||
case SSTATUS: *value = status.raw & 0xC0133; break;
|
case SSTATUS: *value = (status.raw | (((status.raw & 0x6000) == 0x6000) ? 0x80000000 : 0)) & (0x800C0133 | STATUS_FS_MASK); break;
|
||||||
case SIP: *value = getIp().raw & 0x333; break;
|
case SIP: *value = getIp().raw & 0x333; break;
|
||||||
case SIE: *value = ie.raw & 0x333; break;
|
case SIE: *value = ie.raw & 0x333; break;
|
||||||
case STVEC: *value = stvec.raw; break;
|
case STVEC: *value = stvec.raw; break;
|
||||||
|
@ -613,6 +619,11 @@ public:
|
||||||
case FFLAGS: *value = fcsr.flags; break;
|
case FFLAGS: *value = fcsr.flags; break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef UTIME_INPUT
|
||||||
|
case UTIME: *value = dutRfWriteValue; break;
|
||||||
|
case UTIMEH: *value = dutRfWriteValue; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default: return true; break;
|
default: return true; break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -627,12 +638,12 @@ public:
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define maskedWrite(dst, src, mask) dst=(dst & ~mask)|(src & mask);
|
#define maskedWrite(dst, src, mask) dst=((dst) & ~(mask))|((src) & (mask));
|
||||||
|
|
||||||
virtual bool csrWrite(int32_t csr, uint32_t value){
|
virtual bool csrWrite(int32_t csr, uint32_t value){
|
||||||
if(((csr >> 8) & 0x3) > privilege) return true;
|
if(((csr >> 8) & 0x3) > privilege) return true;
|
||||||
switch(csr){
|
switch(csr){
|
||||||
case MSTATUS: status.raw = value; break;
|
case MSTATUS: status.raw = value & 0x7FFFFFFF; break;
|
||||||
case MIP: ipSoft = value; break;
|
case MIP: ipSoft = value; break;
|
||||||
case MIE: ie.raw = value; break;
|
case MIE: ie.raw = value; break;
|
||||||
case MTVEC: mtvec.raw = value; break;
|
case MTVEC: mtvec.raw = value; break;
|
||||||
|
@ -644,7 +655,7 @@ public:
|
||||||
case MEDELEG: medeleg = value & (~0x8); break;
|
case MEDELEG: medeleg = value & (~0x8); break;
|
||||||
case MIDELEG: mideleg = value; break;
|
case MIDELEG: mideleg = value; break;
|
||||||
|
|
||||||
case SSTATUS: maskedWrite(status.raw, value,0xC0133 | STATUS_FS_MASK); break;
|
case SSTATUS: maskedWrite(status.raw, value, 0xC0133 | STATUS_FS_MASK); break;
|
||||||
case SIP: maskedWrite(ipSoft, value,0x333); break;
|
case SIP: maskedWrite(ipSoft, value,0x333); break;
|
||||||
case SIE: maskedWrite(ie.raw, value,0x333); break;
|
case SIE: maskedWrite(ie.raw, value,0x333); break;
|
||||||
case STVEC: stvec.raw = value; break;
|
case STVEC: stvec.raw = value; break;
|
||||||
|
@ -652,8 +663,7 @@ public:
|
||||||
case STVAL: sbadaddr = value; break;
|
case STVAL: sbadaddr = value; break;
|
||||||
case SEPC: sepc = value; break;
|
case SEPC: sepc = value; break;
|
||||||
case SSCRATCH: sscratch = value; break;
|
case SSCRATCH: sscratch = value; break;
|
||||||
case SATP: satp.raw = value; break;
|
case SATP: satp.raw = value; break;
|
||||||
|
|
||||||
|
|
||||||
#ifdef RVF
|
#ifdef RVF
|
||||||
case FCSR: fcsr.raw = value & 0x7F; break;
|
case FCSR: fcsr.raw = value & 0x7F; break;
|
||||||
|
@ -739,6 +749,7 @@ public:
|
||||||
fpuCompletionTockens -= 1;
|
fpuCompletionTockens -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define rd32 ((i >> 7) & 0x1F)
|
#define rd32 ((i >> 7) & 0x1F)
|
||||||
#define iBits(lo, len) ((i >> lo) & ((1 << len)-1))
|
#define iBits(lo, len) ((i >> lo) & ((1 << len)-1))
|
||||||
#define iBitsSigned(lo, len) int32_t(i) << (32-lo-len) >> (32-len)
|
#define iBitsSigned(lo, len) int32_t(i) << (32-lo-len) >> (32-len)
|
||||||
|
@ -833,6 +844,7 @@ public:
|
||||||
fcsr.flags |= rsp.flags;
|
fcsr.flags |= rsp.flags;
|
||||||
rfWrite(rd32, (u32)rsp.value);
|
rfWrite(rd32, (u32)rsp.value);
|
||||||
}
|
}
|
||||||
|
status.fs = 3;
|
||||||
pcWrite(pc + 4);
|
pcWrite(pc + 4);
|
||||||
} break;
|
} break;
|
||||||
case 0x07: { //Fpu load
|
case 0x07: { //Fpu load
|
||||||
|
@ -860,6 +872,7 @@ public:
|
||||||
cout << "FPU load missmatch DUT=" << hex << commit.value << " REF=" << data << dec << endl;
|
cout << "FPU load missmatch DUT=" << hex << commit.value << " REF=" << data << dec << endl;
|
||||||
fail();
|
fail();
|
||||||
} else {
|
} else {
|
||||||
|
status.fs = 3;
|
||||||
pcWrite(pc + 4);
|
pcWrite(pc + 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -882,6 +895,7 @@ public:
|
||||||
} else {
|
} else {
|
||||||
if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; }
|
if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; }
|
||||||
dWrite(pAddr, size, (uint8_t*) &rsp.value);
|
dWrite(pAddr, size, (uint8_t*) &rsp.value);
|
||||||
|
status.fs = 3;
|
||||||
pcWrite(pc + 4);
|
pcWrite(pc + 4);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -1687,10 +1701,15 @@ public:
|
||||||
//if(mTime == mTimeCmp) printf("SIM timer tick\n");
|
//if(mTime == mTimeCmp) printf("SIM timer tick\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef UTIME_INPUT
|
||||||
|
top->utime = mTime;
|
||||||
|
#endif
|
||||||
|
|
||||||
currentTime = i;
|
currentTime = i;
|
||||||
|
|
||||||
#ifdef FLOW_INFO
|
#ifdef FLOW_INFO
|
||||||
if(i % 2000000 == 0) cout << "**" << endl << "**" << endl << "**" << endl << "**" << endl << "**" << endl << "PROGRESS TRACE_START=" << i << endl;
|
if(i % 5000000 == 0) cout << endl << "**" << endl << "**" << endl << "PROGRESS TRACE_START=" << i << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1764,6 +1783,7 @@ public:
|
||||||
// cout << "- S " << privilegeCounters[1] << endl;
|
// cout << "- S " << privilegeCounters[1] << endl;
|
||||||
// cout << "- M " << privilegeCounters[3] << endl;
|
// cout << "- M " << privilegeCounters[3] << endl;
|
||||||
// }
|
// }
|
||||||
|
riscvRef.dutRfWriteValue = top->VexRiscv->lastStageRegFileWrite_payload_data;
|
||||||
riscvRef.step();
|
riscvRef.step();
|
||||||
bool mIntTimer = false;
|
bool mIntTimer = false;
|
||||||
bool mIntExt = false;
|
bool mIntExt = false;
|
||||||
|
@ -2554,10 +2574,16 @@ public:
|
||||||
virtual void onReset(){
|
virtual void onReset(){
|
||||||
top->dBus_cmd_ready = 1;
|
top->dBus_cmd_ready = 1;
|
||||||
top->dBus_rsp_valid = 0;
|
top->dBus_rsp_valid = 0;
|
||||||
|
#ifdef DBUS_AGGREGATION
|
||||||
|
top->dBus_rsp_payload_aggregated = 0;
|
||||||
|
#endif
|
||||||
#ifdef DBUS_INVALIDATE
|
#ifdef DBUS_INVALIDATE
|
||||||
top->dBus_inv_valid = 0;
|
top->dBus_inv_valid = 0;
|
||||||
top->dBus_ack_ready = 0;
|
top->dBus_ack_ready = 0;
|
||||||
top->dBus_sync_valid = 0;
|
top->dBus_sync_valid = 0;
|
||||||
|
#ifdef DBUS_AGGREGATION
|
||||||
|
top->dBus_sync_payload_aggregated = 0;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3700,7 +3726,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint64_t mask, uint8_t *dataBytes, bool *error) {
|
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size, uint8_t *dataBytes, bool *error) {
|
||||||
uint32_t *data = (uint32_t*)dataBytes;
|
uint32_t *data = (uint32_t*)dataBytes;
|
||||||
if(isPerifRegion(addr)) switch(addr){
|
if(isPerifRegion(addr)) switch(addr){
|
||||||
case 0xF0010000: if(wr && *data != 0) fail(); else *data = 0; break;
|
case 0xF0010000: if(wr && *data != 0) fail(); else *data = 0; break;
|
||||||
|
@ -3733,9 +3759,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " mask=0x" << mask << " data=0x" << data << dec << endl; fail(); break;
|
default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " data=0x" << data << dec << endl; fail(); break;
|
||||||
}
|
}
|
||||||
Workspace::dBusAccess(addr,wr,size,mask,data,error);
|
Workspace::dBusAccess(addr,wr,size,dataBytes,error);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onStdout(char c){
|
virtual void onStdout(char c){
|
||||||
|
@ -4058,6 +4084,30 @@ int main(int argc, char **argv, char **env) {
|
||||||
printf("BOOT\n");
|
printf("BOOT\n");
|
||||||
timespec startedAt = timer_start();
|
timespec startedAt = timer_start();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LINUX_SOC_SMP
|
||||||
|
{
|
||||||
|
|
||||||
|
LinuxSocSmp soc("linuxSmp");
|
||||||
|
#ifndef DEBUG_PLUGIN_EXTERNAL
|
||||||
|
soc.withRiscvRef();
|
||||||
|
soc.loadBin(EMULATOR, 0x80000000);
|
||||||
|
soc.loadBin(VMLINUX, 0x80400000);
|
||||||
|
soc.loadBin(DTB, 0x80FF0000);
|
||||||
|
soc.loadBin(RAMDISK, 0x81000000);
|
||||||
|
#endif
|
||||||
|
//soc.setIStall(true);
|
||||||
|
//soc.setDStall(true);
|
||||||
|
soc.bootAt(0x80000000);
|
||||||
|
soc.run(0);
|
||||||
|
// soc.run((496300000l + 2000000) / 2);
|
||||||
|
// soc.run(438700000l/2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef RVF
|
#ifdef RVF
|
||||||
for(const string &name : riscvTestFloat){
|
for(const string &name : riscvTestFloat){
|
||||||
redo(REDO,RiscvTest(name).withRiscvRef()->bootAt(0x80000188u)->writeWord(0x80000184u, 0x00305073)->run();)
|
redo(REDO,RiscvTest(name).withRiscvRef()->bootAt(0x80000188u)->writeWord(0x80000184u, 0x00305073)->run();)
|
||||||
|
@ -4141,27 +4191,6 @@ int main(int argc, char **argv, char **env) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef LINUX_SOC_SMP
|
|
||||||
{
|
|
||||||
|
|
||||||
LinuxSocSmp soc("linuxSmp");
|
|
||||||
#ifndef DEBUG_PLUGIN_EXTERNAL
|
|
||||||
soc.withRiscvRef();
|
|
||||||
soc.loadBin(EMULATOR, 0x80000000);
|
|
||||||
soc.loadBin(VMLINUX, 0xC0000000);
|
|
||||||
soc.loadBin(DTB, 0xC4000000);
|
|
||||||
soc.loadBin(RAMDISK, 0xC2000000);
|
|
||||||
#endif
|
|
||||||
//soc.setIStall(true);
|
|
||||||
//soc.setDStall(true);
|
|
||||||
soc.bootAt(0x80000000);
|
|
||||||
soc.run(0);
|
|
||||||
// soc.run((496300000l + 2000000) / 2);
|
|
||||||
// soc.run(438700000l/2);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,15 @@ ifneq ($(EXTERNAL_INTERRUPT),no)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(shell grep utime ${VEXRISCV_FILE} -w),)
|
||||||
|
ADDCFLAGS += -CFLAGS -DUTIME_INPUT
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(shell grep dBus_rsp_payload_aggregated ${VEXRISCV_FILE} -w),)
|
||||||
|
ADDCFLAGS += -CFLAGS -DDBUS_AGGREGATION
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(RUN_HEX),no)
|
ifneq ($(RUN_HEX),no)
|
||||||
ADDCFLAGS += -CFLAGS -DRUN_HEX='\"$(RUN_HEX)\"'
|
ADDCFLAGS += -CFLAGS -DRUN_HEX='\"$(RUN_HEX)\"'
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -55,11 +55,11 @@ class FpuTest extends FunSuite{
|
||||||
}
|
}
|
||||||
|
|
||||||
def testP(p : FpuParameter){
|
def testP(p : FpuParameter){
|
||||||
val portCount = 4
|
val portCount = 1
|
||||||
|
|
||||||
val config = SimConfig
|
val config = SimConfig
|
||||||
config.allOptimisation
|
config.allOptimisation
|
||||||
// if(p.withDouble) config.withFstWave
|
if(p.withDouble) config.withFstWave
|
||||||
config.compile(new FpuCore(portCount, p){
|
config.compile(new FpuCore(portCount, p){
|
||||||
for(i <- 0 until portCount) out(Bits(5 bits)).setName(s"flagAcc$i") := io.port(i).completion.flags.asBits
|
for(i <- 0 until portCount) out(Bits(5 bits)).setName(s"flagAcc$i") := io.port(i).completion.flags.asBits
|
||||||
setDefinitionName("FpuCore"+ (if(p.withDouble) "Double" else ""))
|
setDefinitionName("FpuCore"+ (if(p.withDouble) "Double" else ""))
|
||||||
|
@ -1286,6 +1286,17 @@ class FpuTest extends FunSuite{
|
||||||
//TODO double <-> simple convertions
|
//TODO double <-> simple convertions
|
||||||
if(p.withDouble) {
|
if(p.withDouble) {
|
||||||
|
|
||||||
|
load(0, 1.0)
|
||||||
|
load(0, 2.0)
|
||||||
|
load(0, 2.5)
|
||||||
|
load(0, 0.75)
|
||||||
|
load(0, -5)
|
||||||
|
load(0, 0)
|
||||||
|
load(0, Double.PositiveInfinity)
|
||||||
|
load(0, Double.NaN)
|
||||||
|
dut.clockDomain.waitSampling(200)
|
||||||
|
simSuccess()
|
||||||
|
|
||||||
for(_ <- 0 until 10000) testSgnjF64()
|
for(_ <- 0 until 10000) testSgnjF64()
|
||||||
println("f64 sgnj done")
|
println("f64 sgnj done")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue