{ description = "Packages for synthesizing machine learning hardware modules"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; librelane.url = "github:librelane/librelane/3.0.2"; benchmark-circuits.url = "github:s-holst/benchmark-circuits"; sv2v-src = { url = "github:zachjs/sv2v"; flake = false; }; cvfpu-src = { url = "git+https://github.com/openhwgroup/cvfpu.git?submodules=1"; flake = false; }; }; outputs = { self, nixpkgs, librelane, benchmark-circuits, sv2v-src, cvfpu-src }: let systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; forAllSystems = nixpkgs.lib.genAttrs systems; in { packages = forAllSystems (system: let pkgs = nixpkgs.legacyPackages.${system}; librelane-pkg = librelane.packages.${system}.default; gsclib = benchmark-circuits.packages.${system}.iwls-gsclib; sky130-pdk = benchmark-circuits.packages.${system}.sky130-pdk; sv2v = pkgs.haskell.lib.compose.justStaticExecutables (pkgs.haskell.packages.ghc910.callCabal2nix "sv2v" sv2v-src { }); run-sv2v = {data_width}: '' sed -e 's/default disable iff/\/\/default disable iff/' <$src/src/common_cells/src/rr_arb_tree.sv >rr_arb_tree_patched.sv sv2v \ -I$src/src/common_cells/include \ $src/src/common_cells/src/cf_math_pkg.sv \ $src/src/common_cells/src/lzc.sv \ rr_arb_tree_patched.sv \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/clk/rtl/gated_clk_cell.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_ctrl.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_ff1.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_pack_single.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_prepare.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_round_single.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_special.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_srt_single.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fdsu/rtl/pa_fdsu_top.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fpu/rtl/pa_fpu_dp.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fpu/rtl/pa_fpu_frbus.v \ $src/vendor/opene906/E906_RTL_FACTORY/gen_rtl/fpu/rtl/pa_fpu_src_type.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_ctrl.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_double.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_ff1.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_pack.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_prepare.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_round.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_scalar_dp.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_srt_radix16_bound_table.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_srt_radix16_with_sqrt.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_srt.v \ $src/vendor/openc910/C910_RTL_FACTORY/gen_rtl/vfdsu/rtl/ct_vfdsu_top.v \ $src/src/fpnew_pkg.sv \ $src/src/fpnew_cast_multi.sv \ $src/src/fpnew_divsqrt_th_64_multi.sv \ $src/src/fpnew_opgroup_multifmt_slice.sv \ $src/src/fpnew_noncomp.sv \ $src/src/fpnew_rounding.sv \ $src/src/fpnew_classifier.sv \ $src/src/fpnew_fma.sv \ $srcExtra/fma_float${toString data_width}.sv | sed -e 's/\$finish/\/\/\$finish/; s/\(initial \)*\$display/\/\/\$display/' > top.v ''; run-yosys = {verilog_file ? "top.v", data_width ? 0, sum_width ? 0}: '' yosys <out.log 2>&1 # Read design read_verilog ${verilog_file} hierarchy -check -top top '' + (if data_width > 0 then "-chparam DATA_WIDTH ${toString data_width}" else "") + (if sum_width > 0 then "-chparam SUM_WIDTH ${toString sum_width}" else "") + '' # Coarse-grain synthesis flatten; proc; memory; opt; fsm; opt; # FSM pass re-codes states wreduce; opt; splitnets; opt; # Technology mapping techmap; opt; clean; dfflibmap -liberty ${gsclib}/GSCLib_3.0.lib abc -liberty ${gsclib}/GSCLib_3.0.lib opt_clean # Write netlist write_verilog -noattr nl.v EOF ''; run-librelane = {verilog_file ? "top.v", data_width ? 0, sum_width ? 0, clock_period ? 20}: '' mkdir top cat > top/config.yaml << EOF DESIGN_NAME: top '' + (if data_width > 0 then "SYNTH_PARAMETERS: [ 'DATA_WIDTH=${toString data_width}' " + (if sum_width > 0 then ", 'SUM_WIDTH=${toString sum_width}' ]\n" else "]\n") else "") + '' VERILOG_FILES: [ ${verilog_file} ] CLOCK_PERIOD: ${toString clock_period} EOF cat top/config.yaml librelane --manual-pdk --pdk-root ${sky130-pdk} --run-tag run top/config.yaml ''; mk_fma_fixed_gsclib = {data_width, sum_width}: pkgs.stdenv.mkDerivation { name = "fma_fixed_${toString data_width}_${toString sum_width}_gsclib"; src = ./.; unpackPhase = "true"; buildPhase = run-yosys { verilog_file = "$src/fma_fixed.v"; inherit data_width; inherit sum_width; }; installPhase = '' ODIR=fma_fixed_${toString data_width}_${toString sum_width}_gsclib mkdir -p $out/$ODIR/{log,nl} cp out.log $out/$ODIR/log/top.log cp nl.v $out/$ODIR/nl/top.nl.v ''; buildInputs = [ pkgs.yosys ]; }; mk_fma_float_gsclib = {data_width}: pkgs.stdenv.mkDerivation { name = "fma_float_${toString data_width}_gsclib"; src = cvfpu-src; srcExtra = ./.; unpackPhase = "true"; buildPhase = run-sv2v {inherit data_width;} + run-yosys {}; installPhase = '' ODIR=fma_float_${toString data_width}_gsclib mkdir -p $out/$ODIR/{log,nl} cp out.log $out/$ODIR/log/top.log cp nl.v $out/$ODIR/nl/top.nl.v ''; buildInputs = [ pkgs.yosys sv2v ]; }; mk_fma_fixed_sky130 = {data_width, sum_width, clock_period} : pkgs.stdenv.mkDerivation { name = "fma_fixed_${toString data_width}_${toString sum_width}_sky130"; src = ./.; unpackPhase = "true"; buildPhase = run-librelane { verilog_file = "$src/fma_fixed.v"; inherit data_width; inherit sum_width; inherit clock_period;}; installPhase = '' ODIR=fma_fixed_${toString data_width}_${toString sum_width}_sky130 mkdir -p $out/$ODIR cp -r top/runs/run/final/. $out/$ODIR/ ''; buildInputs = [ librelane-pkg ]; }; mk_fma_float_sky130 = {data_width, clock_period}: pkgs.stdenv.mkDerivation { name = "fma_float_${toString data_width}_sky130"; src = cvfpu-src; srcExtra = ./.; unpackPhase = "true"; buildPhase = run-sv2v {inherit data_width;} + run-librelane {inherit clock_period;}; installPhase = '' ODIR=fma_float_${toString data_width}_sky130 mkdir -p $out/$ODIR cp -r top/runs/run/final/. $out/$ODIR/ ''; buildInputs = [ librelane-pkg sv2v ]; }; in { fma_fixed_8_24_gsclib = mk_fma_fixed_gsclib {data_width = 8; sum_width = 24; }; fma_fixed_16_40_gsclib = mk_fma_fixed_gsclib {data_width = 16; sum_width = 40; }; fma_fixed_32_72_gsclib = mk_fma_fixed_gsclib {data_width = 32; sum_width = 72; }; fma_fixed_8_24_sky130 = mk_fma_fixed_sky130 {data_width = 8; sum_width = 24; clock_period=20; }; fma_fixed_16_40_sky130 = mk_fma_fixed_sky130 {data_width = 16; sum_width = 40; clock_period=20; }; fma_fixed_32_72_sky130 = mk_fma_fixed_sky130 {data_width = 32; sum_width = 72; clock_period=20; }; fma_float_16_gsclib = mk_fma_float_gsclib {data_width = 16; }; fma_float_32_gsclib = mk_fma_float_gsclib {data_width = 32; }; fma_float_64_gsclib = mk_fma_float_gsclib {data_width = 64; }; fma_float_16_sky130 = mk_fma_float_sky130 {data_width = 16; clock_period=40; }; fma_float_32_sky130 = mk_fma_float_sky130 {data_width = 32; clock_period=50; }; fma_float_64_sky130 = mk_fma_float_sky130 {data_width = 64; clock_period=115; }; default = pkgs.symlinkJoin { name = "fma_all"; paths = with self.packages.${system}; [ fma_fixed_8_24_gsclib fma_fixed_16_40_gsclib fma_fixed_32_72_gsclib fma_fixed_8_24_sky130 fma_fixed_16_40_sky130 fma_fixed_32_72_sky130 fma_float_16_gsclib fma_float_32_gsclib fma_float_64_gsclib fma_float_16_sky130 fma_float_32_sky130 fma_float_64_sky130 ]; }; } ); }; }