Skip to content

Commit

Permalink
Merge pull request #17 from shahzaibk23/main
Browse files Browse the repository at this point in the history
Modified Peripherals Object to Add Peripheral Generically via JSON
  • Loading branch information
shahzaibk23 authored Apr 17, 2023
2 parents 9501e3a + 3b19e00 commit 67ce0e3
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 40 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/scala.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ jobs:
java-version: '11'
distribution: 'temurin'
cache: 'sbt'
- name: Install Verilator
run: sudo apt-get install verilator
- name: Run tests
run: sbt test
# Optional: This step uploads information to the GitHub dependency graph and unblocking Dependabot alerts for the repository
- name: Upload dependency graph
uses: scalacenter/sbt-dependency-submission@ab086b50c947c9774b70f39fc7f6e20ca2706c91
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ ThisBuild / organization := "com.github.merl"
name := "Caravan"
libraryDependencies ++= Seq(
"edu.berkeley.cs" %% "chisel3" % "3.4.2",
"edu.berkeley.cs" %% "chiseltest" % "0.3.2" % "test"
"edu.berkeley.cs" %% "chiseltest" % "0.3.2" % "test",
"com.typesafe.play" %% "play-json" % "2.9.2"
)
scalacOptions ++= Seq(
"-Xsource:2.11",
Expand Down
12 changes: 12 additions & 0 deletions peripherals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"peripherals": [
{
"name": "GPIO",
"value": 0
},
{
"name": "DCCM",
"value": 1
}
]
}
8 changes: 4 additions & 4 deletions src/main/scala/caravan/bus/common/BusDecoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ import chisel3.util.{MuxCase, log2Ceil}
/** creating a type inside object so that it can be easily imported
* BusMap type provides a short way of mentioning mutable.Map[Peripheral, (UInt, UInt)] everywhere */
object BusMap {
type BusMap = mutable.Map[Peripherals.Type, (UInt, UInt, DeviceAdapter)]
type BusMap = mutable.Map[UInt, (UInt, UInt, DeviceAdapter)]
}

import BusMap._
/** This class provides the user an API to define peripherals and their address mapping */
class AddressMap {
private val map: BusMap = mutable.Map[Peripherals.Type, (UInt, UInt, DeviceAdapter)]()
private val map: BusMap = mutable.Map[UInt, (UInt, UInt, DeviceAdapter)]()
/** addDevice provides the user to add each device to the address map */
/** FIXME: there is no restriction on adding two peripherals with same base address.
* logically this should never happen, however user can add two peripherals with same base addresses
* there is no check for this and would break the code in later steps when we decode the addr of a peripheral */
def addDevice(peripheral: Peripherals.Type, baseAddr: UInt, addrMask: UInt, devAdapter: DeviceAdapter): Unit = map += (peripheral -> (baseAddr, addrMask, devAdapter))
def addDevice(peripheral: UInt, baseAddr: UInt, addrMask: UInt, devAdapter: DeviceAdapter): Unit = map += (peripheral -> (baseAddr, addrMask, devAdapter))
/** an helper function that returns the map [Encapsulation] */
def getMap(): BusMap = map
def getDevices: Seq[(DeviceAdapter, Peripherals.Type)] = {
def getDevices: Seq[(DeviceAdapter, UInt)] = {
getMap().map(f => (f._2._3, f._1)).toSeq
}
}
Expand Down
42 changes: 38 additions & 4 deletions src/main/scala/caravan/bus/common/PeripheralsMap.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
package caravan.bus.common

import play.api.libs.json._
import java.io.File
import java.nio.file.{Files, Paths}
import scala.io.Source
import chisel3._
import chisel3.experimental.ChiselEnum
import chisel3.util._

/*
* USAGE:
- first do `Peripherls.addValuesFromJson(/path/to/json/file)`
- then simply get the value of each peripheral by `Peripheral.get("peripheralName")`
- JSON format is in 'caravan/peripherals.json'
*/

object Peripherals {

private var names: Map[String, UInt] = Map()

// Read JSON file
def readJsonFile(jsonFilename: String): JsValue = {
val jsonString: String = Source.fromFile(jsonFilename).getLines.mkString
Json.parse(jsonString)
}

// Parse JSON and add values to Object
def addValuesFromJson(jsonFilename: String): Unit = {
val json: JsValue = readJsonFile(jsonFilename)
val peripherals: List[JsValue] = (json \ "peripherals").as[List[JsValue]]

peripherals.foreach { peripheral =>
val name: String = (peripheral \ "name").as[String]
val value: Int = (peripheral \ "value").as[Int]
names += (name -> value.U)
}
}

object Peripherals extends ChiselEnum {
val GPIO = Value(0.U)
val DCCM = Value(1.U)
}
// Get the value of a peripheral by its name
def get(value: String): UInt = names.get(value).getOrElse(0.U)
}
6 changes: 4 additions & 2 deletions src/main/scala/caravan/bus/tilelink/SwitchHarness.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Tileli
val ackResp = Output(Bool())
})

Peripherals.addValuesFromJson("peripherals.json")

io.ackResp := false.B
implicit val request = new TLRequest()
implicit val response = new TLResponse()
Expand All @@ -32,8 +34,8 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Tileli
val tlErr = Module(new TilelinkError())

val addressMap = new AddressMap
addressMap.addDevice(Peripherals.DCCM, "h40000000".U(32.W), "h00000fff".U(32.W), dccmDev)
addressMap.addDevice(Peripherals.GPIO, "h40001000".U(32.W), "h00000fff".U(32.W), gpioDev)
addressMap.addDevice(Peripherals.get("DCCM"), "h40000000".U(32.W), "h00000fff".U(32.W), dccmDev)
addressMap.addDevice(Peripherals.get("GPIO"), "h40001000".U(32.W), "h00000fff".U(32.W), gpioDev)
val devices = addressMap.getDevices

val switch = Module(new Switch1toN[TLHost, TLDevice](new TilelinkMaster(), new TilelinkSlave(), devices.size))
Expand Down
7 changes: 5 additions & 2 deletions src/main/scala/caravan/bus/wishbone/Harness.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Wishbo
val errResp = Output(Bool())
val ackResp = Output(Bool())
})

Peripherals.addValuesFromJson("peripherals.json")

io.ackResp := false.B

implicit val request = new WBRequest()
Expand All @@ -72,8 +75,8 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Wishbo
val wbErr = Module(new WishboneErr())

val addressMap = new AddressMap
addressMap.addDevice(Peripherals.DCCM, "h40000000".U(32.W), "h00000fff".U(32.W), dccmDev)
addressMap.addDevice(Peripherals.GPIO, "h40001000".U(32.W), "h00000fff".U(32.W), gpioDev)
addressMap.addDevice(Peripherals.get("DCCM"), "h40000000".U(32.W), "h00000fff".U(32.W), dccmDev)
addressMap.addDevice(Peripherals.get("GPIO"), "h40001000".U(32.W), "h00000fff".U(32.W), gpioDev)
val devices = addressMap.getDevices

val switch = Module(new Switch1toN[WBHost, WBDevice](new WishboneMaster(), new WishboneSlave(), devices.size))
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/tilelink/ErrorTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.VerilatorBackendAnnotation

class ErrorTest extends FreeSpec with ChiselScalatestTester {
"Testing Error Module" in {
"Tilelink Testing Error Module" in {
implicit val config = TilelinkConfig()
test(new TilelinkError()).withAnnotations(Seq(VerilatorBackendAnnotation)) { c =>
c.clock.step(20)
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/tilelink/GPIOControllerTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.VerilatorBackendAnnotation

class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
"write 40 in OUTPUT_EN_REG and read it back" in {
"tilelink write 40 in OUTPUT_EN_REG and read it back" in {
implicit val config = TilelinkConfig()
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand All @@ -27,7 +27,7 @@ class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
}
}

"write 40 in WDATA_REG and read it back" in {
"tilelink write 40 in WDATA_REG and read it back" in {
implicit val config = TilelinkConfig()
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand All @@ -47,7 +47,7 @@ class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
}
}

"write 40 in RDATA_REG and read it back" in {
"tilelink write 40 in RDATA_REG and read it back" in {
implicit val config = TilelinkConfig()
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand All @@ -67,7 +67,7 @@ class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
}
}

"write 40 in a register not available causing error" in {
"tilelink write 40 in a register not available causing error" in {
implicit val config = TilelinkConfig()
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand Down
6 changes: 3 additions & 3 deletions src/test/scala/tilelink/HarnessTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import common.MemoryDumpFileHelper // necessary to import


class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper {
"should write and read full word" in {
"tilelink should write and read full word" in {
implicit val config = TilelinkConfig()
// val programFile = getFile
test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -41,7 +41,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil
println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString)
}
}
"should write full word and read first byte" in {
"tilelink should write full word and read first byte" in {
implicit val config = TilelinkConfig()
// val programFile = getFile
test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -80,7 +80,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil
println("EXPECTED DATA IS: " + "hf".U.litValue().toInt + " GOT " + c.io.dataResp.peek().litValue().toInt.toString)
}
}
"should write full word and read first two bytes" in {
"tilelink should write full word and read first two bytes" in {
implicit val config = TilelinkConfig()
// val programFile = getFile
test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down
6 changes: 3 additions & 3 deletions src/test/scala/tilelink/SwitchHarnessTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import common.MemoryDumpFileHelper // necessary to import

class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper {

"should write to all GPIO registers and read them back" in {
"tilelink should write to all GPIO registers and read them back" in {
implicit val config = TilelinkConfig()
// val programFile = getFile
test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -91,7 +91,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD
}
}

"should write to a false GPIO register and produce error" in {
"tilelink should write to a false GPIO register and produce error" in {
implicit val config = TilelinkConfig()
// val programFile = getFile
test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -198,7 +198,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD
// }
// }

"should write to a device that is not in memory map and produce error" in {
"tilelink should write to a device that is not in memory map and produce error" in {
implicit val config = TilelinkConfig()
// val programFile = getFile
test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/wishbone/GpioControllerTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.VerilatorBackendAnnotation

class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
"write 40 in OUTPUT_EN_REG and read it back" in {
"wishbone write 40 in OUTPUT_EN_REG and read it back" in {
implicit val config = WishboneConfig(10, 32)
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand All @@ -27,7 +27,7 @@ class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
}
}

"write 40 in WDATA_REG and read it back" in {
"wishbone write 40 in WDATA_REG and read it back" in {
implicit val config = WishboneConfig(10, 32)
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand All @@ -47,7 +47,7 @@ class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
}
}

"write 40 in RDATA_REG and read it back" in {
"wishbone write 40 in RDATA_REG and read it back" in {
implicit val config = WishboneConfig(10, 32)
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand All @@ -67,7 +67,7 @@ class GpioControllerTest extends FreeSpec with ChiselScalatestTester {
}
}

"write 40 in a register not available causing error" in {
"wishbone write 40 in a register not available causing error" in {
implicit val config = WishboneConfig(10, 32)
test(new DummyGpioController()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(5)
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/wishbone/HarnessTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.scalatest.FreeSpec
import common.MemoryDumpFileHelper // necessary to import

class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper {
"should write and read full word" in {
"wishbone should write and read full word" in {
implicit val config = WishboneConfig(10, 32)
// val programFile = getFile
test(new WishboneHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -49,7 +49,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil
}
}

"should write full word and read first byte" in {
"wishbone should write full word and read first byte" in {
implicit val config = WishboneConfig(10, 32)
// val programFile = getFile
test(new WishboneHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -88,7 +88,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil
}
}

"should write full word and read first two bytes" in {
"wishbone should write full word and read first two bytes" in {
implicit val config = WishboneConfig(10, 32)
// val programFile = getFile
test(new WishboneHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -127,7 +127,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil
}
}

"should write a full word and read full word" in {
"wishbone should write a full word and read full word" in {
implicit val config = WishboneConfig(10, 32)
// val programFile = getFile
test(new WishboneHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/wishbone/SwitchHarnessTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import common.MemoryDumpFileHelper // necessary to import

class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper {

"should write to all GPIO registers and read them back" in {
"wishbone should write to all GPIO registers and read them back" in {
implicit val config = WishboneConfig(32, 32)
// val programFile = getFile
test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -91,7 +91,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD
}
}

"should write to a false GPIO register and produce error" in {
"wishbone should write to a false GPIO register and produce error" in {
implicit val config = WishboneConfig(32, 32)
// val programFile = getFile
test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down Expand Up @@ -123,7 +123,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD
// "should write data to multiple rows and read them back from memory" in {
// implicit val config = WishboneConfig(32, 32)
// val programFile = getFile
// test(new SwitchHarness(programFile)).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
// test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
// c.clock.step(5)
// sendRequestToMem("h40000000".U, "h00100120".U, "b1111".U, true.B)
// println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString)
Expand Down Expand Up @@ -198,7 +198,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD
// }
// }

"should write to a device that is not in memory map and produce error" in {
"wishbone should write to a device that is not in memory map and produce error" in {
implicit val config = WishboneConfig(32, 32)
// val programFile = getFile
test(new SwitchHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/wishbone/WishboneHostTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import chiseltest.internal.VerilatorBackendAnnotation

class WishboneHostTest extends FreeSpec with ChiselScalatestTester {

"just work" in {
"wishbone just work" in {
implicit val config = WishboneConfig(10, 32)
test(new WishboneHost).withAnnotations(Seq(VerilatorBackendAnnotation)) {c =>
c.clock.step(14)
Expand Down

0 comments on commit 67ce0e3

Please sign in to comment.