Skip to content

Commit

Permalink
Update assertion package
Browse files Browse the repository at this point in the history
  • Loading branch information
Vict0rAH committed Nov 21, 2020
1 parent 78836a8 commit f7c6461
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 36 deletions.
47 changes: 35 additions & 12 deletions assertion/src/main/scala/assertionTiming/concurrentAssertion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import chisel3._
*
* @author Victor Alexander Hansen, [email protected]
* @author Niels Frederik Flemming Holm Frandsen, [email protected]
*
* Works only with registers
*/

/** assertNever():
Expand All @@ -30,7 +32,6 @@ object assertNever {
fork {
for (i <- 0 until cycles) {
assert(!cond(), message)
System.out.println("Test")
dut.clock.step(1)
}
}
Expand All @@ -46,7 +47,6 @@ object assertAlways {
fork {
for (i <- 0 until cycles) {
assert(cond(), message)
System.out.println("Test")
dut.clock.step(1)
}
}
Expand All @@ -57,17 +57,28 @@ object assertAlways {
* Checks for the argument condition to be true just once within the number of
* clock cycles passed, a liveness property. Fails if the condition is not true
* at least once within the window of cycles
*
* Must be joined
*/
object assertEventually {
def apply[T <: Module](dut: T, cond: () => Boolean, message: String, cycles: Int) = {

var i = 0
fork {
for (i <- 0 until cycles) {
/*for (i <- 0 until cycles) {
if (cond()) {
break
} else {
} else if (i == cycles - 1){
assert(false, message)
}
dut.clock.step(1)
}*/
while (!cond()) {
if (i == cycles-1) {
assert(false, message)
}
i += 1
dut.clock.step(1)
}
}
}
Expand All @@ -78,36 +89,48 @@ object assertEventually {
* clock cycles passed, and hold true until the last cycle. Fails if the
* condition is not true at least once within the window of cycles, or if
* condition becomes false after it becomes true.
*
* Must be joined
*/
object assertEventuallyAlways {
def apply[T <: Module](dut: T, cond: () => Boolean, message: String, cycles: Int) = {

var k = 0
for (i <- 0 until cycles) {
var i = 0
/*for (i <- 0 until cycles) {
if (cond()) {
break
} else {
// Exception
assert(false, message)
}
k += 1
}
}*/

for (j <- 0 until cycles - k) {
assert(cond(), message)
fork {
while (!cond()) {
if (i == cycles-1) {
assert(false, message)
}
i += 1
dut.clock.step(1)
}

for (j <- 0 until cycles - i) {
assert(cond(), message)
dut.clock.step(1)
}
}
}
}

/** assertOneHot():
* checks for one hot encoding violations
* checks if exactly one bit of the expression is high
*/
/*object assertOneHot {
object assertOneHot {
def apply(cond: UInt, message: String, cycles: Int) {

for (i <- 0 until cycles) {
assert(cond == 1.U << cond/2.U)
}
}
}
**/
7 changes: 5 additions & 2 deletions assertion/src/main/scala/mainClass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import concurrent._
// Compiles, but simple test does not yet work
class mainClass extends Module {
val io = IO(new Bundle {
val s = Input(UInt(4.W))
val s = Input(Bool())
val c = Output(UInt(4.W))
})

io.c := io.s
val reg = RegInit(0.U (4.W))

reg := Mux(io.s, 4.U, 0.U)
io.c := reg

//conAssert(true.B, "Error", 10)
}
Expand Down
165 changes: 149 additions & 16 deletions assertion/src/test/scala/concurrentAssertionTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,161 @@ import chiseltest._
class concurrentAssertionTest extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "The mainClass"

it should "test an assertion to always be true" in {
// assertAlways
it should "test assertAlways" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(4.U)
dut.io.s.poke(true.B)
dut.clock.step(1)
assertAlways(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)
}
}
}

it should "test that assertAlways fails when poking false" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(true.B)
dut.clock.step(1)
val t = assertAlways(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

dut.clock.step(10)
dut.io.s.poke(false.B)
dut.clock.step(1)
}
}
}

it should "test time depency of clock cycles" in {
test(new mainClass()) {
dut => {

timescope {
dut.clock.step(1)
dut.io.s.poke(4.U)
System.out.println("Start")
dut.clock.step(1)
}

timescope {
dut.clock.step(100)
System.out.println("Slut")
//dut.io.s.poke(4.U)
//t.join
}
// Test of assertAlways
dut.io.s.poke(true.B)
dut.clock.step(1)
assertAlways(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

dut.clock.step(21)
dut.io.s.poke(false.B)
dut.clock.step(1)

// Test of assertNever
dut.io.s.poke(false.B)
dut.clock.step(1)
assertNever(dut, () => dut.io.c.peek.litValue == 4, "Error", 40)

dut.clock.step(41)
dut.io.s.poke(true.B)
dut.clock.step(1)
}
}
}

// assertNever
it should "test assertNever" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(false.B)
dut.clock.step(1)
assertNever(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)
}
}
}

it should "test assertNever fails" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(false.B)
dut.clock.step(1)
val t = assertNever(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

dut.clock.step(15)
dut.io.s.poke(true.B)
dut.clock.step(1)
}
}
}

//assertEventually
it should "test assertEventually passes, once true regardless of what happens next" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(false.B)
dut.clock.step(1)
val t = assertEventually(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

dut.clock.step(5)
dut.io.s.poke(true.B)
dut.clock.step(1)
dut.io.s.poke(false.B)
t.join
}
}
}

it should "test assertEventually fails when exceeding clock cycles" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(false.B)
dut.clock.step(1)
val t = assertEventually(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

t.join
}
}
}

// assertEventuallyAlways
it should "test assertEventuallyAlways pass" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(false.B)
dut.clock.step(1)
val t = assertEventuallyAlways(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

dut.clock.step(1)
dut.io.s.poke(true.B)

t.join
}
}
}

it should "fail, if cond does not hold true once true" in {
test(new mainClass()) {
dut => {

dut.io.s.poke(false.B)
dut.clock.step(1)
val t = assertEventuallyAlways(dut, () => dut.io.c.peek.litValue == 4, "Error", 20)

dut.clock.step(5)
dut.io.s.poke(true.B)
dut.clock.step(1)
dut.io.s.poke(false.B)

t.join
}
}
}
}

/*class concurrentAssertionTest2 extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "The oneHot"
// assertOneHot
it should "pass if only one bit is high" in {
test(new oneHot()) {
dut => {
}
}
}
}
}*/
10 changes: 4 additions & 6 deletions assertion/src/test/scala/timescopeTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,17 @@ class timescopeTest extends FlatSpec with ChiselScalatestTester with Matchers {
test(new mainClass()) {
dut => {

dut.io.s.poke(4.U)
dut.io.s.poke(true.B)
dut.clock.step(1)
fork {
for (i <- 0 until 20) {
assert(dut.io.c.peek.litValue() == 4, "Error")
dut.clock.step(1)
}
}
//timescope {
dut.clock.step(10)
dut.io.s.poke(0.U)
//}
dut.clock.step(10)
dut.io.s.poke(false.B)
}
}
}
}
}

0 comments on commit f7c6461

Please sign in to comment.