1
0

tilelink2: use byte-aligned addressing

This makes it possible to fully validate user input in a monitor.
We will override the lower bits with constant 0s in the TL connect.
This commit is contained in:
Wesley W. Terpstra 2016-08-22 13:18:01 -07:00
parent 45e152e97e
commit 8cff45f254
2 changed files with 48 additions and 30 deletions

View File

@ -11,16 +11,13 @@ class TLEdgeOut(
{ {
// Transfers // Transfers
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
// !!! Monitor: lgSize >= beatBytes
// !!! Monitor: check address alignment
// !!! Monitor: check param values
val legal = manager.supportsAcquire(toAddress, lgSize) val legal = manager.supportsAcquire(toAddress, lgSize)
val a = new TLBundleA(bundle) val a = new TLBundleA(bundle)
a.opcode := TLMessages.Acquire a.opcode := TLMessages.Acquire
a.param := growPermissions a.param := growPermissions
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := SInt(-1).asUInt a.wmask := SInt(-1).asUInt
a.data := UInt(0) a.data := UInt(0)
(legal, a) (legal, a)
@ -33,7 +30,7 @@ class TLEdgeOut(
c.param := shrinkPermissions c.param := shrinkPermissions
c.size := lgSize c.size := lgSize
c.source := fromSource c.source := fromSource
c.address := toAddress >> log2Up(manager.beatBytes) c.address := toAddress
c.data := UInt(0) c.data := UInt(0)
c.error := Bool(false) c.error := Bool(false)
(legal, c) (legal, c)
@ -46,7 +43,7 @@ class TLEdgeOut(
c.param := shrinkPermissions c.param := shrinkPermissions
c.size := lgSize c.size := lgSize
c.source := fromSource c.source := fromSource
c.address := toAddress >> log2Up(manager.beatBytes) c.address := toAddress
c.data := data c.data := data
c.error := Bool(false) c.error := Bool(false)
(legal, c) (legal, c)
@ -58,7 +55,7 @@ class TLEdgeOut(
c.param := reportPermissions c.param := reportPermissions
c.size := lgSize c.size := lgSize
c.source := UInt(0) c.source := UInt(0)
c.address := toAddress >> log2Up(manager.beatBytes) c.address := toAddress
c.data := UInt(0) c.data := UInt(0)
c.error := Bool(false) c.error := Bool(false)
c c
@ -70,7 +67,7 @@ class TLEdgeOut(
c.param := reportPermissions c.param := reportPermissions
c.size := lgSize c.size := lgSize
c.source := UInt(0) c.source := UInt(0)
c.address := toAddress >> log2Up(manager.beatBytes) c.address := toAddress
c.data := data c.data := data
c.error := Bool(false) c.error := Bool(false)
c c
@ -90,7 +87,7 @@ class TLEdgeOut(
a.param := UInt(0) a.param := UInt(0)
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := fullMask(toAddress, lgSize) a.wmask := fullMask(toAddress, lgSize)
a.data := UInt(0) a.data := UInt(0)
(legal, a) (legal, a)
@ -103,21 +100,20 @@ class TLEdgeOut(
a.param := UInt(0) a.param := UInt(0)
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := fullMask(toAddress, lgSize) a.wmask := fullMask(toAddress, lgSize)
a.data := data a.data := data
(legal, a) (legal, a)
} }
def Put(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, wmask: UInt) = { def Put(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, wmask: UInt) = {
// !!! Monitor: check that wmask is contained in lgSize
val legal = manager.supportsPutPartial(toAddress, lgSize) val legal = manager.supportsPutPartial(toAddress, lgSize)
val a = new TLBundleA(bundle) val a = new TLBundleA(bundle)
a.opcode := TLMessages.PutPartialData a.opcode := TLMessages.PutPartialData
a.param := UInt(0) a.param := UInt(0)
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := wmask a.wmask := wmask
a.data := data a.data := data
(legal, a) (legal, a)
@ -130,7 +126,7 @@ class TLEdgeOut(
a.param := atomic a.param := atomic
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := fullMask(toAddress, lgSize) a.wmask := fullMask(toAddress, lgSize)
a.data := data a.data := data
(legal, a) (legal, a)
@ -143,7 +139,7 @@ class TLEdgeOut(
a.param := atomic a.param := atomic
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := fullMask(toAddress, lgSize) a.wmask := fullMask(toAddress, lgSize)
a.data := data a.data := data
(legal, a) (legal, a)
@ -156,7 +152,7 @@ class TLEdgeOut(
a.param := param a.param := param
a.size := lgSize a.size := lgSize
a.source := fromSource a.source := fromSource
a.address := toAddress >> log2Up(manager.beatBytes) a.address := toAddress
a.wmask := fullMask(toAddress, lgSize) a.wmask := fullMask(toAddress, lgSize)
a.data := UInt(0) a.data := UInt(0)
(legal, a) (legal, a)
@ -168,7 +164,7 @@ class TLEdgeOut(
c.param := UInt(0) c.param := UInt(0)
c.size := lgSize c.size := lgSize
c.source := UInt(0) c.source := UInt(0)
c.address := toAddress >> log2Up(manager.beatBytes) c.address := toAddress
c.data := UInt(0) c.data := UInt(0)
c.error := error c.error := error
c c
@ -180,7 +176,7 @@ class TLEdgeOut(
c.param := UInt(0) c.param := UInt(0)
c.size := lgSize c.size := lgSize
c.source := UInt(0) c.source := UInt(0)
c.address := toAddress >> log2Up(manager.beatBytes) c.address := toAddress
c.data := data c.data := data
c.error := Bool(false) c.error := Bool(false)
c c
@ -200,7 +196,7 @@ class TLEdgeIn(
b.param := capPermissions b.param := capPermissions
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := fullMask(fromAddress, lgSize) b.wmask := fullMask(fromAddress, lgSize)
b.data := UInt(0) b.data := UInt(0)
(legal, b) (legal, b)
@ -250,7 +246,7 @@ class TLEdgeIn(
b.param := UInt(0) b.param := UInt(0)
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := fullMask(fromAddress, lgSize) b.wmask := fullMask(fromAddress, lgSize)
b.data := UInt(0) b.data := UInt(0)
(legal, b) (legal, b)
@ -263,7 +259,7 @@ class TLEdgeIn(
b.param := UInt(0) b.param := UInt(0)
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := fullMask(fromAddress, lgSize) b.wmask := fullMask(fromAddress, lgSize)
b.data := data b.data := data
(legal, b) (legal, b)
@ -276,7 +272,7 @@ class TLEdgeIn(
b.param := UInt(0) b.param := UInt(0)
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := wmask b.wmask := wmask
b.data := data b.data := data
(legal, b) (legal, b)
@ -289,7 +285,7 @@ class TLEdgeIn(
b.param := atomic b.param := atomic
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := fullMask(fromAddress, lgSize) b.wmask := fullMask(fromAddress, lgSize)
b.data := data b.data := data
(legal, b) (legal, b)
@ -302,7 +298,7 @@ class TLEdgeIn(
b.param := atomic b.param := atomic
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := fullMask(fromAddress, lgSize) b.wmask := fullMask(fromAddress, lgSize)
b.data := data b.data := data
(legal, b) (legal, b)
@ -315,13 +311,12 @@ class TLEdgeIn(
b.param := param b.param := param
b.size := lgSize b.size := lgSize
b.source := toSource b.source := toSource
b.address := fromAddress >> log2Up(manager.beatBytes) b.address := fromAddress
b.wmask := fullMask(fromAddress, lgSize) b.wmask := fullMask(fromAddress, lgSize)
b.data := UInt(0) b.data := UInt(0)
(legal, b) (legal, b)
} }
def AccessAck(toSource: UInt, lgSize: UInt, error: Bool = Bool(false)) = { def AccessAck(toSource: UInt, lgSize: UInt, error: Bool = Bool(false)) = {
val d = new TLBundleD(bundle) val d = new TLBundleD(bundle)
d.opcode := TLMessages.AccessAck d.opcode := TLMessages.AccessAck

View File

@ -272,16 +272,39 @@ case class TLEdgeParameters(
val maxTransfer = max(client.maxTransfer, manager.maxTransfer) val maxTransfer = max(client.maxTransfer, manager.maxTransfer)
val maxLgSize = log2Up(maxTransfer) val maxLgSize = log2Up(maxTransfer)
// Sanity check the link...
require (maxTransfer >= manager.beatBytes)
val bundle = TLBundleParameters( val bundle = TLBundleParameters(
addressBits = log2Up(manager.maxAddress + 1) - log2Up(manager.beatBytes), addressBits = log2Up(manager.maxAddress + 1),
dataBits = manager.beatBytes * 8, dataBits = manager.beatBytes * 8,
sourceBits = log2Up(client.endSourceId), sourceBits = log2Up(client.endSourceId),
sinkBits = log2Up(manager.endSinkId), sinkBits = log2Up(manager.endSinkId),
sizeBits = log2Up(maxLgSize+1)) sizeBits = log2Up(maxLgSize+1))
def addressMask(lgSize: UInt) = Vec.tabulate(maxLgSize) { UInt(_) < lgSize } .toBits.asUInt def isAligned(address: UInt, lgSize: UInt) =
def isAligned(address: UInt, lgSize: UInt) = (address & addressMask(lgSize)) === UInt(0) if (maxLgSize == 0) Bool(true) else {
val mask = Vec.tabulate(maxLgSize) { UInt(_) < lgSize }
// !!! wrong: address & mask.toBits.asUInt === UInt(0)
def fullMask(address: UInt, lgSize: UInt) = UInt(0) }
// This gets used everywhere, so make the smallest circuit possible ...
def fullMask(address: UInt, lgSize: UInt) = {
val lgBytes = log2Ceil(manager.beatBytes)
def helper(i: Int): Seq[(Bool, Bool)] = {
if (i == 0) {
Seq((lgSize >= UInt(lgBytes), Bool(true)))
} else {
val sub = helper(i-1)
val size = lgSize === UInt(lgBytes - i)
Seq.tabulate (1 << i) { j =>
val (sub_acc, sub_eq) = sub(j/2)
val eq = sub_eq && address(lgBytes - i) === Bool(j % 2 == 1)
val acc = sub_acc || (size && eq)
(acc, eq)
}
}
}
Vec(helper(lgBytes).map(_._1)).toBits.asUInt
}
} }