Machine Learning Hardware Modules
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

212 lines
9.8 KiB

{
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 <<EOF >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
];
};
}
);
};
}