2023-05-02 00:02:20 +08:00
|
|
|
// These tests will be only enabled if circt-lec is built.
|
|
|
|
// REQUIRES: circt-lec
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @basic(in %in: i1, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
hw.output %in : i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @not(in %in: i1, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%true = hw.constant true
|
|
|
|
%out = comb.xor bin %in, %true : i1
|
|
|
|
hw.output %out : i1
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.add
|
|
|
|
// RUN: circt-lec %s -c1=adder -c2=completeAdder -v=false | FileCheck %s --check-prefix=COMB_ADD
|
|
|
|
// COMB_ADD: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @adder(in %in1: i2, in %in2: i2, out out: i2) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%sum = comb.add bin %in1, %in2 : i2
|
|
|
|
hw.output %sum : i2
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @halfAdder(in %in1: i1, in %in2: i1, out carry: i1, out sum: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%sum = comb.xor bin %in1, %in2 : i1
|
|
|
|
%carry = comb.and bin %in1, %in2 : i1
|
|
|
|
hw.output %carry, %sum: i1, i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @completeAdder(in %in1: i2, in %in2 : i2, out out: i2) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%in1_0 = comb.extract %in1 from 0 : (i2) -> i1
|
|
|
|
%in1_1 = comb.extract %in1 from 1 : (i2) -> i1
|
|
|
|
%in2_0 = comb.extract %in2 from 0 : (i2) -> i1
|
|
|
|
%in2_1 = comb.extract %in2 from 1 : (i2) -> i1
|
|
|
|
%c1, %s1 = hw.instance "h1" @halfAdder(in1: %in1_0: i1, in2: %in2_0: i1) -> (carry: i1, sum: i1)
|
|
|
|
%c2, %s2 = hw.instance "h2" @halfAdder(in1: %in1_1: i1, in2: %in2_1: i1) -> (carry: i1, sum: i1)
|
|
|
|
%c3, %s3 = hw.instance "h3" @halfAdder(in1: %s2: i1, in2: %c1: i1) -> (carry: i1, sum: i1)
|
|
|
|
%fullsum = comb.concat %s3, %s1 : i1, i1
|
|
|
|
hw.output %fullsum : i2
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.and
|
|
|
|
// RUN: circt-lec %s -c1=and -c2=decomposedAnd -v=false | FileCheck %s --check-prefix=COMB_AND
|
|
|
|
// COMB_AND: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @and(in %in1: i1, in %in2: i1, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%out = comb.and bin %in1, %in2 : i1
|
|
|
|
hw.output %out : i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @decomposedAnd(in %in1: i1, in %in2: i1, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%not_in1 = hw.instance "n_in1" @not(in: %in1: i1) -> (out: i1)
|
|
|
|
%not_in2 = hw.instance "n_in2" @not(in: %in2: i1) -> (out: i1)
|
|
|
|
%not_and = comb.or bin %not_in1, %not_in2 : i1
|
|
|
|
%and = hw.instance "and" @not(in: %not_and: i1) -> (out: i1)
|
|
|
|
hw.output %and : i1
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.concat
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.divs
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.divu
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.extract
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.icmp
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.mods
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.modu
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.mul
|
|
|
|
// RUN: circt-lec %s -c1=mulBy2 -c2=addTwice -v=false | FileCheck %s --check-prefix=COMB_MUL
|
|
|
|
// COMB_MUL: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @mulBy2(in %in: i2, out out: i2) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%two = hw.constant 2 : i2
|
|
|
|
%res = comb.mul bin %in, %two : i2
|
|
|
|
hw.output %res : i2
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @addTwice(in %in: i2, out out: i2) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%res = comb.add bin %in, %in : i2
|
|
|
|
hw.output %res : i2
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.mux
|
|
|
|
// RUN: circt-lec %s -c1=mux -c2=decomposedMux -v=false | FileCheck %s --check-prefix=COMB_MUX
|
|
|
|
// COMB_MUX: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @mux(in %cond: i1, in %tvalue: i8, in %fvalue: i8, out out: i8) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%res = comb.mux bin %cond, %tvalue, %fvalue : i8
|
|
|
|
hw.output %res : i8
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @decomposedMux(in %cond: i1, in %tvalue: i8, in %fvalue: i8, out out: i8) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%cond_bar = hw.instance "n" @not(in: %cond: i1) -> (out: i1)
|
|
|
|
%lead_0 = hw.constant 0 : i7
|
|
|
|
%c_t = comb.concat %lead_0, %cond : i7, i1
|
|
|
|
%c_f = comb.concat %lead_0, %cond_bar : i7, i1
|
|
|
|
%t = comb.mul bin %tvalue, %c_t : i8
|
|
|
|
%f = comb.mul bin %fvalue, %c_f : i8
|
|
|
|
%res = comb.add bin %t, %f : i8
|
|
|
|
hw.output %res : i8
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.or
|
|
|
|
// RUN: circt-lec %s -c1=or -c2=decomposedOr -v=false | FileCheck %s --check-prefix=COMB_OR
|
|
|
|
// COMB_OR: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @or(in %in1: i1, in %in2: i1, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%out = comb.or bin %in1, %in2 : i1
|
|
|
|
hw.output %out : i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @decomposedOr(in %in1: i1, in %in2: i1, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%not_in1 = hw.instance "n_in1" @not(in: %in1: i1) -> (out: i1)
|
|
|
|
%not_in2 = hw.instance "n_in2" @not(in: %in2: i1) -> (out: i1)
|
|
|
|
%not_or = comb.and bin %not_in1, %not_in2 : i1
|
|
|
|
%or = hw.instance "or" @not(in: %not_or: i1) -> (out: i1)
|
|
|
|
hw.output %or : i1
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.parity
|
|
|
|
// RUN: circt-lec %s -c1=parity -c2=decomposedParity -v=false | FileCheck %s --check-prefix=COMB_PARITY
|
|
|
|
// COMB_PARITY: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @parity(in %in: i8, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%res = comb.parity bin %in : i8
|
|
|
|
hw.output %res : i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @decomposedParity(in %in: i8, out out: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%b0 = comb.extract %in from 0 : (i8) -> i1
|
|
|
|
%b1 = comb.extract %in from 1 : (i8) -> i1
|
|
|
|
%b2 = comb.extract %in from 2 : (i8) -> i1
|
|
|
|
%b3 = comb.extract %in from 3 : (i8) -> i1
|
|
|
|
%b4 = comb.extract %in from 4 : (i8) -> i1
|
|
|
|
%b5 = comb.extract %in from 5 : (i8) -> i1
|
|
|
|
%b6 = comb.extract %in from 6 : (i8) -> i1
|
|
|
|
%b7 = comb.extract %in from 7 : (i8) -> i1
|
|
|
|
%res = comb.xor bin %b0, %b1, %b2, %b3, %b4, %b5, %b6, %b7 : i1
|
|
|
|
hw.output %res : i1
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.replicate
|
|
|
|
// RUN: circt-lec %s -c1=replicate -c2=decomposedReplicate -v=false | FileCheck %s --check-prefix=COMB_REPLICATE
|
|
|
|
// COMB_REPLICATE: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @replicate(in %in: i2, out out: i8) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%res = comb.replicate %in : (i2) -> i8
|
|
|
|
hw.output %res : i8
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @decomposedReplicate(in %in: i2, out out: i8) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%res = comb.concat %in, %in, %in, %in : i2, i2, i2, i2
|
|
|
|
hw.output %res : i8
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.shl
|
|
|
|
// RUN: circt-lec %s -c1=shl -c2=decomposedShl -v=false | FileCheck %s --check-prefix=COMB_SHL
|
|
|
|
// COMB_SHL: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @shl(in %in1: i2, in %in2: i2, out out: i2) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%res = comb.shl bin %in1, %in2 : i2
|
|
|
|
hw.output %res : i2
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @decomposedShl(in %in1: i2, in %in2: i2, out out: i2) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%zero = hw.constant 0 : i2
|
|
|
|
%one = hw.constant 1 : i2
|
|
|
|
%two = hw.constant 2 : i2
|
|
|
|
// first possible shift
|
|
|
|
%cond1 = comb.icmp bin ugt %in2, %zero : i2
|
|
|
|
%mul1 = comb.mux bin %cond1, %two, %one : i2
|
|
|
|
%shl1 = comb.mul bin %in1, %mul1 : i2
|
|
|
|
// avoid subtraction underflow
|
|
|
|
%cond1_1 = comb.icmp bin eq %in2, %zero : i2
|
|
|
|
%sub1 = comb.mux bin %cond1_1, %zero, %one : i2
|
|
|
|
%in2_2 = comb.sub bin %in2, %sub1 : i2
|
|
|
|
// second possible shift
|
|
|
|
%cond2 = comb.icmp bin ugt %in2_2, %zero : i2
|
|
|
|
%mul2 = comb.mux bin %cond2, %two, %one : i2
|
|
|
|
%shl2 = comb.mul bin %shl1, %mul2 : i2
|
|
|
|
hw.output %shl2 : i2
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.shrs
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.shru
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
// comb.sub
|
|
|
|
// RUN: circt-lec %s -c1=subtractor -c2=completeSubtractor -v=false | FileCheck %s --check-prefix=COMB_SUB
|
|
|
|
// COMB_SUB: c1 == c2
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @subtractor(in %in1: i8, in %in2: i8, out out: i8) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%diff = comb.sub bin %in1, %in2 : i8
|
|
|
|
hw.output %diff : i8
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @halfSubtractor(in %in1: i1, in %in2: i1, out borrow: i1, out diff: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%diff = comb.xor bin %in1, %in2 : i1
|
|
|
|
%not_in1 = hw.instance "n_in1" @not(in: %in1: i1) -> (out: i1)
|
|
|
|
%borrow = comb.and bin %not_in1, %in2 : i1
|
|
|
|
hw.output %borrow, %diff: i1, i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @fullSubtractor(in %in1: i1, in %in2: i1, in %b_in: i1, out borrow: i1, out diff: i1) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%b1, %d1 = hw.instance "s1" @halfSubtractor(in1: %in1: i1, in2: %in2: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b2, %d_out = hw.instance "s2" @halfSubtractor(in1: %d1: i1, in2: %b_in: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b_out = comb.or bin %b1, %b2 : i1
|
|
|
|
hw.output %b_out, %d_out: i1, i1
|
|
|
|
}
|
|
|
|
|
2023-09-29 05:30:15 +08:00
|
|
|
hw.module @completeSubtractor(in %in1: i8, in %in2 : i8, out out: i8) {
|
2023-05-02 00:02:20 +08:00
|
|
|
%in1_0 = comb.extract %in1 from 0 : (i8) -> i1
|
|
|
|
%in1_1 = comb.extract %in1 from 1 : (i8) -> i1
|
|
|
|
%in1_2 = comb.extract %in1 from 2 : (i8) -> i1
|
|
|
|
%in1_3 = comb.extract %in1 from 3 : (i8) -> i1
|
|
|
|
%in1_4 = comb.extract %in1 from 4 : (i8) -> i1
|
|
|
|
%in1_5 = comb.extract %in1 from 5 : (i8) -> i1
|
|
|
|
%in1_6 = comb.extract %in1 from 6 : (i8) -> i1
|
|
|
|
%in1_7 = comb.extract %in1 from 7 : (i8) -> i1
|
|
|
|
%in2_0 = comb.extract %in2 from 0 : (i8) -> i1
|
|
|
|
%in2_1 = comb.extract %in2 from 1 : (i8) -> i1
|
|
|
|
%in2_2 = comb.extract %in2 from 2 : (i8) -> i1
|
|
|
|
%in2_3 = comb.extract %in2 from 3 : (i8) -> i1
|
|
|
|
%in2_4 = comb.extract %in2 from 4 : (i8) -> i1
|
|
|
|
%in2_5 = comb.extract %in2 from 5 : (i8) -> i1
|
|
|
|
%in2_6 = comb.extract %in2 from 6 : (i8) -> i1
|
|
|
|
%in2_7 = comb.extract %in2 from 7 : (i8) -> i1
|
|
|
|
%b0, %d0 = hw.instance "s0" @halfSubtractor(in1: %in1_0: i1, in2: %in2_0: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b1, %d1 = hw.instance "s1" @fullSubtractor(in1: %in1_1: i1, in2: %in2_1: i1, b_in: %b0: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b2, %d2 = hw.instance "s2" @fullSubtractor(in1: %in1_2: i1, in2: %in2_2: i1, b_in: %b1: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b3, %d3 = hw.instance "s3" @fullSubtractor(in1: %in1_3: i1, in2: %in2_3: i1, b_in: %b2: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b4, %d4 = hw.instance "s4" @fullSubtractor(in1: %in1_4: i1, in2: %in2_4: i1, b_in: %b3: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b5, %d5 = hw.instance "s5" @fullSubtractor(in1: %in1_5: i1, in2: %in2_5: i1, b_in: %b4: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b6, %d6 = hw.instance "s6" @fullSubtractor(in1: %in1_6: i1, in2: %in2_6: i1, b_in: %b5: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%b7, %d7 = hw.instance "s7" @fullSubtractor(in1: %in1_7: i1, in2: %in2_7: i1, b_in: %b6: i1) -> (borrow: i1, diff: i1)
|
|
|
|
%diff = comb.concat %d7, %d6, %d5, %d4, %d3, %d2, %d1, %d0 : i1, i1, i1, i1, i1, i1, i1, i1
|
|
|
|
hw.output %diff : i8
|
|
|
|
}
|
|
|
|
|
|
|
|
// comb.xor
|
|
|
|
// TODO
|