Readme, axmults in workflow
This commit is contained in:
parent
13c085f169
commit
aeacd72d24
6
.github/workflows/generate.yml
vendored
6
.github/workflows/generate.yml
vendored
@ -28,10 +28,12 @@ jobs:
|
||||
# You can test your matrix by printing the current Python version
|
||||
- name: Display Python version
|
||||
run: python -c "import sys; print(sys.version)"
|
||||
- name: Run generating
|
||||
- name: Run generating adds and mults
|
||||
run: python generate_test.py
|
||||
- name: Run generating
|
||||
- name: Run generating mac
|
||||
run: python generate_mac.py
|
||||
- name: Run generating axmults
|
||||
run: python generate_axmults.py
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
|
71
README.md
71
README.md
@ -1,7 +1,19 @@
|
||||
# ArithsGen – tool for arithmetic circuits generation
|
||||
[](https://www.python.org/)
|
||||
[](https://ehw-fit.github.io/ariths-gen)
|
||||
|
||||
|
||||
## Description
|
||||
ArithsGen presents an open source tool that enables generation of various arithmetic circuits along with the possibility to export them to various representations which all serve their specific purpose. C language for easy simulation, Verilog for logic synthesis, BLIF for formal verification possibilities and CGP to enable further global optimization.
|
||||
|
||||
In contrast to standard HDL languages Python supports
|
||||
* Multiple output formats (BLIF, Verilog, C, Integer netlis)
|
||||
* Advanced langugage construction (better configuration, inheritance, etc.)
|
||||
* Support of various PDKs (for using library cells as half-adders and full-adders)
|
||||
|
||||
## Prebuild circuits
|
||||
To enable the fast work with the circuits, we published pre-build arithmetic circuits in various formats in [generated_circuits](generated_circuits) folder and as a [Release](https://github.com/ehw-fit/ariths-gen/releases).
|
||||
|
||||
### Usage
|
||||
```bash
|
||||
python3 generate_test.py
|
||||
@ -11,18 +23,19 @@ ls
|
||||
|
||||
### Example of generation
|
||||
```py
|
||||
#Example generation of Verilog representation of 8-bit unsigned dadda multiplier that uses cla to provide the final product
|
||||
a = Bus(N=8, prefix="a_bus")
|
||||
b = Bus(N=8, prefix="b_bus")
|
||||
#Example generation of Verilog representation of 8-bit unsigned dadda multiplier that uses cla to provide the final product
|
||||
a = Bus(N=8, prefix="a_bus")
|
||||
b = Bus(N=8, prefix="b_bus")
|
||||
|
||||
u_dadda = UnsignedDaddaMultiplier(a=a, b=b, prefix="h_u_dadda_cla8", unsigned_adder_class_name=UnsignedCarryLookaheadAdder)
|
||||
u_dadda.get_v_code_hier(open("h_u_dadda_cla8.v", "w"))
|
||||
u_dadda = UnsignedDaddaMultiplier(a=a, b=b, prefix="h_u_dadda_cla8", unsigned_adder_class_name=UnsignedCarryLookaheadAdder)
|
||||
u_dadda.get_v_code_hier(open("h_u_dadda_cla8.v", "w"))
|
||||
```
|
||||
|
||||
### Simple arithmetic circuits
|
||||
See ()[rca.py]
|
||||
See [Ripple Carry Adder](ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py) file for a basic example.
|
||||
|
||||
### Complex circuits
|
||||
It is possible to combine some basic circuit to generate more complex circuits (such as MAC). The design can be parametrised (i.e., you can pass `UnsignedArraymultiplier` as an input parameter).
|
||||
|
||||
```py
|
||||
from ariths_gen.core.arithmetic_circuits.arithmetic_circuit import ArithmeticCircuit
|
||||
@ -52,7 +65,8 @@ if __name__ == "__main__":
|
||||
```
|
||||
|
||||
## Documentation
|
||||
https://ehw-fit.github.io/ariths-gen/
|
||||
The automatically generated documentation is available at
|
||||
https://ehw-fit.github.io/ariths-gen/ .
|
||||
|
||||
|
||||
## Supporting various PDK kits
|
||||
@ -65,6 +79,49 @@ set_pdk45_library()
|
||||
|
||||
You can add a support of arbitrary PDK (see an [example](ariths_gen/pdk.py) ).
|
||||
|
||||
|
||||
## Approximate circuits
|
||||
Besides the accurate arithmetic circuits you can generate some approximate circuits. Currently we support _Broken Array Multiplier_ and _Truncated Multiplier_. For more details please follow files in folder [approximate_multipliers](ariths_gen/multi_bit_circuits/approximate_multipliers/). You can simply run
|
||||
```bash
|
||||
python3 generate_axmuls.py
|
||||
```
|
||||
to get the approximate circuits.
|
||||
|
||||
The module supports also evaluation of the proposed circuits. You can call the instation as a function (even with numpy-array input) to obtain the results for one multiplication
|
||||
|
||||
```py
|
||||
from ariths_gen.wire_components.buses import Bus
|
||||
from ariths_gen.multi_bit_circuits.approximate_multipliers import UnsignedBrokenArrayMultiplier
|
||||
a = Bus(N=8, prefix="a_bus")
|
||||
b = Bus(N=8, prefix="b_bus")
|
||||
|
||||
# Create BAM
|
||||
bam = UnsignedBrokenArrayMultiplier(a, b, horizontal_cut=4, vertical_cut=4)
|
||||
|
||||
print("43 * 84 = ", bam(43, 84), " expected: ", 43 * 84)
|
||||
# 43 * 84 = 3440 expected: 3612
|
||||
```
|
||||
even for all possible combinations
|
||||
|
||||
```py
|
||||
# Evaluate all using b'casting
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
va = np.arange(256).reshape(1, -1)
|
||||
vb = va.reshape(-1, 1)
|
||||
r = bam(va, vb)
|
||||
|
||||
cax = plt.imshow(np.abs(r - (va * vb)))
|
||||
plt.colorbar(cax)
|
||||
plt.title("Absolute difference")
|
||||
plt.xlabel("a")
|
||||
plt.ylabel("b")
|
||||
|
||||
print("Mean average error", np.abs(r - (va * vb)).mean())
|
||||
# Mean average error 956.25
|
||||
```
|
||||

|
||||
|
||||
## Formal verification
|
||||
The `yosys_equiv_check.sh` script enables to formally check the equivalence of generated Verilog and BLIF representations of the same circuit.
|
||||
It uses the Yosys Open SYnthesis Suite tool by Clifford Wolf. For further information, please visit: http://www.clifford.at/yosys/documentation.html.
|
||||
|
@ -13,17 +13,20 @@ from ariths_gen.multi_bit_circuits.approximate_multipliers import (
|
||||
|
||||
from ariths_gen.pdk import *
|
||||
import os
|
||||
from itertools import product
|
||||
|
||||
def open_file_with_folder(filename, mode):
|
||||
d = os.path.dirname(filename)
|
||||
if d:
|
||||
os.makedirs(d, exist_ok = True)
|
||||
return open(filename, mode)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Use HA and FA technology from pdk45 library
|
||||
set_pdk45_library()
|
||||
# Optional use HA and FA technology from pdk45 library
|
||||
#set_pdk45_library()
|
||||
|
||||
# 8-bit unsigned BAMs
|
||||
paths = ["BrokenArrayMultiplier/C/flat", "BrokenArrayMultiplier/C/hier", "BrokenArrayMultiplier/Verilog/flat", "BrokenArrayMultiplier/Verilog/hier"]
|
||||
for path in paths:
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
root_path = "test_circuits/ax"
|
||||
|
||||
i = 0
|
||||
for h in range(0, 8):
|
||||
@ -35,28 +38,23 @@ if __name__ == "__main__":
|
||||
b = Bus(prefix="b", N=N)
|
||||
|
||||
u_bam = UnsignedBrokenArrayMultiplier(a, b, name=f"f_u_bam{N}_h{h}_v{v}", horizontal_cut=h, vertical_cut=v)
|
||||
u_bam.get_c_code_flat(file_object=open(f"BrokenArrayMultiplier/C/flat/f_u_bam{N}_h{h}_v{v}.c", "w"))
|
||||
u_bam.get_v_code_flat(file_object=open(f"BrokenArrayMultiplier/Verilog/flat/f_u_bam{N}_h{h}_v{v}.v", "w"))
|
||||
u_bam.get_c_code_flat(open_file_with_folder(os.path.join(root_path, f"BAM/C/flat/f_u_bam{N}_h{h}_v{v}.c"), "w"))
|
||||
u_bam.get_v_code_flat(open_file_with_folder(os.path.join(root_path, f"BAM/Verilog/flat/f_u_bam{N}_h{h}_v{v}.v"), "w"))
|
||||
|
||||
u_bam = UnsignedBrokenArrayMultiplier(a, b, name=f"h_u_bam{N}_h{h}_v{v}", horizontal_cut=h, vertical_cut=v)
|
||||
u_bam.get_c_code_hier(file_object=open(f"BrokenArrayMultiplier/C/hier/h_u_bam{N}_h{h}_v{v}.c", "w"))
|
||||
u_bam.get_v_code_hier(file_object=open(f"BrokenArrayMultiplier/Verilog/hier/h_u_bam{N}_h{h}_v{v}.v", "w"))
|
||||
u_bam.get_c_code_hier(open_file_with_folder(os.path.join(root_path, f"BAM/C/hier/h_u_bam{N}_h{h}_v{v}.c"), "w"))
|
||||
u_bam.get_v_code_hier(open_file_with_folder(os.path.join(root_path, f"BAM/Verilog/hier/h_u_bam{N}_h{h}_v{v}.v"), "w"))
|
||||
|
||||
# 8-bit unsigned TMs
|
||||
paths = ["TruncatedMultiplier/C/flat", "TruncatedMultiplier/C/hier", "TruncatedMultiplier/Verilog/flat", "TruncatedMultiplier/Verilog/hier"]
|
||||
for path in paths:
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
# 8-bit unsigned TMs
|
||||
for i in range(0, 8):
|
||||
N=8
|
||||
a = Bus(prefix="a", N=N)
|
||||
b = Bus(prefix="b", N=N)
|
||||
|
||||
u_tm = UnsignedTruncatedMultiplier(a, b, name=f"f_u_tm{N}_k{i}", truncation_cut=i)
|
||||
u_tm.get_c_code_flat(file_object=open(f"TruncatedMultiplier/C/flat/f_u_tm{N}_k{i}.c", "w"))
|
||||
u_tm.get_v_code_flat(file_object=open(f"TruncatedMultiplier/Verilog/flat/f_u_tm{N}_k{i}.v", "w"))
|
||||
u_tm.get_c_code_flat(open_file_with_folder(os.path.join(root_path, f"TM/C/flat/f_u_tm{N}_k{i}.c"), "w"))
|
||||
u_tm.get_v_code_flat(open_file_with_folder(os.path.join(root_path, f"TM/Verilog/flat/f_u_tm{N}_k{i}.v"), "w"))
|
||||
|
||||
u_tm = UnsignedTruncatedMultiplier(a, b, name=f"h_u_tm{N}_k{i}", truncation_cut=i)
|
||||
u_tm.get_c_code_hier(file_object=open(f"TruncatedMultiplier/C/hier/h_u_tm{N}_k{i}.c", "w"))
|
||||
u_tm.get_v_code_hier(file_object=open(f"TruncatedMultiplier/Verilog/hier/h_u_tm{N}_k{i}.v", "w"))
|
||||
u_tm.get_c_code_hier(open_file_with_folder(os.path.join(root_path, f"TM/C/hier/h_u_tm{N}_k{i}.c"), "w"))
|
||||
u_tm.get_v_code_hier(open_file_with_folder(os.path.join(root_path, f"TM/Verilog/hier/h_u_tm{N}_k{i}.v"), "w"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user