val path = System.getProperty("user.dir") + "/source/load-ivy.sc" interp.load.module(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath(path))) import chisel3._ import chisel3.util._ import chisel3.tester._ import chisel3.tester.RawTester.test class MyModule extends Module { val io = IO(new Bundle { val in = Input(UInt(4.W)) val out = Output(UInt(4.W)) }) } class MyModule extends Module { val io = IO(new Bundle { val in = Input(UInt(4.W)) val out = Output(UInt(4.W)) }) val two = 1 + 1 println(two) val utwo = 1.U + 1.U println(utwo) io.out := io.in } println(getVerilog(new MyModule)) class MyModuleTwo extends Module { val io = IO(new Bundle { val in = Input(UInt(4.W)) val out = Output(UInt(4.W)) }) val twotwo = 1.U + 1 println(twotwo) io.out := io.in } println(getVerilog(new MyModule)) class MyOperators extends Module { val io = IO(new Bundle { val in = Input(UInt(4.W)) val out_add = Output(UInt(4.W)) val out_sub = Output(UInt(4.W)) val out_mul = Output(UInt(4.W)) }) io.out_add := 1.U + 4.U io.out_sub := 2.U - 1.U io.out_mul := 4.U * 2.U } println(getVerilog(new MyOperators)) test(new MyOperators) {c => c.io.out_add.expect(5.U) c.io.out_sub.expect(1.U) c.io.out_mul.expect(8.U) } println("SUCCESS!!") class MyOperatorsTwo extends Module { val io = IO(new Bundle { val in = Input(UInt(4.W)) val out_mux = Output(UInt(4.W)) val out_cat = Output(UInt(4.W)) }) val s = true.B io.out_mux := Mux(s, 3.U, 0.U) // should return 3.U, since s is true io.out_cat := Cat(2.U, 1.U) // concatenates 2 (b10) with 1 (b1) to give 5 (101) } println(getVerilog(new MyOperatorsTwo)) test(new MyOperatorsTwo) { c => c.io.out_mux.expect(3.U) c.io.out_cat.expect(5.U) } println("SUCCESS!!") class MAC extends Module { val io = IO(new Bundle { val in_a = Input(UInt(4.W)) val in_b = Input(UInt(4.W)) val in_c = Input(UInt(4.W)) val out = Output(UInt(8.W)) }) ??? } test(new MAC) { c => val cycles = 100 import scala.util.Random for (i <- 0 until cycles) { val in_a = Random.nextInt(16) val in_b = Random.nextInt(16) val in_c = Random.nextInt(16) c.io.in_a.poke(in_a.U) c.io.in_b.poke(in_b.U) c.io.in_c.poke(in_c.U) c.io.out.expect((in_a * in_b + in_c).U) } } println("SUCCESS!!") class Arbiter extends Module { val io = IO(new Bundle { // FIFO val fifo_valid = Input(Bool()) val fifo_ready = Output(Bool()) val fifo_data = Input(UInt(16.W)) // PE0 val pe0_valid = Output(Bool()) val pe0_ready = Input(Bool()) val pe0_data = Output(UInt(16.W)) // PE1 val pe1_valid = Output(Bool()) val pe1_ready = Input(Bool()) val pe1_data = Output(UInt(16.W)) }) ??? } test(new Arbiter) { c => import scala.util.Random val data = Random.nextInt(65536) c.io.fifo_data.poke(data.U) for (i <- 0 until 8) { c.io.fifo_valid.poke((((i >> 0) % 2) != 0).B) c.io.pe0_ready.poke((((i >> 1) % 2) != 0).B) c.io.pe1_ready.poke((((i >> 2) % 2) != 0).B) c.io.fifo_ready.expect((i > 1).B) c.io.pe0_valid.expect((i == 3 || i == 7).B) c.io.pe1_valid.expect((i == 5).B) if (i == 3 || i ==7) { c.io.pe0_data.expect((data).U) } else if (i == 5) { c.io.pe1_data.expect((data).U) } } } println("SUCCESS!!") class ParameterizedAdder(saturate: Boolean) extends Module { val io = IO(new Bundle { val in_a = Input(UInt(4.W)) val in_b = Input(UInt(4.W)) val out = Output(UInt(4.W)) }) ??? } for (saturate <- Seq(true, false)) { test(new ParameterizedAdder(saturate)) { c => // 100 random tests val cycles = 100 import scala.util.Random import scala.math.min for (i <- 0 until cycles) { val in_a = Random.nextInt(16) val in_b = Random.nextInt(16) c.io.in_a.poke(in_a.U) c.io.in_b.poke(in_b.U) if (saturate) { c.io.out.expect(min(in_a + in_b, 15).U) } else { c.io.out.expect(((in_a + in_b) % 16).U) } } // ensure we test saturation vs. truncation c.io.in_a.poke(15.U) c.io.in_b.poke(15.U) if (saturate) { c.io.out.expect(15.U) } else { c.io.out.expect(14.U) } } } println("SUCCESS!!")