Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
… master
  • Loading branch information
Vict0rAH committed Nov 24, 2020
2 parents ec2ced1 + f6c41fa commit 54a4c87
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 31 deletions.
18 changes: 14 additions & 4 deletions FIRRTLCoverage/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
# Test coverage at FIRRTL level

This project wil make ti possible to get accurate test coverage data from chisel code by introducing a way to measure the coverage of FIRRTL code.
This project wil make it possible to get accurate test coverage data from chisel code by introducing a way to measure the coverage of FIRRTL code. Coverage is understood as the hardware paths that reaches a register or similar state preserving elements. A mux or similar can block paths. Chisel will have to annotate chisel code in a way that makes it possible to trace specific FIRRTL operations back to the scala source that made them. FIRRTL needs to support loading these new annotations and preserve them through its various optimizations and transformations that it does. Treade will need to support these new annotations and record the annotations as the attached hardware is used.

## TODO
## Sources
This project requires changes to FIRRTL, Treadle and Chisel3. As those are all major projects, the source will not be available in this folder. Instead One can Check out my forks to view the changes i've made.

https://github.com/TheAIBot/chisel3

https://github.com/TheAIBot/treadle

* Tag FIRRTL code with chisel source code location
* Implement a way to measure FIRRTL coverage
https://github.com/TheAIBot/firrtl

## TODO
* Tag FIRRTL code with chisel source code location annotations
* FIRRTL annotation support
* Treadle annotation support
* Implement a way to understand the outputted coverage report

## Text material

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ Slides for testing in software - https://docs.google.com/presentation/d/1vtVaw38
- Verify and note the test coverage parameters obtained from testing the designs(Mux, ALU with an accumulator, LIFO Queue, BubbleFIFO) in SystemVerilog following a UVM framework.
- Develop test further to get maximum test coverage.
- found in `./VerificationUsingSystemVerilog/`

### FIRRTL Coverage
- by Andreas Gramstrup Correia
- This project wil make it possible to get accurate test coverage data from chisel code by introducing a way to measure the coverage of FIRRTL code.
- found in `./FIRRTLCoverage/`
4 changes: 1 addition & 3 deletions axi4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
This project focuses on implementation of AXI4 master interface definitions and a small framework providing support for all of the defined transactions from the AXI master's point of view in the protocol.

## TODO
- Implement basic interface tests
- Evaluate functional master
- Use cover groups

### Extras
- Functional AXI slave (like above)
Expand Down Expand Up @@ -66,7 +64,7 @@ Additionally, two global signals are used (see page A2-28)

Channel descriptions are available in `./src/main/scala/axi4/Defs.scala`. DUVs must conform to the signal names and interfaces provided to function correctly - hence, their IO should extend either the available master or slave interfaces. To enable this more easily, an AXI master can simply extend the Master class found in `./src/main/scala/axi4/Master.scala`, and vice-versa for AXI slaves for which the relevant class is found in `./src/main/scala/axi4/Slave.scala`.

An example of a black-boxed block-RAM with AXI interface is provided in `./src/main/scala/AXI4Memory.scala` - note, however, that due to copyright of the IP source code, you will need to generate the appropriate IP block within Xilinx Vivado to use the blackbox.
An example of a black-boxed block-RAM with AXI interface is provided in `./src/main/scala/VivadoAXIMemory.scala` - note, however, that due to copyright of the IP source code, you will need to generate the appropriate IP block within Xilinx Vivado to use the blackbox. A basic tester is provided in `./src/test/scala/VivadoAXIMemoryTester.scala`.

### References
The full public protocol specification is available from ARM [here](https://developer.arm.com/documentation/ihi0022/e/) and in PDF format [here](http://www.gstitt.ece.ufl.edu/courses/fall15/eel4720_5721/labs/refs/AXI4_specification.pdf). A good video introduction is available from [ARM's YouTube channel](https://www.youtube.com/watch?v=7Vl9JrGgNwk).
Expand Down
7 changes: 4 additions & 3 deletions axi4/src/main/scala/VivadoAXIMemory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import axi4._
import chisel3._
import chisel3.util._
import chisel3.experimental._

/** Vivado IP BRAM with full AXI4 interface */
class mymem extends BlackBox with HasBlackBoxResource {
Expand Down Expand Up @@ -68,8 +67,10 @@ class mymem extends BlackBox with HasBlackBoxResource {
val s00_axi_aresetn = Input(Reset())
})

/** Verilog file in /src/main/resources - top file is mymem.v */
/** Verilog files in /src/main/resources - top file is mymem.v */
addResource("/mymem.v")
addResource("/myaximem_v1_0.v")
addResource("/myaximem_v1_0_S00_AXI.v")
}

/** Wrapper for mymem */
Expand Down Expand Up @@ -135,5 +136,5 @@ class VivadoAXIMemory extends Slave(1, 10, 32) {

/** Clock and reset */
mem.io.s00_axi_aclk := clock
mem.io.s00_axi_aresetn := reset
mem.io.s00_axi_aresetn := !reset
}
2 changes: 1 addition & 1 deletion axi4/src/main/scala/axi4/Transaction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ trait Transaction {
* @param size optional beat size, defaults to 1 byte
* @param burst optional burst type, defaults to INCR
*/
class WriteTransaction(addr: BigInt, data: Seq[BigInt], dataW: Int, size: Int = 0, burst: UInt = BurstEncodings.Incr) {
class WriteTransaction(addr: BigInt, data: Seq[BigInt], dataW: Int, size: Int = 0, burst: UInt = BurstEncodings.Incr) extends Transaction {
private[this] val numBytes = 1 << size
private[this] val dtsize = numBytes * data.length
private[this] val lowerBoundary = (addr / dtsize) * dtsize
Expand Down
79 changes: 59 additions & 20 deletions axi4/src/test/scala/VivadoAXIMemoryTester.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,86 @@
import axi4._
import chisel3._
import chiseltest._
import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.VerilatorBackendAnnotation
import org.scalatest._

class VivadoAXIMemoryTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "AXI4 BRAM"

it should "initialize" in {
test(new VivadoAXIMemory()) {
test(new VivadoAXIMemory()).withAnnotations(Seq(VerilatorBackendAnnotation)) {
dut =>
val master = new AXI4FunctionalMaster(dut)
master.initialize()
master.close()
}
}

it should "write and read" in {
test(new VivadoAXIMemory()) {
it should "write and read manually" in {
test(new VivadoAXIMemory()).withAnnotations(Seq(VerilatorBackendAnnotation)) {
dut =>
val master = new AXI4FunctionalMaster(dut)
master.initialize()
master.createWriteTrx(0, Seq[BigInt](42), size = 2)
var r = master.checkResponse()

def printCheck() = {
println("AWREADY = " + dut.io.aw.ready.peek.litToBoolean)
println("WREADY = " + dut.io.dw.ready.peek.litToBoolean)
println("BVALID = " + dut.io.wr.valid.peek.litToBoolean)
println("ARREADY = " + dut.io.ar.ready.peek.litToBoolean)
println("RVALID = " + dut.io.dr.valid.peek.litToBoolean)
}

// Set some initial values on the necessary signals
dut.io.dw.bits.data.poke(42.U)
dut.io.dw.bits.strb.poke("b1111".U)
dut.io.dw.bits.last.poke(true.B)
printCheck()

// Write address
dut.io.aw.valid.poke(true.B)
do {
dut.clock.step()
r = master.checkResponse()
} while (r == None)
var resp = r match {
case Some(r) => r.resp.litValue
case _ => 0
}
println(s"Got response code $resp")
master.createReadTrx(0, size = 2)
var v = master.checkReadData()
} while (!dut.io.aw.ready.peek.litToBoolean)
printCheck()
dut.clock.step()
dut.io.aw.valid.poke(false.B)

// Write some data
dut.io.dw.valid.poke(true.B)
do {
dut.clock.step()
v = master.checkReadData()
} while (v == None)
var values = v match {
case Some(v) => v
case _ => Seq[BigInt](-1)
} while (!dut.io.dw.ready.peek.litToBoolean)
printCheck()
dut.clock.step()
dut.io.dw.valid.poke(false.B)

// Fetch response
dut.io.wr.ready.poke(true.B)
while (!dut.io.wr.valid.peek.litToBoolean) {
dut.clock.step()
}
println(s"Got read data $values")
printCheck()
val r = dut.io.wr.bits.resp.peek.litValue
println(s"Got response $r")

// Read address
dut.io.ar.valid.poke(true.B)
do {
dut.clock.step()
} while (!dut.io.ar.ready.peek.litToBoolean)
printCheck()
dut.clock.step()
dut.io.ar.valid.poke(false.B)

// Read some data
dut.io.dr.ready.poke(true.B)
while (!dut.io.dr.valid.peek.litToBoolean) {
dut.clock.step()
}
printCheck()
dut.io.dr.bits.data.expect(42.U)

master.close()
}
}
Expand Down

0 comments on commit 54a4c87

Please sign in to comment.