1
0
rocket-chip/src/main/scala/rocket/RVC.scala

169 lines
6.7 KiB
Scala
Raw Normal View History

// See LICENSE.SiFive for license details.
package freechips.rocketchip.rocket
2016-07-30 01:36:07 +02:00
import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.tile._
import freechips.rocketchip.util._
2016-07-30 01:36:07 +02:00
class ExpandedInstruction extends Bundle {
val bits = UInt(width = 32)
val rd = UInt(width = 5)
val rs1 = UInt(width = 5)
val rs2 = UInt(width = 5)
val rs3 = UInt(width = 5)
}
class RVCDecoder(x: UInt)(implicit p: Parameters) {
def inst(bits: UInt, rd: UInt = x(11,7), rs1: UInt = x(19,15), rs2: UInt = x(24,20), rs3: UInt = x(31,27)) = {
val res = Wire(new ExpandedInstruction)
res.bits := bits
res.rd := rd
res.rs1 := rs1
res.rs2 := rs2
res.rs3 := rs3
res
}
def rs1p = Cat(UInt(1,2), x(9,7))
def rs2p = Cat(UInt(1,2), x(4,2))
def rs2 = x(6,2)
def rd = x(11,7)
def addi4spnImm = Cat(x(10,7), x(12,11), x(5), x(6), UInt(0,2))
def lwImm = Cat(x(5), x(12,10), x(6), UInt(0,2))
def ldImm = Cat(x(6,5), x(12,10), UInt(0,3))
def lwspImm = Cat(x(3,2), x(12), x(6,4), UInt(0,2))
def ldspImm = Cat(x(4,2), x(12), x(6,5), UInt(0,3))
def swspImm = Cat(x(8,7), x(12,9), UInt(0,2))
def sdspImm = Cat(x(9,7), x(12,10), UInt(0,3))
def luiImm = Cat(Fill(15, x(12)), x(6,2), UInt(0,12))
def addi16spImm = Cat(Fill(3, x(12)), x(4,3), x(5), x(2), x(6), UInt(0,4))
def addiImm = Cat(Fill(7, x(12)), x(6,2))
def jImm = Cat(Fill(10, x(12)), x(8), x(10,9), x(6), x(7), x(2), x(11), x(5,3), UInt(0,1))
def bImm = Cat(Fill(5, x(12)), x(6,5), x(2), x(11,10), x(4,3), UInt(0,1))
def shamt = Cat(x(12), x(6,2))
def x0 = UInt(0,5)
def ra = UInt(1,5)
def sp = UInt(2,5)
def q0 = {
def addi4spn = {
val opc = Mux(x(12,5).orR, UInt(0x13,7), UInt(0x1F,7))
inst(Cat(addi4spnImm, sp, UInt(0,3), rs2p, opc), rs2p, sp, rs2p)
}
def ld = inst(Cat(ldImm, rs1p, UInt(3,3), rs2p, UInt(0x03,7)), rs2p, rs1p, rs2p)
def lw = inst(Cat(lwImm, rs1p, UInt(2,3), rs2p, UInt(0x03,7)), rs2p, rs1p, rs2p)
def fld = inst(Cat(ldImm, rs1p, UInt(3,3), rs2p, UInt(0x07,7)), rs2p, rs1p, rs2p)
def flw = {
if (p(XLen) == 32) inst(Cat(lwImm, rs1p, UInt(2,3), rs2p, UInt(0x07,7)), rs2p, rs1p, rs2p)
else ld
}
def unimp = inst(Cat(lwImm >> 5, rs2p, rs1p, UInt(2,3), lwImm(4,0), UInt(0x3F,7)), rs2p, rs1p, rs2p)
2016-07-30 01:36:07 +02:00
def sd = inst(Cat(ldImm >> 5, rs2p, rs1p, UInt(3,3), ldImm(4,0), UInt(0x23,7)), rs2p, rs1p, rs2p)
def sw = inst(Cat(lwImm >> 5, rs2p, rs1p, UInt(2,3), lwImm(4,0), UInt(0x23,7)), rs2p, rs1p, rs2p)
def fsd = inst(Cat(ldImm >> 5, rs2p, rs1p, UInt(3,3), ldImm(4,0), UInt(0x27,7)), rs2p, rs1p, rs2p)
def fsw = {
if (p(XLen) == 32) inst(Cat(lwImm >> 5, rs2p, rs1p, UInt(2,3), lwImm(4,0), UInt(0x27,7)), rs2p, rs1p, rs2p)
else sd
}
Seq(addi4spn, fld, lw, flw, unimp, fsd, sw, fsw)
}
def q1 = {
def addi = inst(Cat(addiImm, rd, UInt(0,3), rd, UInt(0x13,7)), rd, rd, rs2p)
def addiw = {
val opc = Mux(rd.orR, UInt(0x1B,7), UInt(0x1F,7))
inst(Cat(addiImm, rd, UInt(0,3), rd, opc), rd, rd, rs2p)
}
def jal = {
if (p(XLen) == 32) inst(Cat(jImm(20), jImm(10,1), jImm(11), jImm(19,12), ra, UInt(0x6F,7)), ra, rd, rs2p)
else addiw
}
def li = inst(Cat(addiImm, x0, UInt(0,3), rd, UInt(0x13,7)), rd, x0, rs2p)
def addi16sp = {
val opc = Mux(addiImm.orR, UInt(0x13,7), UInt(0x1F,7))
inst(Cat(addi16spImm, rd, UInt(0,3), rd, opc), rd, rd, rs2p)
}
def lui = {
val opc = Mux(addiImm.orR, UInt(0x37,7), UInt(0x3F,7))
val me = inst(Cat(luiImm(31,12), rd, opc), rd, rd, rs2p)
Mux(rd === x0 || rd === sp, addi16sp, me)
}
def j = inst(Cat(jImm(20), jImm(10,1), jImm(11), jImm(19,12), x0, UInt(0x6F,7)), x0, rs1p, rs2p)
def beqz = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, UInt(0,3), bImm(4,1), bImm(11), UInt(0x63,7)), rs1p, rs1p, x0)
def bnez = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, UInt(1,3), bImm(4,1), bImm(11), UInt(0x63,7)), x0, rs1p, x0)
def arith = {
def srli = Cat(shamt, rs1p, UInt(5,3), rs1p, UInt(0x13,7))
def srai = srli | UInt(1 << 30)
def andi = Cat(addiImm, rs1p, UInt(7,3), rs1p, UInt(0x13,7))
def rtype = {
val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)(Cat(x(12), x(6,5)))
val sub = Mux(x(6,5) === UInt(0), UInt(1 << 30), UInt(0))
val opc = Mux(x(12), UInt(0x3B,7), UInt(0x33,7))
Cat(rs2p, rs1p, funct, rs1p, opc) | sub
}
inst(Seq(srli, srai, andi, rtype)(x(11,10)), rs1p, rs1p, rs2p)
}
Seq(addi, jal, li, lui, arith, j, beqz, bnez)
}
def q2 = {
def slli = inst(Cat(shamt, rd, UInt(1,3), rd, UInt(0x13,7)), rd, rd, rs2)
def ldsp = inst(Cat(ldspImm, sp, UInt(3,3), rd, UInt(0x03,7)), rd, sp, rs2)
def lwsp = inst(Cat(lwspImm, sp, UInt(2,3), rd, UInt(0x03,7)), rd, sp, rs2)
def fldsp = inst(Cat(ldspImm, sp, UInt(3,3), rd, UInt(0x07,7)), rd, sp, rs2)
def flwsp = {
if (p(XLen) == 32) inst(Cat(lwspImm, sp, UInt(2,3), rd, UInt(0x07,7)), rd, sp, rs2)
else ldsp
}
def sdsp = inst(Cat(sdspImm >> 5, rs2, sp, UInt(3,3), sdspImm(4,0), UInt(0x23,7)), rd, sp, rs2)
def swsp = inst(Cat(swspImm >> 5, rs2, sp, UInt(2,3), swspImm(4,0), UInt(0x23,7)), rd, sp, rs2)
def fsdsp = inst(Cat(sdspImm >> 5, rs2, sp, UInt(3,3), sdspImm(4,0), UInt(0x27,7)), rd, sp, rs2)
def fswsp = {
if (p(XLen) == 32) inst(Cat(swspImm >> 5, rs2, sp, UInt(2,3), swspImm(4,0), UInt(0x27,7)), rd, sp, rs2)
else sdsp
}
def jalr = {
val mv = inst(Cat(rs2, x0, UInt(0,3), rd, UInt(0x33,7)), rd, x0, rs2)
val add = inst(Cat(rs2, rd, UInt(0,3), rd, UInt(0x33,7)), rd, rd, rs2)
val jr = Cat(rs2, rd, UInt(0,3), x0, UInt(0x67,7))
val reserved = Cat(jr >> 7, UInt(0x1F,7))
val jr_reserved = inst(Mux(rd.orR, jr, reserved), x0, rd, rs2)
val jr_mv = Mux(rs2.orR, mv, jr_reserved)
val jalr = Cat(rs2, rd, UInt(0,3), ra, UInt(0x67,7))
val ebreak = Cat(jr >> 7, UInt(0x73,7)) | UInt(1 << 20)
val jalr_ebreak = inst(Mux(rd.orR, jalr, ebreak), ra, rd, rs2)
val jalr_add = Mux(rs2.orR, add, jalr_ebreak)
Mux(x(12), jalr_add, jr_mv)
}
Seq(slli, fldsp, lwsp, flwsp, jalr, fsdsp, swsp, fswsp)
}
def q3 = Seq.fill(8)(passthrough)
def passthrough = inst(x)
def decode = {
val s = q0 ++ q1 ++ q2 ++ q3
s(Cat(x(1,0), x(15,13)))
}
}
Heterogeneous Tiles (#550) Fundamental new features: * Added tile package: This package is intended to hold components re-usable across different types of tile. Will be the future location of TL2-RoCC accelerators and new diplomatic versions of intra-tile interfaces. * Adopted [ModuleName]Params convention: Code base was very inconsistent about what to name case classes that provide parameters to modules. Settled on calling them [ModuleName]Params to distinguish them from config.Parameters and config.Config. So far applied mostly only to case classes defined within rocket and tile. * Defined RocketTileParams: A nested case class containing case classes for all the components of a tile (L1 caches and core). Allows all such parameters to vary per-tile. * Defined RocketCoreParams: All the parameters that can be varied per-core. * Defined L1CacheParams: A trait defining the parameters common to L1 caches, made concrete in different derived case classes. * Defined RocketTilesKey: A sequence of RocketTileParams, one for every tile to be created. * Provided HeterogeneousDualCoreConfig: An example of making a heterogeneous chip with two cores, one big and one little. * Changes to legacy code: ReplacementPolicy moved to package util. L1Metadata moved to package tile. Legacy L2 cache agent removed because it can no longer share the metadata array implementation with the L1. Legacy GroundTests on life support. Additional changes that got rolled in along the way: * rocket: Fix critical path through BTB for I$ index bits > pgIdxBits * coreplex: tiles connected via :=* * groundtest: updated to use TileParams * tilelink: cache cork requirements are relaxed to allow more cacheless masters
2017-02-09 22:59:09 +01:00
class RVCExpander(implicit val p: Parameters) extends Module with HasCoreParameters {
2016-07-30 01:36:07 +02:00
val io = new Bundle {
val in = UInt(INPUT, 32)
val out = new ExpandedInstruction
val rvc = Bool(OUTPUT)
}
Heterogeneous Tiles (#550) Fundamental new features: * Added tile package: This package is intended to hold components re-usable across different types of tile. Will be the future location of TL2-RoCC accelerators and new diplomatic versions of intra-tile interfaces. * Adopted [ModuleName]Params convention: Code base was very inconsistent about what to name case classes that provide parameters to modules. Settled on calling them [ModuleName]Params to distinguish them from config.Parameters and config.Config. So far applied mostly only to case classes defined within rocket and tile. * Defined RocketTileParams: A nested case class containing case classes for all the components of a tile (L1 caches and core). Allows all such parameters to vary per-tile. * Defined RocketCoreParams: All the parameters that can be varied per-core. * Defined L1CacheParams: A trait defining the parameters common to L1 caches, made concrete in different derived case classes. * Defined RocketTilesKey: A sequence of RocketTileParams, one for every tile to be created. * Provided HeterogeneousDualCoreConfig: An example of making a heterogeneous chip with two cores, one big and one little. * Changes to legacy code: ReplacementPolicy moved to package util. L1Metadata moved to package tile. Legacy L2 cache agent removed because it can no longer share the metadata array implementation with the L1. Legacy GroundTests on life support. Additional changes that got rolled in along the way: * rocket: Fix critical path through BTB for I$ index bits > pgIdxBits * coreplex: tiles connected via :=* * groundtest: updated to use TileParams * tilelink: cache cork requirements are relaxed to allow more cacheless masters
2017-02-09 22:59:09 +01:00
if (usingCompressed) {
2016-07-30 01:36:07 +02:00
io.rvc := io.in(1,0) =/= UInt(3)
io.out := new RVCDecoder(io.in).decode
} else {
io.rvc := Bool(false)
io.out := new RVCDecoder(io.in).passthrough
}
}