Minor refactor of StoreGen/AMOALU. Bugfix for 32b ops in L2's AMOALU.
This commit is contained in:
parent
e1f573918d
commit
d391f97953
123
uncore/src/main/scala/amoalu.scala
Normal file
123
uncore/src/main/scala/amoalu.scala
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
package uncore
|
||||||
|
import Chisel._
|
||||||
|
|
||||||
|
abstract class StoreGen(typ: UInt, addr: UInt, dat: UInt) {
|
||||||
|
val byte = typ === MT_B || typ === MT_BU
|
||||||
|
val half = typ === MT_H || typ === MT_HU
|
||||||
|
val word = typ === MT_W || typ === MT_WU
|
||||||
|
|
||||||
|
def mask: UInt
|
||||||
|
def data: UInt
|
||||||
|
def wordData: UInt
|
||||||
|
}
|
||||||
|
|
||||||
|
class StoreGen64(typ: UInt, addr: UInt, dat: UInt) extends StoreGen(typ, addr, dat) {
|
||||||
|
def mask =
|
||||||
|
Mux(byte, Bits( 1) << addr(2,0),
|
||||||
|
Mux(half, Bits( 3) << Cat(addr(2,1), Bits(0,1)),
|
||||||
|
Mux(word, Bits( 15) << Cat(addr(2), Bits(0,2)),
|
||||||
|
Bits(255))))
|
||||||
|
|
||||||
|
def data =
|
||||||
|
Mux(byte, Fill(8, dat( 7,0)),
|
||||||
|
Mux(half, Fill(4, dat(15,0)),
|
||||||
|
wordData))
|
||||||
|
def wordData =
|
||||||
|
Mux(word, Fill(2, dat(31,0)),
|
||||||
|
dat)
|
||||||
|
}
|
||||||
|
|
||||||
|
class StoreGenAligned64(typ: UInt, addr: UInt, dat: UInt) extends StoreGen64(typ, addr, dat) {
|
||||||
|
override def data = dat
|
||||||
|
override def wordData = dat
|
||||||
|
}
|
||||||
|
|
||||||
|
class StoreGen32(typ: UInt, addr: UInt, dat: UInt) extends StoreGen(typ, addr, dat){
|
||||||
|
override val word = typ === MT_W
|
||||||
|
|
||||||
|
def mask =
|
||||||
|
Mux(byte, Bits( 1) << addr(2,0),
|
||||||
|
Mux(half, Bits( 3) << Cat(addr(2,1), Bits(0,1)),
|
||||||
|
Bits( 15)))
|
||||||
|
|
||||||
|
def data =
|
||||||
|
Mux(byte, Fill(4, dat( 7,0)),
|
||||||
|
Mux(half, Fill(2, dat(15,0)),
|
||||||
|
wordData))
|
||||||
|
|
||||||
|
def wordData = dat
|
||||||
|
|
||||||
|
def size =
|
||||||
|
Mux(byte, UInt("b000"),
|
||||||
|
Mux(half, UInt("b001"),
|
||||||
|
UInt("b010")))
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoadGen64(typ: UInt, addr: UInt, dat: UInt, zero: Bool) {
|
||||||
|
val t = new StoreGen64(typ, addr, dat)
|
||||||
|
val sign = typ === MT_B || typ === MT_H || typ === MT_W || typ === MT_D
|
||||||
|
|
||||||
|
val wordShift = Mux(addr(2), dat(63,32), dat(31,0))
|
||||||
|
val word = Cat(Mux(t.word, Fill(32, sign && wordShift(31)), dat(63,32)), wordShift)
|
||||||
|
val halfShift = Mux(addr(1), word(31,16), word(15,0))
|
||||||
|
val half = Cat(Mux(t.half, Fill(48, sign && halfShift(15)), word(63,16)), halfShift)
|
||||||
|
val byteShift = Mux(zero, UInt(0), Mux(addr(0), half(15,8), half(7,0)))
|
||||||
|
val byte = Cat(Mux(zero || t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift)
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoadGen32(typ: UInt, addr: UInt, dat: UInt) {
|
||||||
|
val t = new StoreGen32(typ, addr, dat)
|
||||||
|
val sign = typ === MT_B || typ === MT_H || typ === MT_W
|
||||||
|
|
||||||
|
val word = dat
|
||||||
|
val halfShift = Mux(addr(1), word(31,16), word(15,0))
|
||||||
|
val half = Cat(Mux(t.half, Fill(16, sign && halfShift(15)), word(31,16)), halfShift)
|
||||||
|
val byteShift = Mux(addr(0), half(15,8), half(7,0))
|
||||||
|
val byte = Cat(Mux(t.byte, Fill(24, sign && byteShift(7)), half(31,8)), byteShift)
|
||||||
|
}
|
||||||
|
|
||||||
|
class AMOALU(rhsIsAligned: Boolean = false)(implicit p: Parameters) extends CacheModule()(p) {
|
||||||
|
val operandBits = p(AmoAluOperandBits)
|
||||||
|
require(operandBits == 64)
|
||||||
|
val io = new Bundle {
|
||||||
|
val addr = Bits(INPUT, blockOffBits)
|
||||||
|
val cmd = Bits(INPUT, M_SZ)
|
||||||
|
val typ = Bits(INPUT, MT_SZ)
|
||||||
|
val lhs = Bits(INPUT, operandBits)
|
||||||
|
val rhs = Bits(INPUT, operandBits)
|
||||||
|
val out = Bits(OUTPUT, operandBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
val storegen = if(rhsIsAligned) new StoreGenAligned64(io.typ, io.addr, io.rhs)
|
||||||
|
else new StoreGen64(io.typ, io.addr, io.rhs)
|
||||||
|
val rhs = storegen.wordData
|
||||||
|
|
||||||
|
val sgned = io.cmd === M_XA_MIN || io.cmd === M_XA_MAX
|
||||||
|
val max = io.cmd === M_XA_MAX || io.cmd === M_XA_MAXU
|
||||||
|
val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU
|
||||||
|
val word = io.typ === MT_W || io.typ === MT_WU || // Logic minimization:
|
||||||
|
io.typ === MT_B || io.typ === MT_BU
|
||||||
|
|
||||||
|
val mask = ~UInt(0,64) ^ (io.addr(2) << 31)
|
||||||
|
val adder_out = (io.lhs & mask).toUInt + (rhs & mask)
|
||||||
|
|
||||||
|
val cmp_lhs = Mux(word && !io.addr(2), io.lhs(31), io.lhs(63))
|
||||||
|
val cmp_rhs = Mux(word && !io.addr(2), rhs(31), rhs(63))
|
||||||
|
val lt_lo = io.lhs(31,0) < rhs(31,0)
|
||||||
|
val lt_hi = io.lhs(63,32) < rhs(63,32)
|
||||||
|
val eq_hi = io.lhs(63,32) === rhs(63,32)
|
||||||
|
val lt = Mux(word, Mux(io.addr(2), lt_hi, lt_lo), lt_hi || eq_hi && lt_lo)
|
||||||
|
val less = Mux(cmp_lhs === cmp_rhs, lt, Mux(sgned, cmp_lhs, cmp_rhs))
|
||||||
|
|
||||||
|
val out = Mux(io.cmd === M_XA_ADD, adder_out,
|
||||||
|
Mux(io.cmd === M_XA_AND, io.lhs & rhs,
|
||||||
|
Mux(io.cmd === M_XA_OR, io.lhs | rhs,
|
||||||
|
Mux(io.cmd === M_XA_XOR, io.lhs ^ rhs,
|
||||||
|
Mux(Mux(less, min, max), io.lhs,
|
||||||
|
storegen.data)))))
|
||||||
|
|
||||||
|
val wmask = FillInterleaved(8, storegen.mask)
|
||||||
|
io.out := wmask & out | ~wmask & io.lhs
|
||||||
|
}
|
@ -38,79 +38,6 @@ abstract class CacheModule(implicit val p: Parameters) extends Module
|
|||||||
abstract class CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
abstract class CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||||
with HasCacheParameters
|
with HasCacheParameters
|
||||||
|
|
||||||
class StoreGen(typ: UInt, addr: UInt, dat: UInt) {
|
|
||||||
val byte = typ === MT_B || typ === MT_BU
|
|
||||||
val half = typ === MT_H || typ === MT_HU
|
|
||||||
val word = typ === MT_W || typ === MT_WU
|
|
||||||
def mask =
|
|
||||||
Mux(byte, Bits( 1) << addr(2,0),
|
|
||||||
Mux(half, Bits( 3) << Cat(addr(2,1), Bits(0,1)),
|
|
||||||
Mux(word, Bits( 15) << Cat(addr(2), Bits(0,2)),
|
|
||||||
Bits(255))))
|
|
||||||
def data =
|
|
||||||
Mux(byte, Fill(8, dat( 7,0)),
|
|
||||||
Mux(half, Fill(4, dat(15,0)),
|
|
||||||
wordData))
|
|
||||||
lazy val wordData =
|
|
||||||
Mux(word, Fill(2, dat(31,0)),
|
|
||||||
dat)
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadGen(typ: UInt, addr: UInt, dat: UInt, zero: Bool) {
|
|
||||||
val t = new StoreGen(typ, addr, dat)
|
|
||||||
val sign = typ === MT_B || typ === MT_H || typ === MT_W || typ === MT_D
|
|
||||||
|
|
||||||
val wordShift = Mux(addr(2), dat(63,32), dat(31,0))
|
|
||||||
val word = Cat(Mux(t.word, Fill(32, sign && wordShift(31)), dat(63,32)), wordShift)
|
|
||||||
val halfShift = Mux(addr(1), word(31,16), word(15,0))
|
|
||||||
val half = Cat(Mux(t.half, Fill(48, sign && halfShift(15)), word(63,16)), halfShift)
|
|
||||||
val byteShift = Mux(zero, UInt(0), Mux(addr(0), half(15,8), half(7,0)))
|
|
||||||
val byte = Cat(Mux(zero || t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift)
|
|
||||||
}
|
|
||||||
|
|
||||||
class AMOALU(implicit p: Parameters) extends CacheModule()(p) {
|
|
||||||
val operandBits = p(AmoAluOperandBits)
|
|
||||||
require(operandBits == 64)
|
|
||||||
val io = new Bundle {
|
|
||||||
val addr = Bits(INPUT, blockOffBits)
|
|
||||||
val cmd = Bits(INPUT, M_SZ)
|
|
||||||
val typ = Bits(INPUT, MT_SZ)
|
|
||||||
val lhs = Bits(INPUT, operandBits)
|
|
||||||
val rhs = Bits(INPUT, operandBits)
|
|
||||||
val out = Bits(OUTPUT, operandBits)
|
|
||||||
}
|
|
||||||
|
|
||||||
val storegen = new StoreGen(io.typ, io.addr, io.rhs)
|
|
||||||
val rhs = storegen.wordData
|
|
||||||
|
|
||||||
val sgned = io.cmd === M_XA_MIN || io.cmd === M_XA_MAX
|
|
||||||
val max = io.cmd === M_XA_MAX || io.cmd === M_XA_MAXU
|
|
||||||
val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU
|
|
||||||
val word = io.typ === MT_W || io.typ === MT_WU || // Logic minimization:
|
|
||||||
io.typ === MT_B || io.typ === MT_BU
|
|
||||||
|
|
||||||
val mask = ~UInt(0,64) ^ (io.addr(2) << 31)
|
|
||||||
val adder_out = (io.lhs & mask).toUInt + (rhs & mask)
|
|
||||||
|
|
||||||
val cmp_lhs = Mux(word && !io.addr(2), io.lhs(31), io.lhs(63))
|
|
||||||
val cmp_rhs = Mux(word && !io.addr(2), rhs(31), rhs(63))
|
|
||||||
val lt_lo = io.lhs(31,0) < rhs(31,0)
|
|
||||||
val lt_hi = io.lhs(63,32) < rhs(63,32)
|
|
||||||
val eq_hi = io.lhs(63,32) === rhs(63,32)
|
|
||||||
val lt = Mux(word, Mux(io.addr(2), lt_hi, lt_lo), lt_hi || eq_hi && lt_lo)
|
|
||||||
val less = Mux(cmp_lhs === cmp_rhs, lt, Mux(sgned, cmp_lhs, cmp_rhs))
|
|
||||||
|
|
||||||
val out = Mux(io.cmd === M_XA_ADD, adder_out,
|
|
||||||
Mux(io.cmd === M_XA_AND, io.lhs & rhs,
|
|
||||||
Mux(io.cmd === M_XA_OR, io.lhs | rhs,
|
|
||||||
Mux(io.cmd === M_XA_XOR, io.lhs ^ rhs,
|
|
||||||
Mux(Mux(less, min, max), io.lhs,
|
|
||||||
storegen.data)))))
|
|
||||||
|
|
||||||
val wmask = FillInterleaved(8, storegen.mask)
|
|
||||||
io.out := wmask & out | ~wmask & io.lhs
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class ReplacementPolicy {
|
abstract class ReplacementPolicy {
|
||||||
def way: UInt
|
def way: UInt
|
||||||
def miss: Unit
|
def miss: Unit
|
||||||
@ -652,12 +579,12 @@ class L2AcquireTracker(trackerId: Int)(implicit p: Parameters) extends L2XactTra
|
|||||||
|
|
||||||
// Provide a single ALU per tracker to merge Puts and AMOs with data being
|
// Provide a single ALU per tracker to merge Puts and AMOs with data being
|
||||||
// refilled, written back, or extant in the cache
|
// refilled, written back, or extant in the cache
|
||||||
val amoalu = Module(new AMOALU)
|
val amoalu = Module(new AMOALU(rhsIsAligned = true))
|
||||||
amoalu.io.addr := xact.full_addr()
|
amoalu.io.addr := xact.full_addr()
|
||||||
amoalu.io.cmd := xact.op_code()
|
amoalu.io.cmd := xact.op_code()
|
||||||
amoalu.io.typ := xact.op_size()
|
amoalu.io.typ := xact.op_size()
|
||||||
amoalu.io.lhs := io.data.resp.bits.data // default, overwritten by calls to mergeData
|
amoalu.io.lhs := io.data.resp.bits.data // default, overwritten by calls to mergeData
|
||||||
amoalu.io.rhs := xact.data_buffer.head // default, overwritten by calls to mergeData
|
amoalu.io.rhs := xact.data_buffer.head // default, overwritten by calls to mergeData
|
||||||
val amo_result = Reg(init = UInt(0, xact.tlDataBits))
|
val amo_result = Reg(init = UInt(0, xact.tlDataBits))
|
||||||
|
|
||||||
// Utility functions for updating the data and metadata that will be kept in
|
// Utility functions for updating the data and metadata that will be kept in
|
||||||
|
Loading…
Reference in New Issue
Block a user