Add light shifter plugin

This commit is contained in:
Charles Papon 2017-03-16 15:11:06 +01:00
parent 401be6ca83
commit 52a524be06
5 changed files with 181 additions and 89 deletions

View File

@ -92,7 +92,7 @@ trait Pipeline {
inputDefault := stage.inserts(key)
} else {
val stageBefore = stages(stageIndex - 1)
inputDefault := RegNextWhen(stageBefore.output(key), !stageBefore.arbitration.isStuck) //!stage.input.valid || stage.input.ready
inputDefault := RegNextWhen(stageBefore.output(key), !stage.arbitration.isStuck) //!stage.input.valid || stage.input.ready
}
}
}

View File

@ -1,83 +0,0 @@
package SpinalRiscv.Plugin
import SpinalRiscv._
import spinal.core._
import spinal.lib.Reverse
class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
object ShiftCtrlEnum extends SpinalEnum(binarySequential){
val DISABLE, SLL, SRL, SRA = newElement()
}
object SHIFT_CTRL extends Stageable(ShiftCtrlEnum())
object SHIFT_RIGHT extends Stageable(Bits(32 bits))
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
val immediateActions = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True,
REG2_USE -> True
)
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))
))
decoderService.add(List(
SLLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SLL)),
SRLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRL)),
SRAI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRA))
))
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
execute plug new Area{
import execute._
val amplitude = input(SRC2)(4 downto 0).asUInt
val reversed = Mux(input(SHIFT_CTRL) === ShiftCtrlEnum.SLL, Reverse(input(SRC1)), input(SRC1))
insert(SHIFT_RIGHT) := (Cat(input(SHIFT_CTRL) === ShiftCtrlEnum.SRA & reversed.msb, reversed).asSInt >> amplitude)(31 downto 0).asBits
}
memory plug new Area{
import memory._
switch(input(SHIFT_CTRL)){
is(ShiftCtrlEnum.SLL){
output(REGFILE_WRITE_DATA) := Reverse(input(SHIFT_RIGHT))
}
is(ShiftCtrlEnum.SRL,ShiftCtrlEnum.SRA){
output(REGFILE_WRITE_DATA) := input(SHIFT_RIGHT)
}
}
}
}
}

View File

@ -2,15 +2,17 @@ package SpinalRiscv.Plugin
import SpinalRiscv._
import spinal.core._
class IntAluPlugin extends Plugin[VexRiscv]{
object IntAluPlugin{
object AluCtrlEnum extends SpinalEnum(binarySequential){
val ADD_SUB, SLT_SLTU, XOR, OR, AND, SRC1 = newElement()
}
object ALU_CTRL extends Stageable(AluCtrlEnum())
}
class IntAluPlugin extends Plugin[VexRiscv]{
import IntAluPlugin._
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._

View File

@ -0,0 +1,172 @@
package SpinalRiscv.Plugin
import SpinalRiscv._
import spinal.core._
import spinal.lib.Reverse
class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
object ShiftCtrlEnum extends SpinalEnum(binarySequential){
val DISABLE, SLL, SRL, SRA = newElement()
}
object SHIFT_CTRL extends Stageable(ShiftCtrlEnum())
object SHIFT_RIGHT extends Stageable(Bits(32 bits))
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
val immediateActions = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True,
REG2_USE -> True
)
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))
))
decoderService.add(List(
SLLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SLL)),
SRLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRL)),
SRAI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRA))
))
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
execute plug new Area{
import execute._
val amplitude = input(SRC2)(4 downto 0).asUInt
val reversed = Mux(input(SHIFT_CTRL) === ShiftCtrlEnum.SLL, Reverse(input(SRC1)), input(SRC1))
insert(SHIFT_RIGHT) := (Cat(input(SHIFT_CTRL) === ShiftCtrlEnum.SRA & reversed.msb, reversed).asSInt >> amplitude)(31 downto 0).asBits
}
memory plug new Area{
import memory._
switch(input(SHIFT_CTRL)){
is(ShiftCtrlEnum.SLL){
output(REGFILE_WRITE_DATA) := Reverse(input(SHIFT_RIGHT))
}
is(ShiftCtrlEnum.SRL,ShiftCtrlEnum.SRA){
output(REGFILE_WRITE_DATA) := input(SHIFT_RIGHT)
}
}
}
}
}
class LightShifterPlugin extends Plugin[VexRiscv]{
object ShiftCtrlEnum extends SpinalEnum(binarySequential){
val DISABLE, SLL, SRL, SRA = newElement()
}
object SHIFT_CTRL extends Stageable(ShiftCtrlEnum())
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
import IntAluPlugin._
val immediateActions = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.IMI,
ALU_CTRL -> AluCtrlEnum.SRC1,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
LEGAL_INSTRUCTION -> True,
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
ALU_CTRL -> AluCtrlEnum.SRC1,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True,
REG2_USE -> True
)
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))
))
decoderService.add(List(
SLLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SLL)),
SRLI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRL)),
SRAI -> (immediateActions ++ List(SHIFT_CTRL -> ShiftCtrlEnum.SRA))
))
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
execute plug new Area{
import execute._
val isActive = RegInit(False)
val isShift = input(SHIFT_CTRL) =/= ShiftCtrlEnum.DISABLE
val amplitudeReg = Reg(UInt(5 bits))
val amplitude = isActive ? amplitudeReg | input(SRC2)(4 downto 0).asUInt
val shiftInput = isActive ? memory.input(REGFILE_WRITE_DATA) | input(SRC1)
val done = amplitude(4 downto 1) === 0
when(arbitration.isValid && isShift && input(SRC2)(4 downto 0) =/= 0){
insert(REGFILE_WRITE_DATA) := input(SHIFT_CTRL).mux(
ShiftCtrlEnum.SLL -> (shiftInput |<< 1),
default -> (((input(SHIFT_CTRL) === ShiftCtrlEnum.SRA && shiftInput.msb) ## shiftInput).asSInt >> 1).asBits //ALU.SRL,ALU.SRA
)
when(!arbitration.isStuckByOthers){
isActive := True
amplitudeReg := amplitude - 1
when(done){
isActive := False
} otherwise{
arbitration.haltIt := True
}
}
}
}
}
}

View File

@ -37,7 +37,8 @@ object TopLevel {
new RegFilePlugin(Plugin.SYNC),
new IntAluPlugin,
new SrcPlugin,
new FullBarrielShifterPlugin,
// new FullBarrielShifterPlugin,
new LightShifterPlugin,
new DBusSimplePlugin,
new HazardSimplePlugin(false, true, false, true),
// new HazardSimplePlugin(false, false, false, false),