Commit 886e04b9 authored by Jens Korinth's avatar Jens Korinth
Browse files

Change address base type to Long

* addresses can be larger than 32bit, thus need to use Long
* in fact, having the upper-most bit 1 already gave problems
* fixed and updated all dependents
parent 70928314
......@@ -42,10 +42,10 @@ object AxiModuleBuilder extends ModuleBuilder {
implicit val axilite = Axi4Lite.Configuration(AddrWidth(32),
Axi4Lite.Width32)
val exampleRegisterFile = new axi4lite.RegisterFile.Configuration(addressWordBits = 8, regs = Map(
0 -> new ConstantRegister(value = BigInt("10101010", 16)),
4 -> new ConstantRegister(value = BigInt("20202020", 16)),
8 -> new ConstantRegister(value = BigInt("30303030", 16)),
16 -> new ConstantRegister(value = BigInt("40404040", 16), bitfield = Map(
0L -> new ConstantRegister(value = BigInt("10101010", 16)),
4L -> new ConstantRegister(value = BigInt("20202020", 16)),
8L -> new ConstantRegister(value = BigInt("30303030", 16)),
16L -> new ConstantRegister(value = BigInt("40404040", 16), bitfield = Map(
"Byte #3" -> BitRange(31, 24),
"Byte #2" -> BitRange(23, 16),
"Byte #1" -> BitRange(15, 8),
......@@ -53,7 +53,7 @@ object AxiModuleBuilder extends ModuleBuilder {
))
))(Axi4Lite.Configuration(AddrWidth(32), Axi4Lite.Width32))
val largeRegisterFile = new axi4lite.RegisterFile.Configuration(addressWordBits = 8, regs = (0 until 256 map { i =>
val largeRegisterFile = new axi4lite.RegisterFile.Configuration(addressWordBits = 8, regs = (0L until 256L map { i =>
i * 4 -> new Register(Some(s"ConfigReg_$i"), width = Axi4Lite.Width32)
}).toMap)(Axi4Lite.Configuration(AddrWidth(32), Axi4Lite.Width32))
......
......@@ -7,16 +7,16 @@ import chisel.miscutils.Logging
/** AXI4Lite master transaction model. */
sealed abstract trait MasterAction {
def isRead: Boolean
def address: Int
def address: Long
def value: Option[BigInt]
}
final case class MasterRead(address: Int) extends MasterAction {
final case class MasterRead(address: Long) extends MasterAction {
def isRead: Boolean = true
def value: Option[BigInt] = None
}
final case class MasterWrite(address: Int, v: BigInt) extends MasterAction {
final case class MasterWrite(address: Long, v: BigInt) extends MasterAction {
def isRead: Boolean = false
def value: Option[BigInt] = Some(v)
}
......@@ -39,7 +39,7 @@ final case class MasterWrite(address: Int, v: BigInt) extends MasterAction {
})
val cnt = RegInit(UInt(log2Ceil(action.length + 1).W), init = 0.U)
io.finished := cnt === action.length.U
io.finished := RegNext(cnt === action.length.U)
val ra_valid = RegInit(false.B)
val rd_ready = RegInit(false.B)
......
......@@ -12,12 +12,12 @@ object RegisterFile {
* @param width Register data width (in bits).
* @param regs Map from offsets in addrGranularity to register implementations.
**/
case class Configuration(addressWordBits: Int = 8, regs: Map[Int, ControlRegister], fifoDepth: PosInt = 2)
case class Configuration(addressWordBits: Int = 8, regs: Map[Long, ControlRegister], fifoDepth: PosInt = 2)
(implicit axi: Axi4Lite.Configuration) {
/* internal helpers: */
private def overlap(p: (BitRange, BitRange)) = p._1.overlapsWith(p._2)
private def makeRange(a: Int): BitRange =
BitRange(a * addressWordBits + axi.dataWidth.toInt - 1, a * addressWordBits)
private def makeRange(a: Long): BitRange =
BitRange(a * addressWordBits + axi.dataWidth.toLong - 1, a * addressWordBits)
private lazy val m = regs.keys.toList.sorted map makeRange
private lazy val o = (m.take(m.length - 1) zip m.tail) map { case (r1, r2) => ((r1, r2), r1.overlapsWith(r2)) }
o filter (_._2) foreach { case ((r1, r2), _) => require(!r1.overlapsWith(r2), s"$r1 and $r2 must not overlap") }
......
package chisel.axi.axi4lite
import chisel3._
import chisel.axi._
import Chisel.{Reg, UInt}
......@@ -56,7 +57,7 @@ class ConstantRegister(name: Option[String] = None, bitfield: BitfieldMap = Map(
**/
class Register(name: Option[String] = None, bitfield: BitfieldMap = Map(), width: Int)
extends ControlRegister(name, bitfield) {
private lazy val _r = Reg(UInt(width = width))
private lazy val _r = RegInit(0.U(width))
def read(): Option[UInt] = Some(_r)
override def write(v: UInt) = {
_r := v
......
......@@ -2,7 +2,7 @@ package chisel.axi
package object axi4lite {
/** Tuple-type for bit ranges. */
sealed case class BitRange(to: Int, from: Int) {
sealed case class BitRange(to: Long, from: Long) {
require (to >= from && from >= 0, "BitRange: invalid range (%d, %d)".format(to, from))
def overlapsWith(other: BitRange): Boolean = !(to < other.from || from > other.to)
}
......
......@@ -20,7 +20,7 @@ import org.scalatest.prop.Checkers
* @param regs register map for register file
* @param actions master actions to perform
**/
class RegFileTest(val size: Int, val off: Int, regs: Map[Int, ControlRegister], actions: Seq[MasterAction])
class RegFileTest(val size: Int, val off: Int, regs: Map[Long, ControlRegister], actions: Seq[MasterAction])
(implicit axi: Axi4Lite.Configuration, logLevel: Logging.Level) extends Module {
val cfg = new RegisterFile.Configuration(regs = regs)
val saxi = Module(new RegisterFile(cfg))
......@@ -42,7 +42,7 @@ class RegisterFileSpec extends ChiselFlatSpec with Checkers {
// basic Chisel arguments
val chiselArgs = Array("--fint-write-vcd")
private def generateActionsFromRegMap(regs: Map[Int, Option[ControlRegister]]): Seq[MasterAction] =
private def generateActionsFromRegMap(regs: Map[Long, Option[ControlRegister]]): Seq[MasterAction] =
regs.toSeq.sortBy(_._1) map { _ match {
case (i, Some(r)) => r match {
case c: Register => Seq(MasterWrite(i, i), MasterRead(i))
......@@ -52,7 +52,7 @@ class RegisterFileSpec extends ChiselFlatSpec with Checkers {
case (i, None) => Seq(MasterRead(i), MasterWrite(i, i))
}} reduce (_ ++ _)
private def genericTest(width: DataWidth, regs: Map[Int, Option[ControlRegister]])
private def genericTest(width: DataWidth, regs: Map[Long, Option[ControlRegister]])
(implicit axi: Axi4Lite.Configuration) = {
val testDir = "test/axi4lite/RegisterFileSpec/generic/%d/%d".format(width: Int, scala.util.Random.nextInt)
println(s"Test results here: $testDir, width = $width")
......@@ -62,7 +62,7 @@ class RegisterFileSpec extends ChiselFlatSpec with Checkers {
{ m => new GenericTester(width, regs, m) }
}
private class GenericTester(width: DataWidth, regs: Map[Int, Option[ControlRegister]], m: RegFileTest) extends PeekPokeTester(m) {
private class GenericTester(width: DataWidth, regs: Map[Long, Option[ControlRegister]], m: RegFileTest) extends PeekPokeTester(m) {
def waitForReadData {
if (peek(m.io.rdata.valid) != 0) {
println("read data is still valid at start of waitForReadData, waiting ...")
......
......@@ -56,9 +56,9 @@ package object generators {
def maybeRegGen(width: DataWidth): () => Gen[Option[ControlRegister]] = () =>
Gen.option(Gen.oneOf(basicRegGen(width), constRegGen(width)))
def registerMapGen(width: DataWidth): Gen[Map[Int, Option[ControlRegister]]] =
def registerMapGen(width: DataWidth): Gen[Map[Long, Option[ControlRegister]]] =
Gen.nonEmptyBuildableOf[Seq[Option[ControlRegister]], Option[ControlRegister]](maybeRegGen(width)())
.map (_.zipWithIndex.map { case (r, i) => (i * (width / 8), r) }.toMap)
.map (_.zipWithIndex.map { case (r, i) => (i.toLong * (width / 8), r) }.toMap)
.retryUntil (l => (l map (_._2.nonEmpty) fold false) (_ || _))
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment