diff --git a/README.md b/README.md index 1476eae..434ad0c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ -# bc_arithmetic_circuits_generator -FIT BUT bachelor's degree project +# ArithsGen – tool for arithmetic circuits generation +### FIT BUT bachelor's degree project + +## 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 automatization. + +### Usage + python3 ariths_gen.py + +### Example of generation + #Example of 8-bit unsigned dadda multiplier that uses rca 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_rca8", unsigned_adder_class_name=UnsignedRippleCarryAdder) + u_dadda.get_v_code_hier(open("h_u_dadda_rca8.v", "w")) \ No newline at end of file diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_fa.c b/Tests/C_circuits/flat/Adders/f_fa.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_fa.c rename to Tests/C_circuits/flat/Adders/f_fa.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_ha.c b/Tests/C_circuits/flat/Adders/f_ha.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_ha.c rename to Tests/C_circuits/flat/Adders/f_ha.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_s_rca2.c b/Tests/C_circuits/flat/Adders/f_s_rca2.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_s_rca2.c rename to Tests/C_circuits/flat/Adders/f_s_rca2.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_s_rca6.c b/Tests/C_circuits/flat/Adders/f_s_rca6.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_s_rca6.c rename to Tests/C_circuits/flat/Adders/f_s_rca6.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_s_rca8.c b/Tests/C_circuits/flat/Adders/f_s_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_s_rca8.c rename to Tests/C_circuits/flat/Adders/f_s_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_u_rca3.c b/Tests/C_circuits/flat/Adders/f_u_rca3.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_u_rca3.c rename to Tests/C_circuits/flat/Adders/f_u_rca3.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_u_rca5.c b/Tests/C_circuits/flat/Adders/f_u_rca5.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_u_rca5.c rename to Tests/C_circuits/flat/Adders/f_u_rca5.c diff --git a/Tests/C_circuits/Flat_circuits/Adders/f_u_rca8.c b/Tests/C_circuits/flat/Adders/f_u_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Adders/f_u_rca8.c rename to Tests/C_circuits/flat/Adders/f_u_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul1.c b/Tests/C_circuits/flat/Multipliers/f_s_arrmul1.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul1.c rename to Tests/C_circuits/flat/Multipliers/f_s_arrmul1.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul10.c b/Tests/C_circuits/flat/Multipliers/f_s_arrmul10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul10.c rename to Tests/C_circuits/flat/Multipliers/f_s_arrmul10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul2.c b/Tests/C_circuits/flat/Multipliers/f_s_arrmul2.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul2.c rename to Tests/C_circuits/flat/Multipliers/f_s_arrmul2.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul3.c b/Tests/C_circuits/flat/Multipliers/f_s_arrmul3.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul3.c rename to Tests/C_circuits/flat/Multipliers/f_s_arrmul3.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul5.c b/Tests/C_circuits/flat/Multipliers/f_s_arrmul5.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul5.c rename to Tests/C_circuits/flat/Multipliers/f_s_arrmul5.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul8.c b/Tests/C_circuits/flat/Multipliers/f_s_arrmul8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_arrmul8.c rename to Tests/C_circuits/flat/Multipliers/f_s_arrmul8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_pg_rca10.c b/Tests/C_circuits/flat/Multipliers/f_s_dadda_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_pg_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_s_dadda_pg_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_pg_rca4.c b/Tests/C_circuits/flat/Multipliers/f_s_dadda_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_pg_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_s_dadda_pg_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_pg_rca8.c b/Tests/C_circuits/flat/Multipliers/f_s_dadda_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_pg_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_s_dadda_pg_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_rca10.c b/Tests/C_circuits/flat/Multipliers/f_s_dadda_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_s_dadda_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_rca4.c b/Tests/C_circuits/flat/Multipliers/f_s_dadda_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_s_dadda_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_rca8.c b/Tests/C_circuits/flat/Multipliers/f_s_dadda_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_dadda_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_s_dadda_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_pg_rca10.c b/Tests/C_circuits/flat/Multipliers/f_s_wallace_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_pg_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_s_wallace_pg_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_pg_rca4.c b/Tests/C_circuits/flat/Multipliers/f_s_wallace_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_pg_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_s_wallace_pg_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_pg_rca8.c b/Tests/C_circuits/flat/Multipliers/f_s_wallace_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_pg_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_s_wallace_pg_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_rca10.c b/Tests/C_circuits/flat/Multipliers/f_s_wallace_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_s_wallace_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_rca4.c b/Tests/C_circuits/flat/Multipliers/f_s_wallace_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_s_wallace_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_rca8.c b/Tests/C_circuits/flat/Multipliers/f_s_wallace_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_s_wallace_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_s_wallace_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul1.c b/Tests/C_circuits/flat/Multipliers/f_u_arrmul1.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul1.c rename to Tests/C_circuits/flat/Multipliers/f_u_arrmul1.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul10.c b/Tests/C_circuits/flat/Multipliers/f_u_arrmul10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul10.c rename to Tests/C_circuits/flat/Multipliers/f_u_arrmul10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul2.c b/Tests/C_circuits/flat/Multipliers/f_u_arrmul2.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul2.c rename to Tests/C_circuits/flat/Multipliers/f_u_arrmul2.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul3.c b/Tests/C_circuits/flat/Multipliers/f_u_arrmul3.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul3.c rename to Tests/C_circuits/flat/Multipliers/f_u_arrmul3.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul5.c b/Tests/C_circuits/flat/Multipliers/f_u_arrmul5.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul5.c rename to Tests/C_circuits/flat/Multipliers/f_u_arrmul5.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul8.c b/Tests/C_circuits/flat/Multipliers/f_u_arrmul8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_arrmul8.c rename to Tests/C_circuits/flat/Multipliers/f_u_arrmul8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_pg_rca10.c b/Tests/C_circuits/flat/Multipliers/f_u_dadda_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_pg_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_u_dadda_pg_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_pg_rca4.c b/Tests/C_circuits/flat/Multipliers/f_u_dadda_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_pg_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_u_dadda_pg_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_pg_rca8.c b/Tests/C_circuits/flat/Multipliers/f_u_dadda_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_pg_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_u_dadda_pg_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_rca10.c b/Tests/C_circuits/flat/Multipliers/f_u_dadda_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_u_dadda_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_rca4.c b/Tests/C_circuits/flat/Multipliers/f_u_dadda_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_u_dadda_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_rca8.c b/Tests/C_circuits/flat/Multipliers/f_u_dadda_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_dadda_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_u_dadda_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_pg_rca10.c b/Tests/C_circuits/flat/Multipliers/f_u_wallace_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_pg_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_u_wallace_pg_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_pg_rca4.c b/Tests/C_circuits/flat/Multipliers/f_u_wallace_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_pg_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_u_wallace_pg_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_pg_rca8.c b/Tests/C_circuits/flat/Multipliers/f_u_wallace_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_pg_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_u_wallace_pg_rca8.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_rca10.c b/Tests/C_circuits/flat/Multipliers/f_u_wallace_rca10.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_rca10.c rename to Tests/C_circuits/flat/Multipliers/f_u_wallace_rca10.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_rca4.c b/Tests/C_circuits/flat/Multipliers/f_u_wallace_rca4.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_rca4.c rename to Tests/C_circuits/flat/Multipliers/f_u_wallace_rca4.c diff --git a/Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_rca8.c b/Tests/C_circuits/flat/Multipliers/f_u_wallace_rca8.c similarity index 100% rename from Tests/C_circuits/Flat_circuits/Multipliers/f_u_wallace_rca8.c rename to Tests/C_circuits/flat/Multipliers/f_u_wallace_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_fa.c b/Tests/C_circuits/hierarchical/Adders/h_fa.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_fa.c rename to Tests/C_circuits/hierarchical/Adders/h_fa.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_ha.c b/Tests/C_circuits/hierarchical/Adders/h_ha.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_ha.c rename to Tests/C_circuits/hierarchical/Adders/h_ha.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca2.c b/Tests/C_circuits/hierarchical/Adders/h_s_rca2.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca2.c rename to Tests/C_circuits/hierarchical/Adders/h_s_rca2.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca4.c b/Tests/C_circuits/hierarchical/Adders/h_s_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca4.c rename to Tests/C_circuits/hierarchical/Adders/h_s_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca6.c b/Tests/C_circuits/hierarchical/Adders/h_s_rca6.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca6.c rename to Tests/C_circuits/hierarchical/Adders/h_s_rca6.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca8.c b/Tests/C_circuits/hierarchical/Adders/h_s_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_s_rca8.c rename to Tests/C_circuits/hierarchical/Adders/h_s_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_u_rca3.c b/Tests/C_circuits/hierarchical/Adders/h_u_rca3.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_u_rca3.c rename to Tests/C_circuits/hierarchical/Adders/h_u_rca3.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_u_rca5.c b/Tests/C_circuits/hierarchical/Adders/h_u_rca5.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_u_rca5.c rename to Tests/C_circuits/hierarchical/Adders/h_u_rca5.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Adders/h_u_rca8.c b/Tests/C_circuits/hierarchical/Adders/h_u_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Adders/h_u_rca8.c rename to Tests/C_circuits/hierarchical/Adders/h_u_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul1.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul1.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul1.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul1.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul10.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul2.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul2.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul2.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul2.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul3.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul3.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul3.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul3.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul5.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul5.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul5.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul5.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul8.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_arrmul8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_arrmul8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_pg_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_pg_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_pg_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_pg_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_pg_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_pg_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_pg_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_pg_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_pg_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_dadda_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_dadda_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_pg_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_pg_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_pg_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_pg_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_pg_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_pg_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_pg_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_pg_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_pg_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_s_wallace_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_s_wallace_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul1.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul1.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul1.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul1.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul10.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul2.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul2.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul2.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul2.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul3.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul3.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul3.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul3.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul5.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul5.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul5.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul5.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul8.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_arrmul8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_arrmul8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_pg_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_pg_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_pg_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_pg_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_pg_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_pg_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_pg_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_pg_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_pg_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_dadda_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_pg_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_pg_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_pg_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_pg_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_pg_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_pg_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_pg_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_pg_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_pg_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_pg_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_pg_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_pg_rca8.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_rca10.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_rca10.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_rca10.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_rca10.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_rca4.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_rca4.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_rca4.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_rca4.c diff --git a/Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_rca8.c b/Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_rca8.c similarity index 100% rename from Tests/C_circuits/Hierarchical_circuits/Multipliers/h_u_wallace_rca8.c rename to Tests/C_circuits/hierarchical/Multipliers/h_u_wallace_rca8.c diff --git a/Tests/README.md b/Tests/README.md new file mode 100644 index 0000000..f011d1a --- /dev/null +++ b/Tests/README.md @@ -0,0 +1,11 @@ +# Testing of arithmetic circuits generated to C code using ArithsGen + +## Description +Script checks correct functionality of various architectures of unsigned/signed adders and multipliers located in 'c_circuits' folder. Folder contains circuits in flattened as well as in hierarchical representation to ensure proper testing. Script automatically compiles and runs all tests and echoes the results back to console. + +**Note** that these circuits were manually modified to allow such a testing (added main with nested loops and asserts)! + +## Execute permission + chmod +x c_tests.sh +## Usage + ./c_tests.sh \ No newline at end of file diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_fa.v b/Tests/Verilog_circuits/flat/Adders/f_fa.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_fa.v rename to Tests/Verilog_circuits/flat/Adders/f_fa.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_fa_test.v b/Tests/Verilog_circuits/flat/Adders/f_fa_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_fa_test.v rename to Tests/Verilog_circuits/flat/Adders/f_fa_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_ha.v b/Tests/Verilog_circuits/flat/Adders/f_ha.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_ha.v rename to Tests/Verilog_circuits/flat/Adders/f_ha.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_ha_test.v b/Tests/Verilog_circuits/flat/Adders/f_ha_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_ha_test.v rename to Tests/Verilog_circuits/flat/Adders/f_ha_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca2.v b/Tests/Verilog_circuits/flat/Adders/f_s_rca2.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca2.v rename to Tests/Verilog_circuits/flat/Adders/f_s_rca2.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca2_test.v b/Tests/Verilog_circuits/flat/Adders/f_s_rca2_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca2_test.v rename to Tests/Verilog_circuits/flat/Adders/f_s_rca2_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca6.v b/Tests/Verilog_circuits/flat/Adders/f_s_rca6.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca6.v rename to Tests/Verilog_circuits/flat/Adders/f_s_rca6.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca6_test.v b/Tests/Verilog_circuits/flat/Adders/f_s_rca6_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca6_test.v rename to Tests/Verilog_circuits/flat/Adders/f_s_rca6_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca8.v b/Tests/Verilog_circuits/flat/Adders/f_s_rca8.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca8.v rename to Tests/Verilog_circuits/flat/Adders/f_s_rca8.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca8_test.v b/Tests/Verilog_circuits/flat/Adders/f_s_rca8_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_s_rca8_test.v rename to Tests/Verilog_circuits/flat/Adders/f_s_rca8_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca3.v b/Tests/Verilog_circuits/flat/Adders/f_u_rca3.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca3.v rename to Tests/Verilog_circuits/flat/Adders/f_u_rca3.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca3_test.v b/Tests/Verilog_circuits/flat/Adders/f_u_rca3_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca3_test.v rename to Tests/Verilog_circuits/flat/Adders/f_u_rca3_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca5.v b/Tests/Verilog_circuits/flat/Adders/f_u_rca5.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca5.v rename to Tests/Verilog_circuits/flat/Adders/f_u_rca5.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca5_test.v b/Tests/Verilog_circuits/flat/Adders/f_u_rca5_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca5_test.v rename to Tests/Verilog_circuits/flat/Adders/f_u_rca5_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca8.v b/Tests/Verilog_circuits/flat/Adders/f_u_rca8.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca8.v rename to Tests/Verilog_circuits/flat/Adders/f_u_rca8.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca8_test.v b/Tests/Verilog_circuits/flat/Adders/f_u_rca8_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Adders/f_u_rca8_test.v rename to Tests/Verilog_circuits/flat/Adders/f_u_rca8_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul1.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul1.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul1.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul1.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul10.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul10.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul10.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul10.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul10_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul10_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul10_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul10_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul1_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul1_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul1_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul1_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul2.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul2.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul2.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul2.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul2_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul2_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul2_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul2_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul3.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul3.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul3.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul3.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul3_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul3_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul3_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul3_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul5.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul5.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul5.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul5.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul5_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul5_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul5_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul5_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul8.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul8.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul8.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul8.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul8_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul8_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_s_arr_mul8_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_s_arr_mul8_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul1.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul1.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul1.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul1.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul10.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul10.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul10.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul10.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul10_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul10_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul10_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul10_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul1_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul1_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul1_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul1_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul2.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul2.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul2.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul2.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul2_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul2_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul2_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul2_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul3.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul3.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul3.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul3.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul3_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul3_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul3_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul3_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul5.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul5.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul5.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul5.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul5_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul5_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul5_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul5_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul8.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul8.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul8.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul8.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul8_test.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul8_test.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_arr_mul8_test.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_arr_mul8_test.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul2.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul2.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul2.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul2.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul4.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul4.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul4.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul4.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul6.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul6.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul6.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul6.v diff --git a/Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul8.v b/Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul8.v similarity index 100% rename from Tests/Verilog_circuits/Flat_circuits/Multipliers/f_u_dadda_mul8.v rename to Tests/Verilog_circuits/flat/Multipliers/f_u_dadda_mul8.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_fa.v b/Tests/Verilog_circuits/hierarchical/Adders/h_fa.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_fa.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_fa.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_fa_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_fa_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_fa_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_fa_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_ha.v b/Tests/Verilog_circuits/hierarchical/Adders/h_ha.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_ha.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_ha.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_ha_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_ha_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_ha_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_ha_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca2.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca2.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca2.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca2.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca2_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca2_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca2_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca2_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca4.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca4.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca4.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca4.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca4_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca4_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca4_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca4_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca6.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca6.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca6.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca6.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca6_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca6_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca6_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca6_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca8.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca8.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca8.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca8.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca8_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_s_rca8_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_s_rca8_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_s_rca8_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca3.v b/Tests/Verilog_circuits/hierarchical/Adders/h_u_rca3.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca3.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_u_rca3.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca3_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_u_rca3_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca3_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_u_rca3_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca5.v b/Tests/Verilog_circuits/hierarchical/Adders/h_u_rca5.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca5.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_u_rca5.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca5_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_u_rca5_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca5_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_u_rca5_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca8.v b/Tests/Verilog_circuits/hierarchical/Adders/h_u_rca8.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca8.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_u_rca8.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca8_test.v b/Tests/Verilog_circuits/hierarchical/Adders/h_u_rca8_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Adders/h_u_rca8_test.v rename to Tests/Verilog_circuits/hierarchical/Adders/h_u_rca8_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul1.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul1.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul1.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul1.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul10.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul10.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul10.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul10.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul10_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul10_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul10_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul10_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul1_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul1_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul1_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul1_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul2.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul2.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul2.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul2.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul2_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul2_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul2_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul2_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul3.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul3.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul3.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul3.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul3_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul3_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul3_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul3_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul5.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul5.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul5.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul5.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul5_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul5_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul5_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul5_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul8.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul8.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul8.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul8.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul8_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul8_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_s_arr_mul8_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_s_arr_mul8_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul1.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul1.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul1.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul1.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul10.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul10.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul10.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul10.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul10_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul10_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul10_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul10_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul1_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul1_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul1_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul1_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul2.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul2.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul2.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul2.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul2_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul2_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul2_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul2_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul3.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul3.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul3.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul3.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul3_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul3_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul3_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul3_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul5.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul5.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul5.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul5.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul5_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul5_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul5_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul5_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul8.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul8.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul8.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul8.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul8_test.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul8_test.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_arr_mul8_test.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_arr_mul8_test.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul2.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul2.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul2.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul2.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul4.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul4.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul4.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul4.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul6.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul6.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul6.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul6.v diff --git a/Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul8.v b/Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul8.v similarity index 100% rename from Tests/Verilog_circuits/Hierarchical_circuits/Multipliers/h_u_dadda_mul8.v rename to Tests/Verilog_circuits/hierarchical/Multipliers/h_u_dadda_mul8.v diff --git a/arithmetic_circuits_generator.py b/arithmetic_circuits_generator.py deleted file mode 100644 index 0b33290..0000000 --- a/arithmetic_circuits_generator.py +++ /dev/null @@ -1,88 +0,0 @@ -from wire_components import wire, bus -from logic_gates import logic_gate, and_gate, nand_gate, or_gate, nor_gate, xor_gate, xnor_gate, not_gate -from one_bit_circuits import constant_wire_value_1, constant_wire_value_0, half_adder, full_adder -from multi_bit_circuits import unsigned_ripple_carry_adder, signed_ripple_carry_adder, unsigned_pg_ripple_carry_adder, signed_pg_ripple_carry_adder, unsigned_array_multiplier, signed_array_multiplier, unsigned_dadda_multiplier, signed_dadda_multiplier, unsigned_wallace_multiplier, signed_wallace_multiplier, unsigned_carry_lookahead_adder, signed_carry_lookahead_adder -import sys - - -""" TESTING """ -if __name__ == "__main__": - N = 4 - a = bus(N=N, prefix="a") - b = bus(N=N, prefix="b") - - representation = "h" - - - # RCA - name = f"{representation}_u_rca{N}" - circuit = unsigned_ripple_carry_adder(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_rca{N}" - circuit = unsigned_ripple_carry_adder(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - #RCA with PG - name = f"{representation}_u_pg_rca{N}" - circuit = unsigned_pg_ripple_carry_adder(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_pg_rca{N}" - circuit = signed_pg_ripple_carry_adder(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - #CLA with PG - name = f"{representation}_u_cla{N}" - circuit = unsigned_carry_lookahead_adder(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_cla{N}" - circuit = signed_carry_lookahead_adder(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - - # Arrmul - name = f"{representation}_u_arrmul{N}" - circuit = unsigned_array_multiplier(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_arrmul{N}" - circuit = signed_array_multiplier(a, b, prefix=name) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - # Wallace - name = f"{representation}_u_wallace_rca{N}" - circuit = unsigned_wallace_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_wallace_rca{N}" - circuit = signed_wallace_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_u_wallace_pg_rca{N}" - circuit = unsigned_wallace_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_pg_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_wallace_pg_rca{N}" - circuit = signed_wallace_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_pg_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - # Dadda - name = f"{representation}_u_dadda_rca{N}" - circuit = unsigned_dadda_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_dadda_rca{N}" - circuit = signed_dadda_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - - name = f"{representation}_u_dadda_pg_rca{N}" - circuit = unsigned_dadda_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_pg_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - - name = f"{representation}_s_dadda_pg_rca{N}" - circuit = signed_dadda_multiplier(a, b, prefix=name, unsigned_adder_class_name=unsigned_pg_ripple_carry_adder) - circuit.get_c_code_hier(open(f"{name}.c", "w")) - diff --git a/ariths_gen.py b/ariths_gen.py new file mode 100644 index 0000000..81ebc6b --- /dev/null +++ b/ariths_gen.py @@ -0,0 +1,118 @@ +from ariths_gen.wire_components import( + Wire, + Bus +) + +from ariths_gen.one_bit_circuits.logic_gates import( + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + FullAdder +) + +from ariths_gen.multi_bit_circuits.adders import( + UnsignedCarryLookaheadAdder, + UnsignedPGRippleCarryAdder, + UnsignedRippleCarryAdder, + SignedCarryLookaheadAdder, + SignedPGRippleCarryAdder, + SignedRippleCarryAdder +) + +from ariths_gen.multi_bit_circuits.multipliers import( + UnsignedDaddaMultiplier, + UnsignedArrayMultiplier, + UnsignedWallaceMultiplier, + SignedArrayMultiplier, + SignedDaddaMultiplier, + SignedWallaceMultiplier +) + + +""" Generation of circuits """ +if __name__ == "__main__": + N = 8 + a = Bus(N=N, prefix="a") + b = Bus(N=N, prefix="b") + representation = "h" + + # RCA + name = f"{representation}_u_rca{N}" + circuit = UnsignedRippleCarryAdder(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_rca{N}" + circuit = SignedRippleCarryAdder(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + #RCA with PG + name = f"{representation}_u_pg_rca{N}" + circuit = UnsignedPGRippleCarryAdder(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_pg_rca{N}" + circuit = SignedPGRippleCarryAdder(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + #CLA with PG + name = f"{representation}_u_cla{N}" + circuit = UnsignedCarryLookaheadAdder(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_cla{N}" + circuit = SignedCarryLookaheadAdder(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + + # Arrmul + name = f"{representation}_u_arrmul{N}" + circuit = UnsignedArrayMultiplier(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_arrmul{N}" + circuit = SignedArrayMultiplier(a, b, prefix=name) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + # Wallace + name = f"{representation}_u_wallace_rca{N}" + circuit = UnsignedWallaceMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_wallace_rca{N}" + circuit = SignedWallaceMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_u_wallace_pg_rca{N}" + circuit = UnsignedWallaceMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedPGRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_wallace_pg_rca{N}" + circuit = SignedWallaceMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedPGRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + # Dadda + name = f"{representation}_u_dadda_rca{N}" + circuit = UnsignedDaddaMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_dadda_rca{N}" + circuit = SignedDaddaMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + + name = f"{representation}_u_dadda_pg_rca{N}" + circuit = UnsignedDaddaMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedPGRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + + name = f"{representation}_s_dadda_pg_rca{N}" + circuit = SignedDaddaMultiplier(a, b, prefix=name, unsigned_adder_class_name=UnsignedPGRippleCarryAdder) + circuit.get_v_code_hier(open(f"{name}.v", "w")) + diff --git a/ariths_gen/__init__.py b/ariths_gen/__init__.py new file mode 100644 index 0000000..bb424c2 --- /dev/null +++ b/ariths_gen/__init__.py @@ -0,0 +1,14 @@ +from ariths_gen.wire_components import( + wires, + buses +) + +from ariths_gen.one_bit_circuits import( + logic_gates, + one_bit_components +) + +from ariths_gen.multi_bit_circuits import( + adders, + multipliers +) \ No newline at end of file diff --git a/ariths_gen/__pycache__/__init__.cpython-38.pyc b/ariths_gen/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..3a8da75 Binary files /dev/null and b/ariths_gen/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/__pycache__/wires.cpython-38.pyc b/ariths_gen/__pycache__/wires.cpython-38.pyc new file mode 100644 index 0000000..449cc82 Binary files /dev/null and b/ariths_gen/__pycache__/wires.cpython-38.pyc differ diff --git a/ariths_gen/core/__init__.py b/ariths_gen/core/__init__.py new file mode 100644 index 0000000..7e02ada --- /dev/null +++ b/ariths_gen/core/__init__.py @@ -0,0 +1,15 @@ +from .arithmetic_circuit import ( + ArithmeticCircuit +) + +from .multiplier_circuit import ( + MultiplierCircuit +) + +from .two_input_one_bit_circuit import ( + TwoInputOneBitCircuit +) + +from .three_input_one_bit_circuit import ( + ThreeInputOneBitCircuit +) \ No newline at end of file diff --git a/ariths_gen/core/__pycache__/__init__.cpython-38.pyc b/ariths_gen/core/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..c0605d5 Binary files /dev/null and b/ariths_gen/core/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/core/__pycache__/arithmetic_circuit.cpython-38.pyc b/ariths_gen/core/__pycache__/arithmetic_circuit.cpython-38.pyc new file mode 100644 index 0000000..c4e1efe Binary files /dev/null and b/ariths_gen/core/__pycache__/arithmetic_circuit.cpython-38.pyc differ diff --git a/ariths_gen/core/__pycache__/arithmetic_circuits.cpython-38.pyc b/ariths_gen/core/__pycache__/arithmetic_circuits.cpython-38.pyc new file mode 100644 index 0000000..38fb584 Binary files /dev/null and b/ariths_gen/core/__pycache__/arithmetic_circuits.cpython-38.pyc differ diff --git a/ariths_gen/core/__pycache__/multiplier_circuit.cpython-38.pyc b/ariths_gen/core/__pycache__/multiplier_circuit.cpython-38.pyc new file mode 100644 index 0000000..21f457c Binary files /dev/null and b/ariths_gen/core/__pycache__/multiplier_circuit.cpython-38.pyc differ diff --git a/ariths_gen/core/__pycache__/three_input_one_bit_circuit.cpython-38.pyc b/ariths_gen/core/__pycache__/three_input_one_bit_circuit.cpython-38.pyc new file mode 100644 index 0000000..c8b18d9 Binary files /dev/null and b/ariths_gen/core/__pycache__/three_input_one_bit_circuit.cpython-38.pyc differ diff --git a/ariths_gen/core/__pycache__/two_input_one_bit_circuit.cpython-38.pyc b/ariths_gen/core/__pycache__/two_input_one_bit_circuit.cpython-38.pyc new file mode 100644 index 0000000..b383d53 Binary files /dev/null and b/ariths_gen/core/__pycache__/two_input_one_bit_circuit.cpython-38.pyc differ diff --git a/arithmetic_circuits.py b/ariths_gen/core/arithmetic_circuit.py similarity index 67% rename from arithmetic_circuits.py rename to ariths_gen/core/arithmetic_circuit.py index a75258b..01639e9 100644 --- a/arithmetic_circuits.py +++ b/ariths_gen/core/arithmetic_circuit.py @@ -1,11 +1,21 @@ -from logic_gates import logic_gate, and_gate, nand_gate, or_gate, nor_gate, xor_gate, xnor_gate, not_gate -from wire_components import wire, bus -import math +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +from ariths_gen.wire_components import( + Wire, + Bus +) """ ARITHMETIC CIRCUITS """ - - -class arithmetic_circuit(): +class ArithmeticCircuit(): def __init__(self): self.components = [] self.circuit_wires = [] @@ -26,9 +36,9 @@ class arithmetic_circuit(): def get_unique_one_bit_components(self): one_bit_comps = [] for c in self.components: - if isinstance(c, logic_gate): + if isinstance(c, LogicGate): continue - elif type(getattr(c, 'a')) == wire: + elif type(getattr(c, 'a')) == Wire: one_bit_comps.append(c) else: one_bit_comps.extend(c.get_unique_one_bit_components()) @@ -38,9 +48,9 @@ class arithmetic_circuit(): def get_unique_multi_bit_components(self): multi_bit_comps = [] for c in self.components: - if isinstance(c, logic_gate): + if isinstance(c, LogicGate): continue - elif type(getattr(c, 'a')) == wire: + elif type(getattr(c, 'a')) == Wire: continue else: multi_bit_comps.append(c) @@ -80,7 +90,7 @@ class arithmetic_circuit(): self.inputs = [i[0] for i in self.circuit_wires if i[0] not in [o.out for o in self.components]] # Search for circuit's wire unique index for cgp chromosome generation - def get_circuit_wire_index(self, wire: wire): + def get_circuit_wire_index(self, wire: Wire): for w in self.circuit_wires: if wire.name.endswith(w[1]): return w[2] @@ -89,7 +99,7 @@ class arithmetic_circuit(): def get_circuit_gates(self): gates = [] for c in self.components: - if isinstance(c, logic_gate): + if isinstance(c, LogicGate): gates.append(c) else: gates.extend((c.get_circuit_gates())) @@ -98,7 +108,7 @@ class arithmetic_circuit(): # Get list of all wires in circuit along with their index position for cgp chromosome generation def get_cgp_wires(self): self.circuit_wires = [] - if isinstance(self.a, bus): + if isinstance(self.a, Bus): [self.circuit_wires.append((w, f"_{w.name}", len(self.circuit_wires))) for w in self.a.bus] [self.circuit_wires.append((w, f"_{w.name}", len(self.circuit_wires))) for w in self.b.bus] else: @@ -138,11 +148,11 @@ class arithmetic_circuit(): def get_inits_c_flat(self): return f"{self.a.get_wire_assign_c()}" + \ f"{self.b.get_wire_assign_c()}" + \ - "".join([c.get_assign_c_flat() if isinstance(c, logic_gate) else c.get_init_c_flat() for c in self.components]) + "".join([c.get_assign_c_flat() if isinstance(c, LogicGate) else c.get_init_c_flat() for c in self.components]) # For multi-bit circuit wires initialization def get_init_c_flat(self): - return "".join([c.get_assign_c_flat() if isinstance(c, logic_gate) else c.get_init_c_flat() for c in self.components]) + return "".join([c.get_assign_c_flat() if isinstance(c, LogicGate) else c.get_init_c_flat() for c in self.components]) def get_function_out_c_flat(self): return "".join([f" {self.out.prefix} |= {o.return_wire_value_c(offset=self.out.bus.index(o))};\n" for o in self.out.bus]) @@ -166,14 +176,14 @@ class arithmetic_circuit(): def get_function_block_c(self): # Obtain proper adder name with its bit width - adder_prefix = self.__class__(a=bus("a") , b=bus("b")).prefix + str(self.N) - adder_block = self.__class__(a=bus(N=self.N, prefix="a"), b=bus(N=self.N, prefix="b"), prefix=adder_prefix) + adder_prefix = self.__class__(a=Bus("a") , b=Bus("b")).prefix + str(self.N) + adder_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=adder_prefix) return f"{adder_block.get_circuit_c()}\n\n" def get_declaration_c_hier(self): return "".join(self.a.get_wire_declaration_c()) + \ "".join(self.b.get_wire_declaration_c()) + \ - "".join([c.out.get_declaration_c() if isinstance(c, logic_gate) else c.get_wire_declaration_c_hier() for c in self.components]) + "".join([c.out.get_declaration_c() if isinstance(c, LogicGate) else c.get_wire_declaration_c_hier() for c in self.components]) def get_wire_declaration_c_hier(self): return f" {self.c_data_type} {self.prefix}_{self.a.prefix} = 0;\n" + \ @@ -184,12 +194,12 @@ class arithmetic_circuit(): def get_init_c_hier(self): return f"{self.a.get_wire_assign_c()}" + \ f"{self.b.get_wire_assign_c()}" + \ - "".join([f" {c.out.name} = {c.get_gate_invocation_c()}" if isinstance(c, logic_gate) else c.get_out_invocation_c(circuit_prefix=self.prefix) for c in self.components]) + "".join([f" {c.out.name} = {c.get_gate_invocation_c()}" if isinstance(c, LogicGate) else c.get_out_invocation_c(circuit_prefix=self.prefix) for c in self.components]) def get_out_invocation_c(self, circuit_prefix: str): # Getting name of circuit type and insitu copying out bus for proper C code generation without affecting actual generated composition circuit_type = self.prefix.replace(circuit_prefix+"_", "") - out = bus(prefix=self.prefix+"_"+self.out.prefix, wires_list=self.out.bus) + out = Bus(prefix=self.prefix+"_"+self.out.prefix, wires_list=self.out.bus) return "".join([f" {self.prefix}_{self.a.prefix} |= {w.return_wire_value_c(offset=self.a.bus.index(w))};\n" for w in self.a.bus]) + \ "".join([f" {self.prefix}_{self.b.prefix} |= {w.return_wire_value_c(offset=self.b.bus.index(w))};\n" for w in self.b.bus]) + \ f" {out.prefix} = {circuit_type}({self.prefix}_{self.a.prefix}, {self.prefix}_{self.b.prefix});\n" + \ @@ -229,10 +239,10 @@ class arithmetic_circuit(): def get_inits_v_flat(self): return f"{self.a.get_wire_assign_v()}" + \ f"{self.b.get_wire_assign_v()}" + \ - "".join([c.get_assign_v_flat() if isinstance(c, logic_gate) else c.get_init_v_flat() for c in self.components]) + "".join([c.get_assign_v_flat() if isinstance(c, LogicGate) else c.get_init_v_flat() for c in self.components]) def get_init_v_flat(self): - return "".join([c.get_assign_v_flat() if isinstance(c, logic_gate) else c.get_init_v_flat() for c in self.components]) + return "".join([c.get_assign_v_flat() if isinstance(c, LogicGate) else c.get_init_v_flat() for c in self.components]) def get_function_out_v_flat(self): return "".join([f" assign {self.out.prefix}[{self.out.bus.index(o)}] = {o.prefix};\n" for o in self.out.bus]) @@ -254,14 +264,14 @@ class arithmetic_circuit(): def get_function_block_v(self): # Obtain proper adder name with its bit width - adder_prefix = self.__class__(a=bus("a") , b=bus("b")).prefix + str(self.N) - adder_block = self.__class__(a=bus(N=self.N, prefix="a"), b=bus(N=self.N, prefix="b"), prefix=adder_prefix) + adder_prefix = self.__class__(a=Bus("a") , b=Bus("b")).prefix + str(self.N) + adder_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=adder_prefix) return f"{adder_block.get_circuit_v()}\n\n" def get_declaration_v_hier(self): return "".join(self.a.get_wire_declaration_v()) + \ "".join(self.b.get_wire_declaration_v()) + \ - "".join([c.out.get_declaration_v() if isinstance(c, logic_gate) else c.get_wire_declaration_v_hier() for c in self.components]) + "".join([c.out.get_declaration_v() if isinstance(c, LogicGate) else c.get_wire_declaration_v_hier() for c in self.components]) def get_wire_declaration_v_hier(self): return f" wire [{self.a.N-1}:0] {self.prefix}_{self.a.prefix};\n" + \ @@ -272,12 +282,12 @@ class arithmetic_circuit(): def get_init_v_hier(self): return f"{self.a.get_wire_assign_v()}" + \ f"{self.b.get_wire_assign_v()}" + \ - "".join([c.get_gate_invocation_v() if isinstance(c, logic_gate) else c.get_invocation_v(circuit_prefix=self.prefix) for c in self.components]) + "".join([c.get_gate_invocation_v() if isinstance(c, LogicGate) else c.get_invocation_v(circuit_prefix=self.prefix) for c in self.components]) def get_invocation_v(self, circuit_prefix: str): # Getting name of circuit type and insitu copying out bus for proper Verilog code generation without affecting actual generated composition circuit_type = self.prefix.replace(circuit_prefix+"_", "") - out = bus(prefix=self.prefix+"_"+self.out.prefix, wires_list=self.out.bus) + out = Bus(prefix=self.prefix+"_"+self.out.prefix, wires_list=self.out.bus) return "".join([f" assign {self.prefix}_{self.a.prefix}[{self.a.bus.index(w)}] = {w.name};\n" for w in self.a.bus]) + \ "".join([f" assign {self.prefix}_{self.b.prefix}[{self.b.bus.index(w)}] = {w.name};\n" for w in self.b.bus]) + \ f" {circuit_type} {circuit_type}_{self.out.prefix}({self.prefix}_{self.a.prefix}, {self.prefix}_{self.b.prefix}, {out.prefix});\n" + \ @@ -317,7 +327,7 @@ class arithmetic_circuit(): f"{self.b.get_wire_assign_blif()}" def get_function_blif_flat(self): - return "".join(c.get_init_function_blif_flat() if isinstance(c, logic_gate) else c.get_function_blif_flat() for c in self.components) + return "".join(c.get_init_function_blif_flat() if isinstance(c, LogicGate) else c.get_function_blif_flat() for c in self.components) def get_function_out_blif(self): return f"{self.out.get_wire_assign_blif(output=True)}" @@ -333,7 +343,7 @@ class arithmetic_circuit(): # HIERARCHICAL BLIF # def get_function_blif_hier(self): - return "".join(c.get_invocation_blif_hier(init=True) if isinstance(c, logic_gate) else c.get_invocation_blif_hier(circuit_prefix=self.prefix) for c in self.components) + return "".join(c.get_invocation_blif_hier(init=True) if isinstance(c, LogicGate) else c.get_invocation_blif_hier(circuit_prefix=self.prefix) for c in self.components) def get_invocation_blif_hier(self, circuit_prefix: str): # Getting name of circuit type for proper Blif code generation without affecting actual generated composition @@ -359,8 +369,8 @@ class arithmetic_circuit(): def get_function_block_blif(self): # Obtain proper adder name with its bit width - adder_prefix = self.__class__(a=bus("a") , b=bus("b")).prefix + str(self.N) - adder_block = self.__class__(a=bus(N=self.N, prefix="a"), b=bus(N=self.N, prefix="b"), prefix=adder_prefix) + adder_prefix = self.__class__(a=Bus("a") , b=Bus("b")).prefix + str(self.N) + adder_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=adder_prefix) return f"{adder_block.get_circuit_blif()}" # Generating hierarchical BLIF code representation of circuit @@ -387,103 +397,4 @@ class arithmetic_circuit(): file_object.write(self.get_parameters_cgp()) file_object.write(self.get_triplet_cgp()) file_object.write(self.get_output_cgp()) - file_object.close() - - -""" MULTIPLIER CIRCUITS """ - - -class multiplier_circuit(arithmetic_circuit): - def __init__(self): - super().__init__() - - """ Array multipliers """ - # Used in array multipliers to get previous row's component output wires - # for further connection to another component's input - def get_previous_partial_product(self, a_index: int, b_index: int, offset: int = 0): - # To get the index of previous row's connecting adder and its generated pp - index = ((b_index-2) * (self.N*2)) + ((self.N-1)+2*(a_index+2)) + offset - - # Get carry wire as input for the last adder in current row - if a_index == self.N-1: - index = index-2 - return self.components[index].get_carry_wire() - # Get sum wire as input for current adder - else: - return self.components[index].get_sum_wire() - - """ Dadda multiplier """ - # Used in dadda multipliers to get multiplier's maximum height - @staticmethod - def get_maximum_height(initial_value: int): - stage = 0 - d = 2 - while True: - stage += 1 - max_height = d - # Calculating maximum height sequence - # d(j=1) = 2; d(j+1) = floor(1.5*d) - d = math.floor(1.5*d) - if d >= initial_value: - return stage, max_height - - def init_column_heights(self, signed=False): - columns = [[num] if num <= self.N else [num - (num - self.N)*2] for num in range(1, self.out.N)] - columns = [self.add_column_wires(column=col, column_index=columns.index(col)) for col in columns] - return columns - - def add_column_wires(self, column: list, column_index: int): - [column.append([]) for _ in range(column[0])] - if column_index <= self.N-1: - [column[column[0]-index].append(self.a.get_wire(index)) for index in range(0, column[0])] - [column[index+1].append(self.b.get_wire(index)) for index in range(0, column[0])] - else: - [column[self.a.N-index].append(self.a.get_wire(index)) for index in range(self.a.N-1, self.a.N-column[0]-1, -1)] - [column[index-(self.a.N-1-column[0])].append(self.b.get_wire(index)) for index in range(self.a.N-column[0], self.a.N)] - - # TODO check and refactor - # Filling unsigned pp matrix with AND gates - if self.__class__.__name__ == "unsigned_dadda_multiplier" or self.__class__.__name__ == "unsigned_wallace_multiplier": - column[1:] = [and_gate(a=column[i][0], b=column[i][1], prefix=self.prefix+'_and_'+str(column[i][0].index)+'_'+str(column[i][1].index)) for i in range(1, len(column))] - # Filling signed pp matrix with AND/NAND gates (based on Baugh-Wooley multiplication algorithm) - else: - # First half of partial product columns contains only AND gates - if column_index < self.N-1 or column_index == self.out.N-2: - column[1:] = [and_gate(a=column[i][0], b=column[i][1], prefix=self.prefix+'_and_'+str(column[i][0].index)+'_'+str(column[i][1].index)) for i in range(1, len(column))] - # Second half of partial product columns contains NAND/AND gates - else: - column[1] = nand_gate(a=column[1][0], b=column[1][1], prefix=self.prefix+'_nand_'+str(column[1][0].index)+'_'+str(column[1][1].index)) - column[-1] = nand_gate(a=column[-1][0], b=column[-1][1], prefix=self.prefix+'_nand_'+str(column[-1][0].index)+'_'+str(column[-1][1].index)) - if len(column[2:-1]) != 0: - column[2:-1] = [and_gate(a=column[i][0], b=column[i][1], prefix=self.prefix+'_and_'+str(column[i][0].index)+'_'+str(column[i][1].index)) for i in range(2, len(column)-1)] - - return column - - def get_column_height(self, column_num: int): - return self.columns[column_num][0] - - def update_column_heights(self, curr_column: int, curr_height_change: int, next_column: int = 0, next_height_change: int = 0): - self.columns[curr_column][0] = self.get_column_height(curr_column)+curr_height_change - if next_column-1 == curr_column: - self.columns[next_column][0] = self.get_column_height(next_column)+next_height_change - - def get_column_wire(self, column: int, bit: int): - if isinstance(self.columns[column][bit], and_gate) or isinstance(self.columns[column][bit], nand_gate): - self.add_component(self.columns[column][bit]) - return self.get_previous_component(1).out - else: - return self.columns[column][bit] - - def update_column_wires(self, curr_column: int, adder: arithmetic_circuit, next_column: int = 0): - if hasattr(adder, "c"): - self.columns[curr_column].pop(1) - self.columns[curr_column].pop(1) - self.columns[curr_column].pop(1) - self.columns[curr_column].insert(self.get_column_height(curr_column), adder.get_sum_wire()) - else: - self.columns[curr_column].pop(1) - self.columns[curr_column].pop(1) - self.columns[curr_column].insert(self.get_column_height(curr_column), adder.get_sum_wire()) - - if next_column-1 == curr_column: - self.columns[next_column].insert(1, adder.get_carry_wire()) + file_object.close() \ No newline at end of file diff --git a/ariths_gen/core/multiplier_circuit.py b/ariths_gen/core/multiplier_circuit.py new file mode 100644 index 0000000..5cf79b3 --- /dev/null +++ b/ariths_gen/core/multiplier_circuit.py @@ -0,0 +1,117 @@ +from .arithmetic_circuit import( + ArithmeticCircuit +) + +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +from ariths_gen.wire_components import( + Wire, + Bus +) + +import math + +""" MULTIPLIER CIRCUITS """ +class MultiplierCircuit(ArithmeticCircuit): + def __init__(self): + super().__init__() + + """ Array multipliers """ + # Used in array multipliers to get previous row's component output wires + # for further connection to another component's input + def get_previous_partial_product(self, a_index: int, b_index: int, offset: int = 0): + # To get the index of previous row's connecting adder and its generated pp + index = ((b_index-2) * (self.N*2)) + ((self.N-1)+2*(a_index+2)) + offset + + # Get carry wire as input for the last adder in current row + if a_index == self.N-1: + index = index-2 + return self.components[index].get_carry_wire() + # Get sum wire as input for current adder + else: + return self.components[index].get_sum_wire() + + """ Dadda multiplier """ + # Used in dadda multipliers to get multiplier's maximum height + @staticmethod + def get_maximum_height(initial_value: int): + stage = 0 + d = 2 + while True: + stage += 1 + max_height = d + # Calculating maximum height sequence + # d(j=1) = 2; d(j+1) = floor(1.5*d) + d = math.floor(1.5*d) + if d >= initial_value: + return stage, max_height + + def init_column_heights(self, signed=False): + columns = [[num] if num <= self.N else [num - (num - self.N)*2] for num in range(1, self.out.N)] + columns = [self.add_column_wires(column=col, column_index=columns.index(col)) for col in columns] + return columns + + def add_column_wires(self, column: list, column_index: int): + [column.append([]) for _ in range(column[0])] + if column_index <= self.N-1: + [column[column[0]-index].append(self.a.get_wire(index)) for index in range(0, column[0])] + [column[index+1].append(self.b.get_wire(index)) for index in range(0, column[0])] + else: + [column[self.a.N-index].append(self.a.get_wire(index)) for index in range(self.a.N-1, self.a.N-column[0]-1, -1)] + [column[index-(self.a.N-1-column[0])].append(self.b.get_wire(index)) for index in range(self.a.N-column[0], self.a.N)] + + # TODO check and refactor + # Filling unsigned pp matrix with AND gates + if self.__class__.__name__ == "unsigned_dadda_multiplier" or self.__class__.__name__ == "unsigned_wallace_multiplier": + column[1:] = [AndGate(a=column[i][0], b=column[i][1], prefix=self.prefix+'_and_'+str(column[i][0].index)+'_'+str(column[i][1].index)) for i in range(1, len(column))] + # Filling signed pp matrix with AND/NAND gates (based on Baugh-Wooley multiplication algorithm) + else: + # First half of partial product columns contains only AND gates + if column_index < self.N-1 or column_index == self.out.N-2: + column[1:] = [AndGate(a=column[i][0], b=column[i][1], prefix=self.prefix+'_and_'+str(column[i][0].index)+'_'+str(column[i][1].index)) for i in range(1, len(column))] + # Second half of partial product columns contains NAND/AND gates + else: + column[1] = NandGate(a=column[1][0], b=column[1][1], prefix=self.prefix+'_nand_'+str(column[1][0].index)+'_'+str(column[1][1].index)) + column[-1] = NandGate(a=column[-1][0], b=column[-1][1], prefix=self.prefix+'_nand_'+str(column[-1][0].index)+'_'+str(column[-1][1].index)) + if len(column[2:-1]) != 0: + column[2:-1] = [AndGate(a=column[i][0], b=column[i][1], prefix=self.prefix+'_and_'+str(column[i][0].index)+'_'+str(column[i][1].index)) for i in range(2, len(column)-1)] + + return column + + def get_column_height(self, column_num: int): + return self.columns[column_num][0] + + def update_column_heights(self, curr_column: int, curr_height_change: int, next_column: int = 0, next_height_change: int = 0): + self.columns[curr_column][0] = self.get_column_height(curr_column)+curr_height_change + if next_column-1 == curr_column: + self.columns[next_column][0] = self.get_column_height(next_column)+next_height_change + + def get_column_wire(self, column: int, bit: int): + if isinstance(self.columns[column][bit], AndGate) or isinstance(self.columns[column][bit], NandGate): + self.add_component(self.columns[column][bit]) + return self.get_previous_component(1).out + else: + return self.columns[column][bit] + + def update_column_wires(self, curr_column: int, adder: ArithmeticCircuit, next_column: int = 0): + if hasattr(adder, "c"): + self.columns[curr_column].pop(1) + self.columns[curr_column].pop(1) + self.columns[curr_column].pop(1) + self.columns[curr_column].insert(self.get_column_height(curr_column), adder.get_sum_wire()) + else: + self.columns[curr_column].pop(1) + self.columns[curr_column].pop(1) + self.columns[curr_column].insert(self.get_column_height(curr_column), adder.get_sum_wire()) + + if next_column-1 == curr_column: + self.columns[next_column].insert(1, adder.get_carry_wire()) diff --git a/ariths_gen/core/three_input_one_bit_circuit.py b/ariths_gen/core/three_input_one_bit_circuit.py new file mode 100644 index 0000000..1f30318 --- /dev/null +++ b/ariths_gen/core/three_input_one_bit_circuit.py @@ -0,0 +1,52 @@ +from .two_input_one_bit_circuit import( + TwoInputOneBitCircuit +) + +class ThreeInputOneBitCircuit(TwoInputOneBitCircuit): + def __init__(self): + super().__init__() + + """ C CODE GENERATION """ + # FLAT C # + # Function prototype with three inputs + def get_prototype_c(self): + return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.prefix}, {self.c_data_type} {self.b.prefix}, {self.c_data_type} {self.c.prefix})" + "{" + "\n" + + # HIERARCHICAL C # + # Subcomponent generation (3 inputs) + def get_out_invocation_c(self, **kwargs): + circuit_class = self.__class__() + return "".join([f' {o.name} = ({circuit_class.prefix}({self.a.name}, {self.b.name}, {self.c.name}) >> {self.out.bus.index(o)}) & 0x01;\n' for o in self.out.bus]) + + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + # Module prototype with three inputs + def get_prototype_v(self): + return f"module {self.prefix}(input {self.a.name}, input {self.b.name}, input {self.c.name}{''.join([f', output {o.name}' for o in self.out.bus])});\n" + + # HIERARCHICAL VERILOG # + # Subcomponent generation (3 inputs) + def get_invocation_v(self, **kwargs): + circuit_class = self.__class__() + return f" {circuit_class.prefix} {circuit_class.prefix}_{self.out.get_wire().name}({self.a.name}, {self.b.name}, {self.c.name}{''.join([f', {o.name}' for o in self.out.bus])});\n" + + """ BLIF CODE GENERATION """ + # FLAT BLIF # + # Model prototype with three inputs + def get_declaration_blif(self): + return f".inputs {self.a.name} {self.b.name} {self.c.name}\n" + \ + f".outputs{self.out.get_wire_declaration_blif(array=False)}\n" + + # HIERARCHICAL BLIF # + # Subcomponent generation (3 inputs) + def get_invocation_blif_hier(self, **kwargs): + circuit_class = self.__class__() + return f"{self.get_wire_mapping_blif()}" + \ + f".subckt {circuit_class.prefix} a={self.inputs[0].name} b={self.inputs[1].name} cin={self.inputs[2].name}{''.join([f' {o.name}={self.out.get_wire(circuit_class.out.bus.index(o)).name}' for o in circuit_class.out.bus])}\n" + + """ CGP CODE GENERATION """ + # FLAT CGP # + # Chromosome prototype with three inputs + def get_parameters_cgp(self): + self.circuit_gates = self.get_circuit_gates() + return f"{{3,2,1,{len(self.circuit_gates)},2,1,0}}" \ No newline at end of file diff --git a/ariths_gen/core/two_input_one_bit_circuit.py b/ariths_gen/core/two_input_one_bit_circuit.py new file mode 100644 index 0000000..d79a5d0 --- /dev/null +++ b/ariths_gen/core/two_input_one_bit_circuit.py @@ -0,0 +1,144 @@ +from .arithmetic_circuit import( + ArithmeticCircuit +) + +class TwoInputOneBitCircuit(ArithmeticCircuit): + def __init__(self): + super().__init__() + + """ C CODE GENERATION """ + # FLAT C # + # Obtaining list of all the unique circuit wires from all contained logic gates + # to ensure non-recurring declaration of same wires + def get_declaration_c_flat(self): + self.get_circuit_wires() + # Unique declaration of all circuit's interconnections + return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) + + # Wires values initialization and assignment + def get_init_c_flat(self): + return "".join([i.get_assign_c(name=i.get_wire_value_c(name=i.name.replace(self.prefix+"_",""))) for i in self.inputs]) + \ + "".join([f" {c.out.name} = {c.get_init_c_flat()};\n" for c in self.components]) + + # Generating flat C code representation of circuit + def get_c_code_flat(self, file_object): + file_object.write(self.get_includes_c()) + file_object.write(self.get_prototype_c()) + file_object.write(self.out.get_declaration_c()) + file_object.write(self.get_declaration_c_flat()+"\n") + file_object.write(self.get_init_c_flat()+"\n") + file_object.write(self.get_function_out_c_flat()) + file_object.write(f" return {self.out.prefix}"+";\n}") + file_object.close() + + # HIERARCHICAL C # + # Subcomponent generation + def get_function_block_c(self): + adder_block = self.__class__() + return f"{adder_block.get_circuit_c()}\n\n" + + def get_wire_declaration_c_hier(self): + return f"{self.out.get_wire_declaration_c()}" + + def get_out_invocation_c(self, **kwargs): + circuit_class = self.__class__() + return "".join([f' {o.name} = ({circuit_class.prefix}({self.a.name}, {self.b.name}) >> {self.out.bus.index(o)}) & 0x01;\n' for o in self.out.bus]) + + # Self circuit hierarchical generation + def get_declaration_c_hier(self): + self.get_circuit_wires() + # Unique declaration of all circuit's interconnections + return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) + + def get_init_c_hier(self): + return "".join([i.get_assign_c(name=i.get_wire_value_c(name=i.name.replace(self.prefix+"_",""))) for i in self.inputs]) + \ + "".join([f" {c.out.name} = {c.get_gate_invocation_c(remove_prefix=False)}" for c in self.components]) + + def get_function_out_c_hier(self): + return "".join([f" {self.out.prefix} |= {o.return_wire_value_c(offset=self.out.bus.index(o))};\n" for o in self.out.bus]) + + """ VERILOG CODE GENERATION """ + # FLAT VERILOG # + def get_prototype_v(self): + return f"module {self.prefix}(input {self.a.name}, input {self.b.name}{''.join([f', output {o.name}' for o in self.out.bus])});\n" + + def get_declaration_v_flat(self): + self.get_circuit_wires() + # Unique declaration of all circuit's interconnections + return "".join([c[0].get_declaration_v() for c in self.circuit_wires]) + + # Wires values initialization and assignment + def get_init_v_flat(self): + return "".join([i.get_assign_v(name=i.name.replace(self.prefix+"_","")) for i in self.inputs]) + \ + "".join([f" assign {c.out.name} = {c.get_init_v_flat()};\n" for c in self.components]) + + # Generating flat Verilog code representation of circuit + def get_v_code_flat(self, file_object): + file_object.write(self.get_prototype_v()) + file_object.write(self.get_declaration_v_flat()+"\n") + file_object.write(self.get_init_v_flat()) + file_object.write(f"endmodule") + file_object.close() + + # HIERARCHICAL VERILOG # + # Subcomponent generation + def get_function_block_v(self): + adder_block = self.__class__() + return f"{adder_block.get_circuit_v()}\n\n" + + def get_wire_declaration_v_hier(self): + return f"{self.out.get_wire_declaration_v()}" + + def get_invocation_v(self, **kwargs): + circuit_class = self.__class__() + return f" {circuit_class.prefix} {circuit_class.prefix}_{self.out.get_wire().name}({self.a.name}, {self.b.name}{''.join([f', {o.name}' for o in self.out.bus])});\n" + + # Self circuit hierarchical generation + def get_declaration_v_hier(self): + self.get_circuit_wires() + # Unique declaration of all circuit's interconnections + return "".join([c[0].get_declaration_v() for c in self.circuit_wires if c[0] not in self.out.bus]) + + def get_init_v_hier(self): + return "".join([i.get_assign_v(name=i.name.replace(self.prefix+"_","")) for i in self.inputs]) + + def get_function_out_v_hier(self): + return "".join([f"{c.get_gate_invocation_v(remove_prefix=False)}" for c in self.components]) + + """ BLIF CODE GENERATION """ + # FLAT BLIF # + def get_declaration_blif(self): + return f".inputs {self.a.name} {self.b.name}\n" + \ + f".outputs{self.out.get_wire_declaration_blif(array=False)}\n" + + def get_wire_mapping_blif(self): + # For unique mapping of all circuit's input interconnections + self.get_circuit_wires() + return "".join([i.get_assign_blif(name=i.name.replace(self.prefix+"_","")) for i in self.inputs]) + + def get_function_blif_flat(self): + return f"{self.get_wire_mapping_blif()}"+"".join([c.get_function_blif_flat() for c in self.components]) + + def get_function_out_blif(self): + return f"" + + # HIERARCHICAL BLIF # + # Subcomponent generation + def get_function_block_blif(self): + adder_block = self.__class__() + return f"{adder_block.get_circuit_blif()}" + + def get_invocation_blif_hier(self, **kwargs): + circuit_class = self.__class__() + return f"{self.get_wire_mapping_blif()}" + \ + f".subckt {circuit_class.prefix} a={self.inputs[0].name} b={self.inputs[1].name}{''.join([f' {o.name}={self.out.get_wire(circuit_class.out.bus.index(o)).name}' for o in circuit_class.out.bus])}\n" + + # Self circuit hierarchical generation + def get_function_blif_hier(self): + return f"{self.get_wire_mapping_blif()}"+"".join(c.get_invocation_blif_hier(init=False) for c in self.components) + + """ CGP CODE GENERATION """ + # FLAT CGP # + def get_parameters_cgp(self): + self.circuit_gates = self.get_circuit_gates() + return f"{{2,2,1,{len(self.circuit_gates)},2,1,0}}" \ No newline at end of file diff --git a/ariths_gen/multi_bit_circuits/__init__.py b/ariths_gen/multi_bit_circuits/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ariths_gen/multi_bit_circuits/__pycache__/__init__.cpython-38.pyc b/ariths_gen/multi_bit_circuits/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..5463835 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/adders/__init__.py b/ariths_gen/multi_bit_circuits/adders/__init__.py new file mode 100644 index 0000000..59c15dc --- /dev/null +++ b/ariths_gen/multi_bit_circuits/adders/__init__.py @@ -0,0 +1,14 @@ +from ariths_gen.multi_bit_circuits.adders.ripple_carry_adder import( + UnsignedRippleCarryAdder, + SignedRippleCarryAdder +) + +from ariths_gen.multi_bit_circuits.adders.pg_ripple_carry_adder import( + UnsignedPGRippleCarryAdder, + SignedPGRippleCarryAdder +) + +from ariths_gen.multi_bit_circuits.adders.carry_lookahead_adder import( + UnsignedCarryLookaheadAdder, + SignedCarryLookaheadAdder +) \ No newline at end of file diff --git a/ariths_gen/multi_bit_circuits/adders/__pycache__/__init__.cpython-38.pyc b/ariths_gen/multi_bit_circuits/adders/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..b0fee07 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/adders/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/adders/__pycache__/carry_lookahead_adder.cpython-38.pyc b/ariths_gen/multi_bit_circuits/adders/__pycache__/carry_lookahead_adder.cpython-38.pyc new file mode 100644 index 0000000..873e8f1 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/adders/__pycache__/carry_lookahead_adder.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/adders/__pycache__/pg_ripple_carry_adder.cpython-38.pyc b/ariths_gen/multi_bit_circuits/adders/__pycache__/pg_ripple_carry_adder.cpython-38.pyc new file mode 100644 index 0000000..4a86203 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/adders/__pycache__/pg_ripple_carry_adder.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/adders/__pycache__/ripple_carry_adder.cpython-38.pyc b/ariths_gen/multi_bit_circuits/adders/__pycache__/ripple_carry_adder.cpython-38.pyc new file mode 100644 index 0000000..7f14d1a Binary files /dev/null and b/ariths_gen/multi_bit_circuits/adders/__pycache__/ripple_carry_adder.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py b/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py new file mode 100644 index 0000000..4fc8f28 --- /dev/null +++ b/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py @@ -0,0 +1,128 @@ +from ariths_gen.wire_components import( + Wire, + Bus +) +from ariths_gen.core import( + ArithmeticCircuit, + MultiplierCircuit +) +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + PGLogicBlock, + ConstantWireValue0, + ConstantWireValue1, + FullAdder, + FullAdderPG +) +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +class UnsignedCarryLookaheadAdder(ArithmeticCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "u_cla"): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Lists containing all propagate/generate wires + self.propagate = [] + self.generate = [] + + # Output wires for N sum bits and additional cout bit + self.out = Bus("out", self.N+1) + + # Constant wire with value 0 for cin 0 + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + # Used as a first generate wire for obtaining next carry bits + self.generate.append(constant_wire_0.out.get_wire()) + + # Gradual addition of propagate/generate logic blocks and AND/OR gates for Cout bits generation, XOR gates for Sum bits generation + for input_index in range(self.N): + pg_block = PGLogicBlock(self.a.get_wire(input_index), self.b.get_wire(input_index), prefix=self.prefix+"_pg_logic"+str(input_index)) + self.propagate.append(pg_block.get_propagate_wire()) + self.generate.append(pg_block.get_generate_wire()) + self.add_component(pg_block) + + if input_index == 0: + obj_sum_xor = XorGate(pg_block.get_sum_wire(), constant_wire_0.out.get_wire(), prefix=self.prefix+"_xor"+str(input_index)) + self.add_component(obj_sum_xor) + self.out.connect(input_index, obj_sum_xor.out) + + # Carry propagation calculation + obj_and = AndGate(self.propagate[input_index], self.generate[input_index], prefix=self.prefix+"_and"+str(self.get_instance_num(cls=AndGate))) + self.add_component(obj_and) + + # Carry bit generation + obj_cout_or = OrGate(pg_block.get_generate_wire(), self.get_previous_component().out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=OrGate))) + self.add_component(obj_cout_or) + else: + obj_sum_xor = XorGate(pg_block.get_sum_wire(), self.get_previous_component(2).out, prefix=self.prefix+"_xor"+str(input_index)) + self.add_component(obj_sum_xor) + self.out.connect(input_index, obj_sum_xor.out) + + # For each pg pair values algorithmically combine two input AND gates to replace multiple input gates (resolves fan-in issue) + composite_and_gates = [] + # And combine AND gate pairs into OR gates + composite_or_gates = [] + + # Carry propagation calculation + for g_index in range(len(self.generate)-1): + for p_index in range(g_index, len(self.propagate)): + # No gate to cascade with, add to list + if len(composite_and_gates) == 0: + obj_and = AndGate(self.propagate[p_index], self.generate[g_index], prefix=self.prefix+"_and"+str(self.get_instance_num(cls=AndGate))) + # Combine 2 gates into another one to cascade them + else: + # Create new AND gate + obj_and = AndGate(self.propagate[p_index], self.generate[g_index], prefix=self.prefix+"_and"+str(self.get_instance_num(cls=AndGate))) + self.add_component(obj_and) + + # Combine new gate with previous one stored in list + obj_and = AndGate(self.get_previous_component(1).out, self.get_previous_component(2).out, prefix=self.prefix+"_and"+str(self.get_instance_num(cls=AndGate))) + composite_and_gates.pop(composite_and_gates.index(self.get_previous_component(2))) + + # Add gate to circuit components and to list of composite AND gates for this pg pair value + self.add_component(obj_and) + composite_and_gates.append(obj_and) + + composite_or_gates.append(composite_and_gates.pop()) + + # Final OR gates cascade using generated AND gates representing multiple input AND gates (cascade of multiple two input ones) + for a in range(len(composite_or_gates)-1): + obj_or = OrGate(self.get_previous_component().out, composite_or_gates[a].out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=OrGate))) + self.add_component(obj_or) + + # Carry bit generation + obj_cout_or = OrGate(pg_block.get_generate_wire(), self.get_previous_component().out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=OrGate))) + self.add_component(obj_cout_or) + + # Connecting last output bit to last cout + if input_index == (self.N-1): + self.out.connect(self.N, obj_cout_or.out) + + +class SignedCarryLookaheadAdder(UnsignedCarryLookaheadAdder, ArithmeticCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "s_cla"): + super().__init__(a=a, b=b, prefix=prefix) + self.c_data_type = "int64_t" + + # Additional XOR gates to ensure correct sign extension in case of sign addition + sign_xor_1 = XorGate(self.a.get_wire(self.N-1), self.b.get_wire(self.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(sign_xor_1) + sign_xor_2 = XorGate(sign_xor_1.out, self.get_previous_component(2).out, prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(sign_xor_2) + self.out.connect(self.N, sign_xor_2.out) \ No newline at end of file diff --git a/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py b/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py new file mode 100644 index 0000000..815c103 --- /dev/null +++ b/ariths_gen/multi_bit_circuits/adders/pg_ripple_carry_adder.py @@ -0,0 +1,76 @@ +from ariths_gen.wire_components import( + Wire, + Bus +) +from ariths_gen.core import( + ArithmeticCircuit, + MultiplierCircuit +) +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + PGLogicBlock, + ConstantWireValue0, + ConstantWireValue1, + FullAdder, + FullAdderPG +) +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +class UnsignedPGRippleCarryAdder(ArithmeticCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "u_pg_rca"): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for N sum bits and additional cout bit + self.out = Bus("out", self.N+1) + + # Gradual addition of 1-bit adder components + for input_index in range(self.N): + if input_index == 0: + # Constant wire with value 0 for cin 0 + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + obj_fa_cla = FullAdderPG(self.a.get_wire(input_index), self.b.get_wire(input_index), constant_wire_0.out.get_wire(), prefix=self.prefix+"_fa"+str(input_index)) + else: + obj_fa_cla = FullAdderPG(self.a.get_wire(input_index), self.b.get_wire(input_index), self.get_previous_component().out, prefix=self.prefix+"_fa"+str(input_index)) + + self.add_component(obj_fa_cla) + self.out.connect(input_index, obj_fa_cla.get_sum_wire()) + + obj_and = AndGate(self.get_previous_component().c, self.get_previous_component().get_propagate_wire(), prefix=self.prefix+"_and"+str(input_index)) + obj_or = OrGate(obj_and.out, self.get_previous_component().get_generate_wire(), prefix=self.prefix+"_or"+str(input_index)) + self.add_component(obj_and) + self.add_component(obj_or) + + # Connecting last output bit to last cout + if input_index == (self.N-1): + self.out.connect(self.N, obj_or.out) + + +class SignedPGRippleCarryAdder(UnsignedPGRippleCarryAdder, ArithmeticCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "s_pg_rca"): + super().__init__(a=a, b=b, prefix=prefix) + self.c_data_type = "int64_t" + + # Additional XOR gates to ensure correct sign extension in case of sign addition + sign_xor_1 = XorGate(self.a.get_wire(self.N-1), self.b.get_wire(self.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(sign_xor_1) + sign_xor_2 = XorGate(sign_xor_1.out, self.get_previous_component(2).out, prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(sign_xor_2) + self.out.connect(self.N, sign_xor_2.out) \ No newline at end of file diff --git a/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py b/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py new file mode 100644 index 0000000..4926ba9 --- /dev/null +++ b/ariths_gen/multi_bit_circuits/adders/ripple_carry_adder.py @@ -0,0 +1,68 @@ +from ariths_gen.wire_components import( + Wire, + Bus +) +from ariths_gen.core import( + ArithmeticCircuit, + MultiplierCircuit +) +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + PGLogicBlock, + ConstantWireValue0, + ConstantWireValue1, + FullAdder, + FullAdderPG +) +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +class UnsignedRippleCarryAdder(ArithmeticCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "u_rca"): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for N sum bits and additional cout bit + self.out = Bus("out", self.N+1) + + # Gradual addition of 1-bit adder components + for input_index in range(self.N): + # First adder is a half adder + if input_index == 0: + obj_adder = HalfAdder(self.a.get_wire(input_index), self.b.get_wire(input_index), prefix=self.prefix+"_ha") + # Rest adders are full adders + else: + obj_adder = FullAdder(self.a.get_wire(input_index), self.b.get_wire(input_index), self.get_previous_component().get_carry_wire(), prefix=self.prefix+"_fa"+str(input_index)) + + self.add_component(obj_adder) + self.out.connect(input_index, obj_adder.get_sum_wire()) + if input_index == (self.N-1): + self.out.connect(self.N, obj_adder.get_carry_wire()) + + +class SignedRippleCarryAdder(UnsignedRippleCarryAdder, ArithmeticCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "s_rca"): + super().__init__(a=a, b=b, prefix=prefix) + self.c_data_type = "int64_t" + + # Additional XOR gates to ensure correct sign extension in case of sign addition + sign_xor_1 = XorGate(self.get_previous_component(1).a, self.get_previous_component(1).b, prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(sign_xor_1) + sign_xor_2 = XorGate(sign_xor_1.out, self.get_previous_component(2).get_carry_wire(), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(sign_xor_2) + self.out.connect(self.N, sign_xor_2.out) \ No newline at end of file diff --git a/ariths_gen/multi_bit_circuits/multipliers/__init__.py b/ariths_gen/multi_bit_circuits/multipliers/__init__.py new file mode 100644 index 0000000..d219a7e --- /dev/null +++ b/ariths_gen/multi_bit_circuits/multipliers/__init__.py @@ -0,0 +1,14 @@ +from ariths_gen.multi_bit_circuits.multipliers.array_multiplier import( + UnsignedArrayMultiplier, + SignedArrayMultiplier +) + +from ariths_gen.multi_bit_circuits.multipliers.wallace_multiplier import( + UnsignedWallaceMultiplier, + SignedWallaceMultiplier +) + +from ariths_gen.multi_bit_circuits.multipliers.dadda_multiplier import( + UnsignedDaddaMultiplier, + SignedDaddaMultiplier +) \ No newline at end of file diff --git a/ariths_gen/multi_bit_circuits/multipliers/__pycache__/__init__.cpython-38.pyc b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..ff08f87 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/multipliers/__pycache__/array_multiplier.cpython-38.pyc b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/array_multiplier.cpython-38.pyc new file mode 100644 index 0000000..68a7cf8 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/array_multiplier.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/multipliers/__pycache__/dadda_multiplier.cpython-38.pyc b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/dadda_multiplier.cpython-38.pyc new file mode 100644 index 0000000..aba97a3 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/dadda_multiplier.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/multipliers/__pycache__/wallace_multiplier.cpython-38.pyc b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/wallace_multiplier.cpython-38.pyc new file mode 100644 index 0000000..355ed89 Binary files /dev/null and b/ariths_gen/multi_bit_circuits/multipliers/__pycache__/wallace_multiplier.cpython-38.pyc differ diff --git a/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py b/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py new file mode 100644 index 0000000..298460e --- /dev/null +++ b/ariths_gen/multi_bit_circuits/multipliers/array_multiplier.py @@ -0,0 +1,157 @@ +from ariths_gen.wire_components import( + Wire, + Bus +) +from ariths_gen.core import( + ArithmeticCircuit, + MultiplierCircuit +) +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + ConstantWireValue0, + ConstantWireValue1, + FullAdder, + FullAdderPG +) +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +# MULTIPLIERS +class UnsignedArrayMultiplier(MultiplierCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "u_arrmul"): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for multiplication product + self.out = Bus("out", self.N*2) + + # Gradual generation of partial products + for b_multiplier_index in range(self.N): + for a_multiplicand_index in range(self.N): + # AND gates generation for calculation of partial products + obj_and = AndGate(self.a.get_wire(a_multiplicand_index), self.b.get_wire(b_multiplier_index), prefix=self.prefix+"_and"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_and) + + if b_multiplier_index != 0: + previous_product = self.components[a_multiplicand_index + b_multiplier_index].out if b_multiplier_index == 1 else self.get_previous_partial_product(a_index=a_multiplicand_index, b_index=b_multiplier_index) + # HA generation for first 1-bit adder in each row starting from the second one + if a_multiplicand_index == 0: + obj_adder = HalfAdder(self.get_previous_component().out, previous_product, prefix=self.prefix+"_ha"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_adder) + # Product generation + self.out.connect(b_multiplier_index, obj_adder.get_sum_wire()) + + # HA generation, last 1-bit adder in second row + elif a_multiplicand_index == self.N-1 and b_multiplier_index == 1: + obj_adder = HalfAdder(self.get_previous_component().out, self.get_previous_component(number=2).get_carry_wire(), prefix=self.prefix+"_ha"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_adder) + + # FA generation + else: + obj_adder = FullAdder(self.get_previous_component().out, previous_product, self.get_previous_component(number=2).get_carry_wire(), prefix=self.prefix+"_fa"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_adder) + + # PRODUCT GENERATION + if a_multiplicand_index == 0 and b_multiplier_index == 0: + self.out.connect(a_multiplicand_index, obj_and.out) + + # 1 bit multiplier case + if a_multiplicand_index == self.N-1: + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + + self.out.connect(a_multiplicand_index+1, constant_wire_0.out.get_wire()) + + elif b_multiplier_index == self.N-1: + self.out.connect(b_multiplier_index + a_multiplicand_index, obj_adder.get_sum_wire()) + + if a_multiplicand_index == self.N-1: + self.out.connect(self.out.N-1, obj_adder.get_carry_wire()) + + +class SignedArrayMultiplier(MultiplierCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "s_arrmul"): + super().__init__() + self.c_data_type = "int64_t" + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for multiplication product + self.out = Bus("out", self.N*2) + + # Generating wire with constant logic value 1 + constant_wire_1 = ConstantWireValue1(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_1) + + # To adjust proper wire connection between adders and AND/NAND gates + # we add offset equal to first block in circuits components list (used for generation of wire with constant value 1) + components_offset = 1 + + # Gradual generation of partial products + for b_multiplier_index in range(self.N): + for a_multiplicand_index in range(self.N): + # AND and NAND gates generation for calculation of partial products and sign extension + if (b_multiplier_index == self.N-1 and a_multiplicand_index != self.N-1) or (b_multiplier_index != self.N-1 and a_multiplicand_index == self.N-1): + obj_nand = NandGate(self.a.get_wire(a_multiplicand_index), self.b.get_wire(b_multiplier_index), prefix=self.prefix+"_nand"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_nand) + else: + obj_and = AndGate(self.a.get_wire(a_multiplicand_index), self.b.get_wire(b_multiplier_index), prefix=self.prefix+"_and"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_and) + + if b_multiplier_index != 0: + previous_product = self.components[a_multiplicand_index + b_multiplier_index + components_offset].out if b_multiplier_index == 1 else self.get_previous_partial_product(a_index=a_multiplicand_index, b_index=b_multiplier_index, offset=components_offset) + # HA generation for first 1-bit adder in each row starting from the second one + if a_multiplicand_index == 0: + obj_adder = HalfAdder(self.get_previous_component().out, previous_product, prefix=self.prefix+"_ha"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_adder) + # Product generation + self.out.connect(b_multiplier_index, obj_adder.get_sum_wire()) + + # FA generation + else: + if a_multiplicand_index == self.N-1 and b_multiplier_index == 1: + previous_product = constant_wire_1.out.get_wire() + + obj_adder = FullAdder(self.get_previous_component().out, previous_product, self.get_previous_component(number=2).get_carry_wire(), prefix=self.prefix+"_fa"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) + self.add_component(obj_adder) + + # PRODUCT GENERATION + if a_multiplicand_index == 0 and b_multiplier_index == 0: + self.out.connect(a_multiplicand_index, obj_and.out) + + # 1 bit multiplier case + if a_multiplicand_index == self.N-1: + obj_nor = NorGate(constant_wire_1.out.get_wire(), self.get_previous_component().out, prefix=self.prefix+"_nor_zero_extend") + self.add_component(obj_nor) + + self.out.connect(a_multiplicand_index+1, obj_nor.out) + + elif b_multiplier_index == self.N-1: + self.out.connect(b_multiplier_index + a_multiplicand_index, obj_adder.get_sum_wire()) + + if a_multiplicand_index == self.N-1: + obj_xor = XorGate(self.get_previous_component().get_carry_wire(), constant_wire_1.out.get_wire(), prefix=self.prefix+"_xor"+str(a_multiplicand_index+1)+"_"+str(b_multiplier_index)) + self.add_component(obj_xor) + + self.out.connect(self.out.N-1, obj_xor.out) diff --git a/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py b/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py new file mode 100644 index 0000000..c180d57 --- /dev/null +++ b/ariths_gen/multi_bit_circuits/multipliers/dadda_multiplier.py @@ -0,0 +1,217 @@ +from ariths_gen.multi_bit_circuits.adders.ripple_carry_adder import UnsignedRippleCarryAdder +from ariths_gen.wire_components import( + Wire, + Bus +) +from ariths_gen.core import( + ArithmeticCircuit, + MultiplierCircuit +) +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + ConstantWireValue0, + ConstantWireValue1, + FullAdder, + FullAdderPG +) +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +class UnsignedDaddaMultiplier(MultiplierCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "u_dadda_rca", unsigned_adder_class_name: str = UnsignedRippleCarryAdder): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for multiplication product + self.out = Bus("out", self.N*2) + + # Get starting stage and maximum possible column height + self.stage, self.d = self.get_maximum_height(initial_value=min(self.a.N, self.b.N)) + # Initialize all columns partial products forming AND gates matrix + self.columns = self.init_column_heights() + + # Perform reduction until stage 0 + for stage in range(self.stage, 0, -1): + col = 0 + while col < len(self.columns): + if self.get_column_height(col) == self.d + 1: + # Add half adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = HalfAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add ha's generated sum to the bottom of current column + # add ha's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + + elif self.get_column_height(col) > self.d: + # Add full adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = FullAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=FullAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add fa's generated sum to the bottom of current column + # add fa's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + + # Next iteration with same column in case there is need for further reduction + col -= 1 + col += 1 + # Update maximum possible column height + _, self.d = self.get_maximum_height(stage) + + # Output generation + # First output bit from single first pp AND gate + self.out.connect(0, self.get_column_wire(column=0, bit=1)) + # Final addition of remaining bits + # 1 bit multiplier case + if self.N == 1: + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + self.out.connect(1, constant_wire_0.out.get_wire()) + # 2 bit multiplier case + elif self.N == 2: + obj_ha = HalfAdder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(1, obj_ha.get_sum_wire()) + + obj_ha = HalfAdder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(2, obj_ha.get_sum_wire()) + self.out.connect(3, obj_ha.get_carry_wire()) + # Final addition of remaining bits using chosen unsigned multi bit adder + else: + # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) + adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) + + adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") + self.add_component(final_adder) + + [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] + + +class SignedDaddaMultiplier(MultiplierCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "s_dadda_rca", unsigned_adder_class_name: str = UnsignedRippleCarryAdder): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for multiplication product + self.out = Bus("out", self.N*2) + + # Get starting stage and maximum possible column height + self.stage, self.d = self.get_maximum_height(initial_value=min(self.a.N, self.b.N)) + # Initialize all columns partial products forming AND/NAND gates matrix based on Baugh-Wooley multiplication + self.columns = self.init_column_heights() + + # Generating wire with constant logic value 1 for signed multiplication + # Based on Baugh-Wooley multiplication algorithm + # Not used for 1 bit multiplier + if self.N != 1: + constant_wire_1 = ConstantWireValue1(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_1) + + # Adding constant wire with value 1 to achieve signedness + # (adding constant value bit to last column (with one bit) to combine them in XOR gate to get the correct final multplication output bit at the end) + self.columns[self.N].insert(1, constant_wire_1.out.get_wire()) + self.update_column_heights(curr_column=self.N, curr_height_change=1) + + # Perform reduction until stage 0 + for stage in range(self.stage, 0, -1): + col = 0 + while col < len(self.columns): + if self.get_column_height(col) == self.d + 1: + # Add half adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = HalfAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add ha's generated sum to the bottom of current column + # add ha's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + elif self.get_column_height(col) > self.d: + # Add full adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = FullAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=FullAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add fa's generated sum to the bottom of current column + # add fa's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + # Next iteration with same column in case there is need for further reduction + col -= 1 + col += 1 + # Update maximum possible column height + _, self.d = self.get_maximum_height(stage) + + # Output generation + # First output bit from single first pp AND gate + self.out.connect(0, self.get_column_wire(column=0, bit=1)) + # Final addition of remaining bits + # 1 bit multiplier case (no sign extension) + if self.N == 1: + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + self.out.connect(1, constant_wire_0.out.get_wire()) + return + # 2 bit multiplier case + elif self.N == 2: + obj_ha = HalfAdder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(1, obj_ha.get_sum_wire()) + + obj_ha = HalfAdder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(2, obj_ha.get_sum_wire()) + self.out.connect(3, obj_ha.get_carry_wire()) + # Final addition of remaining bits using chosen unsigned multi bit adder + else: + # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) + adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) + + adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") + self.add_component(final_adder) + + [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] + + # Final XOR to ensure proper sign extension + obj_xor = XorGate(constant_wire_1.out.get_wire(), self.out.get_wire(self.out.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(obj_xor) + self.out.connect(self.out.N-1, obj_xor.out) diff --git a/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py b/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py new file mode 100644 index 0000000..277e68a --- /dev/null +++ b/ariths_gen/multi_bit_circuits/multipliers/wallace_multiplier.py @@ -0,0 +1,209 @@ +from ariths_gen.multi_bit_circuits.adders.ripple_carry_adder import UnsignedRippleCarryAdder +from ariths_gen.wire_components import( + Wire, + Bus +) +from ariths_gen.core import( + ArithmeticCircuit, + MultiplierCircuit +) +from ariths_gen.one_bit_circuits.one_bit_components import( + HalfAdder, + ConstantWireValue0, + ConstantWireValue1, + FullAdder, + FullAdderPG +) +from ariths_gen.one_bit_circuits.logic_gates import( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) + +class UnsignedWallaceMultiplier(MultiplierCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "u_wallace_rca", unsigned_adder_class_name: str = UnsignedRippleCarryAdder): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for multiplication product + self.out = Bus("out", self.N*2) + + # Initialize all columns partial products forming AND gates matrix + self.columns = self.init_column_heights() + + # Perform reduction until all columns have 2 or less bits in them + while not all(height <= 2 for (height, *_) in self.columns): + col = 0 + while col < len(self.columns): + # If column has exactly 3 bits in height and all previous columns has maximum of 2 bits in height, combine them in a half adder + if self.get_column_height(col) == 3 and all(height <= 2 for (height, *_) in self.columns[0:col-1]): + # Add half adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = HalfAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add ha's generated sum to the bottom of current column + # add ha's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + + # If column has more than 3 bits in height, combine them in a full adder + elif self.get_column_height(col) > 3: + # Add full adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = FullAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=FullAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add fa's generated sum to the bottom of current column + # add fa's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + col += 1 + + # Output generation + # First output bit from single first pp AND gate + self.out.connect(0, self.get_column_wire(column=0, bit=1)) + # Final addition of remaining bits + # 1 bit multiplier case + if self.N == 1: + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + self.out.connect(1, constant_wire_0.out.get_wire()) + # 2 bit multiplier case + elif self.N == 2: + obj_ha = HalfAdder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(1, obj_ha.get_sum_wire()) + + obj_ha = HalfAdder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(2, obj_ha.get_sum_wire()) + self.out.connect(3, obj_ha.get_carry_wire()) + # Final addition of remaining bits using chosen unsigned multi bit adder + else: + # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) + adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) + + adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") + self.add_component(final_adder) + + [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] + + +class SignedWallaceMultiplier(MultiplierCircuit): + def __init__(self, a: Bus, b: Bus, prefix: str = "s_wallace_rca", unsigned_adder_class_name: str = UnsignedRippleCarryAdder): + super().__init__() + self.N = max(a.N, b.N) + self.prefix = prefix + self.a = Bus(prefix=a.prefix, wires_list=a.bus) + self.b = Bus(prefix=b.prefix, wires_list=b.bus) + + # Bus sign extension in case buses have different lengths + self.a.bus_extend(N=self.N, prefix=a.prefix) + self.b.bus_extend(N=self.N, prefix=b.prefix) + + # Output wires for multiplication product + self.out = Bus("out", self.N*2) + + # Initialize all columns partial products forming AND/NAND gates matrix based on Baugh-Wooley multiplication + self.columns = self.init_column_heights() + + # Generating wire with constant logic value 1 for signed multiplication + # Based on Baugh-Wooley multiplication algorithm + # Not used for 1 bit multiplier + if self.N != 1: + constant_wire_1 = ConstantWireValue1(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_1) + + # Adding constant wire with value 1 to achieve signedness + # (adding constant value bit to last column (with one bit) to combine them in XOR gate to get the correct final multplication output bit at the end) + self.columns[self.N].insert(1, constant_wire_1.out.get_wire()) + self.update_column_heights(curr_column=self.N, curr_height_change=1) + + # Perform reduction until all columns have 2 or less bits in them + while not all(height <= 2 for (height, *_) in self.columns): + col = 0 + while col < len(self.columns): + # If column has exactly 3 bits in height and all previous columns has maximum of 2 bits in height, combine them in a half adder + if self.get_column_height(col) == 3 and all(height <= 2 for (height, *_) in self.columns[0:col-1]): + # Add half adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = HalfAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add ha's generated sum to the bottom of current column + # add ha's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + + # If column has more than 3 bits in height, combine them in a full adder + elif self.get_column_height(col) > 3: + # Add full adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components + obj_adder = FullAdder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=FullAdder))) + self.add_component(obj_adder) + + # Update the number of current and next column wires + self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) + + # Update current and next column wires arrangement + # add fa's generated sum to the bottom of current column + # add fa's generated cout to the top of next column + self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) + col += 1 + + # Output generation + # First output bit from single first pp AND gate + self.out.connect(0, self.get_column_wire(column=0, bit=1)) + # Final addition of remaining bits + # 1 bit multiplier case + if self.N == 1: + constant_wire_0 = ConstantWireValue0(self.a.get_wire(), self.b.get_wire()) + self.add_component(constant_wire_0) + self.out.connect(1, constant_wire_0.out.get_wire()) + return + # 2 bit multiplier case + elif self.N == 2: + obj_ha = HalfAdder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(1, obj_ha.get_sum_wire()) + + obj_ha = HalfAdder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=HalfAdder))) + self.add_component(obj_ha) + self.out.connect(2, obj_ha.get_sum_wire()) + self.out.connect(3, obj_ha.get_carry_wire()) + # Final addition of remaining bits using chosen unsigned multi bit adder + else: + # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) + adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) + + adder_a = Bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) + adder_b = Bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) + final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") + self.add_component(final_adder) + + [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] + + # Final XOR to ensure proper sign extension + obj_xor = XorGate(constant_wire_1.out.get_wire(), self.out.get_wire(self.out.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=XorGate))) + self.add_component(obj_xor) + self.out.connect(self.out.N-1, obj_xor.out) diff --git a/ariths_gen/one_bit_circuits/__init__.py b/ariths_gen/one_bit_circuits/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ariths_gen/one_bit_circuits/__pycache__/__init__.cpython-38.pyc b/ariths_gen/one_bit_circuits/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..c242bd7 Binary files /dev/null and b/ariths_gen/one_bit_circuits/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/one_bit_circuits/logic_gates/__init__.py b/ariths_gen/one_bit_circuits/logic_gates/__init__.py new file mode 100644 index 0000000..923c48c --- /dev/null +++ b/ariths_gen/one_bit_circuits/logic_gates/__init__.py @@ -0,0 +1,10 @@ +from .logic_gates import ( + LogicGate, + AndGate, + NandGate, + OrGate, + NorGate, + XorGate, + XnorGate, + NotGate +) diff --git a/ariths_gen/one_bit_circuits/logic_gates/__pycache__/__init__.cpython-38.pyc b/ariths_gen/one_bit_circuits/logic_gates/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..e523ad7 Binary files /dev/null and b/ariths_gen/one_bit_circuits/logic_gates/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/one_bit_circuits/logic_gates/__pycache__/logic_gates.cpython-38.pyc b/ariths_gen/one_bit_circuits/logic_gates/__pycache__/logic_gates.cpython-38.pyc new file mode 100644 index 0000000..1138bb1 Binary files /dev/null and b/ariths_gen/one_bit_circuits/logic_gates/__pycache__/logic_gates.cpython-38.pyc differ diff --git a/logic_gates.py b/ariths_gen/one_bit_circuits/logic_gates/logic_gates.py similarity index 83% rename from logic_gates.py rename to ariths_gen/one_bit_circuits/logic_gates/logic_gates.py index eb3a869..97993d6 100644 --- a/logic_gates.py +++ b/ariths_gen/one_bit_circuits/logic_gates/logic_gates.py @@ -1,13 +1,13 @@ -from wire_components import wire +from ariths_gen.wire_components import Wire """ LOGIC GATE COMPONENTS """ # Two-input # -class logic_gate(): - def __init__(self, a: wire, b: wire, prefix: str = "gate"): - self.a = wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value) - self.b = wire(name=prefix+"_"+b.name.replace(prefix+"_", ""), value=b.value) +class LogicGate(): + def __init__(self, a: Wire, b: Wire, prefix: str = "gate"): + self.a = Wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value) + self.b = Wire(name=prefix+"_"+b.name.replace(prefix+"_", ""), value=b.value) self.prefix = prefix def get_component_types(self): @@ -46,7 +46,7 @@ class logic_gate(): # HIERARCHICAL C # def get_function_block_c(self): - gate_block = not_gate(a=wire(name="a")) if isinstance(self, not_gate) else type(self)(a=wire(name="a"), b=wire(name="b")) + gate_block = NotGate(a=Wire(name="a")) if isinstance(self, NotGate) else type(self)(a=Wire(name="a"), b=Wire(name="b")) return f"{gate_block.get_prototype_c()}" + \ f" return "+(gate_block.get_function_c())+";\n}\n\n" @@ -55,7 +55,7 @@ class logic_gate(): b_name = self.b.name.replace(self.prefix+"_", "") if remove_prefix is True else self.b.name return f"{self.gate_type}({a_name}, {b_name});\n" - def get_gate_output_c(self, a: wire, b: wire, offset: int = 0): + def get_gate_output_c(self, a: Wire, b: Wire, offset: int = 0): return f"({self.gate_type}({a.name}, {b.name}) & 0x01) << {offset}" """ VERILOG CODE GENERATION """ @@ -84,7 +84,7 @@ class logic_gate(): # HIERARCHICAL VERILOG # def get_function_block_v(self): - gate_block = not_gate(a=wire(name="a")) if isinstance(self, not_gate) else type(self)(a=wire(name="a"), b=wire(name="b")) + gate_block = NotGate(a=Wire(name="a")) if isinstance(self, NotGate) else type(self)(a=Wire(name="a"), b=Wire(name="b")) return f"{gate_block.get_prototype_v()}" + \ f" assign {gate_block.out.name} = {gate_block.get_init_v_flat()};\n" + \ f"endmodule\n\n" @@ -119,7 +119,7 @@ class logic_gate(): # HIERARCHICAL BLIF # def get_function_block_blif(self): - gate_block = not_gate(a=wire(name="a")) if isinstance(self, not_gate) else type(self)(a=wire(name="a"), b=wire(name="b")) + gate_block = NotGate(a=Wire(name="a")) if isinstance(self, NotGate) else type(self)(a=Wire(name="a"), b=Wire(name="b")) return f"{gate_block.get_prototype_blif()}" + \ f"{gate_block.get_declaration_blif()}" + \ f"{gate_block.get_function_blif_flat()}" + \ @@ -153,8 +153,8 @@ class logic_gate(): file_object.close() -class inverted_logic_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "gate"): +class InvertedLogicGate(LogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "gate"): super().__init__(a, b, prefix) """ C CODE GENERATION """ @@ -171,13 +171,13 @@ class inverted_logic_gate(logic_gate): return "~("+(super().get_init_v_flat())+")" -class and_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): +class AndGate(LogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "and_gate" self.cgp_function = 2 self.operator = "&" - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ BLIF CODE GENERATION """ def get_function_blif_flat(self): @@ -185,13 +185,13 @@ class and_gate(logic_gate): f"11 1\n" -class nand_gate(inverted_logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): +class NandGate(InvertedLogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "nand_gate" self.cgp_function = 5 self.operator = "&" - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ BLIF CODE GENERATION """ def get_function_blif_flat(self): @@ -199,13 +199,13 @@ class nand_gate(inverted_logic_gate): f"0- 1\n-0 1\n" -class or_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): +class OrGate(LogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "or_gate" self.cgp_function = 3 self.operator = "|" - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ BLIF CODE GENERATION """ def get_function_blif_flat(self): @@ -213,13 +213,13 @@ class or_gate(logic_gate): f"1- 1\n-1 1\n" -class nor_gate(inverted_logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): +class NorGate(InvertedLogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "nor_gate" self.cgp_function = 6 self.operator = "|" - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ BLIF CODE GENERATION """ def get_function_blif_flat(self): @@ -227,13 +227,13 @@ class nor_gate(inverted_logic_gate): f"00 1\n" -class xor_gate(logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): +class XorGate(LogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "xor_gate" self.cgp_function = 4 self.operator = "^" - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ BLIF CODE GENERATION """ def get_function_blif_flat(self): @@ -241,13 +241,13 @@ class xor_gate(logic_gate): f"01 1\n10 1\n" -class xnor_gate(inverted_logic_gate): - def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0): +class XnorGate(InvertedLogicGate): + def __init__(self, a: Wire, b: Wire, prefix: str = "", outid: int = 0): super().__init__(a, b, prefix) self.gate_type = "xnor_gate" self.cgp_function = 7 self.operator = "^" - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ BLIF CODE GENERATION """ def get_function_blif_flat(self): @@ -256,14 +256,14 @@ class xnor_gate(inverted_logic_gate): # Single-input # -class not_gate(inverted_logic_gate): - def __init__(self, a: wire, prefix: str = "", outid: int = 0): +class NotGate(InvertedLogicGate): + def __init__(self, a: Wire, prefix: str = "", outid: int = 0): self.gate_type = "not_gate" self.cgp_function = 1 self.operator = "~" - self.a = wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value) + self.a = Wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value) self.prefix = prefix - self.out = wire(name=prefix+"_y"+str(outid)) + self.out = Wire(name=prefix+"_y"+str(outid)) """ C CODE GENERATION """ # FLAT C # @@ -288,7 +288,7 @@ class not_gate(inverted_logic_gate): a_name = self.a.name.replace(self.prefix+"_", "") if remove_prefix is True else self.a.name return f"{self.gate_type}({a_name});" - def get_gate_output_c(self, a: wire, offset: int = 0): + def get_gate_output_c(self, a: Wire, offset: int = 0): return f"({self.gate_type}({a.name}) & 0x01) << {offset}" """ VERILOG CODE GENERATION """ diff --git a/ariths_gen/one_bit_circuits/one_bit_components/__init__.py b/ariths_gen/one_bit_circuits/one_bit_components/__init__.py new file mode 100644 index 0000000..bfd86a0 --- /dev/null +++ b/ariths_gen/one_bit_circuits/one_bit_components/__init__.py @@ -0,0 +1,12 @@ +from typing import FrozenSet +from .two_input_one_bit_components import ( + HalfAdder, + PGLogicBlock, + ConstantWireValue0, + ConstantWireValue1 +) + +from .three_input_one_bit_components import( + FullAdder, + FullAdderPG +) \ No newline at end of file diff --git a/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/__init__.cpython-38.pyc b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..c716d2a Binary files /dev/null and b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/one_bit_circuits.cpython-38.pyc b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/one_bit_circuits.cpython-38.pyc new file mode 100644 index 0000000..a52f932 Binary files /dev/null and b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/one_bit_circuits.cpython-38.pyc differ diff --git a/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/three_input_one_bit_components.cpython-38.pyc b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/three_input_one_bit_components.cpython-38.pyc new file mode 100644 index 0000000..27b7c61 Binary files /dev/null and b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/three_input_one_bit_components.cpython-38.pyc differ diff --git a/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/two_input_one_bit_components.cpython-38.pyc b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/two_input_one_bit_components.cpython-38.pyc new file mode 100644 index 0000000..5067e79 Binary files /dev/null and b/ariths_gen/one_bit_circuits/one_bit_components/__pycache__/two_input_one_bit_components.cpython-38.pyc differ diff --git a/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py b/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py new file mode 100644 index 0000000..357af28 --- /dev/null +++ b/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py @@ -0,0 +1,72 @@ +from ariths_gen.core import ThreeInputOneBitCircuit +from ariths_gen.one_bit_circuits.logic_gates import LogicGate, AndGate, NandGate, OrGate, NorGate, XorGate, XnorGate, NotGate +from ariths_gen.wire_components import Wire, Bus + +# THREE INPUT CIRCUITS +class FullAdder(ThreeInputOneBitCircuit): + def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa"): + super().__init__() + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + self.c = c + # 2 wires for component's bus output (sum, cout) + self.out = Bus("out", self.N+1) + + # PG logic + propagate_xor = XorGate(a, b, prefix=self.prefix, outid=0) + self.add_component(propagate_xor) + generate_and = AndGate(a, b, prefix=self.prefix, outid=1) + self.add_component(generate_and) + + # Sum + # XOR gate for calculation of 1-bit sum + obj_xor = XorGate(propagate_xor.out, c, prefix=self.prefix, outid=2) + self.add_component(obj_xor) + self.out.connect(0, obj_xor.out) + + # Cout + # AND gate for calculation of 1-bit cout + obj_and = AndGate(propagate_xor.out, c, prefix=self.prefix, outid=3) + self.add_component(obj_and) + + obj_or = OrGate(generate_and.out, obj_and.out, prefix=self.prefix, outid=4) + self.add_component(obj_or) + + self.out.connect(1, obj_or.out) + + +class FullAdderPG(ThreeInputOneBitCircuit): + def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa_cla"): + super().__init__() + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + self.c = c + # 3 wires for component's bus output (sum, propagate, generate) + self.out = Bus("out", self.N+2) + + # PG logic + propagate_xor = XorGate(a, b, prefix=self.prefix, outid=0) + self.add_component(propagate_xor) + self.out.connect(0, propagate_xor.out) + + generate_and = AndGate(a, b, prefix=self.prefix, outid=1) + self.add_component(generate_and) + self.out.connect(1, generate_and.out) + + # Sum output + sum_xor = XorGate(propagate_xor.out, c, prefix=self.prefix, outid=2) + self.add_component(sum_xor) + self.out.connect(2, sum_xor.out) + + def get_propagate_wire(self): + return self.out.get_wire(0) + + def get_generate_wire(self): + return self.out.get_wire(1) + + def get_sum_wire(self): + return self.out.get_wire(2) \ No newline at end of file diff --git a/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py b/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py new file mode 100644 index 0000000..a4a0de4 --- /dev/null +++ b/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py @@ -0,0 +1,106 @@ +from ariths_gen.core import TwoInputOneBitCircuit +from ariths_gen.one_bit_circuits.logic_gates import LogicGate, AndGate, NandGate, OrGate, NorGate, XorGate, XnorGate, NotGate +from ariths_gen.wire_components import Wire, Bus + +# TWO INPUT CIRCUITS +class HalfAdder(TwoInputOneBitCircuit): + def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "ha"): + super().__init__() + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + # 2 wires for component's bus output (sum, cout) + self.out = Bus("out", self.N+1) + + # Sum + # XOR gate for calculation of 1-bit sum + obj_xor = XorGate(a, b, prefix=self.prefix, outid=0) + self.add_component(obj_xor) + self.out.connect(0, obj_xor.out) + + # Cout + # AND gate for calculation of 1-bit cout + obj_and = AndGate(a, b, prefix=self.prefix, outid=1) + self.add_component(obj_and) + self.out.connect(1, obj_and.out) + + +class PGLogicBlock(TwoInputOneBitCircuit): + def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "pg_logic"): + super().__init__() + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + # 3 wires for component's bus output (propagate, generate, sum) + self.out = Bus("out", self.N+2) + + # PG logic + propagate_or = OrGate(a, b, prefix=self.prefix, outid=0) + self.add_component(propagate_or) + generate_and = AndGate(a, b, prefix=self.prefix, outid=1) + self.add_component(generate_and) + sum_xor = XorGate(a, b, prefix=self.prefix, outid=2) + self.add_component(sum_xor) + + self.out.connect(0, propagate_or.out) + self.out.connect(1, generate_and.out) + self.out.connect(2, sum_xor.out) + + def get_propagate_wire(self): + return self.out.get_wire(0) + + def get_generate_wire(self): + return self.out.get_wire(1) + + def get_sum_wire(self): + return self.out.get_wire(2) + +class ConstantWireValue0(TwoInputOneBitCircuit): + def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "constant_wire_value_0"): + super().__init__() + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + # 1 wire for component's bus output (constant wire) + self.out = Bus("out", self.N) + + # Generation of wire with constant value 0 + obj_xor = XorGate(self.a, self.b, prefix=self.prefix, outid=0) + obj_xnor = XnorGate(self.a, self.b, prefix=self.prefix, outid=1) + obj_nor = NorGate(obj_xor.out, obj_xnor.out, prefix=self.prefix, outid=2) + obj_nor.out.name = "constant_wire_0" + obj_nor.out.prefix = "constant_wire_0" + + self.add_component(obj_xor) + self.add_component(obj_xnor) + self.add_component(obj_nor) + + # Constant wire output + self.out.connect(0, obj_nor.out) + + +class ConstantWireValue1(TwoInputOneBitCircuit): + def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "constant_wire_value_1"): + super().__init__() + self.c_data_type = "uint8_t" + self.prefix = prefix + self.a = a + self.b = b + # 1 wire for component's bus output (constant wire) + self.out = Bus("out", self.N) + + # Generation of wire with constant value 1 + obj_xor = XorGate(self.a, self.b, prefix=self.prefix, outid=0) + obj_xnor = XnorGate(self.a, self.b, prefix=self.prefix, outid=1) + obj_or = OrGate(obj_xor.out, obj_xnor.out, prefix=self.prefix, outid=2) + obj_or.out.name = "constant_wire_1" + obj_or.out.prefix = "constant_wire_1" + self.add_component(obj_xor) + self.add_component(obj_xnor) + self.add_component(obj_or) + + # Constant wire output + self.out.connect(0, obj_or.out) diff --git a/ariths_gen/wire_components/__init__.py b/ariths_gen/wire_components/__init__.py new file mode 100644 index 0000000..4dd734d --- /dev/null +++ b/ariths_gen/wire_components/__init__.py @@ -0,0 +1,2 @@ +from .wires import Wire +from .buses import Bus \ No newline at end of file diff --git a/ariths_gen/wire_components/__pycache__/__init__.cpython-38.pyc b/ariths_gen/wire_components/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..2ae2734 Binary files /dev/null and b/ariths_gen/wire_components/__pycache__/__init__.cpython-38.pyc differ diff --git a/ariths_gen/wire_components/__pycache__/buses.cpython-38.pyc b/ariths_gen/wire_components/__pycache__/buses.cpython-38.pyc new file mode 100644 index 0000000..ca8a615 Binary files /dev/null and b/ariths_gen/wire_components/__pycache__/buses.cpython-38.pyc differ diff --git a/ariths_gen/wire_components/__pycache__/wires.cpython-38.pyc b/ariths_gen/wire_components/__pycache__/wires.cpython-38.pyc new file mode 100644 index 0000000..4a3597b Binary files /dev/null and b/ariths_gen/wire_components/__pycache__/wires.cpython-38.pyc differ diff --git a/wire_components.py b/ariths_gen/wire_components/buses.py similarity index 53% rename from wire_components.py rename to ariths_gen/wire_components/buses.py index 37d2734..2e338ac 100644 --- a/wire_components.py +++ b/ariths_gen/wire_components/buses.py @@ -1,60 +1,9 @@ -""" WIRE COMPONENTS """ +from .wires import Wire - -class wire(): - def __init__(self, name: str, value: int = 0, index: int = 0): - self.name = name - if self.name.endswith("_"+str(index)): - self.prefix = name[0:int(name.rfind(str(index))-1)] - else: - self.prefix = name - self.value = value - self.index = index - - """ C CODE GENERATION """ - def get_declaration_c(self): - return f" uint8_t {self.name} = {self.value};\n" - - def get_wire_value_c(self, name: str = "", offset: int = 0): - w_name = self.name if name == "" else name - return f"(({w_name} >> {offset}) & 0x01)" - - def get_assign_c(self, name: str): - return f" {self.name} = {name};\n" - - def return_wire_value_c(self, offset: int = 0): - return f"({self.name} & 0x01) << {offset}" - - """ VERILOG CODE GENERATION """ - def get_declaration_v(self): - return f" wire {self.name};\n" - - def get_assign_v(self, name: str, offset: int = 0, array: bool = False): - if array is True: - return f" assign {self.name} = {name}[{offset}];\n" - else: - return f" assign {self.name} = {name};\n" - - """ BLIF CODE GENERATION """ - def get_declaration_blif(self, name: str = "", offset: int = 0, array: bool = False): - if array is True: - return f" {name}[{offset}]" - else: - return f" {self.name}" - - def get_assign_blif(self, name: str, output: bool = False): - if output is True: - return f".names {self.name} {name}\n" + \ - f"1 1\n" - else: - return f".names {name} {self.name}\n" + \ - f"1 1\n" - - -class bus(): +class Bus(): def __init__(self, prefix: str, N: int = 1, wires_list: list = None): if wires_list is None: - self.bus = [wire(name=prefix+"_"+str(i), index=i) for i in range(N)] + self.bus = [Wire(name=prefix+"_"+str(i), index=i) for i in range(N)] self.prefix = prefix self.N = N else: @@ -64,7 +13,7 @@ class bus(): # Connecting output wire of the inner circuit component to the input of another component # (or to the wire of the circuit's output bus) - def connect(self, out_wire_index: int, inner_component_out_wire: wire): + def connect(self, out_wire_index: int, inner_component_out_wire: Wire): self.bus[out_wire_index] = inner_component_out_wire def get_wire(self, wire_index: int = 0): @@ -72,7 +21,7 @@ class bus(): def bus_extend(self, N: int, prefix: str = "bus"): if self.N < N: - self.bus += [wire(name=prefix+"_"+str(i), index=i) for i in range(self.N, N)] + self.bus += [Wire(name=prefix+"_"+str(i), index=i) for i in range(self.N, N)] self.N = N """ C CODE GENERATION """ diff --git a/ariths_gen/wire_components/wires.py b/ariths_gen/wire_components/wires.py new file mode 100644 index 0000000..44b83c6 --- /dev/null +++ b/ariths_gen/wire_components/wires.py @@ -0,0 +1,48 @@ +class Wire(): + def __init__(self, name: str, value: int = 0, index: int = 0): + self.name = name + if self.name.endswith("_"+str(index)): + self.prefix = name[0:int(name.rfind(str(index))-1)] + else: + self.prefix = name + self.value = value + self.index = index + + """ C CODE GENERATION """ + def get_declaration_c(self): + return f" uint8_t {self.name} = {self.value};\n" + + def get_wire_value_c(self, name: str = "", offset: int = 0): + w_name = self.name if name == "" else name + return f"(({w_name} >> {offset}) & 0x01)" + + def get_assign_c(self, name: str): + return f" {self.name} = {name};\n" + + def return_wire_value_c(self, offset: int = 0): + return f"({self.name} & 0x01) << {offset}" + + """ VERILOG CODE GENERATION """ + def get_declaration_v(self): + return f" wire {self.name};\n" + + def get_assign_v(self, name: str, offset: int = 0, array: bool = False): + if array is True: + return f" assign {self.name} = {name}[{offset}];\n" + else: + return f" assign {self.name} = {name};\n" + + """ BLIF CODE GENERATION """ + def get_declaration_blif(self, name: str = "", offset: int = 0, array: bool = False): + if array is True: + return f" {name}[{offset}]" + else: + return f" {self.name}" + + def get_assign_blif(self, name: str, output: bool = False): + if output is True: + return f".names {self.name} {name}\n" + \ + f"1 1\n" + else: + return f".names {name} {self.name}\n" + \ + f"1 1\n" \ No newline at end of file diff --git a/multi_bit_circuits.py b/multi_bit_circuits.py deleted file mode 100644 index 3fb782e..0000000 --- a/multi_bit_circuits.py +++ /dev/null @@ -1,712 +0,0 @@ -from arithmetic_circuits import arithmetic_circuit, multiplier_circuit -from one_bit_circuits import half_adder, full_adder, constant_wire_value_0, constant_wire_value_1, full_adder_pg, pg_logic_block -from logic_gates import logic_gate, and_gate, nand_gate, or_gate, nor_gate, xor_gate, xnor_gate, not_gate -from wire_components import wire, bus - -""" MULTI BIT CIRCUITS """ - - -# ADDERS -class unsigned_ripple_carry_adder(arithmetic_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "u_rca"): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for N sum bits and additional cout bit - self.out = bus("out", self.N+1) - - # Gradual addition of 1-bit adder components - for input_index in range(self.N): - # First adder is a half adder - if input_index == 0: - obj_adder = half_adder(self.a.get_wire(input_index), self.b.get_wire(input_index), prefix=self.prefix+"_ha") - # Rest adders are full adders - else: - obj_adder = full_adder(self.a.get_wire(input_index), self.b.get_wire(input_index), self.get_previous_component().get_carry_wire(), prefix=self.prefix+"_fa"+str(input_index)) - - self.add_component(obj_adder) - self.out.connect(input_index, obj_adder.get_sum_wire()) - if input_index == (self.N-1): - self.out.connect(self.N, obj_adder.get_carry_wire()) - - -class signed_ripple_carry_adder(unsigned_ripple_carry_adder, arithmetic_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "s_rca"): - super().__init__(a=a, b=b, prefix=prefix) - self.c_data_type = "int64_t" - - # Additional XOR gates to ensure correct sign extension in case of sign addition - sign_xor_1 = xor_gate(self.get_previous_component(1).a, self.get_previous_component(1).b, prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(sign_xor_1) - sign_xor_2 = xor_gate(sign_xor_1.out, self.get_previous_component(2).get_carry_wire(), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(sign_xor_2) - self.out.connect(self.N, sign_xor_2.out) - - -class unsigned_pg_ripple_carry_adder(arithmetic_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "u_pg_rca"): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for N sum bits and additional cout bit - self.out = bus("out", self.N+1) - - # Gradual addition of 1-bit adder components - for input_index in range(self.N): - if input_index == 0: - # Constant wire with value 0 for cin 0 - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - obj_fa_cla = full_adder_pg(self.a.get_wire(input_index), self.b.get_wire(input_index), constant_wire_0.out.get_wire(), prefix=self.prefix+"_fa"+str(input_index)) - else: - obj_fa_cla = full_adder_pg(self.a.get_wire(input_index), self.b.get_wire(input_index), self.get_previous_component().out, prefix=self.prefix+"_fa"+str(input_index)) - - self.add_component(obj_fa_cla) - self.out.connect(input_index, obj_fa_cla.get_sum_wire()) - - obj_and = and_gate(self.get_previous_component().c, self.get_previous_component().get_propagate_wire(), prefix=self.prefix+"_and"+str(input_index)) - obj_or = or_gate(obj_and.out, self.get_previous_component().get_generate_wire(), prefix=self.prefix+"_or"+str(input_index)) - self.add_component(obj_and) - self.add_component(obj_or) - - # Connecting last output bit to last cout - if input_index == (self.N-1): - self.out.connect(self.N, obj_or.out) - - -class signed_pg_ripple_carry_adder(unsigned_pg_ripple_carry_adder, arithmetic_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "s_pg_rca"): - super().__init__(a=a, b=b, prefix=prefix) - self.c_data_type = "int64_t" - - # Additional XOR gates to ensure correct sign extension in case of sign addition - sign_xor_1 = xor_gate(self.a.get_wire(self.N-1), self.b.get_wire(self.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(sign_xor_1) - sign_xor_2 = xor_gate(sign_xor_1.out, self.get_previous_component(2).out, prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(sign_xor_2) - self.out.connect(self.N, sign_xor_2.out) - - -class unsigned_carry_lookahead_adder(arithmetic_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "u_cla"): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Lists containing all propagate/generate wires - self.propagate = [] - self.generate = [] - - # Output wires for N sum bits and additional cout bit - self.out = bus("out", self.N+1) - - # Constant wire with value 0 for cin 0 - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - # Used as a first generate wire for obtaining next carry bits - self.generate.append(constant_wire_0.out.get_wire()) - - # Gradual addition of propagate/generate logic blocks and AND/OR gates for Cout bits generation, XOR gates for Sum bits generation - for input_index in range(self.N): - pg_block = pg_logic_block(self.a.get_wire(input_index), self.b.get_wire(input_index), prefix=self.prefix+"_pg_logic"+str(input_index)) - self.propagate.append(pg_block.get_propagate_wire()) - self.generate.append(pg_block.get_generate_wire()) - self.add_component(pg_block) - - if input_index == 0: - obj_sum_xor = xor_gate(pg_block.get_sum_wire(), constant_wire_0.out.get_wire(), prefix=self.prefix+"_xor"+str(input_index)) - self.add_component(obj_sum_xor) - self.out.connect(input_index, obj_sum_xor.out) - - # Carry propagation calculation - obj_and = and_gate(self.propagate[input_index], self.generate[input_index], prefix=self.prefix+"_and"+str(self.get_instance_num(cls=and_gate))) - self.add_component(obj_and) - - # Carry bit generation - obj_cout_or = or_gate(pg_block.get_generate_wire(), self.get_previous_component().out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=or_gate))) - self.add_component(obj_cout_or) - else: - obj_sum_xor = xor_gate(pg_block.get_sum_wire(), self.get_previous_component(2).out, prefix=self.prefix+"_xor"+str(input_index)) - self.add_component(obj_sum_xor) - self.out.connect(input_index, obj_sum_xor.out) - - # For each pg pair values algorithmically combine two input AND gates to replace multiple input gates (resolves fan-in issue) - composite_and_gates = [] - # And combine AND gate pairs into OR gates - composite_or_gates = [] - - # Carry propagation calculation - for g_index in range(len(self.generate)-1): - for p_index in range(g_index, len(self.propagate)): - # No gate to cascade with, add to list - if len(composite_and_gates) == 0: - obj_and = and_gate(self.propagate[p_index], self.generate[g_index], prefix=self.prefix+"_and"+str(self.get_instance_num(cls=and_gate))) - # Combine 2 gates into another one to cascade them - else: - # Create new AND gate - obj_and = and_gate(self.propagate[p_index], self.generate[g_index], prefix=self.prefix+"_and"+str(self.get_instance_num(cls=and_gate))) - self.add_component(obj_and) - - # Combine new gate with previous one stored in list - obj_and = and_gate(self.get_previous_component(1).out, self.get_previous_component(2).out, prefix=self.prefix+"_and"+str(self.get_instance_num(cls=and_gate))) - composite_and_gates.pop(composite_and_gates.index(self.get_previous_component(2))) - - # Add gate to circuit components and to list of composite AND gates for this pg pair value - self.add_component(obj_and) - composite_and_gates.append(obj_and) - - composite_or_gates.append(composite_and_gates.pop()) - - # Final OR gates cascade using generated AND gates representing multiple input AND gates (cascade of multiple two input ones) - for a in range(len(composite_or_gates)-1): - obj_or = or_gate(self.get_previous_component().out, composite_or_gates[a].out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=or_gate))) - self.add_component(obj_or) - - # Carry bit generation - obj_cout_or = or_gate(pg_block.get_generate_wire(), self.get_previous_component().out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=or_gate))) - self.add_component(obj_cout_or) - - # Connecting last output bit to last cout - if input_index == (self.N-1): - self.out.connect(self.N, obj_cout_or.out) - - -class signed_carry_lookahead_adder(unsigned_carry_lookahead_adder, arithmetic_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "s_cla"): - super().__init__(a=a, b=b, prefix=prefix) - self.c_data_type = "int64_t" - - # Additional XOR gates to ensure correct sign extension in case of sign addition - sign_xor_1 = xor_gate(self.a.get_wire(self.N-1), self.b.get_wire(self.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(sign_xor_1) - sign_xor_2 = xor_gate(sign_xor_1.out, self.get_previous_component(2).out, prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(sign_xor_2) - self.out.connect(self.N, sign_xor_2.out) - - -# MULTIPLIERS -class unsigned_array_multiplier(multiplier_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "u_arrmul"): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for multiplication product - self.out = bus("out", self.N*2) - - # Gradual generation of partial products - for b_multiplier_index in range(self.N): - for a_multiplicand_index in range(self.N): - # AND gates generation for calculation of partial products - obj_and = and_gate(self.a.get_wire(a_multiplicand_index), self.b.get_wire(b_multiplier_index), prefix=self.prefix+"_and"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_and) - - if b_multiplier_index != 0: - previous_product = self.components[a_multiplicand_index + b_multiplier_index].out if b_multiplier_index == 1 else self.get_previous_partial_product(a_index=a_multiplicand_index, b_index=b_multiplier_index) - # HA generation for first 1-bit adder in each row starting from the second one - if a_multiplicand_index == 0: - obj_adder = half_adder(self.get_previous_component().out, previous_product, prefix=self.prefix+"_ha"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_adder) - # Product generation - self.out.connect(b_multiplier_index, obj_adder.get_sum_wire()) - - # HA generation, last 1-bit adder in second row - elif a_multiplicand_index == self.N-1 and b_multiplier_index == 1: - obj_adder = half_adder(self.get_previous_component().out, self.get_previous_component(number=2).get_carry_wire(), prefix=self.prefix+"_ha"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_adder) - - # FA generation - else: - obj_adder = full_adder(self.get_previous_component().out, previous_product, self.get_previous_component(number=2).get_carry_wire(), prefix=self.prefix+"_fa"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_adder) - - # PRODUCT GENERATION - if a_multiplicand_index == 0 and b_multiplier_index == 0: - self.out.connect(a_multiplicand_index, obj_and.out) - - # 1 bit multiplier case - if a_multiplicand_index == self.N-1: - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - - self.out.connect(a_multiplicand_index+1, constant_wire_0.out.get_wire()) - - elif b_multiplier_index == self.N-1: - self.out.connect(b_multiplier_index + a_multiplicand_index, obj_adder.get_sum_wire()) - - if a_multiplicand_index == self.N-1: - self.out.connect(self.out.N-1, obj_adder.get_carry_wire()) - - -class signed_array_multiplier(multiplier_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "s_arrmul"): - super().__init__() - self.c_data_type = "int64_t" - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for multiplication product - self.out = bus("out", self.N*2) - - # Generating wire with constant logic value 1 - constant_wire_1 = constant_wire_value_1(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_1) - - # To adjust proper wire connection between adders and AND/NAND gates - # we add offset equal to first block in circuits components list (used for generation of wire with constant value 1) - components_offset = 1 - - # Gradual generation of partial products - for b_multiplier_index in range(self.N): - for a_multiplicand_index in range(self.N): - # AND and NAND gates generation for calculation of partial products and sign extension - if (b_multiplier_index == self.N-1 and a_multiplicand_index != self.N-1) or (b_multiplier_index != self.N-1 and a_multiplicand_index == self.N-1): - obj_nand = nand_gate(self.a.get_wire(a_multiplicand_index), self.b.get_wire(b_multiplier_index), prefix=self.prefix+"_nand"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_nand) - else: - obj_and = and_gate(self.a.get_wire(a_multiplicand_index), self.b.get_wire(b_multiplier_index), prefix=self.prefix+"_and"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_and) - - if b_multiplier_index != 0: - previous_product = self.components[a_multiplicand_index + b_multiplier_index + components_offset].out if b_multiplier_index == 1 else self.get_previous_partial_product(a_index=a_multiplicand_index, b_index=b_multiplier_index, offset=components_offset) - # HA generation for first 1-bit adder in each row starting from the second one - if a_multiplicand_index == 0: - obj_adder = half_adder(self.get_previous_component().out, previous_product, prefix=self.prefix+"_ha"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_adder) - # Product generation - self.out.connect(b_multiplier_index, obj_adder.get_sum_wire()) - - # FA generation - else: - if a_multiplicand_index == self.N-1 and b_multiplier_index == 1: - previous_product = constant_wire_1.out.get_wire() - - obj_adder = full_adder(self.get_previous_component().out, previous_product, self.get_previous_component(number=2).get_carry_wire(), prefix=self.prefix+"_fa"+str(a_multiplicand_index)+"_"+str(b_multiplier_index)) - self.add_component(obj_adder) - - # PRODUCT GENERATION - if a_multiplicand_index == 0 and b_multiplier_index == 0: - self.out.connect(a_multiplicand_index, obj_and.out) - - # 1 bit multiplier case - if a_multiplicand_index == self.N-1: - obj_nor = nor_gate(constant_wire_1.out.get_wire(), self.get_previous_component().out, prefix=self.prefix+"_nor_zero_extend") - self.add_component(obj_nor) - - self.out.connect(a_multiplicand_index+1, obj_nor.out) - - elif b_multiplier_index == self.N-1: - self.out.connect(b_multiplier_index + a_multiplicand_index, obj_adder.get_sum_wire()) - - if a_multiplicand_index == self.N-1: - obj_xor = xor_gate(self.get_previous_component().get_carry_wire(), constant_wire_1.out.get_wire(), prefix=self.prefix+"_xor"+str(a_multiplicand_index+1)+"_"+str(b_multiplier_index)) - self.add_component(obj_xor) - - self.out.connect(self.out.N-1, obj_xor.out) - - -class unsigned_wallace_multiplier(multiplier_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "u_wallace_rca", unsigned_adder_class_name: str = unsigned_ripple_carry_adder): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for multiplication product - self.out = bus("out", self.N*2) - - # Initialize all columns partial products forming AND gates matrix - self.columns = self.init_column_heights() - - # Perform reduction until all columns have 2 or less bits in them - while not all(height <= 2 for (height, *_) in self.columns): - col = 0 - while col < len(self.columns): - # If column has exactly 3 bits in height and all previous columns has maximum of 2 bits in height, combine them in a half adder - if self.get_column_height(col) == 3 and all(height <= 2 for (height, *_) in self.columns[0:col-1]): - # Add half adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = half_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add ha's generated sum to the bottom of current column - # add ha's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - - # If column has more than 3 bits in height, combine them in a full adder - elif self.get_column_height(col) > 3: - # Add full adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = full_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=full_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add fa's generated sum to the bottom of current column - # add fa's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - col += 1 - - # Output generation - # First output bit from single first pp AND gate - self.out.connect(0, self.get_column_wire(column=0, bit=1)) - # Final addition of remaining bits - # 1 bit multiplier case - if self.N == 1: - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - self.out.connect(1, constant_wire_0.out.get_wire()) - # 2 bit multiplier case - elif self.N == 2: - obj_ha = half_adder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(1, obj_ha.get_sum_wire()) - - obj_ha = half_adder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(2, obj_ha.get_sum_wire()) - self.out.connect(3, obj_ha.get_carry_wire()) - # Final addition of remaining bits using chosen unsigned multi bit adder - else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) - - adder_a = bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - adder_b = bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") - self.add_component(final_adder) - - [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] - - -class signed_wallace_multiplier(multiplier_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "s_wallace_rca", unsigned_adder_class_name: str = unsigned_ripple_carry_adder): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for multiplication product - self.out = bus("out", self.N*2) - - # Initialize all columns partial products forming AND/NAND gates matrix based on Baugh-Wooley multiplication - self.columns = self.init_column_heights() - - # Generating wire with constant logic value 1 for signed multiplication - # Based on Baugh-Wooley multiplication algorithm - # Not used for 1 bit multiplier - if self.N != 1: - constant_wire_1 = constant_wire_value_1(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_1) - - # Adding constant wire with value 1 to achieve signedness - # (adding constant value bit to last column (with one bit) to combine them in XOR gate to get the correct final multplication output bit at the end) - self.columns[self.N].insert(1, constant_wire_1.out.get_wire()) - self.update_column_heights(curr_column=self.N, curr_height_change=1) - - # Perform reduction until all columns have 2 or less bits in them - while not all(height <= 2 for (height, *_) in self.columns): - col = 0 - while col < len(self.columns): - # If column has exactly 3 bits in height and all previous columns has maximum of 2 bits in height, combine them in a half adder - if self.get_column_height(col) == 3 and all(height <= 2 for (height, *_) in self.columns[0:col-1]): - # Add half adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = half_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add ha's generated sum to the bottom of current column - # add ha's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - - # If column has more than 3 bits in height, combine them in a full adder - elif self.get_column_height(col) > 3: - # Add full adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = full_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=full_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add fa's generated sum to the bottom of current column - # add fa's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - col += 1 - - # Output generation - # First output bit from single first pp AND gate - self.out.connect(0, self.get_column_wire(column=0, bit=1)) - # Final addition of remaining bits - # 1 bit multiplier case - if self.N == 1: - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - self.out.connect(1, constant_wire_0.out.get_wire()) - return - # 2 bit multiplier case - elif self.N == 2: - obj_ha = half_adder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(1, obj_ha.get_sum_wire()) - - obj_ha = half_adder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(2, obj_ha.get_sum_wire()) - self.out.connect(3, obj_ha.get_carry_wire()) - # Final addition of remaining bits using chosen unsigned multi bit adder - else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) - - adder_a = bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - adder_b = bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") - self.add_component(final_adder) - - [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] - - # Final XOR to ensure proper sign extension - obj_xor = xor_gate(constant_wire_1.out.get_wire(), self.out.get_wire(self.out.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(obj_xor) - self.out.connect(self.out.N-1, obj_xor.out) - -class unsigned_dadda_multiplier(multiplier_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "u_dadda_rca", unsigned_adder_class_name: str = unsigned_ripple_carry_adder): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for multiplication product - self.out = bus("out", self.N*2) - - # Get starting stage and maximum possible column height - self.stage, self.d = self.get_maximum_height(initial_value=min(self.a.N, self.b.N)) - # Initialize all columns partial products forming AND gates matrix - self.columns = self.init_column_heights() - - # Perform reduction until stage 0 - for stage in range(self.stage, 0, -1): - col = 0 - while col < len(self.columns): - if self.get_column_height(col) == self.d + 1: - # Add half adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = half_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add ha's generated sum to the bottom of current column - # add ha's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - - elif self.get_column_height(col) > self.d: - # Add full adder and also AND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = full_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=full_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add fa's generated sum to the bottom of current column - # add fa's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - - # Next iteration with same column in case there is need for further reduction - col -= 1 - col += 1 - # Update maximum possible column height - _, self.d = self.get_maximum_height(stage) - - # Output generation - # First output bit from single first pp AND gate - self.out.connect(0, self.get_column_wire(column=0, bit=1)) - # Final addition of remaining bits - # 1 bit multiplier case - if self.N == 1: - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - self.out.connect(1, constant_wire_0.out.get_wire()) - # 2 bit multiplier case - elif self.N == 2: - obj_ha = half_adder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(1, obj_ha.get_sum_wire()) - - obj_ha = half_adder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(2, obj_ha.get_sum_wire()) - self.out.connect(3, obj_ha.get_carry_wire()) - # Final addition of remaining bits using chosen unsigned multi bit adder - else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) - - adder_a = bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - adder_b = bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") - self.add_component(final_adder) - - [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] - - -class signed_dadda_multiplier(multiplier_circuit): - def __init__(self, a: bus, b: bus, prefix: str = "s_dadda_rca", unsigned_adder_class_name: str = unsigned_ripple_carry_adder): - super().__init__() - self.N = max(a.N, b.N) - self.prefix = prefix - self.a = bus(prefix=a.prefix, wires_list=a.bus) - self.b = bus(prefix=b.prefix, wires_list=b.bus) - - # Bus sign extension in case buses have different lengths - self.a.bus_extend(N=self.N, prefix=a.prefix) - self.b.bus_extend(N=self.N, prefix=b.prefix) - - # Output wires for multiplication product - self.out = bus("out", self.N*2) - - # Get starting stage and maximum possible column height - self.stage, self.d = self.get_maximum_height(initial_value=min(self.a.N, self.b.N)) - # Initialize all columns partial products forming AND/NAND gates matrix based on Baugh-Wooley multiplication - self.columns = self.init_column_heights() - - # Generating wire with constant logic value 1 for signed multiplication - # Based on Baugh-Wooley multiplication algorithm - # Not used for 1 bit multiplier - if self.N != 1: - constant_wire_1 = constant_wire_value_1(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_1) - - # Adding constant wire with value 1 to achieve signedness - # (adding constant value bit to last column (with one bit) to combine them in XOR gate to get the correct final multplication output bit at the end) - self.columns[self.N].insert(1, constant_wire_1.out.get_wire()) - self.update_column_heights(curr_column=self.N, curr_height_change=1) - - # Perform reduction until stage 0 - for stage in range(self.stage, 0, -1): - col = 0 - while col < len(self.columns): - if self.get_column_height(col) == self.d + 1: - # Add half adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = half_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-1, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add ha's generated sum to the bottom of current column - # add ha's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - elif self.get_column_height(col) > self.d: - # Add full adder and also AND/NAND gates if neccesarry (via get_column_wire invocation) into list of circuit components - obj_adder = full_adder(self.get_column_wire(column=col, bit=1), self.get_column_wire(column=col, bit=2), self.get_column_wire(column=col, bit=3), prefix=self.prefix+"_fa"+str(self.get_instance_num(cls=full_adder))) - self.add_component(obj_adder) - - # Update the number of current and next column wires - self.update_column_heights(curr_column=col, curr_height_change=-2, next_column=col+1, next_height_change=1) - - # Update current and next column wires arrangement - # add fa's generated sum to the bottom of current column - # add fa's generated cout to the top of next column - self.update_column_wires(curr_column=col, next_column=col+1, adder=self.get_previous_component(1)) - # Next iteration with same column in case there is need for further reduction - col -= 1 - col += 1 - # Update maximum possible column height - _, self.d = self.get_maximum_height(stage) - - # Output generation - # First output bit from single first pp AND gate - self.out.connect(0, self.get_column_wire(column=0, bit=1)) - # Final addition of remaining bits - # 1 bit multiplier case (no sign extension) - if self.N == 1: - constant_wire_0 = constant_wire_value_0(self.a.get_wire(), self.b.get_wire()) - self.add_component(constant_wire_0) - self.out.connect(1, constant_wire_0.out.get_wire()) - return - # 2 bit multiplier case - elif self.N == 2: - obj_ha = half_adder(self.get_column_wire(column=1, bit=1), self.get_column_wire(column=1, bit=2), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(1, obj_ha.get_sum_wire()) - - obj_ha = half_adder(self.get_previous_component().get_carry_wire(), self.get_column_wire(column=2, bit=1), prefix=self.prefix+"_ha"+str(self.get_instance_num(cls=half_adder))) - self.add_component(obj_ha) - self.out.connect(2, obj_ha.get_sum_wire()) - self.out.connect(3, obj_ha.get_carry_wire()) - # Final addition of remaining bits using chosen unsigned multi bit adder - else: - # Obtain proper adder name with its bit width (columns bit pairs minus the first alone bit) - adder_prefix = unsigned_adder_class_name(a=a , b=b).prefix + str(len(self.columns)-1) - - adder_a = bus(prefix=f"{adder_prefix}_a", wires_list=[self.get_column_wire(column=col, bit=1) for col in range(1, len(self.columns))]) - adder_b = bus(prefix=f"{adder_prefix}_b", wires_list=[self.get_column_wire(column=col, bit=2) for col in range(1, len(self.columns))]) - final_adder = unsigned_adder_class_name(a=adder_a, b=adder_b, prefix=self.prefix+f"_{adder_prefix}") - self.add_component(final_adder) - - [self.out.connect(o, final_adder.out.get_wire(o-1)) for o in range(1, len(self.out.bus))] - - # Final XOR to ensure proper sign extension - obj_xor = xor_gate(constant_wire_1.out.get_wire(), self.out.get_wire(self.out.N-1), prefix=self.prefix+"_xor"+str(self.get_instance_num(cls=xor_gate))) - self.add_component(obj_xor) - self.out.connect(self.out.N-1, obj_xor.out) diff --git a/one_bit_circuits.py b/one_bit_circuits.py deleted file mode 100644 index 8cc53fd..0000000 --- a/one_bit_circuits.py +++ /dev/null @@ -1,371 +0,0 @@ -from arithmetic_circuits import arithmetic_circuit -from logic_gates import logic_gate, and_gate, nand_gate, or_gate, nor_gate, xor_gate, xnor_gate, not_gate -from wire_components import wire, bus - -""" ONE BIT CIRCUITS """ - - -class two_input_one_bit_circuit(arithmetic_circuit): - def __init__(self): - super().__init__() - - """ C CODE GENERATION """ - # FLAT C # - # Obtaining list of all the unique circuit wires from all contained logic gates - # to ensure non-recurring declaration of same wires - def get_declaration_c_flat(self): - self.get_circuit_wires() - # Unique declaration of all circuit's interconnections - return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) - - # Wires values initialization and assignment - def get_init_c_flat(self): - return "".join([i.get_assign_c(name=i.get_wire_value_c(name=i.name.replace(self.prefix+"_",""))) for i in self.inputs]) + \ - "".join([f" {c.out.name} = {c.get_init_c_flat()};\n" for c in self.components]) - - # Generating flat C code representation of circuit - def get_c_code_flat(self, file_object): - file_object.write(self.get_includes_c()) - file_object.write(self.get_prototype_c()) - file_object.write(self.out.get_declaration_c()) - file_object.write(self.get_declaration_c_flat()+"\n") - file_object.write(self.get_init_c_flat()+"\n") - file_object.write(self.get_function_out_c_flat()) - file_object.write(f" return {self.out.prefix}"+";\n}") - file_object.close() - - # HIERARCHICAL C # - # Subcomponent generation - def get_function_block_c(self): - adder_block = self.__class__() - return f"{adder_block.get_circuit_c()}\n\n" - - def get_wire_declaration_c_hier(self): - return f"{self.out.get_wire_declaration_c()}" - - def get_out_invocation_c(self, **kwargs): - circuit_class = self.__class__() - return "".join([f' {o.name} = ({circuit_class.prefix}({self.a.name}, {self.b.name}) >> {self.out.bus.index(o)}) & 0x01;\n' for o in self.out.bus]) - - # Self circuit hierarchical generation - def get_declaration_c_hier(self): - self.get_circuit_wires() - # Unique declaration of all circuit's interconnections - return "".join([c[0].get_declaration_c() for c in self.circuit_wires]) - - def get_init_c_hier(self): - return "".join([i.get_assign_c(name=i.get_wire_value_c(name=i.name.replace(self.prefix+"_",""))) for i in self.inputs]) + \ - "".join([f" {c.out.name} = {c.get_gate_invocation_c(remove_prefix=False)}" for c in self.components]) - - def get_function_out_c_hier(self): - return "".join([f" {self.out.prefix} |= {o.return_wire_value_c(offset=self.out.bus.index(o))};\n" for o in self.out.bus]) - - """ VERILOG CODE GENERATION """ - # FLAT VERILOG # - def get_prototype_v(self): - return f"module {self.prefix}(input {self.a.name}, input {self.b.name}{''.join([f', output {o.name}' for o in self.out.bus])});\n" - - def get_declaration_v_flat(self): - self.get_circuit_wires() - # Unique declaration of all circuit's interconnections - return "".join([c[0].get_declaration_v() for c in self.circuit_wires]) - - # Wires values initialization and assignment - def get_init_v_flat(self): - return "".join([i.get_assign_v(name=i.name.replace(self.prefix+"_","")) for i in self.inputs]) + \ - "".join([f" assign {c.out.name} = {c.get_init_v_flat()};\n" for c in self.components]) - - # Generating flat Verilog code representation of circuit - def get_v_code_flat(self, file_object): - file_object.write(self.get_prototype_v()) - file_object.write(self.get_declaration_v_flat()+"\n") - file_object.write(self.get_init_v_flat()) - file_object.write(f"endmodule") - file_object.close() - - # HIERARCHICAL VERILOG # - # Subcomponent generation - def get_function_block_v(self): - adder_block = self.__class__() - return f"{adder_block.get_circuit_v()}\n\n" - - def get_wire_declaration_v_hier(self): - return f"{self.out.get_wire_declaration_v()}" - - def get_invocation_v(self, **kwargs): - circuit_class = self.__class__() - return f" {circuit_class.prefix} {circuit_class.prefix}_{self.out.get_wire().name}({self.a.name}, {self.b.name}{''.join([f', {o.name}' for o in self.out.bus])});\n" - - # Self circuit hierarchical generation - def get_declaration_v_hier(self): - self.get_circuit_wires() - # Unique declaration of all circuit's interconnections - return "".join([c[0].get_declaration_v() for c in self.circuit_wires if c[0] not in self.out.bus]) - - def get_init_v_hier(self): - return "".join([i.get_assign_v(name=i.name.replace(self.prefix+"_","")) for i in self.inputs]) - - def get_function_out_v_hier(self): - return "".join([f"{c.get_gate_invocation_v(remove_prefix=False)}" for c in self.components]) - - """ BLIF CODE GENERATION """ - # FLAT BLIF # - def get_declaration_blif(self): - return f".inputs {self.a.name} {self.b.name}\n" + \ - f".outputs{self.out.get_wire_declaration_blif(array=False)}\n" - - def get_wire_mapping_blif(self): - # For unique mapping of all circuit's input interconnections - self.get_circuit_wires() - return "".join([i.get_assign_blif(name=i.name.replace(self.prefix+"_","")) for i in self.inputs]) - - def get_function_blif_flat(self): - return f"{self.get_wire_mapping_blif()}"+"".join([c.get_function_blif_flat() for c in self.components]) - - def get_function_out_blif(self): - return f"" - - # HIERARCHICAL BLIF # - # Subcomponent generation - def get_function_block_blif(self): - adder_block = self.__class__() - return f"{adder_block.get_circuit_blif()}" - - def get_invocation_blif_hier(self, **kwargs): - circuit_class = self.__class__() - return f"{self.get_wire_mapping_blif()}" + \ - f".subckt {circuit_class.prefix} a={self.inputs[0].name} b={self.inputs[1].name}{''.join([f' {o.name}={self.out.get_wire(circuit_class.out.bus.index(o)).name}' for o in circuit_class.out.bus])}\n" - - # Self circuit hierarchical generation - def get_function_blif_hier(self): - return f"{self.get_wire_mapping_blif()}"+"".join(c.get_invocation_blif_hier(init=False) for c in self.components) - - """ CGP CODE GENERATION """ - # FLAT CGP # - def get_parameters_cgp(self): - self.circuit_gates = self.get_circuit_gates() - return f"{{2,2,1,{len(self.circuit_gates)},2,1,0}}" - - -class three_input_one_bit_circuit(two_input_one_bit_circuit): - def __init__(self): - super().__init__() - - """ C CODE GENERATION """ - # FLAT C # - # Function prototype with three inputs - def get_prototype_c(self): - return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.prefix}, {self.c_data_type} {self.b.prefix}, {self.c_data_type} {self.c.prefix})" + "{" + "\n" - - # HIERARCHICAL C # - # Subcomponent generation (3 inputs) - def get_out_invocation_c(self, **kwargs): - circuit_class = self.__class__() - return "".join([f' {o.name} = ({circuit_class.prefix}({self.a.name}, {self.b.name}, {self.c.name}) >> {self.out.bus.index(o)}) & 0x01;\n' for o in self.out.bus]) - - """ VERILOG CODE GENERATION """ - # FLAT VERILOG # - # Module prototype with three inputs - def get_prototype_v(self): - return f"module {self.prefix}(input {self.a.name}, input {self.b.name}, input {self.c.name}{''.join([f', output {o.name}' for o in self.out.bus])});\n" - - # HIERARCHICAL VERILOG # - # Subcomponent generation (3 inputs) - def get_invocation_v(self, **kwargs): - circuit_class = self.__class__() - return f" {circuit_class.prefix} {circuit_class.prefix}_{self.out.get_wire().name}({self.a.name}, {self.b.name}, {self.c.name}{''.join([f', {o.name}' for o in self.out.bus])});\n" - - """ BLIF CODE GENERATION """ - # FLAT BLIF # - # Model prototype with three inputs - def get_declaration_blif(self): - return f".inputs {self.a.name} {self.b.name} {self.c.name}\n" + \ - f".outputs{self.out.get_wire_declaration_blif(array=False)}\n" - - # HIERARCHICAL BLIF # - # Subcomponent generation (3 inputs) - def get_invocation_blif_hier(self, **kwargs): - circuit_class = self.__class__() - return f"{self.get_wire_mapping_blif()}" + \ - f".subckt {circuit_class.prefix} a={self.inputs[0].name} b={self.inputs[1].name} cin={self.inputs[2].name}{''.join([f' {o.name}={self.out.get_wire(circuit_class.out.bus.index(o)).name}' for o in circuit_class.out.bus])}\n" - - """ CGP CODE GENERATION """ - # FLAT CGP # - # Chromosome prototype with three inputs - def get_parameters_cgp(self): - self.circuit_gates = self.get_circuit_gates() - return f"{{3,2,1,{len(self.circuit_gates)},2,1,0}}" - - -# TWO INPUT CIRCUITS -class half_adder(two_input_one_bit_circuit): - def __init__(self, a: wire = wire(name="a"), b: wire = wire(name="b"), prefix: str = "ha"): - super().__init__() - self.c_data_type = "uint8_t" - self.prefix = prefix - self.a = a - self.b = b - # 2 wires for component's bus output (sum, cout) - self.out = bus("out", self.N+1) - - # Sum - # XOR gate for calculation of 1-bit sum - obj_xor = xor_gate(a, b, prefix=self.prefix, outid=0) - self.add_component(obj_xor) - self.out.connect(0, obj_xor.out) - - # Cout - # AND gate for calculation of 1-bit cout - obj_and = and_gate(a, b, prefix=self.prefix, outid=1) - self.add_component(obj_and) - self.out.connect(1, obj_and.out) - - -class pg_logic_block(two_input_one_bit_circuit): - def __init__(self, a: wire = wire(name="a"), b: wire = wire(name="b"), prefix: str = "pg_logic"): - super().__init__() - self.c_data_type = "uint8_t" - self.prefix = prefix - self.a = a - self.b = b - # 3 wires for component's bus output (propagate, generate, sum) - self.out = bus("out", self.N+2) - - # PG logic - propagate_or = or_gate(a, b, prefix=self.prefix, outid=0) - self.add_component(propagate_or) - generate_and = and_gate(a, b, prefix=self.prefix, outid=1) - self.add_component(generate_and) - sum_xor = xor_gate(a, b, prefix=self.prefix, outid=2) - self.add_component(sum_xor) - - self.out.connect(0, propagate_or.out) - self.out.connect(1, generate_and.out) - self.out.connect(2, sum_xor.out) - - def get_propagate_wire(self): - return self.out.get_wire(0) - - def get_generate_wire(self): - return self.out.get_wire(1) - - def get_sum_wire(self): - return self.out.get_wire(2) - -class constant_wire_value_0(two_input_one_bit_circuit): - def __init__(self, a: wire = wire(name="a"), b: wire = wire(name="b"), prefix: str = "constant_wire_value_0"): - super().__init__() - self.c_data_type = "uint8_t" - self.prefix = prefix - self.a = a - self.b = b - # 1 wire for component's bus output (constant wire) - self.out = bus("out", self.N) - - # Generation of wire with constant value 0 - obj_xor = xor_gate(self.a, self.b, prefix=self.prefix, outid=0) - obj_xnor = xnor_gate(self.a, self.b, prefix=self.prefix, outid=1) - obj_nor = nor_gate(obj_xor.out, obj_xnor.out, prefix=self.prefix, outid=2) - obj_nor.out.name = "constant_wire_0" - obj_nor.out.prefix = "constant_wire_0" - - self.add_component(obj_xor) - self.add_component(obj_xnor) - self.add_component(obj_nor) - - # Constant wire output - self.out.connect(0, obj_nor.out) - - -class constant_wire_value_1(two_input_one_bit_circuit): - def __init__(self, a: wire = wire(name="a"), b: wire = wire(name="b"), prefix: str = "constant_wire_value_1"): - super().__init__() - self.c_data_type = "uint8_t" - self.prefix = prefix - self.a = a - self.b = b - # 1 wire for component's bus output (constant wire) - self.out = bus("out", self.N) - - # Generation of wire with constant value 1 - obj_xor = xor_gate(self.a, self.b, prefix=self.prefix, outid=0) - obj_xnor = xnor_gate(self.a, self.b, prefix=self.prefix, outid=1) - obj_or = or_gate(obj_xor.out, obj_xnor.out, prefix=self.prefix, outid=2) - obj_or.out.name = "constant_wire_1" - obj_or.out.prefix = "constant_wire_1" - self.add_component(obj_xor) - self.add_component(obj_xnor) - self.add_component(obj_or) - - # Constant wire output - self.out.connect(0, obj_or.out) - - -# THREE INPUT CIRCUITS -class full_adder(three_input_one_bit_circuit): - def __init__(self, a: wire = wire(name="a"), b: wire = wire(name="b"), c: wire = wire(name="cin"), prefix: str = "fa"): - super().__init__() - self.c_data_type = "uint8_t" - self.prefix = prefix - self.a = a - self.b = b - self.c = c - # 2 wires for component's bus output (sum, cout) - self.out = bus("out", self.N+1) - - # PG logic - propagate_xor = xor_gate(a, b, prefix=self.prefix, outid=0) - self.add_component(propagate_xor) - generate_and = and_gate(a, b, prefix=self.prefix, outid=1) - self.add_component(generate_and) - - # Sum - # XOR gate for calculation of 1-bit sum - obj_xor = xor_gate(propagate_xor.out, c, prefix=self.prefix, outid=2) - self.add_component(obj_xor) - self.out.connect(0, obj_xor.out) - - # Cout - # AND gate for calculation of 1-bit cout - obj_and = and_gate(propagate_xor.out, c, prefix=self.prefix, outid=3) - self.add_component(obj_and) - - obj_or = or_gate(generate_and.out, obj_and.out, prefix=self.prefix, outid=4) - self.add_component(obj_or) - - self.out.connect(1, obj_or.out) - - -class full_adder_pg(three_input_one_bit_circuit): - def __init__(self, a: wire = wire(name="a"), b: wire = wire(name="b"), c: wire = wire(name="cin"), prefix: str = "fa_cla"): - super().__init__() - self.c_data_type = "uint8_t" - self.prefix = prefix - self.a = a - self.b = b - self.c = c - # 3 wires for component's bus output (sum, propagate, generate) - self.out = bus("out", self.N+2) - - # PG logic - propagate_xor = xor_gate(a, b, prefix=self.prefix, outid=0) - self.add_component(propagate_xor) - self.out.connect(0, propagate_xor.out) - - generate_and = and_gate(a, b, prefix=self.prefix, outid=1) - self.add_component(generate_and) - self.out.connect(1, generate_and.out) - - # Sum output - sum_xor = xor_gate(propagate_xor.out, c, prefix=self.prefix, outid=2) - self.add_component(sum_xor) - self.out.connect(2, sum_xor.out) - - def get_propagate_wire(self): - return self.out.get_wire(0) - - def get_generate_wire(self): - return self.out.get_wire(1) - - def get_sum_wire(self): - return self.out.get_wire(2) \ No newline at end of file