Skip to content

Commit

Permalink
Wrappers for CIRCT Moore MIR (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
maerhart authored Mar 31, 2022
1 parent 9bd6d54 commit a456553
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 3 deletions.
2 changes: 1 addition & 1 deletion circt
Submodule circt updated 183 files
1 change: 1 addition & 0 deletions src/bin/moore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ fn elaborate_name(
mlir_cx.load_dialect(circt::hw::dialect());
mlir_cx.load_dialect(circt::comb::dialect());
mlir_cx.load_dialect(circt::llhd::dialect());
mlir_cx.load_dialect(circt::moore::dialect());
mlir_cx.load_dialect(circt::seq::dialect());

// Attach a custom diagnostic handler to the context such that we
Expand Down
2 changes: 2 additions & 0 deletions src/circt-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ fn main() {
"CIRCTCAPIComb",
"CIRCTCAPIHW",
"CIRCTCAPILLHD",
"CIRCTCAPIMoore",
"CIRCTCAPISV",
"CIRCTCAPISeq",
"CIRCTComb",
"CIRCTHW",
"CIRCTLLHD",
"CIRCTMoore",
"CIRCTSV",
"CIRCTSeq",
"LLVMBinaryFormat",
Expand Down
1 change: 1 addition & 0 deletions src/circt-sys/wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "circt-c/Dialect/Comb.h"
#include "circt-c/Dialect/HW.h"
#include "circt-c/Dialect/LLHD.h"
#include "circt-c/Dialect/Moore.h"
#include "circt-c/Dialect/Seq.h"
#include "mlir-c/AffineExpr.h"
#include "mlir-c/AffineMap.h"
Expand Down
22 changes: 22 additions & 0 deletions src/circt/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
use crate::crate_prelude::*;

def_operation!(ModuleOp, "builtin.module");
def_operation!(
UnrealizedConversionCastOp,
"builtin.unrealized_conversion_cast"
);

impl ModuleOp {
/// Create a new module.
Expand All @@ -25,3 +29,21 @@ impl ModuleOp {

impl SingleRegionOp for ModuleOp {}
impl SingleBlockOp for ModuleOp {}

impl UnrealizedConversionCastOp {
/// Create a new unrealized conversion cast operation.
pub fn new(
builder: &mut Builder,
values: impl IntoIterator<Item = Value>,
result_tys: impl IntoIterator<Item = Type>,
) -> Self {
builder.build_with(|_, state| {
for value in values {
state.add_operand(value);
}
for rty in result_tys {
state.add_result(rty);
}
})
}
}
1 change: 1 addition & 0 deletions src/circt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub mod func;
pub mod hw;
pub mod llhd;
pub mod mlir;
pub mod moore;
pub mod seq;

pub use builtin::*;
Expand Down
5 changes: 5 additions & 0 deletions src/circt/src/mlir/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ pub fn get_integer_attr_big(ty: Type, value: &BigInt) -> Attribute {
}
}

/// Create a new unit attribute.
pub fn get_unit_attr(cx: Context) -> Attribute {
Attribute::from_raw(unsafe { mlirUnitAttrGet(cx.raw()) })
}

/// Create a new integer attribute from an i64 value.
pub fn get_integer_attr(ty: Type, value: i64) -> Attribute {
Attribute::from_raw(unsafe { mlirIntegerAttrGet(ty.raw(), value) })
Expand Down
82 changes: 82 additions & 0 deletions src/circt/src/moore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) 2016-2021 Fabian Schuiki

use crate::crate_prelude::*;

/// Define a shift operation with value and amount operands and a
/// unit attribute indicating whether the shift is arithmetic.
macro_rules! def_shift_operation {
($name:ident, $operation_name:expr) => {
def_operation_single_result!($name, $operation_name);

impl $name {
pub fn new(
builder: &mut Builder,
value: Value,
amount: Value,
arithmetic: bool,
) -> Self {
builder.build_with(|builder, state| {
state.add_operand(value);
state.add_operand(amount);
if arithmetic {
state.add_attribute("arithmetic", get_unit_attr(builder.cx));
}
state.add_result(value.ty());
})
}
}
};
}

pub fn dialect() -> DialectHandle {
DialectHandle::from_raw(unsafe { mlirGetDialectHandle__moore__() })
}

/// Get the size of a simple bit-vector in bits.
pub fn get_simple_bitvector_size(ty: Type) -> usize {
assert!(unsafe { mooreIsSimpleBitVectorType(ty.raw()) });
unsafe { mooreGetSimpleBitVectorSize(ty.raw()) as usize }
}

/// Check if type is four-valued.
pub fn is_four_valued(ty: Type) -> bool {
unsafe { mooreIsFourValuedType(ty.raw()) }
}

/// Create a new simple bit-vector type.
pub fn get_simple_bitvector_type(
cx: Context,
four_valued: bool,
signed: bool,
size: usize,
) -> Type {
Type::from_raw(unsafe {
mooreSimpleBitVectorTypeGet(cx.raw(), four_valued, signed, size as u32)
})
}

def_shift_operation!(ShlOp, "moore.mir.shl");
def_shift_operation!(ShrOp, "moore.mir.shr");
def_operation_single_result!(ConcatOp, "moore.mir.concat");

impl ConcatOp {
pub fn new(builder: &mut Builder, values: impl IntoIterator<Item = Value>) -> Self {
builder.build_with(|builder, state| {
let mut width = 0;
let mut four_valued = false;
for value in values {
state.add_operand(value);
if is_four_valued(value.ty()) {
four_valued = true;
}
width += get_simple_bitvector_size(value.ty());
}
state.add_result(get_simple_bitvector_type(
builder.cx,
four_valued,
false,
width,
));
})
}
}
106 changes: 104 additions & 2 deletions src/svlog/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1956,8 +1956,8 @@ where
hidden
};
match op {
mir::ShiftOp::Left => self.mk_shl(value, hidden, amount),
mir::ShiftOp::Right => self.mk_shr(value, hidden, amount),
mir::ShiftOp::Left => self.mk_moore_shl(value, hidden, amount, arith),
mir::ShiftOp::Right => self.mk_moore_shr(value, hidden, amount, arith),
}
}

Expand Down Expand Up @@ -3349,6 +3349,57 @@ where
)
}

fn mk_moore_shl(
&mut self,
value: HybridValue,
hidden: HybridValue,
amount: HybridValue,
arithmetic: bool,
) -> HybridValue {
let value_moore_type = circt::moore::get_simple_bitvector_type(
self.mcx,
false,
false,
circt::mlir::integer_type_width(value.1.ty()),
);
let amount_moore_type = circt::moore::get_simple_bitvector_type(
self.mcx,
false,
false,
circt::mlir::integer_type_width(amount.1.ty()),
);
let value_cast_to_moore = circt::builtin::UnrealizedConversionCastOp::new(
self.mlir_builder,
std::iter::once(value.1),
std::iter::once(value_moore_type),
)
.result(0);
let amount_cast_to_moore = circt::builtin::UnrealizedConversionCastOp::new(
self.mlir_builder,
std::iter::once(amount.1),
std::iter::once(amount_moore_type),
)
.result(0);
let shift = circt::moore::ShlOp::new(
self.mlir_builder,
value_cast_to_moore,
amount_cast_to_moore,
arithmetic,
)
.into();
let cast_to_llhd = circt::builtin::UnrealizedConversionCastOp::new(
self.mlir_builder,
std::iter::once(shift),
std::iter::once(value.1.ty()),
)
.result(0);

(
self.builder.ins().shl(value.0, hidden.0, amount.0),
cast_to_llhd,
)
}

fn mk_shl(
&mut self,
value: HybridValue,
Expand All @@ -3361,6 +3412,57 @@ where
)
}

fn mk_moore_shr(
&mut self,
value: HybridValue,
hidden: HybridValue,
amount: HybridValue,
arithmetic: bool,
) -> HybridValue {
let value_moore_type = circt::moore::get_simple_bitvector_type(
self.mcx,
false,
false,
circt::mlir::integer_type_width(value.1.ty()),
);
let amount_moore_type = circt::moore::get_simple_bitvector_type(
self.mcx,
false,
false,
circt::mlir::integer_type_width(amount.1.ty()),
);
let value_cast_to_moore = circt::builtin::UnrealizedConversionCastOp::new(
self.mlir_builder,
std::iter::once(value.1),
std::iter::once(value_moore_type),
)
.result(0);
let amount_cast_to_moore = circt::builtin::UnrealizedConversionCastOp::new(
self.mlir_builder,
std::iter::once(amount.1),
std::iter::once(amount_moore_type),
)
.result(0);
let shift = circt::moore::ShrOp::new(
self.mlir_builder,
value_cast_to_moore,
amount_cast_to_moore,
arithmetic,
)
.into();
let cast_to_llhd = circt::builtin::UnrealizedConversionCastOp::new(
self.mlir_builder,
std::iter::once(shift),
std::iter::once(value.1.ty()),
)
.result(0);

(
self.builder.ins().shr(value.0, hidden.0, amount.0),
cast_to_llhd,
)
}

fn mk_shr(
&mut self,
value: HybridValue,
Expand Down
17 changes: 17 additions & 0 deletions test/mlir/expressions.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: moore -e foo --format=mlir-native %s | FileCheck %s

// CHECK-LABEL: func @ShiftExpressions(%arg0: i22, %arg1: i6) {
function void ShiftExpressions(bit signed [21:0] x, bit [5:0] y);
// CHECK: moore.mir.shl %{{.+}}, %{{.+}} : !moore.packed<range<bit, 21:0>>, !moore.packed<range<bit, 5:0>>
// CHECK: moore.mir.shl arithmetic %{{.+}}, %{{.+}} : !moore.packed<range<bit, 21:0>>, !moore.packed<range<bit, 5:0>>
bit [21:0] a = x << y;
bit signed [21:0] b = x <<< y;

// CHECK: moore.mir.shr %{{.+}}, %{{.+}} : !moore.packed<range<bit, 21:0>>, !moore.packed<range<bit, 5:0>>
// CHECK: moore.mir.shr arithmetic %{{.+}}, %{{.+}} : !moore.packed<range<bit, 21:0>>, !moore.packed<range<bit, 5:0>>
bit [21:0] c = x >> y;
bit signed [21:0] d = x >>> y;
endfunction

module foo;
endmodule

0 comments on commit a456553

Please sign in to comment.