Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[arcilator] Add clock divider integration test #7705

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions include/circt/Dialect/Arc/ArcOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -450,21 +450,6 @@ class ClockTreeLikeOp<string mnemonic, list<Trait> traits = []>:
let regions = (region SizedRegion<1>:$body);
}

def ClockTreeOp : ClockTreeLikeOp<"clock_tree"> {
let summary = "A clock tree";
let arguments = (ins I1:$clock);
let assemblyFormat = [{
$clock attr-dict-with-keyword $body
}];
}

def PassThroughOp : ClockTreeLikeOp<"passthrough"> {
let summary = "Clock-less logic that is on the pass-through path";
let assemblyFormat = [{
attr-dict-with-keyword $body
}];
}

def InitialOp : ClockTreeLikeOp<"initial"> {
let summary = "Region to be executed at the start of simulation";
let assemblyFormat = [{
Expand Down
2 changes: 0 additions & 2 deletions include/circt/Dialect/Arc/ArcPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ createInferMemoriesPass(const InferMemoriesOptions &options = {});
std::unique_ptr<mlir::Pass> createInlineArcsPass();
std::unique_ptr<mlir::Pass> createIsolateClocksPass();
std::unique_ptr<mlir::Pass> createLatencyRetimingPass();
std::unique_ptr<mlir::Pass> createLegalizeStateUpdatePass();
std::unique_ptr<mlir::Pass> createLowerArcsToFuncsPass();
std::unique_ptr<mlir::Pass> createLowerClocksToFuncsPass();
std::unique_ptr<mlir::Pass> createLowerLUTPass();
std::unique_ptr<mlir::Pass> createLowerStatePass();
std::unique_ptr<mlir::Pass> createLowerVectorizationsPass(
LowerVectorizationsModeEnum mode = LowerVectorizationsModeEnum::Full);
std::unique_ptr<mlir::Pass> createMakeTablesPass();
Expand Down
17 changes: 7 additions & 10 deletions include/circt/Dialect/Arc/ArcPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,6 @@ def LatencyRetiming : Pass<"arc-latency-retiming", "mlir::ModuleOp"> {
];
}

def LegalizeStateUpdate : Pass<"arc-legalize-state-update", "mlir::ModuleOp"> {
let summary = "Insert temporaries such that state reads don't see writes";
let constructor = "circt::arc::createLegalizeStateUpdatePass()";
let dependentDialects = ["arc::ArcDialect"];
}

def LowerArcsToFuncs : Pass<"arc-lower-arcs-to-funcs", "mlir::ModuleOp"> {
let summary = "Lower arc definitions into functions";
let constructor = "circt::arc::createLowerArcsToFuncsPass()";
Expand All @@ -187,12 +181,15 @@ def LowerLUT : Pass<"arc-lower-lut", "arc::DefineOp"> {
let dependentDialects = ["hw::HWDialect", "comb::CombDialect"];
}

def LowerState : Pass<"arc-lower-state", "mlir::ModuleOp"> {
def LowerStatePass : Pass<"arc-lower-state", "mlir::ModuleOp"> {
let summary = "Split state into read and write ops grouped by clock tree";
let constructor = "circt::arc::createLowerStatePass()";
let dependentDialects = [
"arc::ArcDialect", "mlir::scf::SCFDialect", "mlir::func::FuncDialect",
"mlir::LLVM::LLVMDialect", "comb::CombDialect", "seq::SeqDialect"
"arc::ArcDialect",
"comb::CombDialect",
"mlir::LLVM::LLVMDialect",
"mlir::func::FuncDialect",
"mlir::scf::SCFDialect",
"seq::SeqDialect",
];
}

Expand Down
64 changes: 64 additions & 0 deletions integration_test/arcilator/JIT/clock-divider.mlir
Original file line number Diff line number Diff line change
@@ -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() {
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
%7 = arith.extui %i0 : i1 to i32
%8 = arith.extui %4 : i1 to i32
%9 = arith.extui %5 : i1 to i32
%10 = arith.extui %6 : i1 to i32
llvm.call @printf(%3, %7, %8, %9, %10) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32, i32, i32, i32) -> i32
}
}

return
}

llvm.mlir.global constant @string("%u %u %u %u\n\00") : !llvm.array<13 x i8>

llvm.func @printf(!llvm.ptr, ...) -> i32
9 changes: 4 additions & 5 deletions integration_test/arcilator/JIT/dpi.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ func.func @add_mlir_impl(%arg0: i32, %arg1: i32, %arg2: !llvm.ptr) {
llvm.store %0, %arg2 : i32, !llvm.ptr
return
}

hw.module @arith(in %clock : i1, in %a : i32, in %b : i32, out c : i32, out d : i32) {
%seq_clk = seq.to_clock %clock

%0 = sim.func.dpi.call @add_mlir(%a, %b) clock %seq_clk : (i32, i32) -> i32
%1 = sim.func.dpi.call @mul_shared(%a, %b) clock %seq_clk : (i32, i32) -> i32
hw.output %0, %1 : i32, i32
}

func.func @main() {
%c2_i32 = arith.constant 2 : i32
%c3_i32 = arith.constant 3 : i32
Expand All @@ -34,18 +35,16 @@ func.func @main() {
arc.sim.instantiate @arith as %arg0 {
arc.sim.set_input %arg0, "a" = %c2_i32 : i32, !arc.sim.instance<@arith>
arc.sim.set_input %arg0, "b" = %c3_i32 : i32, !arc.sim.instance<@arith>
arc.sim.set_input %arg0, "clock" = %one : i1, !arc.sim.instance<@arith>

arc.sim.step %arg0 : !arc.sim.instance<@arith>
arc.sim.set_input %arg0, "clock" = %zero : i1, !arc.sim.instance<@arith>
arc.sim.step %arg0 : !arc.sim.instance<@arith>
%0 = arc.sim.get_port %arg0, "c" : i32, !arc.sim.instance<@arith>
%1 = arc.sim.get_port %arg0, "d" : i32, !arc.sim.instance<@arith>

arc.sim.emit "c", %0 : i32
arc.sim.emit "d", %1 : i32

arc.sim.step %arg0 : !arc.sim.instance<@arith>
arc.sim.set_input %arg0, "clock" = %one : i1, !arc.sim.instance<@arith>
arc.sim.step %arg0 : !arc.sim.instance<@arith>
%2 = arc.sim.get_port %arg0, "c" : i32, !arc.sim.instance<@arith>
%3 = arc.sim.get_port %arg0, "d" : i32, !arc.sim.instance<@arith>
arc.sim.emit "c", %2 : i32
Expand Down
1 change: 1 addition & 0 deletions integration_test/arcilator/JIT/initial-shift-reg.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module {
%true = arith.constant 1 : i1

arc.sim.instantiate @shiftreg as %model {
arc.sim.step %model : !arc.sim.instance<@shiftreg>
arc.sim.set_input %model, "en" = %false : i1, !arc.sim.instance<@shiftreg>
arc.sim.set_input %model, "reset" = %false : i1, !arc.sim.instance<@shiftreg>
arc.sim.set_input %model, "din" = %ff : i8, !arc.sim.instance<@shiftreg>
Expand Down
3 changes: 2 additions & 1 deletion integration_test/arcilator/JIT/reg.mlir
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: arcilator %s --run --jit-entry=main | FileCheck %s
// REQUIRES: arcilator-jit

// CHECK: o1 = 2
// CHECK: o1 = 2
// CHECK-NEXT: o2 = 5
// CHECK-NEXT: o1 = 3
// CHECK-NEXT: o2 = 6
Expand Down Expand Up @@ -41,6 +41,7 @@ func.func @main() {
%step = arith.constant 1 : index

arc.sim.instantiate @counter as %model {
arc.sim.step %model : !arc.sim.instance<@counter>
%init_val1 = arc.sim.get_port %model, "o1" : i8, !arc.sim.instance<@counter>
%init_val2 = arc.sim.get_port %model, "o2" : i8, !arc.sim.instance<@counter>

Expand Down
5 changes: 3 additions & 2 deletions lib/Conversion/ConvertToArcs/ConvertToArcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ using llvm::MapVector;

static bool isArcBreakingOp(Operation *op) {
return op->hasTrait<OpTrait::ConstantLike>() ||
isa<hw::InstanceOp, seq::CompRegOp, MemoryOp, ClockedOpInterface,
seq::InitialOp, seq::ClockGateOp, sim::DPICallOp>(op) ||
isa<hw::InstanceOp, seq::CompRegOp, MemoryOp, MemoryReadPortOp,
ClockedOpInterface, seq::InitialOp, seq::ClockGateOp,
sim::DPICallOp>(op) ||
op->getNumResults() > 1;
}

Expand Down
8 changes: 7 additions & 1 deletion lib/Dialect/Arc/ArcTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ using namespace mlir;
#define GET_TYPEDEF_CLASSES
#include "circt/Dialect/Arc/ArcTypes.cpp.inc"

unsigned StateType::getBitWidth() { return hw::getBitWidth(getType()); }
unsigned StateType::getBitWidth() {
if (llvm::isa<seq::ClockType>(getType()))
return 1;
return hw::getBitWidth(getType());
}

LogicalResult
StateType::verify(llvm::function_ref<InFlightDiagnostic()> emitError,
Type innerType) {
if (llvm::isa<seq::ClockType>(innerType))
return success();
if (hw::getBitWidth(innerType) < 0)
return emitError() << "state type must have a known bit width; got "
<< innerType;
Expand Down
4 changes: 2 additions & 2 deletions lib/Dialect/Arc/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ add_circt_dialect_library(CIRCTArcTransforms
InlineArcs.cpp
IsolateClocks.cpp
LatencyRetiming.cpp
LegalizeStateUpdate.cpp
LowerArcsToFuncs.cpp
LowerClocksToFuncs.cpp
LowerLUT.cpp
LowerState.cpp
LowerStateRewrite.cpp
LowerVectorizations.cpp
MakeTables.cpp
MergeIfs.cpp
Expand All @@ -33,6 +32,7 @@ add_circt_dialect_library(CIRCTArcTransforms
CIRCTComb
CIRCTEmit
CIRCTHW
CIRCTLLHD
CIRCTOM
CIRCTSV
CIRCTSeq
Expand Down
Loading
Loading