From 1018d924386cb4289db25c646a1fd9d6bcbea907 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 10 Feb 2021 16:05:36 -0500 Subject: [PATCH 01/12] Add std_exp --- primitives/bitnum/math.futil | 50 +++++++++++++++++++++++++++ primitives/bitnum/unsigned.futil | 1 - primitives/bitnum/unsigned.sv | 20 ----------- tests/correctness/exponent.expect | 5 +++ tests/correctness/exponent.futil | 24 +++++++++++++ tests/correctness/exponent.futil.data | 8 +++++ 6 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 tests/correctness/exponent.expect create mode 100644 tests/correctness/exponent.futil create mode 100644 tests/correctness/exponent.futil.data diff --git a/primitives/bitnum/math.futil b/primitives/bitnum/math.futil index 282b6329a..60f0025c1 100644 --- a/primitives/bitnum/math.futil +++ b/primitives/bitnum/math.futil @@ -1,3 +1,53 @@ extern "math.sv" { primitive sqrt(in: 32, go: 1, clk: 1) -> (out: 32, done: 1); +} + +// Computes the value b^e, where +// b is the `base` and e is the `exp`. +component std_exp(base: 32, exp: 32) -> (out: 32) { + cells { + pow = std_reg(32); + count = std_reg(32); + mul = std_mult(32); + lt = std_lt(32); + incr = std_add(32); + } + wires { + group init { + pow.in = 32'd1; + pow.write_en = 1'd1; + count.in = 32'd0; + count.write_en = 1'd1; + init[done] = pow.done & count.done ? 1'd1; + } + group do_mul { + mul.left = base; + mul.right = pow.out; + pow.in = mul.out; + pow.write_en = 1'd1; + do_mul[done] = pow.done; + } + group incr_count { + incr.left = 32'd1; + incr.right = count.out; + count.in = incr.out; + count.write_en = 1'd1; + incr_count[done] = count.done; + } + group cond { + lt.right = exp; + lt.left = count.out; + cond[done] = 1'd1; + } + + out = pow.out; + } + control { + seq { + init; + while lt.out with cond { + par { do_mul; incr_count; } + } + } + } } \ No newline at end of file diff --git a/primitives/bitnum/unsigned.futil b/primitives/bitnum/unsigned.futil index fb58b6dfb..d57cb15f1 100644 --- a/primitives/bitnum/unsigned.futil +++ b/primitives/bitnum/unsigned.futil @@ -42,6 +42,5 @@ extern "unsigned.sv" { ) -> ( out: width ); - primitive std_exp(exponent: 32, go: 1, clk: 1) -> (out: 32, done: 1); } diff --git a/primitives/bitnum/unsigned.sv b/primitives/bitnum/unsigned.sv index 7027cfbf3..56b7fcea7 100644 --- a/primitives/bitnum/unsigned.sv +++ b/primitives/bitnum/unsigned.sv @@ -274,23 +274,3 @@ module std_mod #( ); assign out = left % right; endmodule - -module std_exp ( - input logic [31:0] exponent, - input logic go, - input logic clk, - output logic [31:0] out, - output logic done -); - always_ff @(posedge clk) begin - if (go) begin - // XXX: This is a hilariously bad approximation - /* verilator lint_off REALCVT */ - out <= /* 2.718281 */ 3 ** exponent; - done <= 1; - end else begin - out <= 0; - done <= 0; - end - end -endmodule diff --git a/tests/correctness/exponent.expect b/tests/correctness/exponent.expect new file mode 100644 index 000000000..bb2ea72f6 --- /dev/null +++ b/tests/correctness/exponent.expect @@ -0,0 +1,5 @@ +{ + "b_x": [ + 9 + ] +} diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil new file mode 100644 index 000000000..9ef0c57c1 --- /dev/null +++ b/tests/correctness/exponent.futil @@ -0,0 +1,24 @@ +import "primitives/std.lib"; +import "primitives/bitnum/math.futil"; +component main() -> () { + cells { + base = std_const(32,3); + exp = std_const(32,2); + b_x = std_mem_d1(32, 1, 1); + std_exp0 = std_exp(); + } + wires { + group fill_memory { + b_x.write_data = std_exp0.out; + b_x.addr0 = 1'd0; + b_x.write_en = 1'd1; + fill_memory[done] = b_x.done; + } + } + control { + seq { + invoke std_exp0(base=base.out, exp=exp.out)(); + fill_memory; + } + } +} \ No newline at end of file diff --git a/tests/correctness/exponent.futil.data b/tests/correctness/exponent.futil.data new file mode 100644 index 000000000..807693dd4 --- /dev/null +++ b/tests/correctness/exponent.futil.data @@ -0,0 +1,8 @@ +{ + "b_x": { + "data": [ + 0 + ], + "bitwidth": 32 + } +} From 57557ae382697b4a3aeace89a746a03b3e73db13 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Wed, 10 Feb 2021 16:06:56 -0500 Subject: [PATCH 02/12] ws --- primitives/bitnum/math.futil | 2 +- tests/correctness/exponent.futil | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/primitives/bitnum/math.futil b/primitives/bitnum/math.futil index 60f0025c1..6e3f932ab 100644 --- a/primitives/bitnum/math.futil +++ b/primitives/bitnum/math.futil @@ -50,4 +50,4 @@ component std_exp(base: 32, exp: 32) -> (out: 32) { } } } -} \ No newline at end of file +} diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil index 9ef0c57c1..5750a2ca7 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/exponent.futil @@ -21,4 +21,4 @@ component main() -> () { fill_memory; } } -} \ No newline at end of file +} From 662d54e5397a97f562ea5ccce3e2f6746e1c8efc Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Thu, 11 Feb 2021 19:18:32 -0500 Subject: [PATCH 03/12] Move to unsigned --- primitives/bitnum/math.futil | 50 ----- primitives/bitnum/unsigned.futil | 50 +++++ tests/correctness/exponent.futil | 1 - tests/correctness/relay/softmax.relay | 6 + tests/correctness/relay/softmax.relay.data | 10 + tests/frontend/relay/softmax.expect | 208 +++++++++++++++++++++ tests/frontend/relay/softmax.relay | 6 + 7 files changed, 280 insertions(+), 51 deletions(-) create mode 100644 tests/correctness/relay/softmax.relay create mode 100644 tests/correctness/relay/softmax.relay.data create mode 100644 tests/frontend/relay/softmax.expect create mode 100644 tests/frontend/relay/softmax.relay diff --git a/primitives/bitnum/math.futil b/primitives/bitnum/math.futil index 6e3f932ab..dbbb9371a 100644 --- a/primitives/bitnum/math.futil +++ b/primitives/bitnum/math.futil @@ -1,53 +1,3 @@ extern "math.sv" { primitive sqrt(in: 32, go: 1, clk: 1) -> (out: 32, done: 1); } - -// Computes the value b^e, where -// b is the `base` and e is the `exp`. -component std_exp(base: 32, exp: 32) -> (out: 32) { - cells { - pow = std_reg(32); - count = std_reg(32); - mul = std_mult(32); - lt = std_lt(32); - incr = std_add(32); - } - wires { - group init { - pow.in = 32'd1; - pow.write_en = 1'd1; - count.in = 32'd0; - count.write_en = 1'd1; - init[done] = pow.done & count.done ? 1'd1; - } - group do_mul { - mul.left = base; - mul.right = pow.out; - pow.in = mul.out; - pow.write_en = 1'd1; - do_mul[done] = pow.done; - } - group incr_count { - incr.left = 32'd1; - incr.right = count.out; - count.in = incr.out; - count.write_en = 1'd1; - incr_count[done] = count.done; - } - group cond { - lt.right = exp; - lt.left = count.out; - cond[done] = 1'd1; - } - - out = pow.out; - } - control { - seq { - init; - while lt.out with cond { - par { do_mul; incr_count; } - } - } - } -} diff --git a/primitives/bitnum/unsigned.futil b/primitives/bitnum/unsigned.futil index d57cb15f1..e269e27dd 100644 --- a/primitives/bitnum/unsigned.futil +++ b/primitives/bitnum/unsigned.futil @@ -44,3 +44,53 @@ extern "unsigned.sv" { ); } + +// Computes the unsigned value b^e, where +// b is the `base` and e is the `exp`. +component std_exp(base: 32, exp: 32) -> (out: 32) { + cells { + pow = std_reg(32); + count = std_reg(32); + mul = std_mult(32); + lt = std_lt(32); + incr = std_add(32); + } + wires { + group init { + pow.in = 32'd1; + pow.write_en = 1'd1; + count.in = 32'd0; + count.write_en = 1'd1; + init[done] = pow.done & count.done ? 1'd1; + } + group do_mul { + mul.left = base; + mul.right = pow.out; + pow.in = mul.out; + pow.write_en = 1'd1; + do_mul[done] = pow.done; + } + group incr_count { + incr.left = 32'd1; + incr.right = count.out; + count.in = incr.out; + count.write_en = 1'd1; + incr_count[done] = count.done; + } + group cond { + lt.right = exp; + lt.left = count.out; + cond[done] = 1'd1; + } + + out = pow.out; + } + control { + seq { + init; + while lt.out with cond { + par { do_mul; incr_count; } + } + } + } +} \ No newline at end of file diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil index 5750a2ca7..15e8dffae 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/exponent.futil @@ -1,5 +1,4 @@ import "primitives/std.lib"; -import "primitives/bitnum/math.futil"; component main() -> () { cells { base = std_const(32,3); diff --git a/tests/correctness/relay/softmax.relay b/tests/correctness/relay/softmax.relay new file mode 100644 index 000000000..89add84d7 --- /dev/null +++ b/tests/correctness/relay/softmax.relay @@ -0,0 +1,6 @@ +v0.0.4 +fn (%x: Tensor[(1, 2), int32]) { + let %x1: Tensor[(1, 2), int32] = nn.softmax(%x); + %x1 +} + diff --git a/tests/correctness/relay/softmax.relay.data b/tests/correctness/relay/softmax.relay.data new file mode 100644 index 000000000..f0d81e4e5 --- /dev/null +++ b/tests/correctness/relay/softmax.relay.data @@ -0,0 +1,10 @@ +{ + "x": { + "data": [[4, 16]], + "bitwidth": 32 + }, + "x1": { + "data": [[0, 0]], + "bitwidth": 32 + } +} \ No newline at end of file diff --git a/tests/frontend/relay/softmax.expect b/tests/frontend/relay/softmax.expect new file mode 100644 index 000000000..56e6c2787 --- /dev/null +++ b/tests/frontend/relay/softmax.expect @@ -0,0 +1,208 @@ +import "primitives/std.lib"; +import "primitives/bitnum/math.futil"; +component main() -> () { + cells { + x = std_mem_d2(32, 1, 10, 1, 4); + x1 = std_mem_d2(32, 1, 10, 1, 4); + nn_softmax_ = nn_softmax(); + } + wires { + + } + control { + seq { + invoke nn_softmax_(x0_0_read_data=x.read_data, x10_0_done=x1.done, x10_0_read_data=x1.read_data)(x0_0_addr0=x.addr0, x0_0_addr1=x.addr1, x10_0_write_data=x1.write_data, x10_0_write_en=x1.write_en, x10_0_addr0=x1.addr0, x10_0_addr1=x1.addr1); + } + } +} +component nn_softmax(x0_0_read_data: 32, x0_0_done: 1, x10_0_read_data: 32, x10_0_done: 1) -> (x0_0_write_data: 32, x0_0_write_en: 1, x0_0_addr0: 1, x0_0_addr1: 4, x10_0_write_data: 32, x10_0_write_en: 1, x10_0_addr0: 1, x10_0_addr1: 4) { + cells { + add0 = std_sadd(32); + add1 = std_add(4); + add2 = std_add(4); + add3 = std_add(1); + bin_read0_0 = std_reg(32); + const0 = std_const(1,0); + const1 = std_const(1,0); + const2 = std_const(32,0); + const3 = std_const(4,0); + const4 = std_const(4,9); + const5 = std_const(4,1); + const6 = std_const(4,0); + const7 = std_const(4,9); + const8 = std_const(4,1); + const9 = std_const(1,1); + div_pipe0 = std_sdiv_pipe(32); + i0 = std_reg(1); + j0 = std_reg(4); + k0 = std_reg(4); + le0 = std_le(1); + le1 = std_le(4); + le2 = std_le(4); + std_exp0 = std_exp(); + std_exp1 = std_exp(); + tmp1_0 = std_reg(32); + tmp2_0 = std_reg(32); + x1_read0_0 = std_reg(32); + x_expsum_0 = std_reg(32); + x_read0_0 = std_reg(32); + x_read1_0 = std_reg(32); + } + wires { + group cond0<"static"=0> { + cond0[done] = 1'd1; + le0.left = i0.out; + le0.right = const1.out; + } + group cond1<"static"=0> { + cond1[done] = 1'd1; + le1.left = j0.out; + le1.right = const4.out; + } + group cond2<"static"=0> { + cond2[done] = 1'd1; + le2.left = k0.out; + le2.right = const7.out; + } + group let0<"static"=1> { + i0.in = const0.out; + i0.write_en = 1'd1; + let0[done] = i0.done; + } + group let1<"static"=1> { + x_expsum_0.in = const2.out; + x_expsum_0.write_en = 1'd1; + let1[done] = x_expsum_0.done; + } + group let2<"static"=1> { + j0.in = const3.out; + j0.write_en = 1'd1; + let2[done] = j0.done; + } + group let3 { + tmp1_0.in = std_exp0.out; + tmp1_0.write_en = 1'd1; + let3[done] = tmp1_0.done; + } + group let4<"static"=1> { + k0.in = const6.out; + k0.write_en = 1'd1; + let4[done] = k0.done; + } + group let5 { + tmp2_0.in = std_exp1.out; + tmp2_0.write_en = 1'd1; + let5[done] = tmp2_0.done; + } + group let6 { + bin_read0_0.in = div_pipe0.out; + bin_read0_0.write_en = div_pipe0.done; + let6[done] = bin_read0_0.done; + div_pipe0.left = x1_read0_0.out; + div_pipe0.right = x_expsum_0.out; + div_pipe0.go = !div_pipe0.done ? 1'd1; + } + group upd0<"static"=1> { + x_read0_0.write_en = 1'd1; + x0_0_addr1 = j0.out; + x0_0_addr0 = i0.out; + x_read0_0.in = 1'd1 ? x0_0_read_data; + upd0[done] = x_read0_0.done ? 1'd1; + } + group upd1<"static"=1> { + x_expsum_0.write_en = 1'd1; + add0.left = x_expsum_0.out; + add0.right = tmp1_0.out; + x_expsum_0.in = 1'd1 ? add0.out; + upd1[done] = x_expsum_0.done ? 1'd1; + } + group upd2<"static"=1> { + j0.write_en = 1'd1; + add1.left = j0.out; + add1.right = const5.out; + j0.in = 1'd1 ? add1.out; + upd2[done] = j0.done ? 1'd1; + } + group upd3<"static"=1> { + x_read1_0.write_en = 1'd1; + x0_0_addr1 = k0.out; + x0_0_addr0 = i0.out; + x_read1_0.in = 1'd1 ? x0_0_read_data; + upd3[done] = x_read1_0.done ? 1'd1; + } + group upd4<"static"=1> { + x10_0_addr1 = k0.out; + x10_0_addr0 = i0.out; + x10_0_write_en = 1'd1; + x10_0_write_data = 1'd1 ? tmp2_0.out; + upd4[done] = x10_0_done ? 1'd1; + } + group upd5<"static"=1> { + x1_read0_0.write_en = 1'd1; + x10_0_addr1 = k0.out; + x10_0_addr0 = i0.out; + x1_read0_0.in = 1'd1 ? x10_0_read_data; + upd5[done] = x1_read0_0.done ? 1'd1; + } + group upd6<"static"=1> { + x10_0_addr1 = k0.out; + x10_0_addr0 = i0.out; + x10_0_write_en = 1'd1; + x10_0_write_data = 1'd1 ? bin_read0_0.out; + upd6[done] = x10_0_done ? 1'd1; + } + group upd7<"static"=1> { + k0.write_en = 1'd1; + add2.left = k0.out; + add2.right = const8.out; + k0.in = 1'd1 ? add2.out; + upd7[done] = k0.done ? 1'd1; + } + group upd8<"static"=1> { + i0.write_en = 1'd1; + add3.left = i0.out; + add3.right = const9.out; + i0.in = 1'd1 ? add3.out; + upd8[done] = i0.done ? 1'd1; + } + } + control { + seq { + let0; + while le0.out with cond0 { + seq { + par { + let1; + seq { + let2; + while le1.out with cond1 { + seq { + upd0; + invoke std_exp0(in=x_read0_0.out)(); + let3; + upd1; + upd2; + } + } + } + } + let4; + while le2.out with cond2 { + seq { + upd3; + invoke std_exp1(in=x_read1_0.out)(); + let5; + upd4; + upd5; + let6; + upd6; + upd7; + } + } + upd8; + } + } + } + } +} + diff --git a/tests/frontend/relay/softmax.relay b/tests/frontend/relay/softmax.relay new file mode 100644 index 000000000..1e3d65075 --- /dev/null +++ b/tests/frontend/relay/softmax.relay @@ -0,0 +1,6 @@ +v0.0.4 +fn (%x: Tensor[(1, 10), int32]) { + let %x1: Tensor[(1, 10), int32] = nn.softmax(%x); + %x1 +} + From 48a8545afd6b6c9bfa9571683d251dce441b0842 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Thu, 11 Feb 2021 20:15:49 -0500 Subject: [PATCH 04/12] Don't add softmax tests here. --- tests/correctness/relay/softmax.relay | 6 - tests/correctness/relay/softmax.relay.data | 10 - tests/frontend/relay/softmax.expect | 208 --------------------- tests/frontend/relay/softmax.relay | 6 - 4 files changed, 230 deletions(-) delete mode 100644 tests/correctness/relay/softmax.relay delete mode 100644 tests/correctness/relay/softmax.relay.data delete mode 100644 tests/frontend/relay/softmax.expect delete mode 100644 tests/frontend/relay/softmax.relay diff --git a/tests/correctness/relay/softmax.relay b/tests/correctness/relay/softmax.relay deleted file mode 100644 index 89add84d7..000000000 --- a/tests/correctness/relay/softmax.relay +++ /dev/null @@ -1,6 +0,0 @@ -v0.0.4 -fn (%x: Tensor[(1, 2), int32]) { - let %x1: Tensor[(1, 2), int32] = nn.softmax(%x); - %x1 -} - diff --git a/tests/correctness/relay/softmax.relay.data b/tests/correctness/relay/softmax.relay.data deleted file mode 100644 index f0d81e4e5..000000000 --- a/tests/correctness/relay/softmax.relay.data +++ /dev/null @@ -1,10 +0,0 @@ -{ - "x": { - "data": [[4, 16]], - "bitwidth": 32 - }, - "x1": { - "data": [[0, 0]], - "bitwidth": 32 - } -} \ No newline at end of file diff --git a/tests/frontend/relay/softmax.expect b/tests/frontend/relay/softmax.expect deleted file mode 100644 index 56e6c2787..000000000 --- a/tests/frontend/relay/softmax.expect +++ /dev/null @@ -1,208 +0,0 @@ -import "primitives/std.lib"; -import "primitives/bitnum/math.futil"; -component main() -> () { - cells { - x = std_mem_d2(32, 1, 10, 1, 4); - x1 = std_mem_d2(32, 1, 10, 1, 4); - nn_softmax_ = nn_softmax(); - } - wires { - - } - control { - seq { - invoke nn_softmax_(x0_0_read_data=x.read_data, x10_0_done=x1.done, x10_0_read_data=x1.read_data)(x0_0_addr0=x.addr0, x0_0_addr1=x.addr1, x10_0_write_data=x1.write_data, x10_0_write_en=x1.write_en, x10_0_addr0=x1.addr0, x10_0_addr1=x1.addr1); - } - } -} -component nn_softmax(x0_0_read_data: 32, x0_0_done: 1, x10_0_read_data: 32, x10_0_done: 1) -> (x0_0_write_data: 32, x0_0_write_en: 1, x0_0_addr0: 1, x0_0_addr1: 4, x10_0_write_data: 32, x10_0_write_en: 1, x10_0_addr0: 1, x10_0_addr1: 4) { - cells { - add0 = std_sadd(32); - add1 = std_add(4); - add2 = std_add(4); - add3 = std_add(1); - bin_read0_0 = std_reg(32); - const0 = std_const(1,0); - const1 = std_const(1,0); - const2 = std_const(32,0); - const3 = std_const(4,0); - const4 = std_const(4,9); - const5 = std_const(4,1); - const6 = std_const(4,0); - const7 = std_const(4,9); - const8 = std_const(4,1); - const9 = std_const(1,1); - div_pipe0 = std_sdiv_pipe(32); - i0 = std_reg(1); - j0 = std_reg(4); - k0 = std_reg(4); - le0 = std_le(1); - le1 = std_le(4); - le2 = std_le(4); - std_exp0 = std_exp(); - std_exp1 = std_exp(); - tmp1_0 = std_reg(32); - tmp2_0 = std_reg(32); - x1_read0_0 = std_reg(32); - x_expsum_0 = std_reg(32); - x_read0_0 = std_reg(32); - x_read1_0 = std_reg(32); - } - wires { - group cond0<"static"=0> { - cond0[done] = 1'd1; - le0.left = i0.out; - le0.right = const1.out; - } - group cond1<"static"=0> { - cond1[done] = 1'd1; - le1.left = j0.out; - le1.right = const4.out; - } - group cond2<"static"=0> { - cond2[done] = 1'd1; - le2.left = k0.out; - le2.right = const7.out; - } - group let0<"static"=1> { - i0.in = const0.out; - i0.write_en = 1'd1; - let0[done] = i0.done; - } - group let1<"static"=1> { - x_expsum_0.in = const2.out; - x_expsum_0.write_en = 1'd1; - let1[done] = x_expsum_0.done; - } - group let2<"static"=1> { - j0.in = const3.out; - j0.write_en = 1'd1; - let2[done] = j0.done; - } - group let3 { - tmp1_0.in = std_exp0.out; - tmp1_0.write_en = 1'd1; - let3[done] = tmp1_0.done; - } - group let4<"static"=1> { - k0.in = const6.out; - k0.write_en = 1'd1; - let4[done] = k0.done; - } - group let5 { - tmp2_0.in = std_exp1.out; - tmp2_0.write_en = 1'd1; - let5[done] = tmp2_0.done; - } - group let6 { - bin_read0_0.in = div_pipe0.out; - bin_read0_0.write_en = div_pipe0.done; - let6[done] = bin_read0_0.done; - div_pipe0.left = x1_read0_0.out; - div_pipe0.right = x_expsum_0.out; - div_pipe0.go = !div_pipe0.done ? 1'd1; - } - group upd0<"static"=1> { - x_read0_0.write_en = 1'd1; - x0_0_addr1 = j0.out; - x0_0_addr0 = i0.out; - x_read0_0.in = 1'd1 ? x0_0_read_data; - upd0[done] = x_read0_0.done ? 1'd1; - } - group upd1<"static"=1> { - x_expsum_0.write_en = 1'd1; - add0.left = x_expsum_0.out; - add0.right = tmp1_0.out; - x_expsum_0.in = 1'd1 ? add0.out; - upd1[done] = x_expsum_0.done ? 1'd1; - } - group upd2<"static"=1> { - j0.write_en = 1'd1; - add1.left = j0.out; - add1.right = const5.out; - j0.in = 1'd1 ? add1.out; - upd2[done] = j0.done ? 1'd1; - } - group upd3<"static"=1> { - x_read1_0.write_en = 1'd1; - x0_0_addr1 = k0.out; - x0_0_addr0 = i0.out; - x_read1_0.in = 1'd1 ? x0_0_read_data; - upd3[done] = x_read1_0.done ? 1'd1; - } - group upd4<"static"=1> { - x10_0_addr1 = k0.out; - x10_0_addr0 = i0.out; - x10_0_write_en = 1'd1; - x10_0_write_data = 1'd1 ? tmp2_0.out; - upd4[done] = x10_0_done ? 1'd1; - } - group upd5<"static"=1> { - x1_read0_0.write_en = 1'd1; - x10_0_addr1 = k0.out; - x10_0_addr0 = i0.out; - x1_read0_0.in = 1'd1 ? x10_0_read_data; - upd5[done] = x1_read0_0.done ? 1'd1; - } - group upd6<"static"=1> { - x10_0_addr1 = k0.out; - x10_0_addr0 = i0.out; - x10_0_write_en = 1'd1; - x10_0_write_data = 1'd1 ? bin_read0_0.out; - upd6[done] = x10_0_done ? 1'd1; - } - group upd7<"static"=1> { - k0.write_en = 1'd1; - add2.left = k0.out; - add2.right = const8.out; - k0.in = 1'd1 ? add2.out; - upd7[done] = k0.done ? 1'd1; - } - group upd8<"static"=1> { - i0.write_en = 1'd1; - add3.left = i0.out; - add3.right = const9.out; - i0.in = 1'd1 ? add3.out; - upd8[done] = i0.done ? 1'd1; - } - } - control { - seq { - let0; - while le0.out with cond0 { - seq { - par { - let1; - seq { - let2; - while le1.out with cond1 { - seq { - upd0; - invoke std_exp0(in=x_read0_0.out)(); - let3; - upd1; - upd2; - } - } - } - } - let4; - while le2.out with cond2 { - seq { - upd3; - invoke std_exp1(in=x_read1_0.out)(); - let5; - upd4; - upd5; - let6; - upd6; - upd7; - } - } - upd8; - } - } - } - } -} - diff --git a/tests/frontend/relay/softmax.relay b/tests/frontend/relay/softmax.relay deleted file mode 100644 index 1e3d65075..000000000 --- a/tests/frontend/relay/softmax.relay +++ /dev/null @@ -1,6 +0,0 @@ -v0.0.4 -fn (%x: Tensor[(1, 10), int32]) { - let %x1: Tensor[(1, 10), int32] = nn.softmax(%x); - %x1 -} - From 4c284ac49ede709e728bd7cfa0a0d97eea369577 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Thu, 11 Feb 2021 20:49:57 -0500 Subject: [PATCH 05/12] Use math --- primitives/bitnum/math.futil | 50 ++++++++++++++++++++++++++++++++ primitives/bitnum/unsigned.futil | 50 -------------------------------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/primitives/bitnum/math.futil b/primitives/bitnum/math.futil index dbbb9371a..6b702303d 100644 --- a/primitives/bitnum/math.futil +++ b/primitives/bitnum/math.futil @@ -1,3 +1,53 @@ extern "math.sv" { primitive sqrt(in: 32, go: 1, clk: 1) -> (out: 32, done: 1); } + +// Computes the unsigned value b^e, where +// b is the `base` and e is the `exp`. +component std_exp(base: 32, exp: 32) -> (out: 32) { + cells { + pow = std_reg(32); + count = std_reg(32); + mul = std_mult(32); + lt = std_lt(32); + incr = std_add(32); + } + wires { + group init { + pow.in = 32'd1; + pow.write_en = 1'd1; + count.in = 32'd0; + count.write_en = 1'd1; + init[done] = pow.done & count.done ? 1'd1; + } + group do_mul { + mul.left = base; + mul.right = pow.out; + pow.in = mul.out; + pow.write_en = 1'd1; + do_mul[done] = pow.done; + } + group incr_count { + incr.left = 32'd1; + incr.right = count.out; + count.in = incr.out; + count.write_en = 1'd1; + incr_count[done] = count.done; + } + group cond { + lt.right = exp; + lt.left = count.out; + cond[done] = 1'd1; + } + + out = pow.out; + } + control { + seq { + init; + while lt.out with cond { + par { do_mul; incr_count; } + } + } + } +} diff --git a/primitives/bitnum/unsigned.futil b/primitives/bitnum/unsigned.futil index e269e27dd..096e87ed8 100644 --- a/primitives/bitnum/unsigned.futil +++ b/primitives/bitnum/unsigned.futil @@ -43,54 +43,4 @@ extern "unsigned.sv" { out: width ); -} - -// Computes the unsigned value b^e, where -// b is the `base` and e is the `exp`. -component std_exp(base: 32, exp: 32) -> (out: 32) { - cells { - pow = std_reg(32); - count = std_reg(32); - mul = std_mult(32); - lt = std_lt(32); - incr = std_add(32); - } - wires { - group init { - pow.in = 32'd1; - pow.write_en = 1'd1; - count.in = 32'd0; - count.write_en = 1'd1; - init[done] = pow.done & count.done ? 1'd1; - } - group do_mul { - mul.left = base; - mul.right = pow.out; - pow.in = mul.out; - pow.write_en = 1'd1; - do_mul[done] = pow.done; - } - group incr_count { - incr.left = 32'd1; - incr.right = count.out; - count.in = incr.out; - count.write_en = 1'd1; - incr_count[done] = count.done; - } - group cond { - lt.right = exp; - lt.left = count.out; - cond[done] = 1'd1; - } - - out = pow.out; - } - control { - seq { - init; - while lt.out with cond { - par { do_mul; incr_count; } - } - } - } } \ No newline at end of file From b3f84fa4595e6d7cab891adeb39f94f4fd5d2ad6 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Thu, 11 Feb 2021 20:56:26 -0500 Subject: [PATCH 06/12] Math --- tests/correctness/exponent.futil | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil index 15e8dffae..b9d1dd0db 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/exponent.futil @@ -1,4 +1,5 @@ import "primitives/std.lib"; +import "primitives/math.futil"; component main() -> () { cells { base = std_const(32,3); From fefb099c060a022360f5048b4ad7d32c01689fcb Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Thu, 11 Feb 2021 21:03:19 -0500 Subject: [PATCH 07/12] bitnum --- tests/correctness/exponent.futil | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil index b9d1dd0db..5750a2ca7 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/exponent.futil @@ -1,5 +1,5 @@ import "primitives/std.lib"; -import "primitives/math.futil"; +import "primitives/bitnum/math.futil"; component main() -> () { cells { base = std_const(32,3); From e9755b8bf0551051959fb596befb9ebc961df1e9 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 16 Feb 2021 12:53:23 -0500 Subject: [PATCH 08/12] Use out, memories. --- tests/correctness/exponent.futil | 22 ++++++++++++++-------- tests/correctness/exponent.futil.data | 14 +++++++++++++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil index 5750a2ca7..3c064e22d 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/exponent.futil @@ -2,22 +2,28 @@ import "primitives/std.lib"; import "primitives/bitnum/math.futil"; component main() -> () { cells { - base = std_const(32,3); - exp = std_const(32,2); - b_x = std_mem_d1(32, 1, 1); + base = std_mem_d1(32, 1, 1); + exp = std_mem_d1(32, 1, 1); + out = std_mem_d1(32, 1, 1); std_exp0 = std_exp(); } wires { + group init { + base.addr0 = 1'd0; + exp.addr0 = 1'd0; + init[done] = 1'd1; + } group fill_memory { - b_x.write_data = std_exp0.out; - b_x.addr0 = 1'd0; - b_x.write_en = 1'd1; - fill_memory[done] = b_x.done; + out.write_data = std_exp0.out; + out.addr0 = 1'd0; + out.write_en = 1'd1; + fill_memory[done] = out.done; } } control { seq { - invoke std_exp0(base=base.out, exp=exp.out)(); + init; + invoke std_exp0(base=base.read_data, exp=exp.read_data)(); fill_memory; } } diff --git a/tests/correctness/exponent.futil.data b/tests/correctness/exponent.futil.data index 807693dd4..512e21361 100644 --- a/tests/correctness/exponent.futil.data +++ b/tests/correctness/exponent.futil.data @@ -1,8 +1,20 @@ { - "b_x": { + "out": { "data": [ 0 ], "bitwidth": 32 + }, + "base": { + "data": [ + 2 + ], + "bitwidth": 32 + }, + "exp": { + "data": [ + 10 + ], + "bitwidth": 32 } } From 5bb10845cef6a17516b4d48e049680b3375f0e59 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 16 Feb 2021 12:54:32 -0500 Subject: [PATCH 09/12] Upd .expect --- tests/correctness/exponent.expect | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/correctness/exponent.expect b/tests/correctness/exponent.expect index bb2ea72f6..7fd85cbc0 100644 --- a/tests/correctness/exponent.expect +++ b/tests/correctness/exponent.expect @@ -1,5 +1,11 @@ { - "b_x": [ - 9 + "base": [ + 2 + ], + "exp": [ + 10 + ], + "out": [ + 1024 ] } From 87e8036e8deab523abb1bcda0ba36702f95bcd89 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 16 Feb 2021 14:21:44 -0500 Subject: [PATCH 10/12] Use registers. --- tests/correctness/exponent.futil | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/correctness/exponent.futil b/tests/correctness/exponent.futil index 3c064e22d..601933b3f 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/exponent.futil @@ -2,16 +2,22 @@ import "primitives/std.lib"; import "primitives/bitnum/math.futil"; component main() -> () { cells { + out = std_mem_d1(32, 1, 1); base = std_mem_d1(32, 1, 1); exp = std_mem_d1(32, 1, 1); - out = std_mem_d1(32, 1, 1); + base_reg = std_reg(32); + exp_reg = std_reg(32); std_exp0 = std_exp(); } wires { group init { base.addr0 = 1'd0; exp.addr0 = 1'd0; - init[done] = 1'd1; + base_reg.in = base.read_data; + exp_reg.in = exp.read_data; + base_reg.write_en = 1'd1; + exp_reg.write_en = 1'd1; + init[done] = base_reg.done & exp_reg.done ? 1'd1; } group fill_memory { out.write_data = std_exp0.out; @@ -23,7 +29,7 @@ component main() -> () { control { seq { init; - invoke std_exp0(base=base.read_data, exp=exp.read_data)(); + invoke std_exp0(base=base_reg.out, exp=exp_reg.out)(); fill_memory; } } From 225a33e88f35eab397601533cee84e789ef2c5e4 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Fri, 19 Feb 2021 15:50:18 -0500 Subject: [PATCH 11/12] Rename to pow. --- primitives/bitnum/math.futil | 2 +- tests/correctness/{exponent.expect => pow.expect} | 0 tests/correctness/{exponent.futil => pow.futil} | 6 +++--- tests/correctness/{exponent.futil.data => pow.futil.data} | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename tests/correctness/{exponent.expect => pow.expect} (100%) rename tests/correctness/{exponent.futil => pow.futil} (85%) rename tests/correctness/{exponent.futil.data => pow.futil.data} (100%) diff --git a/primitives/bitnum/math.futil b/primitives/bitnum/math.futil index 6b702303d..ddda3af7c 100644 --- a/primitives/bitnum/math.futil +++ b/primitives/bitnum/math.futil @@ -4,7 +4,7 @@ extern "math.sv" { // Computes the unsigned value b^e, where // b is the `base` and e is the `exp`. -component std_exp(base: 32, exp: 32) -> (out: 32) { +component std_pow(base: 32, exp: 32) -> (out: 32) { cells { pow = std_reg(32); count = std_reg(32); diff --git a/tests/correctness/exponent.expect b/tests/correctness/pow.expect similarity index 100% rename from tests/correctness/exponent.expect rename to tests/correctness/pow.expect diff --git a/tests/correctness/exponent.futil b/tests/correctness/pow.futil similarity index 85% rename from tests/correctness/exponent.futil rename to tests/correctness/pow.futil index 601933b3f..639345df1 100644 --- a/tests/correctness/exponent.futil +++ b/tests/correctness/pow.futil @@ -7,7 +7,7 @@ component main() -> () { exp = std_mem_d1(32, 1, 1); base_reg = std_reg(32); exp_reg = std_reg(32); - std_exp0 = std_exp(); + std_pow0 = std_pow(); } wires { group init { @@ -20,7 +20,7 @@ component main() -> () { init[done] = base_reg.done & exp_reg.done ? 1'd1; } group fill_memory { - out.write_data = std_exp0.out; + out.write_data = std_pow0.out; out.addr0 = 1'd0; out.write_en = 1'd1; fill_memory[done] = out.done; @@ -29,7 +29,7 @@ component main() -> () { control { seq { init; - invoke std_exp0(base=base_reg.out, exp=exp_reg.out)(); + invoke std_pow0(base=base_reg.out, exp=exp_reg.out)(); fill_memory; } } diff --git a/tests/correctness/exponent.futil.data b/tests/correctness/pow.futil.data similarity index 100% rename from tests/correctness/exponent.futil.data rename to tests/correctness/pow.futil.data From 63bf6873d29988dd5ef975c42ad20a6bb7f90611 Mon Sep 17 00:00:00 2001 From: Chris Gyurgyik <37983775+cgyurgyik@users.noreply.github.com> Date: Sat, 20 Feb 2021 11:36:08 -0500 Subject: [PATCH 12/12] std_sqrt --- primitives/bitnum/math.futil | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/bitnum/math.futil b/primitives/bitnum/math.futil index ddda3af7c..64bc45054 100644 --- a/primitives/bitnum/math.futil +++ b/primitives/bitnum/math.futil @@ -1,5 +1,5 @@ extern "math.sv" { - primitive sqrt(in: 32, go: 1, clk: 1) -> (out: 32, done: 1); + primitive std_sqrt(in: 32, go: 1, clk: 1) -> (out: 32, done: 1); } // Computes the unsigned value b^e, where