Skip to content

feat: Add Calyx bindings #11

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

Merged
merged 13 commits into from
Apr 2, 2025
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ test-*/
test_generator/build
PositTestGenerator

lib/P16
lib/P32
lib/P64
lib/posit_*.sv
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ P64toP32 \
define test_template

test-$(1)/Eval_$(1).v: src/main/scala/*.scala
sbt "run $(1) -td test-$(1)"
sbt "run tb $(1) -td test-$(1)"

test-$(1)/dut.mk: test-$(1)/Eval_$(1).v
$(VERILATOR) -cc --prefix dut --Mdir test-$(1) -CFLAGS "$(VERILATOR_CFLAGS) -include ../csrc/test-$(1).h" test-$(1)/Eval_Posit$(1).v --exe csrc/test-$(3).cpp
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ For more information about Universal numbers and Posit arithmetic and to follow
[Posit Hub] \
[Unum-computing Google group]

## Calyx Binding

Calyx is an infrastructure for accelerator design. This repo has bindings for Calyx Native. These bindings can allow Posit arithmetic for Calyx frontends such as Dahlia.

More information about the Calyx binding and it's usage is in the [lib directory](./lib/README.md)

## Unit Testing

The posit arithmetic modules have been unit tested using Chisel IO testers. For better coverage a random test generator is also available enabled by the [universal] C++ template library. The test generator supplies tests to the hardware units which are simulated using [verilator].
Expand Down
7 changes: 7 additions & 0 deletions lib/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
all: posit_16.sv posit_32.sv posit_64.sv

posit_%.sv: P%
rm -f $@
cat $</*.sv > $@

.PHONY = posit_16.sv posit_32.sv posit_64.sv
34 changes: 34 additions & 0 deletions lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Calyx Bindings for Hardposit

## Build Instructions

1. To generate the System Verilog from the Chisel modules, from the root folder run

```
# From the root folder of the project
sbt run gen P32 full

# For 64 bit posit and 16 bit posit
sbt run gen P32 full
```

For Posit 32, this will create a folder `P32` with one SV file per module.

2. Combine all the SV modules to create a single SV

```
# From lib/
make
```

## Examples

The examples folder contains examples of using the binding in Calyx Native

```
fud e --to dat vector_add.futil -s verilog.data vector_add.fuse.data --through verilog
```

## Frontends

Calyx frontends will have to emit these primitive to use the Hardposit modules.
53 changes: 53 additions & 0 deletions lib/examples/vector_add.fuse.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"a": {
"data": [
0,
1,
2,
3,
0,
1,
2,
3
],
"format": {
"numeric_type": "bitnum",
"is_signed": false,
"width": 32
}
},
"b": {
"data": [
1,
2,
2,
3,
1,
2,
2,
3
],
"format": {
"numeric_type": "bitnum",
"is_signed": false,
"width": 32
}
},
"c": {
"data": [
0,
0,
0,
0,
0,
0,
0,
0
],
"format": {
"numeric_type": "bitnum",
"is_signed": false,
"width": 32
}
}
}
83 changes: 83 additions & 0 deletions lib/examples/vector_add.futil
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import "primitives/core.futil";
import "primitives/memories/seq.futil";
import "primitives/binary_operators.futil";
import "../posit_32.futil";
component main() -> () {
cells {
@external(1) a = seq_mem_d1(32,8,4);
a_read0_0 = std_reg(32);
add0 = posit_32_add();
add1 = std_add(4);
@external(1) b = seq_mem_d1(32,8,4);
b_read0_0 = std_reg(32);
@external(1) c = seq_mem_d1(32,8,4);
const0 = std_const(4,0);
const1 = std_const(4,7);
const2 = std_const(4,1);
i0 = std_reg(4);
le0 = std_le(4);
}
wires {
comb group cond0 {
le0.left = i0.out;
le0.right = const1.out;
}
group let0<"promotable"=1> {
i0.in = const0.out;
i0.write_en = 1'd1;
let0[done] = i0.done;
}
group let1<"promotable"=2> {
a_read0_0.in = a.read_data;
a_read0_0.write_en = a.done;
let1[done] = a_read0_0.done;
a.content_en = 1'd1;
a.addr0 = i0.out;
}
group let2<"promotable"=2> {
b_read0_0.in = b.read_data;
b_read0_0.write_en = b.done;
let2[done] = b_read0_0.done;
b.content_en = 1'd1;
b.addr0 = i0.out;
}
group upd0<"promotable"=1> {
c.content_en = 1'd1;
c.addr0 = i0.out;
c.write_en = 1'd1;
add0.io_num1 = a_read0_0.out;
add0.io_num2 = b_read0_0.out;
add0.io_sub = 1'd0;
c.write_data = add0.io_out;
upd0[done] = c.done;
}
group upd1<"promotable"=1> {
i0.write_en = 1'd1;
add1.left = i0.out;
add1.right = const2.out;
i0.in = add1.out;
upd1[done] = i0.done;
}
}
control {
seq {
@pos(0) let0;
@bound(8) while le0.out with cond0 {
seq {
par {
@pos(1) let1;
@pos(2) let2;
}
@pos(3) upd0;
@pos(0) upd1;
}
}
}
}
}
metadata #{
0: for (let i: ubit<4> = 0..8) {
1: c[i] := a[i] + b[i];
2: c[i] := a[i] + b[i];
3: c[i] := a[i] + b[i];
}#
52 changes: 52 additions & 0 deletions lib/posit_16.futil
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
extern "posit_16.sv" {
comb primitive posit_16_add[](
@write_together(1) io_num1: 16,
@write_together(1) io_num2: 16,
@write_together(1) io_sub: 1,
@clk clock: 1,
@reset reset: 1
) -> (
io_isZero: 1,
io_isNaR : 1,
io_out: 16
);

comb primitive posit_16_mul[](
@write_together(1) io_num1: 16,
@write_together(1) io_num2: 16,
@clk clock: 1,
@reset reset: 1
) -> (
io_isZero: 1,
io_isNaR : 1,
io_out: 16
);

comb primitive posit_16_compare[](
@write_together(1) io_num1: 16,
@write_together(1) io_num2: 16,
@clk clock: 1,
@reset reset: 1
) -> (
io_lt: 1,
io_eq : 1,
io_gt: 1
);

primitive posit_16_divsqrt[](
@write_together(1) io_num1: 16,
@write_together(1) io_num2: 16,
@write_together(1) @interval(1) @go(1) io_validIn: 1,
@write_together(1) io_sqrtOp: 1,
@clk clock: 1,
@reset reset: 1
) -> (
io_readyIn: 1,
io_out: 16,
io_isZero: 1,
io_isNaR : 1,
@done io_validOut_div: 1,
@done io_validOut_sqrt: 1,
io_exceptions: 4,
);
}
52 changes: 52 additions & 0 deletions lib/posit_32.futil
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
extern "posit_32.sv" {
comb primitive posit_32_add[](
@write_together(1) io_num1: 32,
@write_together(1) io_num2: 32,
@write_together(1) io_sub: 1,
@clk clock: 1,
@reset reset: 1
) -> (
io_isZero: 1,
io_isNaR : 1,
io_out: 32
);

comb primitive posit_32_mul[](
@write_together(1) io_num1: 32,
@write_together(1) io_num2: 32,
@clk clock: 1,
@reset reset: 1
) -> (
io_isZero: 1,
io_isNaR : 1,
io_out: 32
);

comb primitive posit_32_compare[](
@write_together(1) io_num1: 32,
@write_together(1) io_num2: 32,
@clk clock: 1,
@reset reset: 1
) -> (
io_lt: 1,
io_eq : 1,
io_gt: 1
);

primitive posit_32_divsqrt[](
@write_together(1) io_num1: 32,
@write_together(1) io_num2: 32,
@write_together(1) @interval(1) @go(1) io_validIn: 1,
@write_together(1) io_sqrtOp: 1,
@clk clock: 1,
@reset reset: 1
) -> (
io_readyIn: 1,
io_out: 32,
io_isZero: 1,
io_isNaR : 1,
@done io_validOut_div: 1,
@done io_validOut_sqrt: 1,
io_exceptions: 4,
);
}
52 changes: 52 additions & 0 deletions lib/posit_64.futil
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
extern "posit_64.sv" {
comb primitive posit_64_add[](
@write_together(1) io_num1: 64,
@write_together(1) io_num2: 64,
@write_together(1) io_sub: 1,
@clk clock: 1,
@reset reset: 1
) -> (
io_isZero: 1,
io_isNaR : 1,
io_out: 64
);

comb primitive posit_64_mul[](
@write_together(1) io_num1: 64,
@write_together(1) io_num2: 64,
@clk clock: 1,
@reset reset: 1
) -> (
io_isZero: 1,
io_isNaR : 1,
io_out: 64
);

comb primitive posit_64_compare[](
@write_together(1) io_num1: 64,
@write_together(1) io_num2: 64,
@clk clock: 1,
@reset reset: 1
) -> (
io_lt: 1,
io_eq : 1,
io_gt: 1
);

primitive posit_64_divsqrt[](
@write_together(1) io_num1: 64,
@write_together(1) io_num2: 64,
@write_together(1) @interval(1) @go(1) io_validIn: 1,
@write_together(1) io_sqrtOp: 1,
@clk clock: 1,
@reset reset: 1
) -> (
io_readyIn: 1,
io_out: 64,
io_isZero: 1,
io_isNaR : 1,
@done io_validOut_div: 1,
@done io_validOut_sqrt: 1,
io_exceptions: 4,
);
}
Loading