diff --git a/FIRRTLCoverage/README.md b/FIRRTLCoverage/README.md index c35205d..5d0435a 100644 --- a/FIRRTLCoverage/README.md +++ b/FIRRTLCoverage/README.md @@ -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 diff --git a/README.md b/README.md index 9cd187c..0adbb76 100644 --- a/README.md +++ b/README.md @@ -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/` diff --git a/axi4/README.md b/axi4/README.md index 4137a29..403a0de 100644 --- a/axi4/README.md +++ b/axi4/README.md @@ -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) @@ -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). diff --git a/axi4/src/main/scala/VivadoAXIMemory.scala b/axi4/src/main/scala/VivadoAXIMemory.scala index 710f889..bd86950 100644 --- a/axi4/src/main/scala/VivadoAXIMemory.scala +++ b/axi4/src/main/scala/VivadoAXIMemory.scala @@ -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 { @@ -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 */ @@ -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 } diff --git a/axi4/src/main/scala/axi4/Transaction.scala b/axi4/src/main/scala/axi4/Transaction.scala index 9e2f34f..cef1765 100644 --- a/axi4/src/main/scala/axi4/Transaction.scala +++ b/axi4/src/main/scala/axi4/Transaction.scala @@ -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 diff --git a/axi4/src/test/scala/VivadoAXIMemoryTester.scala b/axi4/src/test/scala/VivadoAXIMemoryTester.scala index b1704a3..9451feb 100644 --- a/axi4/src/test/scala/VivadoAXIMemoryTester.scala +++ b/axi4/src/test/scala/VivadoAXIMemoryTester.scala @@ -9,13 +9,15 @@ 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() @@ -23,33 +25,70 @@ class VivadoAXIMemoryTester extends FlatSpec with ChiselScalatestTester with Mat } } - 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() } }