From 57b60195110633d562aaa9f701809639b4f025dc Mon Sep 17 00:00:00 2001 From: Fabian Schuiki Date: Sun, 13 Oct 2024 19:36:31 -0700 Subject: [PATCH] [arcilator] Add clock divider integration test Add a test to check that arcilator can simulate a simple clock divider. This exercises a corner case of arcilator's simulation model scheduling, where a state updating its value can trigger other states and module outptus to update their values. In this case, a cascade of clock edges is generated by feeding one state's output into the clock input of the next state. --- .../arcilator/JIT/clock-divider.mlir | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 integration_test/arcilator/JIT/clock-divider.mlir diff --git a/integration_test/arcilator/JIT/clock-divider.mlir b/integration_test/arcilator/JIT/clock-divider.mlir new file mode 100644 index 000000000000..3fe05fd5faf8 --- /dev/null +++ b/integration_test/arcilator/JIT/clock-divider.mlir @@ -0,0 +1,64 @@ +// RUN: arcilator --run %s | FileCheck %s +// REQUIRES: arcilator-jit + +// CHECK: 0 0 0 0 +// CHECK-NEXT: 1 1 1 1 +// CHECK-NEXT: 0 0 1 1 +// CHECK-NEXT: 1 1 0 1 +// CHECK-NEXT: 0 0 0 1 +// CHECK-NEXT: 1 1 1 0 +// CHECK-NEXT: 0 0 1 0 +// CHECK-NEXT: 1 1 0 0 +// CHECK-NEXT: 0 0 0 0 +// CHECK-NEXT: 1 1 1 1 + +arc.define @Not(%arg0: i1) -> i1 { + %true = hw.constant true + %0 = comb.xor %arg0, %true : i1 + arc.output %0 : i1 +} + +hw.module @ClockDivBy4(in %clock: !seq.clock, out div1: !seq.clock, out div2: !seq.clock, out div4: !seq.clock) { + %q0 = arc.state @Not(%q0) clock %clock latency 1 {names = ["q0"]} : (i1) -> i1 + %0 = seq.to_clock %q0 + %q1 = arc.state @Not(%q1) clock %0 latency 1 {names = ["q1"]} : (i1) -> i1 + %1 = seq.to_clock %q1 + hw.output %clock, %0, %1 : !seq.clock, !seq.clock, !seq.clock +} + +func.func @entry() { + %true = hw.constant true + %false = hw.constant false + %clk1 = seq.to_clock %true + %clk0 = seq.to_clock %false + arc.sim.instantiate @ClockDivBy4 as %dut { + arc.sim.step %dut : !arc.sim.instance<@ClockDivBy4> + + %lb = arith.constant 0 : index + %ub = arith.constant 10 : index + %step = arith.constant 1 : index + scf.for %i = %lb to %ub step %step { + %i0 = index.castu %i : index to i1 + %clock = seq.to_clock %i0 + + arc.sim.set_input %dut, "clock" = %clock : !seq.clock, !arc.sim.instance<@ClockDivBy4> + arc.sim.step %dut : !arc.sim.instance<@ClockDivBy4> + + %0 = arc.sim.get_port %dut, "div1" : !seq.clock, !arc.sim.instance<@ClockDivBy4> + %1 = arc.sim.get_port %dut, "div2" : !seq.clock, !arc.sim.instance<@ClockDivBy4> + %2 = arc.sim.get_port %dut, "div4" : !seq.clock, !arc.sim.instance<@ClockDivBy4> + + %3 = llvm.mlir.addressof @string : !llvm.ptr + %4 = seq.from_clock %0 + %5 = seq.from_clock %1 + %6 = seq.from_clock %2 + func.call @printf(%3, %i0, %4, %5, %6) : (!llvm.ptr, i1, i1, i1, i1) -> () + } + } + + return +} + +llvm.mlir.global constant @string("%u %u %u %u\n\00") : !llvm.array<13 x i8> + +func.func private @printf(!llvm.ptr, i1, i1, i1, i1)