qspim cleanup
diff --git a/verilog/rtl/lib/clk_skew_adjust.gv b/verilog/rtl/lib/clk_skew_adjust.gv new file mode 100644 index 0000000..fc811c0 --- /dev/null +++ b/verilog/rtl/lib/clk_skew_adjust.gv
@@ -0,0 +1,205 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// clock skew adjust //// +//// //// +//// This file is part of the YIFive cores project //// +//// https://github.com/dineshannayya/yifive_r0.git //// +//// http://www.opencores.org/cores/yifive/ //// +//// //// +//// Description //// +//// This block is useful for global clock skew adjustment //// +//// logic implementation: //// +//// clk_out = (sel=0) ? clk_in : //// +//// (sel=1) ? clk_d1 : //// +//// (sel=1) ? clk_d2 : //// +//// ..... //// +//// (sel=15)? clk_d15 :clk_in //// +//// //// +//// Note: each d* indicate clk buf delay //// +//// //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.0 - 29th Feb 2021, Dinesh A //// +//// Initial version //// +/// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// Clock-in is east pad direction +// clock out give in other three direction for better placement +///////////////////////////////////////////////////////////////////// +module clk_skew_adjust( +`ifdef USE_POWER_PINS + vccd1,// User area 1 1.8V supply + vssd1,// User area 1 digital ground +`endif +clk_in, sel, clk_out); + + +`ifdef USE_POWER_PINS + input vccd1;// User area 1 1.8V supply + input vssd1;// User area 1 digital ground +`endif + input clk_in; + output clk_out; + input [3:0] sel; + wire in0; + wire in1; + wire in2; + wire in3; + wire in4; + wire in5; + wire in6; + wire in7; + wire in8; + wire in9; + wire in10; + wire in11; + wire in12; + wire in13; + wire in14; + wire in15; + + wire clk_d1; + wire clk_d2; + wire clk_d3; + wire clk_d4; + wire clk_d5; + wire clk_d6; + wire clk_d7; + wire clk_d8; + wire clk_d9; + wire clk_d10; + wire clk_d11; + wire clk_d12; + wire clk_d13; + wire clk_d14; + wire clk_d15; + + wire d00; + wire d01; + wire d02; + wire d03; + wire d04; + wire d05; + wire d06; + wire d07; + wire d10; + wire d11; + wire d12; + wire d13; + wire d20; + wire d21; + wire d30; + + + ctech_delay_clkbuf clkbuf_1 (.A(clk_in), .X(clk_d1)); + ctech_delay_clkbuf clkbuf_2 (.A(clk_d1), .X(clk_d2)); + ctech_delay_clkbuf clkbuf_3 (.A(clk_d2), .X(clk_d3)); + ctech_delay_clkbuf clkbuf_4 (.A(clk_d3), .X(clk_d4)); + ctech_delay_clkbuf clkbuf_5 (.A(clk_d4), .X(clk_d5)); + ctech_delay_clkbuf clkbuf_6 (.A(clk_d5), .X(clk_d6)); + ctech_delay_clkbuf clkbuf_7 (.A(clk_d6), .X(clk_d7)); + ctech_delay_clkbuf clkbuf_8 (.A(clk_d7), .X(clk_d8)); + ctech_delay_clkbuf clkbuf_9 (.A(clk_d8), .X(clk_d9)); + ctech_delay_clkbuf clkbuf_10 (.A(clk_d9), .X(clk_d10)); + ctech_delay_clkbuf clkbuf_11 (.A(clk_d10), .X(clk_d11)); + ctech_delay_clkbuf clkbuf_12 (.A(clk_d11), .X(clk_d12)); + ctech_delay_clkbuf clkbuf_13 (.A(clk_d12), .X(clk_d13)); + ctech_delay_clkbuf clkbuf_14 (.A(clk_d13), .X(clk_d14)); + ctech_delay_clkbuf clkbuf_15 (.A(clk_d14), .X(clk_d15)); + + + // Tap point selection + assign in0 = clk_in; + assign in1 = clk_d1; + assign in2 = clk_d2; + assign in3 = clk_d3; + assign in4 = clk_d4; + assign in5 = clk_d5; + assign in6 = clk_d6; + assign in7 = clk_d7; + assign in8 = clk_d8; + assign in9 = clk_d9; + assign in10 = clk_d10; + assign in11 = clk_d11; + assign in12 = clk_d12; + assign in13 = clk_d13; + assign in14 = clk_d14; + assign in15 = clk_d15; + + + // first level mux - 8 + ctech_mux2x1_2 u_mux_level_00 ( .X (d00) , .A0 (in0), .A1(in1), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_01 ( .X (d01) , .A0 (in2), .A1(in3), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_02 ( .X (d02) , .A0 (in4), .A1(in5), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_03 ( .X (d03) , .A0 (in6), .A1(in7), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_04 ( .X (d04) , .A0 (in8), .A1(in9), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_05 ( .X (d05) , .A0 (in10), .A1(in11), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_06 ( .X (d06) , .A0 (in12), .A1(in13), .S(sel[0])); + ctech_mux2x1_2 u_mux_level_07 ( .X (d07) , .A0 (in14), .A1(in15), .S(sel[0])); + + // second level mux - 4 + ctech_mux2x1_2 u_mux_level_10 ( .X (d10) , .A0 (d00), .A1(d01), .S(sel[1])); + ctech_mux2x1_2 u_mux_level_11 ( .X (d11) , .A0 (d02), .A1(d03), .S(sel[1])); + ctech_mux2x1_2 u_mux_level_12 ( .X (d12) , .A0 (d04), .A1(d05), .S(sel[1])); + ctech_mux2x1_2 u_mux_level_13 ( .X (d13) , .A0 (d06), .A1(d07), .S(sel[1])); + + // third level mux - 2 + ctech_mux2x1_2 u_mux_level_20 ( .X (d20) , .A0 (d10), .A1(d11), .S(sel[2])); + ctech_mux2x1_2 u_mux_level_21 ( .X (d21) , .A0 (d12), .A1(d13), .S(sel[2])); + + // fourth level mux - 1 + ctech_mux2x1_4 u_mux_level_30 ( .X (d30) , .A0 (d20), .A1(d21), .S(sel[3])); + + + assign clk_out = d30; + +endmodule
diff --git a/verilog/rtl/lib/ctech_cells.sv b/verilog/rtl/lib/ctech_cells.sv index 8e3b0de..c9528de 100644 --- a/verilog/rtl/lib/ctech_cells.sv +++ b/verilog/rtl/lib/ctech_cells.sv
@@ -13,6 +13,34 @@ endmodule +module ctech_mux2x1_2 ( + input logic A0, + input logic A1, + input logic S , + output logic X); + +`ifndef SYNTHESIS +assign X = (S) ? A1 : A0; +`else +sky130_fd_sc_hd__mux2_2 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X)); +`endif + +endmodule + +module ctech_mux2x1_4 ( + input logic A0, + input logic A1, + input logic S , + output logic X); + +`ifndef SYNTHESIS +assign X = (S) ? A1 : A0; +`else +sky130_fd_sc_hd__mux2_4 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X)); +`endif + +endmodule + module ctech_buf ( input logic A, output logic X); @@ -49,3 +77,14 @@ endmodule +module ctech_delay_clkbuf ( + input logic A, + output logic X); + +`ifndef SYNTHESIS + assign X = A; +`else + sky130_fd_sc_hd__clkdlybuf4s15_2 u_dly (.X(X),.A(A)); +`endif + +endmodule
diff --git a/verilog/rtl/qspim/src/qspim_top.sv b/verilog/rtl/qspim/src/qspim_top.sv index ec7eb7c..a7c3a4b 100644 --- a/verilog/rtl/qspim/src/qspim_top.sv +++ b/verilog/rtl/qspim/src/qspim_top.sv
@@ -236,18 +236,22 @@ // ADDing Delay cells for Interface hold fix +wire spi_sdo0_d1,spi_sdo0_d2; ctech_delay_buf u_delay1_sdio0 (.X(spi_sdo0_d1),.A(spi_sdo_int[0])); ctech_delay_buf u_delay2_sdio0 (.X(spi_sdo0_d2),.A(spi_sdo0_d1)); ctech_buf u_buf_sdio0 (.X(spi_sdo[0]),.A(spi_sdo0_d2)); +wire spi_sdo1_d1,spi_sdo1_d2; ctech_delay_buf u_delay1_sdio1 (.X(spi_sdo1_d1),.A(spi_sdo_int[1])); ctech_delay_buf u_delay2_sdio1 (.X(spi_sdo1_d2),.A(spi_sdo1_d1)); ctech_buf u_buf_sdio1 (.X(spi_sdo[1]),.A(spi_sdo1_d2)); +wire spi_sdo2_d1,spi_sdo2_d2; ctech_delay_buf u_delay1_sdio2 (.X(spi_sdo2_d1),.A(spi_sdo_int[2])); ctech_delay_buf u_delay2_sdio2 (.X(spi_sdo2_d2),.A(spi_sdo2_d1)); ctech_buf u_buf_sdio2 (.X(spi_sdo[2]),.A(spi_sdo2_d2)); +wire spi_sdo3_d1,spi_sdo3_d2; ctech_delay_buf u_delay1_sdio3 (.X(spi_sdo3_d1),.A(spi_sdo_int[3])); ctech_delay_buf u_delay2_sdio3 (.X(spi_sdo3_d2),.A(spi_sdo3_d1)); ctech_buf u_buf_sdio3 (.X(spi_sdo[3]),.A(spi_sdo3_d2));
diff --git a/verilog/rtl/qspim/synth/Makefile b/verilog/rtl/qspim/synth/Makefile index e69de29..dcf29dc 100644 --- a/verilog/rtl/qspim/synth/Makefile +++ b/verilog/rtl/qspim/synth/Makefile
@@ -0,0 +1,52 @@ +# ////////////////////////////////////////////////////////////////////////////// +# // SPDX-FileCopyrightText: 2021, Dinesh Annayya +# // +# // Licensed under the Apache License, Version 2.0 (the "License"); +# // you may not use this file except in compliance with the License. +# // You may obtain a copy of the License at +# // +# // http://www.apache.org/licenses/LICENSE-2.0 +# // +# // Unless required by applicable law or agreed to in writing, software +# // distributed under the License is distributed on an "AS IS" BASIS, +# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# // See the License for the specific language governing permissions and +# // limitations under the License. +# // SPDX-License-Identifier: Apache-2.0 +# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> +# // ////////////////////////////////////////////////////////////////////////// +#------------------------------------------------------------------------------ +# Makefile for Synthesis +#------------------------------------------------------------------------------ + +# Paths +export ROOT_DIR := $(shell pwd) +export REPORT_DIR := $(ROOT_DIR)/reports +export NETLIST_DIR := $(ROOT_DIR)/netlist +export TMP_DIR := $(ROOT_DIR)/tmp + + +# Targets +.PHONY: clean create synth + +default: clean create synth + +synth: clean create + yosys -g -c synth.tcl -l synth.log + +create: + mkdir -p ./tmp/synthesis; + mkdir -p ./reports; + mkdir -p ./netlist; + $(OPENLANE_ROOT)/scripts/libtrim.pl $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib $(PDK_ROOT)/sky130A/libs.tech/openlane/sky130_fd_sc_hd/no_synth.cells > ./tmp/trimmed.lib + #create No PG Pin library for hand instantiated cells + sed '/pg_pin.*/a \ direction : "inout";' $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib > ./tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib + sed -i 's/pg_pin/pin/' ./tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib + + + +clean: + $(RM) -R synth.log + $(RM) -R $(REPORT_DIR) + $(RM) -R $(NETLIST_DIR) + $(RM) -R $(TMP_DIR)
diff --git a/verilog/rtl/qspim/synth/synth.tcl b/verilog/rtl/qspim/synth/synth.tcl index e69de29..0285cc5 100755 --- a/verilog/rtl/qspim/synth/synth.tcl +++ b/verilog/rtl/qspim/synth/synth.tcl
@@ -0,0 +1,402 @@ +# ////////////////////////////////////////////////////////////////////////////// +# // SPDX-FileCopyrightText: 2021, Dinesh Annayya +# // +# // Licensed under the Apache License, Version 2.0 (the "License"); +# // you may not use this file except in compliance with the License. +# // You may obtain a copy of the License at +# // +# // http://www.apache.org/licenses/LICENSE-2.0 +# // +# // Unless required by applicable law or agreed to in writing, software +# // distributed under the License is distributed on an "AS IS" BASIS, +# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# // See the License for the specific language governing permissions and +# // limitations under the License. +# // SPDX-License-Identifier: Apache-2.0 +# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> +# // ////////////////////////////////////////////////////////////////////////// +# inputs expected as env vars +#set opt $::env(SYNTH_OPT) + +proc convert_pg_pins {lib_in lib_out} { + try_catch sed -E {s/^([[:space:]]+)pg_pin(.*)/\1pin\2\n\1 direction : "inout";/g} $lib_in > $lib_out +} + + + +########### config.tcl ################## +# User config +set ::env(DESIGN_NAME) qspim_top + +# Change if needed +set ::env(VERILOG_FILES) [glob \ + ../src/qspim_if.sv \ + ../src/qspim_clkgen.sv \ + ../src/qspim_ctrl.sv \ + ../src/qspim_fifo.sv \ + ../src/qspim_regs.sv \ + ../src/qspim_rx.sv \ + ../src/qspim_top.sv \ + ../src/qspim_tx.sv \ + ../lib/clk_skew_adjust.gv \ + ../lib/ctech_cells.sv \ + ../lib/reset_sync.sv \ + ] + + +set ::env(SYNTH_DEFINES) [list SYNTHESIS ] + + +set ::env(LIB_SYNTH) ./tmp/trimmed.lib +set ::env(LIB_SYNTH_COMPLETE_NO_PG) ./tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib + + + +# Fill this +set ::env(CLOCK_PERIOD) "10" +set ::env(CLOCK_PORT) "mclk" +set ::env(CLOCK_TREE_SYNTH) 0 + +set ::env(SYNTH_BUFFERING) 0 +set ::env(SYNTH_SIZING) 0 + +set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8" +set ::env(SYNTH_CAP_LOAD) "17.65" +set ::env(SYNTH_MAX_TRAN) "[expr {0.1*10.0}]" + +set ::env(SYNTH_MAX_FANOUT) 6 +set ::env(FP_CORE_UTIL) 50 +set ::env(PL_TARGET_DENSITY) [ expr ($::env(FP_CORE_UTIL)+5) / 100.0 ] +set ::env(CELL_PAD) 4 + +set ::env(SYNTH_NO_FLAT) "0" + +set ::env(SYNTH_READ_BLACKBOX_LIB) "1" + +set ::env(SYNTH_STRATEGY) "AREA 0" +set ::env(SYNTH_TIELO_PORT) "sky130_fd_sc_hd__conb_1 LO" +set ::env(SYNTH_TIEHI_PORT) "sky130_fd_sc_hd__conb_1 HI" +set ::env(SYNTH_MIN_BUF_PORT) "sky130_fd_sc_hd__buf_2 A X" + + +set ::env(CLOCK_NET) $::env(CLOCK_PORT) + + + +set ::env(yosys_tmp_file_tag) "./tmp/" +set ::env(TMP_DIR) "./tmp/" +set ::env(yosys_netlist_dir) "./netlist" +set ::env(yosys_report_file_tag) "./reports/yosys" +set ::env(yosys_result_file_tag) "./reports/yosys.synthesis" + +set ::env(SAVE_NETLIST) $::env(yosys_netlist_dir)/$::env(DESIGN_NAME).gv + + + +########### End of config.tcl +set buffering $::env(SYNTH_BUFFERING) +set sizing $::env(SYNTH_SIZING) + +yosys -import + +set vtop $::env(DESIGN_NAME) +#set sdc_file $::env(SDC_FILE) +set sclib $::env(LIB_SYNTH) + +if { [info exists ::env(SYNTH_DEFINES) ] } { + foreach define $::env(SYNTH_DEFINES) { + log "Defining $define" + verilog_defines -D$define + } +} + +set vIdirsArgs "" +if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} { + foreach dir $::env(VERILOG_INCLUDE_DIRS) { + log "Adding include file -I$dir " + lappend vIdirsArgs "-I$dir" + } + set vIdirsArgs [join $vIdirsArgs] +} + +if { $::env(SYNTH_READ_BLACKBOX_LIB) } { + log "Reading $::env(LIB_SYNTH_COMPLETE_NO_PG) as a blackbox" + read_liberty -lib -ignore_miss_dir -setattr blackbox $::env(LIB_SYNTH_COMPLETE_NO_PG) +} + + +if { [info exists ::env(EXTRA_LIBS) ] } { + foreach lib $::env(EXTRA_LIBS) { + read_liberty {*}$vIdirsArgs -lib -ignore_miss_dir -setattr blackbox $lib + } +} + + + +# ns expected (in sdc as well) +set clock_period [expr {$::env(CLOCK_PERIOD)*1000}] + +set driver $::env(SYNTH_DRIVING_CELL) +set cload $::env(SYNTH_CAP_LOAD) +# input pin cap of IN_3VX8 +set max_FO $::env(SYNTH_MAX_FANOUT) +if {![info exist ::env(SYNTH_MAX_TRAN)]} { + set ::env(SYNTH_MAX_TRAN) [expr {0.1*$clock_period}] +} else { + set ::env(SYNTH_MAX_TRAN) [expr {$::env(SYNTH_MAX_TRAN) * 1000}] +} +set max_Tran $::env(SYNTH_MAX_TRAN) + + +# Mapping parameters +set A_factor 0.00 +set B_factor 0.88 +set F_factor 0.00 + +# Don't change these unless you know what you are doing +set stat_ext ".stat.rpt" +set chk_ext ".chk.rpt" +set gl_ext ".gl.v" +set constr_ext ".$clock_period.constr" +set timing_ext ".timing.txt" +set abc_ext ".abc" + + +# get old sdc, add library specific stuff for abc scripts +set sdc_file $::env(yosys_tmp_file_tag).sdc +set outfile [open ${sdc_file} w] +#puts $outfile $sdc_data +puts $outfile "set_driving_cell ${driver}" +puts $outfile "set_load ${cload}" +close $outfile + + +# ABC Scrips +set abc_rs_K "resub,-K," +set abc_rs "resub" +set abc_rsz "resub,-z" +set abc_rw_K "rewrite,-K," +set abc_rw "rewrite" +set abc_rwz "rewrite,-z" +set abc_rf "refactor" +set abc_rfz "refactor,-z" +set abc_b "balance" + +set abc_resyn2 "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}" +set abc_share "strash; multi,-m; ${abc_resyn2}" +set abc_resyn2a "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}" +set abc_resyn3 "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance" +set abc_resyn2rs "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}" + +set abc_choice "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore" +set abc_choice2 "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore" + +set abc_map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0" +set abc_map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0" +set abc_retime_area "retime,-D,{D},-M,5" +set abc_retime_dly "retime,-D,{D},-M,6" +set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000" + +set abc_area_recovery_1 "${abc_choice}; map;" +set abc_area_recovery_2 "${abc_choice2}; map;" + +set map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0" +set map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0" +set abc_retime_area "retime,-D,{D},-M,5" +set abc_retime_dly "retime,-D,{D},-M,6" +set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000" + +if {$buffering==1} { + set abc_fine_tune "buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}" +} elseif {$sizing} { + set abc_fine_tune "upsize,{D};dnsize,{D}" +} else { + set abc_fine_tune "" +} + + +set delay_scripts [list \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + ] + +set area_scripts [list \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + \ + "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \ + ] + +set all_scripts [list {*}$delay_scripts {*}$area_scripts] + +set strategy_parts [split $::env(SYNTH_STRATEGY)] + +proc synth_strategy_format_err { } { + upvar area_scripts area_scripts + upvar delay_scripts delay_scripts + log -stderr "\[ERROR] Misformatted SYNTH_STRATEGY (\"$::env(SYNTH_STRATEGY)\")." + log -stderr "\[ERROR] Correct format is \"DELAY|AREA 0-[expr [llength $delay_scripts]-1]|0-[expr [llength $area_scripts]-1]\"." + exit 1 +} + +if { [llength $strategy_parts] != 2 } { + synth_strategy_format_err +} + +set strategy_type [lindex $strategy_parts 0] +set strategy_type_idx [lindex $strategy_parts 1] + +if { $strategy_type != "AREA" && $strategy_type != "DELAY" } { + log -stderr "\[ERROR] AREA|DELAY tokens not found. ($strategy_type)" + synth_strategy_format_err +} + +if { $strategy_type == "DELAY" && $strategy_type_idx >= [llength $delay_scripts] } { + log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high." + synth_strategy_format_err +} + +if { $strategy_type == "AREA" && $strategy_type_idx >= [llength $area_scripts] } { + log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high." + synth_strategy_format_err +} + +if { $strategy_type == "DELAY" } { + set strategy $strategy_type_idx +} else { + set strategy [expr {[llength $delay_scripts]+$strategy_type_idx}] +} + + +for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } { + read_verilog -sv {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i] +} + +if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } { + foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) { + read_verilog -sv {*}$vIdirsArgs -lib $verilog_file + } +} +select -module $vtop +show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy +select -clear + +hierarchy -check -top $vtop + +# Infer tri-state buffers. +set tbuf_map false +if { [info exists ::env(TRISTATE_BUFFER_MAP)] } { + if { [file exists $::env(TRISTATE_BUFFER_MAP)] } { + set tbuf_map true + tribuf + } else { + log "WARNING: TRISTATE_BUFFER_MAP is defined but could not be found: $::env(TRISTATE_BUFFER_MAP)" + } +} + +if { $::env(SYNTH_NO_FLAT) } { + synth -top $vtop +} else { + synth -top $vtop -flatten +} + +share -aggressive +opt +opt_clean -purge + +tee -o "$::env(yosys_report_file_tag)_pre.stat" stat + +# Map tri-state buffers. +if { $tbuf_map } { + log {mapping tbuf} + techmap -map $::env(TRISTATE_BUFFER_MAP) + simplemap +} + +# handle technology mapping of 4-MUX, and tell Yosys to infer 4-muxes +if { [info exists ::env(SYNTH_MUX4_MAP)] && [file exists $::env(SYNTH_MUX4_MAP)] } { + muxcover -mux4 + techmap -map $::env(SYNTH_MUX4_MAP) + simplemap +} + +# handle technology mapping of 2-MUX +if { [info exists ::env(SYNTH_MUX_MAP)] && [file exists $::env(SYNTH_MUX_MAP)] } { + techmap -map $::env(SYNTH_MUX_MAP) + simplemap +} + +# handle technology mapping of latches +if { [info exists ::env(SYNTH_LATCH_MAP)] && [file exists $::env(SYNTH_LATCH_MAP)] } { + techmap -map $::env(SYNTH_LATCH_MAP) + simplemap +} + +dfflibmap -liberty $sclib +tee -o "$::env(yosys_report_file_tag)_dff.stat" stat + +if { [info exists ::env(SYNTH_EXPLORE)] && $::env(SYNTH_EXPLORE) } { + design -save myDesign + + for { set index 0 } { $index < [llength $all_scripts] } { incr index } { + log "\[INFO\]: ABC: WireLoad : S_$index" + design -load myDesign + + abc -D $clock_period \ + -constr "$sdc_file" \ + -liberty $sclib \ + -script [lindex $all_scripts $index] + + setundef -zero + + hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT) + + # get rid of the assignments that make verilog2def fail + splitnets + opt_clean -purge + insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT) + + tee -o "$::env(yosys_report_file_tag)_$index$chk_ext" check + write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(yosys_result_file_tag)_$index.v" + design -reset + } +} else { + + log "\[INFO\]: ABC: WireLoad : S_$strategy" + + abc -D $clock_period \ + -constr "$sdc_file" \ + -liberty $sclib \ + -script [lindex $all_scripts $strategy] \ + -showtmp; + + setundef -zero + + hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT) + + # get rid of the assignments that make verilog2def fail + splitnets + opt_clean -purge + insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT) + + tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check + write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)" +} + +if { $::env(SYNTH_NO_FLAT) } { + design -reset + file copy -force $::env(SAVE_NETLIST) $::env(yosys_tmp_file_tag)_unflat.v + read_verilog -sv $::env(SAVE_NETLIST) + synth -top $vtop -flatten + splitnets + opt_clean -purge + insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT) + write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)" + tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check +}