Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
spinal.lib.cpu.riscv.impl.Misc.scala Maven / Gradle / Ivy
package spinal.lib.cpu.riscv.impl
import spinal.core._
import spinal.lib.IMasterSlave
import spinal.lib.cpu.riscv.impl.Utils.InstructionCtrl
case class IrqUsage(isException : Boolean)
object Utils{
object PC extends SpinalEnum(binarySequential){
val INC,BRA,J,JR = newElement()
}
object BR extends SpinalEnum{
val N, NE, EQ, GE, GEU, LT, LTU, J, JR = newElement()
defaultEncoding = SpinalEnumEncoding("opt")(
EQ -> 0,
NE -> 1,
J -> 2,
JR -> 3,
LT -> 4,
GE -> 5,
LTU -> 6,
GEU -> 7,
N -> 8
)
def isSignedComp(that : C) = !that.asBits(1)
}
object OP0 extends SpinalEnum(binarySequential){
val RS, IMU, IMZ, IMJB = newElement()
def X = RS
}
object OP1 extends SpinalEnum(binarySequential){
val RS, IMI, IMS, PC = newElement()
def X = RS
}
object WB extends SpinalEnum(binarySequential){
val ALU, MEM, PC4, CSR1 = newElement()
def X = ALU
}
object MWR extends SpinalEnum(binarySequential){
val R, W, F = newElement()
}
object MSK extends SpinalEnum(binarySequential){
val B,H,W = newElement()
def X = B
}
object MFS extends SpinalEnum{
val N, SI, SD, FA, FD = newElement()
}
object M extends SpinalEnum(binarySequential){
val XRD, XWR = newElement()
def X = XRD
}
object ALU extends SpinalEnum{
val ADD, SLL1, SLT, SLTU, XOR, SRL, OR, AND, SUB, COPY, SRA = newElement()
defaultEncoding = SpinalEnumEncoding("opt")(
ADD -> 0,
SLL1 -> 1,
SLT -> 2,
SLTU -> 3,
XOR -> 4,
SRL -> 5,
OR -> 6,
AND -> 7,
SUB -> (8+0),
COPY -> 15,
SRA -> (8+5)
)
def X = ADD
def isSltX(that : C) = that.asBits === M"-01-"
def isAddSub(that : C) = that.asBits === M"-000"
}
def apply(x : Int) = 2
object CSR extends SpinalEnum(binarySequential){
val N, W, S, C = newElement()
}
case class InstructionCtrl() extends Bundle{
val instVal = Bool()
val br = BR()
val jmp = Bool()
val op0 = OP0()
val op1 = OP1()
val alu = ALU()
val wb = WB()
val rfen = Bool()
val execute0AluBypass = Bool()
val execute1AluBypass = Bool()
val canInternalyStallWriteBack0 = Bool()
val men = Bool()
val m = M()
val msk = MSK()
val csr = CSR()
val mfs = MFS()
val useSrc0 = Bool()
val useSrc1 = Bool()
val extensionTag = Bits()
val extensionData = Bits()
val fencei = Bool()
}
def BASE = M"------------------------------11"
def BASE_MEM = M"-------------------------0-000--"
def BASE_MEM_L = M"--------------------------0-----"
def BASE_MEM_S = M"--------------------------1-----"
def BASE_AUIPC = M"-------------------------00101--"
def BASE_LUI = M"-------------------------01101--"
def BASE_OPX = M"-------------------------0-100--"
def BASE_OPX_I = M"--------------------------0-----"
def BASE_OPX_SHIFT = M"------------------01------------"
def BASE_JALR = M"-------------------------11001--"
def BASE_JAL = M"-------------------------11011--"
def BASE_B = M"-------------------------11000--"
def BASE_CSR = M"-------------------------11100--"
def BASE_CSR_W = M"------------------01------------"
def BASE_CSR_S = M"------------------10------------"
def BASE_CSR_C = M"------------------11------------"
def BASE_CSR_I = M"-----------------1--------------"
def BASE_FENCEI = M"000000000000000000010000000011--"
object InstructionCtrl{
def apply(instruction : Bits) : InstructionCtrl = {
val ctrl = InstructionCtrl()
ctrl.instVal := False
ctrl.br := BR.N
ctrl.jmp := False
ctrl.op0 := OP0.X
ctrl.op1 := OP1.X
ctrl.alu := ALU.ADD
ctrl.wb := WB.X
ctrl.rfen := False
ctrl.execute0AluBypass := False
ctrl.execute1AluBypass := False
ctrl.canInternalyStallWriteBack0 := False
ctrl.men := False
ctrl.m := M.XRD
ctrl.msk.assignFromBits(instruction(13 downto 12))
ctrl.csr := CSR.N
ctrl.mfs := MFS.N
ctrl.useSrc0 := False
ctrl.useSrc1 := False
ctrl.extensionTag := 0
ctrl.extensionData := 0
ctrl.fencei := False
when(instruction === BASE){
ctrl.fencei := instruction === BASE_FENCEI
when(instruction === BASE_MEM){
ctrl.instVal := True
ctrl.op0 := OP0.RS
ctrl.alu := ALU.ADD
ctrl.men := True
ctrl.useSrc0 := True
when(instruction === BASE_MEM_L){
ctrl.op1 := OP1.IMI
ctrl.wb := WB.MEM
ctrl.rfen := True
ctrl.m := M.XRD
}otherwise{
ctrl.op1 := OP1.IMS
ctrl.m := M.XWR
ctrl.useSrc1 := True
}
}
when(instruction === BASE_AUIPC){
ctrl.instVal := True
ctrl.op0 := OP0.IMU
ctrl.op1 := OP1.PC
ctrl.alu := ALU.ADD
ctrl.wb := WB.ALU
ctrl.rfen := True
ctrl.execute0AluBypass := True
ctrl.execute1AluBypass := True
}
when(instruction === BASE_LUI){
ctrl.instVal := True
ctrl.op0 := OP0.IMU
ctrl.alu := ALU.COPY
ctrl.wb := WB.ALU
ctrl.rfen := True
ctrl.execute0AluBypass := True
ctrl.execute1AluBypass := True
}
when(instruction === BASE_OPX){
val isShift = instruction === BASE_OPX_SHIFT
when(instruction === BASE_OPX_I) {
when(!isShift || (instruction === M"0-00000-------------------------" && !(instruction(30) && !instruction(14)))) {
ctrl.instVal := True
ctrl.op0 := OP0.RS
ctrl.op1 := OP1.IMI
ctrl.alu.assignFromBits((isShift && instruction(30)) ## instruction(14 downto 12))
ctrl.wb := WB.ALU
ctrl.rfen := True
ctrl.execute0AluBypass := !isShift
ctrl.execute1AluBypass := True
ctrl.useSrc0 := True
}
}otherwise{
when(instruction === M"0-00000-------------------------"){
when(instruction(30) === False || instruction(14 downto 12) === B"000" || instruction(14 downto 12) === B"101"){
ctrl.instVal := True
ctrl.op0 := OP0.RS
ctrl.op1 := OP1.RS
ctrl.alu.assignFromBits(instruction(30) ## instruction(14 downto 12))
ctrl.wb := WB.ALU
ctrl.rfen := True
ctrl.execute0AluBypass := !isShift
ctrl.execute1AluBypass := True
ctrl.useSrc0 := True
ctrl.useSrc1 := True
}
}
}
}
when(instruction === BASE_JAL){
ctrl.instVal := True
ctrl.br := BR.J
ctrl.alu := ALU.ADD
ctrl.op0 := OP0.IMJB
ctrl.op1 := OP1.PC
ctrl.jmp := True
ctrl.wb := WB.PC4
ctrl.rfen := True
}
when(instruction === BASE_JALR){
ctrl.instVal := True
ctrl.br := BR.JR
ctrl.jmp := True
ctrl.op0 := OP0.RS
ctrl.op1 := OP1.IMI
ctrl.alu := ALU.ADD
ctrl.wb := WB.PC4
ctrl.rfen := True
ctrl.useSrc0 := True
}
when(instruction === BASE_B){
ctrl.instVal := True
ctrl.alu := ALU.ADD
ctrl.op0 := OP0.IMJB
ctrl.op1 := OP1.PC
ctrl.br.assignFromBits(False ## instruction(14 downto 12))
ctrl.useSrc0 := True
ctrl.useSrc1 := True
}
when(instruction === BASE_CSR){
ctrl.instVal := True
when(instruction === BASE_CSR_I){
ctrl.op0 := OP0.IMZ
}otherwise {
ctrl.op0 := OP0.RS
}
ctrl.alu := ALU.COPY
ctrl.wb := WB.CSR1
ctrl.rfen := True
ctrl.csr.assignFromBits(instruction(13 downto 12))
}
}
ctrl
}
}
case class IMM(instruction : Bits) extends Area{
// immediates
def i = instruction(31 downto 20)
def s = instruction(31 downto 25) ## instruction(11 downto 7)
def b = instruction(31) ## instruction(7) ## instruction(30 downto 25) ## instruction(11 downto 8)
def u = instruction(31 downto 12) ## U"x000"
def j = instruction(31) ## instruction(19 downto 12) ## instruction(20) ## instruction(30 downto 21)
def z = instruction(19 downto 15)
// sign-extend immediates
def i_sext = B((19 downto 0) -> i(11)) ## i
def s_sext = B((19 downto 0) -> s(11)) ## s
def b_sext = B((18 downto 0) -> b(11)) ## b ## False
def j_sext = B((10 downto 0) -> j(19)) ## j ## False
}
def src0Range = 19 downto 15
def src1Range = 24 downto 20
def dstRange = 11 downto 7
}
object UtilsTest{
class TopLevel extends Component{
val instruction = in Bits(32 bit)
val result = out(RegNext(Utils.InstructionCtrl(RegNext(instruction))))
}
def main(args: Array[String]) {
SpinalVhdl(new TopLevel())
SpinalVerilog(new TopLevel().setDefinitionName("TopLevelV"))
}
}