Add store/load

This commit is contained in:
Dolu1990 2017-03-11 15:35:56 +01:00
parent fcb70a333f
commit e58f28bc27
2 changed files with 189 additions and 34 deletions

View File

@ -70,9 +70,9 @@ trait Pipeline {
stage.outputs.keysIterator.foreach(key => inputOutputKeys.getOrElseUpdate(key,new KeyInfo).addOutputStageIndex(stageIndex))
}
for((key,info) <- inputOutputKeys){
for((key,info) <- inputOutputKeys) {
//Interconnect inputs -> outputs
for(stageIndex <- info.insertStageId to info.lastOutputStageId;
for (stageIndex <- info.insertStageId to info.lastOutputStageId;
stage = stages(stageIndex)) {
stage.output(key)
val outputDefault = stage.outputsDefault.getOrElse(key, null)
@ -82,7 +82,7 @@ trait Pipeline {
}
//Interconnect outputs -> inputs
for(stageIndex <- info.insertStageId to info.lastInputStageId) {
for (stageIndex <- info.insertStageId to info.lastInputStageId) {
val stage = stages(stageIndex)
stage.input(key)
val inputDefault = stage.inputsDefault.getOrElse(key, null)
@ -95,24 +95,23 @@ trait Pipeline {
}
}
}
}
//Arbitration
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){
stage.arbitration.isStuck := stages.takeRight(stages.length - stageIndex).map(_.arbitration.haltIt).reduce(_ || _)
stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt
//Arbitration
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){
stage.arbitration.isStuck := stages.takeRight(stages.length - stageIndex).map(_.arbitration.haltIt).reduce(_ || _)
stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt
}
for(stageIndex <- 1 until stages.length){
val stageBefore = stages(stageIndex - 1)
val stage = stages(stageIndex)
when(!stageBefore.arbitration.isStuck) {
stage.arbitration.isValid := stage.arbitration.isValid && !stage.arbitration.removeIt
}
for(stageIndex <- 1 until stages.length){
val stageBefore = stages(stageIndex - 1)
val stage = stages(stageIndex)
stage.arbitration.isStuck := stages.takeRight(stages.length-stageIndex).map(_.arbitration.haltIt).reduce(_ || _)
when(!stageBefore.arbitration.isStuck) {
stage.arbitration.isValid := stage.arbitration.isValid && !stage.arbitration.removeIt
}
when(stage.arbitration.removeIt){
stage.arbitration.isValid := False
}
when(stage.arbitration.removeIt){
stage.arbitration.isValid := False
}
}
}

View File

@ -71,13 +71,23 @@ object Riscv{
def SRAI = M"010000-----------101-----0010011"
def ORI = M"-----------------110-----0010011"
def ANDI = M"-----------------111-----0010011"
def LB = M"-----------------000-----0000011"
def LH = M"-----------------001-----0000011"
def LW = M"-----------------010-----0000011"
def LBU = M"-----------------100-----0000011"
def LHU = M"-----------------101-----0000011"
def LWU = M"-----------------110-----0000011"
def SB = M"-----------------000-----0100011"
def SH = M"-----------------001-----0100011"
def SW = M"-----------------010-----0100011"
}
case class VexRiscvConfig(pcWidth : Int){
val plugins = ArrayBuffer[Plugin[VexRiscv]]()
//TODO apply defaults to decoder
//Default Stageables
object BYPASSABLE_EXECUTE_STAGE extends Stageable(Bool)
object BYPASSABLE_MEMORY_STAGE extends Stageable(Bool)
@ -91,6 +101,8 @@ case class VexRiscvConfig(pcWidth : Int){
object REGFILE_WRITE_VALID extends Stageable(Bool)
object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
object SRC1_USE extends Stageable(Bool)
object SRC2_USE extends Stageable(Bool)
object SRC1 extends Stageable(Bits(32 bits))
object SRC2 extends Stageable(Bits(32 bits))
object SRC_ADD_SUB extends Stageable(Bits(32 bits))
@ -99,8 +111,6 @@ case class VexRiscvConfig(pcWidth : Int){
object SRC_LESS_UNSIGNED extends Stageable(Bool)
object ALU_RESULT extends Stageable(Bits(32 bits))
object Src1CtrlEnum extends SpinalEnum(binarySequential){
val RS, IMU, IMZ, IMJB = newElement()
}
@ -126,6 +136,7 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
trait DecoderService{
def add(key : MaskedLiteral,values : Seq[(Stageable[_ <: Data],Any)])
def add(encoding :Seq[(MaskedLiteral,Seq[(Stageable[_ <: Data],Any)])])
def addDefault(key : Stageable[_ <: Data], value : Any)
}
class DecoderSimplePlugin extends Plugin[VexRiscv] with DecoderService {
@ -138,6 +149,15 @@ class DecoderSimplePlugin extends Plugin[VexRiscv] with DecoderService {
})}
}
override def addDefault(key: Stageable[_ <: Data], value: Any): Unit = {
require(!defaults.contains(key))
defaults(key) = value match{
case e : SpinalEnumElement[_] => e()
case e : Data => e
}
}
val defaults = mutable.HashMap[Stageable[_ <: Data], Data]()
val encodings = mutable.HashMap[MaskedLiteral,Seq[(Stageable[_ <: Data], Any)]]()
override def build(pipeline: VexRiscv): Unit = {
@ -145,7 +165,11 @@ class DecoderSimplePlugin extends Plugin[VexRiscv] with DecoderService {
import pipeline.config._
val stageables = encodings.flatMap(_._2.map(_._1)).toSet
stageables.foreach(e => (insert(e).asInstanceOf[Data] := e().asInstanceOf[Data].getZero))
stageables.foreach(e => if(defaults.contains(e.asInstanceOf[Stageable[Data]]))
insert(e.asInstanceOf[Stageable[Data]]) := defaults(e.asInstanceOf[Stageable[Data]])
else
insert(e).assignDontCare())
stageables.foreach(insert(_) match{
case e : Bits => println(e.getWidth)
case _ =>
@ -238,12 +262,131 @@ class IBusSimplePlugin extends Plugin[VexRiscv]{
}
}
case class DBusSimpleCmd() extends Bundle{
val wr = Bool
val address = UInt(32 bits)
val data = Bits(32 bit)
val size = UInt(2 bit)
}
case class DBusSimpleRsp() extends Bundle{
val data = Bits(32 bit)
}
class DBusSimplePlugin extends Plugin[VexRiscv]{
var dCmd : Stream[DBusSimpleCmd] = null
var dRsp : DBusSimpleRsp = null
object MemoryCtrlEnum extends SpinalEnum{
val WR, RD = newElement()
}
object MEMORY_ENABLE extends Stageable(Bool)
object MEMORY_CTRL extends Stageable(MemoryCtrlEnum())
object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
override def setup(pipeline: VexRiscv): Unit = {
import pipeline.config._
import Riscv._
val decoderService = pipeline.service(classOf[DecoderService])
val stdActions = List[(Stageable[_ <: Data],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC_USE_SUB_LESS -> False,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
MEMORY_ENABLE -> True,
SRC1_USE -> True
)
decoderService.addDefault(MEMORY_ENABLE, False)
decoderService.add(List(
LB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LBU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LHU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
LWU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)),
SB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)),
SH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)),
SW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True))
))
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
execute plug new Area{
import execute._
dCmd = master Stream(DBusSimpleCmd())
dCmd.valid := input(MEMORY_ENABLE) && arbitration.isFiring
dCmd.wr := input(INSTRUCTION)(5)
dCmd.address := input(SRC_ADD_SUB).asUInt
dCmd.payload.data := input(SRC2)
dCmd.size := input(INSTRUCTION)(13 downto 12).asUInt
when(input(MEMORY_ENABLE) && !dCmd.ready){
arbitration.haltIt := True
}
}
memory plug new Area {
import memory._
dRsp = in(DBusSimpleRsp())
insert(MEMORY_READ_DATA) := dRsp.data
assert(!(input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
}
writeBack plug new Area {
import memory._
dRsp = in(DBusSimpleRsp())
val rspFormated = input(INSTRUCTION)(13 downto 12).mux(
default -> input(MEMORY_READ_DATA), //W
1 -> B((31 downto 8) -> (input(MEMORY_READ_DATA)(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> input(MEMORY_READ_DATA)(7 downto 0)),
2 -> B((31 downto 16) -> (input(MEMORY_READ_DATA)(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> input(MEMORY_READ_DATA)(15 downto 0))
)
when(input(MEMORY_ENABLE)) {
input(REGFILE_WRITE_DATA) := rspFormated
}
assert(!(input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
}
}
}
//class HazardSimplePlugin extends Plugin[VexRiscv] {
// import Riscv._
// override def build(pipeline: VexRiscv): Unit = {
// import pipeline.config._
// import pipeline._
// val src0Hazard = False
// val src1Hazard = False
//
//
// when(decode.input(INSTRUCTION)(rs1Range) === 0 || !decode.input(SRC1_USE)){
// src0Hazard := False
// }
// when(decode.input(INSTRUCTION)(rs2Range) === 0 || !decode.input(SRC2_USE)){
// src1Hazard := False
// }
// }
//}
trait RegFileReadKind
object ASYNC extends RegFileReadKind
object SYNC extends RegFileReadKind
class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]{
import Riscv._
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
@ -276,9 +419,13 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
insert(REG2) := Mux(rs2 =/= 0, rs2Data, B(0, 32 bit))
}
writeBack plug new Area{
writeBack plug new Area {
import writeBack._
//TODO write regfile
val regFileWrite = global.regFile.writePort
regFileWrite.valid := input(REGFILE_WRITE_VALID) && arbitration.isFiring
regFileWrite.address := input(INSTRUCTION)(rdRange).asUInt
regFileWrite.data := input(REGFILE_WRITE_DATA)
}
}
}
@ -342,7 +489,8 @@ class IntAluPlugin extends Plugin[VexRiscv]{
SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True
BYPASSABLE_MEMORY_STAGE -> True,
SRC1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: Data],Any)](
@ -351,7 +499,9 @@ class IntAluPlugin extends Plugin[VexRiscv]{
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True
BYPASSABLE_MEMORY_STAGE -> True,
SRC1_USE -> True,
SRC2_USE -> True
)
pipeline.service(classOf[DecoderService]).add(List(
@ -383,7 +533,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
import execute._
// mux results
insert(ALU_RESULT) := input(ALU_CTRL).mux(
insert(REGFILE_WRITE_DATA) := input(ALU_CTRL).mux(
AluCtrlEnum.AND -> (input(SRC1) & input(SRC2)),
AluCtrlEnum.OR -> (input(SRC1) | input(SRC2)),
AluCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)),
@ -407,6 +557,8 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
import pipeline.config._
import Riscv._
val immediateActions = List[(Stageable[_ <: Data],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
@ -425,13 +577,15 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
BYPASSABLE_MEMORY_STAGE -> True
)
pipeline.service(classOf[DecoderService]).add(List(
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(SHIFT_CTRL, ShiftCtrlEnum.DISABLE)
decoderService.add(List(
SLL -> (nonImmediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SLL)),
SRL -> (nonImmediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRL)),
SRA -> (nonImmediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRA))
))
pipeline.service(classOf[DecoderService]).add(List(
decoderService.add(List(
SLLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SLL)),
SRLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRL)),
SRAI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRA))
@ -454,10 +608,10 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
import memory._
switch(input(SHIFT_CTRL)){
is(ShiftCtrlEnum.SLL){
output(ALU_RESULT) := Reverse(input(SHIFT_RIGHT))
output(REGFILE_WRITE_DATA) := Reverse(input(SHIFT_RIGHT))
}
is(ShiftCtrlEnum.SRL,ShiftCtrlEnum.SRA){
output(ALU_RESULT) := input(SHIFT_RIGHT)
output(REGFILE_WRITE_DATA) := input(SHIFT_RIGHT)
}
}
}
@ -466,7 +620,7 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
class OutputAluResult extends Plugin[VexRiscv]{
override def build(pipeline: VexRiscv): Unit = {
out(pipeline.writeBack.input(pipeline.config.ALU_RESULT))
out(pipeline.writeBack.input(pipeline.config.REGFILE_WRITE_DATA))
}
}
@ -486,6 +640,8 @@ object TopLevel {
new IntAluPlugin,
new SrcPlugin,
new FullBarrielShifterPlugin,
new DBusSimplePlugin,
new HazardSimplePlugin,
new OutputAluResult
)