From 46d44fa42ae8655cb6d2f87c2d7bbead43706366 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 26 Apr 2019 12:23:47 -0600 Subject: [PATCH] Update VPR7 X2P with new engine --- vpr7_x2p/libarchfpga/arch/README.txt | 11 - vpr7_x2p/libarchfpga/arch/mult_luts_arch.xml | 716 -- vpr7_x2p/libarchfpga/arch/sample_arch.xml | 815 -- .../fpga_spice_include/spice_types.h | 133 +- vpr7_x2p/libarchfpga/include/physical_types.h | 40 +- vpr7_x2p/libarchfpga/read_xml_arch_file.c | 168 +- vpr7_x2p/libarchfpga/read_xml_spice.c | 447 +- vpr7_x2p/tech/PTM_130nm/130nm.pm | 145 - vpr7_x2p/tech/PTM_130nm/130nm.xml | 7493 ---------------- vpr7_x2p/tech/PTM_130nm/readme.txt | 17 - vpr7_x2p/tech/PTM_22nm/22nm.pm | 140 - vpr7_x2p/tech/PTM_22nm/22nm.xml | 7493 ---------------- vpr7_x2p/tech/PTM_22nm/readme.txt | 2 - vpr7_x2p/tech/PTM_45nm/45nm.pm | 141 - vpr7_x2p/tech/PTM_45nm/45nm.xml | 7493 ---------------- vpr7_x2p/tech/PTM_45nm/readme.txt | 17 - .../vpr/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml | 1453 ---- .../vpr/ARCH/k6_N10_scan_chain_template.xml | 1453 ---- .../ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml | 882 -- vpr7_x2p/vpr/ARCH/k6_N10_sram_ptm45nm_TT.xml | 1452 ---- vpr7_x2p/vpr/Circuits/fifo_1bit.act | 67 - vpr7_x2p/vpr/Circuits/fifo_1bit.blif | 103 - vpr7_x2p/vpr/Circuits/fifo_1bit.v | 32 - vpr7_x2p/vpr/Circuits/fifo_1bit.ys | 19 - vpr7_x2p/vpr/Circuits/pip_add.act | 146 - vpr7_x2p/vpr/Circuits/pip_add.blif | 264 - vpr7_x2p/vpr/Circuits/pip_add.v | 142 - vpr7_x2p/vpr/Circuits/s298_prevpr.act | 42 - vpr7_x2p/vpr/Circuits/s298_prevpr.blif | 104 - vpr7_x2p/vpr/Circuits/sync_4bits_add.act | 40 - vpr7_x2p/vpr/Circuits/sync_4bits_add.blif | 91 - vpr7_x2p/vpr/Circuits/sync_4bits_add.v | 90 - vpr7_x2p/vpr/Makefile | 34 +- vpr7_x2p/vpr/SRC/base/OptionTokens.c | 61 +- vpr7_x2p/vpr/SRC/base/OptionTokens.h | 59 +- vpr7_x2p/vpr/SRC/base/ReadOptions.c | 82 +- vpr7_x2p/vpr/SRC/base/ReadOptions.h | 19 +- vpr7_x2p/vpr/SRC/base/SetupVPR.c | 365 +- vpr7_x2p/vpr/SRC/base/SetupVPR.h | 9 + vpr7_x2p/vpr/SRC/base/read_blif.c | 2 +- vpr7_x2p/vpr/SRC/base/read_netlist.c | 2 + vpr7_x2p/vpr/SRC/base/verilog_writer.c | 2 +- vpr7_x2p/vpr/SRC/base/vpr_api.c | 2442 +++--- vpr7_x2p/vpr/SRC/base/vpr_api.h | 9 +- vpr7_x2p/vpr/SRC/base/vpr_types.h | 70 +- vpr7_x2p/vpr/SRC/ctags_vpr_src.sh | 3 +- .../vpr/SRC/fpga_spice/base/fpga_spice_api.h | 5 - .../fpga_spice/base/fpga_spice_bitstream.h | 7 - .../SRC/fpga_spice/base/fpga_spice_utils.c | 7698 ----------------- vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.h | 3 - .../spice/spice_hardlogic_testbench.c | 860 -- .../spice/spice_hardlogic_testbench.h | 9 - vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.c | 387 - vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.h | 20 - .../fpga_spice/spice/spice_lut_testbench.c | 773 -- .../fpga_spice/spice/spice_lut_testbench.h | 10 - vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.h | 19 - .../SRC/fpga_spice/spice/spice_primitives.c | 468 - .../SRC/fpga_spice/spice/spice_primitives.h | 22 - .../vpr/SRC/fpga_spice/verilog/verilog_api.c | 326 - .../vpr/SRC/fpga_spice/verilog/verilog_api.h | 4 - .../fpga_spice/verilog/verilog_autocheck_tb.c | 967 --- .../fpga_spice/verilog/verilog_autocheck_tb.h | 19 - .../SRC/fpga_spice/verilog/verilog_decoder.c | 230 - .../SRC/fpga_spice/verilog/verilog_decoder.h | 7 - .../SRC/fpga_spice/verilog/verilog_global.c | 75 - .../SRC/fpga_spice/verilog/verilog_global.h | 77 - .../vpr/SRC/fpga_spice/verilog/verilog_lut.c | 403 - .../vpr/SRC/fpga_spice/verilog/verilog_lut.h | 10 - .../verilog/verilog_modelsim_autodeck.h | 13 - .../fpga_spice/verilog/verilog_primitives.c | 514 -- .../fpga_spice/verilog/verilog_primitives.h | 22 - .../SRC/fpga_spice/verilog/verilog_routing.h | 87 - .../fpga_spice/verilog/verilog_submodules.h | 6 - .../fpga_spice/verilog/verilog_top_netlist.c | 2962 ------- .../fpga_spice/verilog/verilog_top_netlist.h | 37 - .../SRC/fpga_spice/verilog/verilog_utils.h | 158 - .../base/fpga_x2p_api.c} | 36 +- vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.h | 5 + .../base/fpga_x2p_backannotate_utils.c} | 1162 ++- .../base/fpga_x2p_backannotate_utils.h} | 29 +- .../fpga_x2p/base/fpga_x2p_bitstream_utils.c | 1597 ++++ .../fpga_x2p/base/fpga_x2p_bitstream_utils.h | 80 + .../base/fpga_x2p_globals.c} | 9 +- .../base/fpga_x2p_globals.h} | 13 +- .../SRC/fpga_x2p/base/fpga_x2p_lut_utils.c | 751 ++ .../SRC/fpga_x2p/base/fpga_x2p_lut_utils.h | 59 + .../SRC/fpga_x2p/base/fpga_x2p_mux_utils.c | 1099 +++ .../SRC/fpga_x2p/base/fpga_x2p_mux_utils.h | 85 + .../fpga_x2p/base/fpga_x2p_pbtypes_utils.c | 3153 +++++++ .../fpga_x2p/base/fpga_x2p_pbtypes_utils.h | 242 + .../fpga_x2p/base/fpga_x2p_rr_graph_utils.c | 1157 +++ .../fpga_x2p/base/fpga_x2p_rr_graph_utils.h | 108 + .../base/fpga_x2p_setup.c} | 237 +- .../base/fpga_x2p_setup.h} | 4 +- .../base/fpga_x2p_timing_utils.c} | 6 +- .../base/fpga_x2p_timing_utils.h} | 0 .../vpr/SRC/fpga_x2p/base/fpga_x2p_types.h | 137 + .../vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c | 3514 ++++++++ .../base/fpga_x2p_utils.h} | 354 +- .../{fpga_spice => fpga_x2p}/base/quicksort.c | 0 .../{fpga_spice => fpga_x2p}/base/quicksort.h | 0 .../bitstream/fpga_bitstream.c} | 131 +- .../SRC/fpga_x2p/bitstream/fpga_bitstream.h | 18 + .../bitstream/fpga_bitstream_pbtypes.c | 684 ++ .../bitstream/fpga_bitstream_pbtypes.h | 6 + .../bitstream/fpga_bitstream_primitives.c | 483 ++ .../bitstream/fpga_bitstream_primitives.h | 11 + .../bitstream/fpga_bitstream_routing.c | 592 ++ .../bitstream/fpga_bitstream_routing.h | 8 + .../clb_pin_remap/clb_pin_remap_util.c | 0 .../clb_pin_remap/clb_pin_remap_util.h | 0 .../clb_pin_remap/place_clb_pin_remap.c | 0 .../clb_pin_remap/place_clb_pin_remap.h | 0 .../clb_pin_remap/post_place_timing.c | 0 .../clb_pin_remap/post_place_timing.h | 0 .../fpga_x2p/router/.fpga_x2p_router.c.swp | Bin 0 -> 49152 bytes .../fpga_x2p/router/fpga_x2p_pb_rr_graph.c | 1351 +++ .../fpga_x2p/router/fpga_x2p_pb_rr_graph.h | 42 + .../vpr/SRC/fpga_x2p/router/fpga_x2p_router.c | 849 ++ .../vpr/SRC/fpga_x2p/router/fpga_x2p_router.h | 28 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.c | 21 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.h | 8 + .../SRC/fpga_x2p/shell/cmd_fpga_bitstream.c | 47 + .../SRC/fpga_x2p/shell/cmd_fpga_bitstream.h | 10 + .../vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.c | 79 + .../vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.h | 25 + .../vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.c | 58 + .../vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.h | 25 + .../SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.c | 46 + .../SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.h | 14 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.c | 19 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.h | 8 + .../vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.c | 135 + .../vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.h | 32 + .../fpga_x2p/shell/cmd_vpr_place_and_route.c | 329 + .../fpga_x2p/shell/cmd_vpr_place_and_route.h | 56 + .../vpr/SRC/fpga_x2p/shell/cmd_vpr_power.c | 37 + .../vpr/SRC/fpga_x2p/shell/cmd_vpr_power.h | 11 + .../vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.c | 280 + .../vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.h | 24 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.c | 156 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.h | 8 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.c | 310 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.h | 25 + .../vpr/SRC/fpga_x2p/shell/read_opt_types.h | 63 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_api.h | 2 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_cmds.h | 27 + .../SRC/fpga_x2p/shell/shell_file_postfix.h | 9 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_types.h | 39 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.c | 119 + vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.h | 6 + .../spice/spice_api.c | 113 +- vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.h | 3 + .../spice/spice_globals.c | 4 +- .../spice/spice_globals.h | 2 - .../spice/spice_grid_testbench.c | 7 +- .../spice/spice_grid_testbench.h | 0 .../spice/spice_heads.c | 6 +- .../spice/spice_heads.h | 0 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.c | 673 ++ vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.h | 17 + .../spice/spice_mux.c | 313 +- vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.h | 10 + .../spice/spice_mux_testbench.c | 632 +- .../spice/spice_mux_testbench.h | 6 +- .../spice/spice_pbtypes.c | 661 +- .../spice/spice_pbtypes.h | 19 +- .../vpr/SRC/fpga_x2p/spice/spice_primitive.c | 207 + .../vpr/SRC/fpga_x2p/spice/spice_primitive.h | 8 + .../spice/spice_primitive_testbench.c | 1107 +++ .../spice/spice_primitive_testbench.h | 10 + .../spice/spice_routing.c | 110 +- .../spice/spice_routing.h | 0 .../spice/spice_routing_testbench.c | 7 +- .../spice/spice_routing_testbench.h | 0 .../spice/spice_run_scripts.c | 47 +- .../spice/spice_run_scripts.h | 1 + .../spice/spice_subckt.c | 19 +- .../spice/spice_subckt.h | 0 .../spice/spice_top_netlist.c | 6 +- .../spice/spice_top_netlist.h | 0 .../spice/spice_utils.c | 187 +- .../spice/spice_utils.h | 4 +- .../vpr/SRC/fpga_x2p/verilog/verilog_api.c | 438 + .../vpr/SRC/fpga_x2p/verilog/verilog_api.h | 4 + .../verilog/verilog_autocheck_top_testbench.c | 392 + .../verilog/verilog_autocheck_top_testbench.h | 9 + .../verilog/verilog_compact_netlist.c | 835 ++ .../verilog/verilog_compact_netlist.h | 28 + .../SRC/fpga_x2p/verilog/verilog_decoder.c | 689 ++ .../SRC/fpga_x2p/verilog/verilog_decoder.h | 8 + .../verilog_formal_random_top_testbench.c | 408 + .../verilog_formal_random_top_testbench.h | 9 + .../verilog/verilog_formality_autodeck.c | 139 + .../verilog/verilog_formality_autodeck.h | 5 + .../vpr/SRC/fpga_x2p/verilog/verilog_global.c | 140 + .../vpr/SRC/fpga_x2p/verilog/verilog_global.h | 146 + .../verilog/verilog_include_netlists.c | 120 + .../verilog/verilog_include_netlists.h | 3 + .../verilog/verilog_modelsim_autodeck.c | 391 +- .../verilog/verilog_modelsim_autodeck.h | 8 + .../verilog/verilog_pbtypes.c | 1949 ++--- .../verilog/verilog_pbtypes.h | 106 +- .../SRC/fpga_x2p/verilog/verilog_primitives.c | 746 ++ .../SRC/fpga_x2p/verilog/verilog_primitives.h | 15 + .../fpga_x2p/verilog/verilog_report_timing.c | 1454 ++++ .../fpga_x2p/verilog/verilog_report_timing.h | 9 + .../verilog/verilog_routing.c | 430 +- .../SRC/fpga_x2p/verilog/verilog_routing.h | 126 + .../vpr/SRC/fpga_x2p/verilog/verilog_sdc.c | 1922 ++++ .../vpr/SRC/fpga_x2p/verilog/verilog_sdc.h | 53 + .../fpga_x2p/verilog/verilog_sdc_pb_types.c | 519 ++ .../fpga_x2p/verilog/verilog_sdc_pb_types.h | 43 + .../verilog/verilog_submodules.c | 1885 +++- .../SRC/fpga_x2p/verilog/verilog_submodules.h | 7 + .../SRC/fpga_x2p/verilog/verilog_tcl_utils.c | 404 + .../SRC/fpga_x2p/verilog/verilog_tcl_utils.h | 26 + .../verilog/verilog_top_netlist_utils.c | 1543 ++++ .../verilog/verilog_top_netlist_utils.h | 54 + .../fpga_x2p/verilog/verilog_top_testbench.c | 1421 +++ .../fpga_x2p/verilog/verilog_top_testbench.h | 30 + .../verilog/verilog_utils.c | 2000 ++++- .../vpr/SRC/fpga_x2p/verilog/verilog_utils.h | 282 + .../verilog_verification_top_netlist.c | 440 + .../verilog_verification_top_netlist.h | 9 + vpr7_x2p/vpr/SRC/main.c | 74 +- vpr7_x2p/vpr/SRC/pack/cluster.c | 5 +- vpr7_x2p/vpr/SRC/pack/cluster_legality.c | 16 +- vpr7_x2p/vpr/SRC/pack/output_clustering.c | 6 + vpr7_x2p/vpr/SRC/pack/pb_type_graph.c | 363 +- .../vpr/SRC/pack/pb_type_graph_annotations.c | 8 + vpr7_x2p/vpr/SRC/pack/prepack.c | 34 + vpr7_x2p/vpr/SRC/route/route_common.h | 1 + vpr7_x2p/vpr/SRC/shell_main.c | 19 + vpr7_x2p/vpr/SRC/tags | 6335 ++++++++++++++ vpr7_x2p/vpr/SRC/util/vpr_utils.c | 6 + vpr7_x2p/vpr/SpiceNetlists/adder.sp | 30 + vpr7_x2p/vpr/SpiceNetlists/gate.sp | 16 + vpr7_x2p/vpr/VerilogNetlists/adder.v | 19 + vpr7_x2p/vpr/VerilogNetlists/ff.v | 100 - vpr7_x2p/vpr/VerilogNetlists/io.v | 4 +- vpr7_x2p/vpr/VerilogNetlists/sram.v | 99 - vpr7_x2p/vpr/go.sh | 34 - vpr7_x2p/vpr/go_fpga_spice.sh | 32 + vpr7_x2p/vpr/go_fpga_verilog.sh | 42 + vpr7_x2p/vpr/picorv.sh | 9 - vpr7_x2p/vpr/picorv/arch.xml | 411 - 248 files changed, 48213 insertions(+), 53950 deletions(-) delete mode 100644 vpr7_x2p/libarchfpga/arch/README.txt delete mode 100644 vpr7_x2p/libarchfpga/arch/mult_luts_arch.xml delete mode 100644 vpr7_x2p/libarchfpga/arch/sample_arch.xml delete mode 100644 vpr7_x2p/tech/PTM_130nm/130nm.pm delete mode 100644 vpr7_x2p/tech/PTM_130nm/130nm.xml delete mode 100644 vpr7_x2p/tech/PTM_130nm/readme.txt delete mode 100644 vpr7_x2p/tech/PTM_22nm/22nm.pm delete mode 100644 vpr7_x2p/tech/PTM_22nm/22nm.xml delete mode 100644 vpr7_x2p/tech/PTM_22nm/readme.txt delete mode 100644 vpr7_x2p/tech/PTM_45nm/45nm.pm delete mode 100644 vpr7_x2p/tech/PTM_45nm/45nm.xml delete mode 100644 vpr7_x2p/tech/PTM_45nm/readme.txt delete mode 100644 vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml delete mode 100644 vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_template.xml delete mode 100644 vpr7_x2p/vpr/ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml delete mode 100644 vpr7_x2p/vpr/ARCH/k6_N10_sram_ptm45nm_TT.xml delete mode 100644 vpr7_x2p/vpr/Circuits/fifo_1bit.act delete mode 100644 vpr7_x2p/vpr/Circuits/fifo_1bit.blif delete mode 100644 vpr7_x2p/vpr/Circuits/fifo_1bit.v delete mode 100644 vpr7_x2p/vpr/Circuits/fifo_1bit.ys delete mode 100644 vpr7_x2p/vpr/Circuits/pip_add.act delete mode 100644 vpr7_x2p/vpr/Circuits/pip_add.blif delete mode 100644 vpr7_x2p/vpr/Circuits/pip_add.v delete mode 100644 vpr7_x2p/vpr/Circuits/s298_prevpr.act delete mode 100644 vpr7_x2p/vpr/Circuits/s298_prevpr.blif delete mode 100644 vpr7_x2p/vpr/Circuits/sync_4bits_add.act delete mode 100644 vpr7_x2p/vpr/Circuits/sync_4bits_add.blif delete mode 100644 vpr7_x2p/vpr/Circuits/sync_4bits_add.v mode change 100644 => 100755 vpr7_x2p/vpr/SRC/ctags_vpr_src.sh delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.c delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.h delete mode 100644 vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.h rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_api.c => fpga_x2p/base/fpga_x2p_api.c} (50%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.h rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_backannotate_utils.c => fpga_x2p/base/fpga_x2p_backannotate_utils.c} (72%) rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_backannotate_utils.h => fpga_x2p/base/fpga_x2p_backannotate_utils.h} (75%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_globals.c => fpga_x2p/base/fpga_x2p_globals.c} (83%) rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_globals.h => fpga_x2p/base/fpga_x2p_globals.h} (86%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.h rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_setup.c => fpga_x2p/base/fpga_x2p_setup.c} (88%) rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_setup.h => fpga_x2p/base/fpga_x2p_setup.h} (71%) rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_timing_utils.c => fpga_x2p/base/fpga_x2p_timing_utils.c} (99%) rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_timing_utils.h => fpga_x2p/base/fpga_x2p_timing_utils.h} (100%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_types.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_utils.h => fpga_x2p/base/fpga_x2p_utils.h} (51%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/base/quicksort.c (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/base/quicksort.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice/base/fpga_spice_bitstream.c => fpga_x2p/bitstream/fpga_bitstream.c} (69%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/clb_pin_remap/clb_pin_remap_util.c (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/clb_pin_remap/clb_pin_remap_util.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/clb_pin_remap/place_clb_pin_remap.c (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/clb_pin_remap/place_clb_pin_remap.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/clb_pin_remap/post_place_timing.c (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/clb_pin_remap/post_place_timing.h (100%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/router/.fpga_x2p_router.c.swp create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_pb_rr_graph.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_pb_rr_graph.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt_types.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_api.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_cmds.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_file_postfix.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_types.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_api.c (77%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_globals.c (97%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_globals.h (98%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_grid_testbench.c (99%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_grid_testbench.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_heads.c (98%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_heads.h (100%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_mux.c (82%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_mux_testbench.c (83%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_mux_testbench.h (87%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_pbtypes.c (83%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_pbtypes.h (85%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_routing.c (94%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_routing.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_routing_testbench.c (99%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_routing_testbench.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_run_scripts.c (66%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_run_scripts.h (72%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_subckt.c (99%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_subckt.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_top_netlist.c (99%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_top_netlist.h (100%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_utils.c (96%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/spice/spice_utils.h (98%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/verilog/verilog_modelsim_autodeck.c (57%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/verilog/verilog_pbtypes.c (58%) rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/verilog/verilog_pbtypes.h (57%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/verilog/verilog_routing.c (80%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/verilog/verilog_submodules.c (56%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.h rename vpr7_x2p/vpr/SRC/{fpga_spice => fpga_x2p}/verilog/verilog_utils.c (54%) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.c create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.h create mode 100644 vpr7_x2p/vpr/SRC/shell_main.c create mode 100644 vpr7_x2p/vpr/SRC/tags create mode 100644 vpr7_x2p/vpr/SpiceNetlists/adder.sp create mode 100644 vpr7_x2p/vpr/SpiceNetlists/gate.sp create mode 100644 vpr7_x2p/vpr/VerilogNetlists/adder.v delete mode 100644 vpr7_x2p/vpr/VerilogNetlists/ff.v delete mode 100644 vpr7_x2p/vpr/VerilogNetlists/sram.v delete mode 100755 vpr7_x2p/vpr/go.sh create mode 100755 vpr7_x2p/vpr/go_fpga_spice.sh create mode 100755 vpr7_x2p/vpr/go_fpga_verilog.sh delete mode 100755 vpr7_x2p/vpr/picorv.sh delete mode 100644 vpr7_x2p/vpr/picorv/arch.xml diff --git a/vpr7_x2p/libarchfpga/arch/README.txt b/vpr7_x2p/libarchfpga/arch/README.txt deleted file mode 100644 index 88e5886d9..000000000 --- a/vpr7_x2p/libarchfpga/arch/README.txt +++ /dev/null @@ -1,11 +0,0 @@ -This directory contains sample architecture files that are used in testing -libarchfpga. In addition, the architecture files in this directory are used by -the regression testing facilities of Odin II. - -Please be sure to retain sample_arch.xml and update it with any changes that -are made to the libvpr library. - -Ken Kent -ken@unb.ca -06.18.2009 - diff --git a/vpr7_x2p/libarchfpga/arch/mult_luts_arch.xml b/vpr7_x2p/libarchfpga/arch/mult_luts_arch.xml deleted file mode 100644 index 69b3e5d7c..000000000 --- a/vpr7_x2p/libarchfpga/arch/mult_luts_arch.xml +++ /dev/null @@ -1,716 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad io.clock - io.outpad io.inpad io.clock - io.outpad io.inpad io.clock - io.outpad io.inpad io.clock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/libarchfpga/arch/sample_arch.xml b/vpr7_x2p/libarchfpga/arch/sample_arch.xml deleted file mode 100644 index 31047be29..000000000 --- a/vpr7_x2p/libarchfpga/arch/sample_arch.xml +++ /dev/null @@ -1,815 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad io.clock - io.outpad io.inpad io.clock - io.outpad io.inpad io.clock - io.outpad io.inpad io.clock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2.690e-10 - 2.690e-10 - 2.690e-10 - 2.690e-10 - 2.690e-10 - 2.690e-10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2.690e-10 - 2.690e-10 - 2.690e-10 - 2.690e-10 - 2.690e-10 - 2.690e-10 - - - - - 2.690e-10 - - - - - 1.690e-10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/libarchfpga/fpga_spice_include/spice_types.h b/vpr7_x2p/libarchfpga/fpga_spice_include/spice_types.h index ca10c391a..b9b88683a 100644 --- a/vpr7_x2p/libarchfpga/fpga_spice_include/spice_types.h +++ b/vpr7_x2p/libarchfpga/fpga_spice_include/spice_types.h @@ -4,7 +4,8 @@ /* Xifan TANG: Spice support*/ enum e_spice_tech_lib_type { - SPICE_LIB_INDUSTRY,SPICE_LIB_ACADEMIA + SPICE_LIB_INDUSTRY, + SPICE_LIB_ACADEMIA }; enum spice_model_delay_type { @@ -23,10 +24,9 @@ enum e_spice_model_type { SPICE_MODEL_HARDLOGIC, SPICE_MODEL_SCFF, SPICE_MODEL_IOPAD, - SPICE_MODEL_VDD, - SPICE_MODEL_GND, SPICE_MODEL_INVBUF, - SPICE_MODEL_PASSGATE + SPICE_MODEL_PASSGATE, + SPICE_MODEL_GATE }; enum e_spice_model_design_tech { @@ -47,13 +47,21 @@ enum e_spice_model_buffer_type { }; enum e_spice_model_pass_gate_logic_type { - SPICE_MODEL_PASS_GATE_TRANSMISSION, SPICE_MODEL_PASS_GATE_TRANSISTOR + SPICE_MODEL_PASS_GATE_TRANSMISSION, + SPICE_MODEL_PASS_GATE_TRANSISTOR }; +enum e_spice_model_gate_type { + SPICE_MODEL_GATE_AND, + SPICE_MODEL_GATE_OR +}; /* Transistor-level basic informations*/ enum e_spice_trans_type { - SPICE_TRANS_NMOS, SPICE_TRANS_PMOS, SPICE_TRANS_IO_NMOS, SPICE_TRANS_IO_PMOS + SPICE_TRANS_NMOS, + SPICE_TRANS_PMOS, + SPICE_TRANS_IO_NMOS, + SPICE_TRANS_IO_PMOS }; enum e_wire_model_type { @@ -73,6 +81,13 @@ enum e_spice_model_port_type { SPICE_MODEL_PORT_WLB }; +/* For process corner */ +enum e_process_corner { + BEST_CORNER, + TYPICAL_CORNER, + WORST_CORNER +}; + /* For SRAM */ enum e_sram_orgz { SPICE_SRAM_STANDALONE, @@ -84,24 +99,54 @@ enum e_spice_accuracy_type { SPICE_FRAC, SPICE_ABS }; +enum e_spice_pb_port_type { + SPICE_PB_PORT_INPUT, + SPICE_PB_PORT_OUTPUT, + SPICE_PB_PORT_CLOCK +}; + +enum e_spice_ff_trigger_type { + FF_RE, FF_FE +}; + +enum e_spice_tb_type { + SPICE_CB_MUX_TB, + SPICE_SB_MUX_TB, + SPICE_PB_MUX_TB, + SPICE_GRID_TB, + SPICE_SB_TB, + SPICE_CB_TB, + SPICE_LUT_TB, + SPICE_IO_TB, + SPICE_HARDLOGIC_TB +}; + +enum e_spice_pin2pin_interc_type { + INPUT2INPUT_INTERC, + OUTPUT2OUTPUT_INTERC +}; /* typedef of structs */ typedef struct s_spice_transistor_type t_spice_transistor_type; typedef struct s_spice_tech_lib t_spice_tech_lib; +typedef struct s_spice_model_gate t_spice_model_gate; +typedef struct s_spice_model_rram t_spice_model_rram; +typedef struct s_spice_model_mux t_spice_model_mux; +typedef struct s_spice_model_lut t_spice_model_lut; typedef struct s_spice_model_buffer t_spice_model_buffer; typedef struct s_spice_model_pass_gate_logic t_spice_model_pass_gate_logic; typedef struct s_spice_model_port t_spice_model_port; typedef struct s_spice_model_wire_param t_spice_model_wire_param; +typedef struct s_spice_model_tedge t_spice_model_tedge; typedef struct s_spice_model_netlist t_spice_model_netlist; typedef struct s_spice_model_design_tech_info t_spice_model_design_tech_info; +typedef struct s_spice_model_delay_info t_spice_model_delay_info; typedef struct s_spice_model t_spice_model; typedef struct s_spice_meas_params t_spice_meas_params; typedef struct s_spice_stimulate_params t_spice_stimulate_params; typedef struct s_spice_mc_variation_params t_spice_mc_variation_params; -typedef struct s_spice_model_delay_info t_spice_model_delay_info; typedef struct s_spice_mc_params t_spice_mc_params; typedef struct s_spice_params t_spice_params; -typedef struct s_spice_model_tedge t_spice_model_tedge; typedef struct s_spice t_spice; typedef struct s_spice_mux_arch t_spice_mux_arch; typedef struct s_spice_mux_model t_spice_mux_model; @@ -135,13 +180,15 @@ struct s_spice_tech_lib { struct s_spice_model_buffer { int exist; + char* spice_model_name; + char* location_map; + + t_spice_model* spice_model; enum e_spice_model_buffer_type type; float size; int tapered_buf; /*Valid only when this is a buffer*/ int tap_buf_level; int f_per_stage; - char* spice_model_name; - t_spice_model* spice_model; }; struct s_spice_model_pass_gate_logic { @@ -166,17 +213,27 @@ struct s_spice_model_port { enum e_spice_model_port_type type; int size; char* prefix; + char* lib_name; + char* inv_prefix; + /* Mode select port properties */ boolean mode_select; int default_val; + /* Global port properties */ boolean is_global; boolean is_reset; boolean is_set; boolean is_config_enable; boolean is_prog; + /* The spice model that this port will be connected to */ char* spice_model_name; t_spice_model* spice_model; char* inv_spice_model_name; t_spice_model* inv_spice_model; + /* Tri-state map */ + char* tri_state_map; + /* For frac_lut only */ + int lut_frac_level; + int* lut_output_mask; /* Timing edeges linked to other t_model_ports */ int* num_tedges; /* 1-D Array, show number of tedges of each pin */ t_spice_model_tedge*** tedge; /* 3-D array, considering the each pin in this port, [pin_number][num_edges[iedge]] is an edge pointor */ @@ -194,18 +251,7 @@ struct s_spice_model_netlist { int included; }; -struct s_spice_model_delay_info { - enum spice_model_delay_type type; - char* in_port_name; - char* out_port_name; - char* value; - }; - -/* Information about design technology */ -struct s_spice_model_design_tech_info { - /* Valid for SRAM technology */ - t_spice_model_buffer* buffer_info; - t_spice_model_pass_gate_logic* pass_gate_info; +struct s_spice_model_rram { /* Vaild for RRAM technology only, and this is a mux*/ float ron; float roff; @@ -213,12 +259,45 @@ struct s_spice_model_design_tech_info { float wprog_set_pmos; float wprog_reset_nmos; float wprog_reset_pmos; +}; + +struct s_spice_model_mux { /* Mux information only */ enum e_spice_model_structure structure; int mux_num_level; + boolean add_const_input; + int const_input_val; + boolean advanced_rram_design; +}; + +struct s_spice_model_lut { + /* LUT information */ + boolean frac_lut; +}; + +struct s_spice_model_gate { + /* LUT information */ + enum e_spice_model_gate_type type; +}; + +/* Information about design technology */ +struct s_spice_model_design_tech_info { + /* Valid for SRAM technology */ + t_spice_model_buffer* buffer_info; + t_spice_model_pass_gate_logic* pass_gate_info; + t_spice_model_rram* rram_info; + t_spice_model_mux* mux_info; + t_spice_model_lut* lut_info; + t_spice_model_gate* gate_info; /* Power gate information */ boolean power_gated; - boolean advanced_rram_design; +}; + +struct s_spice_model_delay_info { + enum spice_model_delay_type type; + char* in_port_name; + char* out_port_name; + char* value; }; struct s_spice_model { @@ -230,6 +309,7 @@ struct s_spice_model { t_spice_model_netlist* include_netlist; int is_default; boolean dump_structural_verilog; + boolean dump_explicit_port_map; /* type */ enum e_spice_model_design_tech design_tech; @@ -238,6 +318,8 @@ struct s_spice_model { /* buffering information */ t_spice_model_buffer* lut_input_buffer; + t_spice_model_buffer* lut_input_inverter; + t_spice_model_buffer* lut_intermediate_buffer; t_spice_model_buffer* input_buffer; t_spice_model_buffer* output_buffer; t_spice_model_pass_gate_logic* pass_gate_logic; @@ -357,7 +439,8 @@ struct s_spice { /* Information needed to build a Multiplexer architecture*/ struct s_spice_mux_arch { enum e_spice_model_structure structure; - int num_input; + int num_input; /* All Inputs including those connect to constant generator */ + int num_data_input; /* Inputs for multiplexing datapath signals*/ int num_level; int num_input_basis; int num_input_last_level; @@ -483,6 +566,8 @@ struct s_sram_orgz_info { t_llist* conf_bit_head; /* Conf bits information per grid */ + int grid_nx; /* grid size */ + int grid_ny; int** grid_reserved_conf_bits; int** grid_conf_bits_lsb; int** grid_conf_bits_msb; diff --git a/vpr7_x2p/libarchfpga/include/physical_types.h b/vpr7_x2p/libarchfpga/include/physical_types.h index becd8fcfc..a02b7bc5d 100644 --- a/vpr7_x2p/libarchfpga/include/physical_types.h +++ b/vpr7_x2p/libarchfpga/include/physical_types.h @@ -241,6 +241,7 @@ struct s_pb_type; * port_index_by_type index of port by type (index by input, output, or clock) * equivalence: */ +typedef struct s_port t_port; struct s_port { char* name; t_model_ports *model_port; @@ -262,8 +263,14 @@ struct s_port { /* FPGA_SPICE_model support: * mapped SPICE model port */ t_spice_model_port* spice_model_port; + char* physical_mode_pin; + int physical_mode_pin_rotate_offset; /* The pin number will rotate by an offset unit when mapping to physical modes */ + int phy_mode_pin_rotate_offset_acc; /* The pin number will rotate by an offset unit when mapping to physical modes */ + t_port* phy_pb_type_port; + int phy_pb_type_port_lsb; + int phy_pb_type_port_msb; + /* END */ }; -typedef struct s_port t_port; /** * Info placed between pins that can be processed later for additional information @@ -310,6 +317,9 @@ struct s_interconnect { char *input_string; char *output_string; + /* Baudouin Chauviere: SDC generation */ + char *loop_breaker_string; + /* END */ t_pin_to_pin_annotation *annotations; /* [0..num_annotations-1] */ int num_annotations; @@ -328,6 +338,7 @@ struct s_interconnect { int fan_in; int fan_out; int num_mux; + int spice_model_sram_offset; /* END */ t_interconnect_power * interconnect_power; @@ -376,7 +387,7 @@ struct s_mode { */ int define_idle_mode; int define_physical_mode; - int disabled_in_packing; + boolean disabled_in_packing; /* Power releated members */ t_mode_power * mode_power; @@ -396,6 +407,8 @@ enum e_pb_graph_pin_type { PB_PIN_INPAD, PB_PIN_OUTPAD, PB_PIN_TERMINAL, + PB_PIN_INPUT, + PB_PIN_OUTPUT, PB_PIN_CLOCK }; @@ -409,6 +422,7 @@ enum e_pb_graph_pin_type { * parent_node: parent pb_graph_node * pin_count_in_cluster: Unique number for pin inside cluster */ +typedef struct s_pb_graph_pin t_pb_graph_pin; struct s_pb_graph_pin { t_port *port; int pin_number; @@ -421,6 +435,10 @@ struct s_pb_graph_pin { int pin_count_in_cluster; /* Xifan TANG: FPGA-SPICE */ int temp_net_num; + int rr_node_index_physical_pb; /* rr_node in the physical pb rr_graph*/ + t_pb_graph_pin* physical_pb_graph_pin; + char* name_mux; + /* END */ int scratch_pad; /* temporary data structure useful to store traversal info */ @@ -444,7 +462,6 @@ struct s_pb_graph_pin { t_pb_graph_pin_power * pin_power; }; -typedef struct s_pb_graph_pin t_pb_graph_pin; struct s_pb_graph_pin_power { /* Transistor-level Power Properties */ @@ -524,6 +541,11 @@ struct s_pb_graph_edge { int num_pack_patterns; boolean infer_pattern; /*If TRUE, infer pattern based on patterns connected to it*/ + /* Baudouin Chauviere: SDC Generation */ + boolean is_disabled; + int nb_mux; + int nb_pin; + /* END */ }; typedef struct s_pb_graph_edge t_pb_graph_edge; @@ -573,6 +595,10 @@ struct s_pb_graph_node { t_pb_graph_node_power * pb_node_power; t_interconnect_pins ** interconnect_pins; /* [0..num_modes-1][0..num_interconnect_in_mode] */ + /* Xifan Tang: FPGA-SPICE */ + t_pb_graph_node* physical_pb_graph_node; /* physical pb_graph_node */ + int placement_index_in_top_node; /* index at the top-level pb_graph node */ + /* END */ }; struct s_pb_graph_node_power { @@ -623,6 +649,13 @@ struct s_pb_type { char* spice_model_name; t_spice_model* spice_model; char* mode_bits; /* Mode bits to select */ + int spice_model_sram_offset; + char* physical_pb_type_name; + struct s_pb_type* phy_pb_type; + float physical_pb_type_index_factor; + int physical_pb_type_index_offset; + int temp_placement_index; + /* END */ /* Power related members */ t_pb_type_power * pb_type_power; @@ -636,6 +669,7 @@ struct s_pb_type { int default_mode_num_conf_bits; int default_mode_num_mode_bits; int default_mode_num_iopads; + /* END */ }; typedef struct s_pb_type t_pb_type; diff --git a/vpr7_x2p/libarchfpga/read_xml_arch_file.c b/vpr7_x2p/libarchfpga/read_xml_arch_file.c index c797fb1ac..c6dcd3b30 100644 --- a/vpr7_x2p/libarchfpga/read_xml_arch_file.c +++ b/vpr7_x2p/libarchfpga/read_xml_arch_file.c @@ -927,6 +927,19 @@ static void ProcessPb_Type(INOUTP ezxml_t Parent, t_pb_type * pb_type, pb_type->num_pb = GetIntProperty(Parent, "num_pb", TRUE, 0); } + /* Xifan TANG: FPGA_SPICE, multi-mode support */ + Prop = FindProperty(Parent, "physical_pb_type_name", FALSE); + pb_type->physical_pb_type_name = my_strdup(Prop); + ezxml_set_attr(Parent, "physical_pb_type_name", NULL); + + pb_type->physical_pb_type_index_factor = GetFloatProperty(Parent, "physical_pb_type_index_factor", FALSE, 1.0); + ezxml_set_attr(Parent, "physical_pb_type_index_factor", NULL); + + pb_type->physical_pb_type_index_offset = GetIntProperty(Parent, "physical_pb_type_index_offset", FALSE, 0); + ezxml_set_attr(Parent, "physical_pb_type_index_offset", NULL); + + /* END */ + assert(pb_type->num_pb > 0); num_ports = 0; num_ports += CountChildren(Parent, "input", 0); @@ -1004,14 +1017,20 @@ static void ProcessPb_Type(INOUTP ezxml_t Parent, t_pb_type * pb_type, * We should have a spice_model_name if this mode defines the transistor-level circuit design * Since this is a leaf node */ - pb_type->spice_model_name = my_strdup(FindProperty(Parent, "circuit_model_name", FALSE)); + pb_type->spice_model_name = my_strdup(FindProperty(Parent, "spice_model_name", FALSE)); pb_type->spice_model = NULL; - ezxml_set_attr(Parent,"circuit_model_name",NULL); - /* We can read the mode configuration bits if they are defined */ - if (NULL != pb_type->spice_model_name) { - pb_type->mode_bits = my_strdup(FindProperty(Parent, "mode_bits", FALSE)); - ezxml_set_attr(Parent,"mode_bits",NULL); - } + ezxml_set_attr(Parent, "spice_model_name", NULL); + /* Multi-mode CLB support: + * We can read the mode configuration bits if they are defined + */ + pb_type->mode_bits = my_strdup(FindProperty(Parent, "mode_bits", FALSE)); + ezxml_set_attr(Parent, "mode_bits", NULL); + /* Multi-mode CLB support: + * Specify the offset in sram bits of a spice_model + * This will determine which SRAMs will be configured by this pb_type configuration bits + */ + pb_type->spice_model_sram_offset = GetIntProperty(Parent, "spice_model_sram_offset", FALSE, 0); + ezxml_set_attr(Parent, "spice_model_sram_offset", NULL); /* End Spice Model Support*/ /* Determine if this is a leaf or container pb_type */ @@ -1090,8 +1109,17 @@ static void ProcessPb_Type(INOUTP ezxml_t Parent, t_pb_type * pb_type, * We don't need to search the spice_model_mode_name at this level. * There is only one mode, so it should herit. */ - if (do_spice) { + /* We need to identify the physical mode that refers to physical design interests */ + pb_type->idle_mode_name = my_strdup(FindProperty(Parent,"idle_mode_name", FALSE)); + ezxml_set_attr(Parent,"idle_mode_name",NULL); + if (NULL == pb_type->idle_mode_name) { pb_type->idle_mode_name = my_strdup(pb_type->name); + } + /* Only when the parent mode is a physical mode, we can do this */ + pb_type->physical_mode_name = my_strdup(FindProperty(Parent, "physical_mode_name", FALSE)); + ezxml_set_attr(Parent,"physical_mode_name",NULL); + if (((NULL == pb_type->physical_mode_name) && (NULL == pb_type->parent_mode)) + || ((NULL == pb_type->physical_mode_name) && (NULL != pb_type->parent_mode) && (1 == pb_type->parent_mode->define_physical_mode))) { pb_type->physical_mode_name = my_strdup(pb_type->name); } /*END*/ @@ -1110,12 +1138,7 @@ static void ProcessPb_Type(INOUTP ezxml_t Parent, t_pb_type * pb_type, } ezxml_set_attr(Parent,"idle_mode_name",NULL); /* We need to identify the physical mode that refers to physical design interests */ - if (FindProperty(Parent,"physical_mode_name", do_spice)) { - pb_type->physical_mode_name = my_strdup(FindProperty(Parent,"physical_mode_name",TRUE)); - } else if (do_spice) { - vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d]Pb_Type has more than 1 mode, should define a physical_mode_name.\n",Parent->line); - exit(1); - } + pb_type->physical_mode_name = my_strdup(FindProperty(Parent,"physical_mode_name", FALSE)); ezxml_set_attr(Parent,"physical_mode_name",NULL); /*END*/ pb_type->modes = (t_mode*) my_calloc(pb_type->num_modes, @@ -1268,11 +1291,21 @@ static void ProcessPb_TypePort(INOUTP ezxml_t Parent, t_port * port, ezxml_set_attr(Parent, "chain", NULL); port->equivalent = GetBooleanProperty(Parent, "equivalent", FALSE, FALSE); + ezxml_set_attr(Parent, "equivalent", NULL); port->num_pins = GetIntProperty(Parent, "num_pins", TRUE, 0); port->is_non_clock_global = GetBooleanProperty(Parent, "is_non_clock_global", FALSE, FALSE); + /* FPGA-SPICE multi-mode CLB support */ + Prop = FindProperty(Parent, "physical_mode_pin", FALSE); + port->physical_mode_pin = my_strdup(Prop); + ezxml_set_attr(Parent, "physical_mode_pin", NULL); + + port->physical_mode_pin_rotate_offset = GetIntProperty(Parent, "physical_mode_pin_rotate_offset", FALSE, 0); + ezxml_set_attr(Parent, "physical_mode_pin_rotate_offset", NULL); + /* END */ + if (0 == strcmp(Parent->name, "input")) { port->type = IN_PORT; port->is_clock = FALSE; @@ -1330,8 +1363,9 @@ static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) { mode->interconnect[i].type = MUX_INTERC; } + /* Xifan TANG: SPICE Support */ - Prop = FindProperty(Cur, "circuit_model_name", FALSE); + Prop = FindProperty(Cur, "spice_model_name", FALSE); /* Default spice_model will be define later*/ mode->interconnect[i].spice_model_name = my_strdup(Prop); mode->interconnect[i].spice_model = NULL; @@ -1339,7 +1373,10 @@ static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) { mode->interconnect[i].fan_in = 0; mode->interconnect[i].fan_out = 0; mode->interconnect[i].num_mux = 0; - ezxml_set_attr(Cur, "circuit_model_name", NULL); + ezxml_set_attr(Cur, "spice_model_name", NULL); + /* Get sram offset */ + mode->interconnect[i].spice_model_sram_offset = GetIntProperty(Cur, "spice_model_sram_offset", FALSE, 0); + ezxml_set_attr(Cur, "spice_model_sram_offset", NULL); /* END */ mode->interconnect[i].line_num = Cur->line; @@ -1359,6 +1396,23 @@ static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) { mode->interconnect[i].name = my_strdup(Prop); ezxml_set_attr(Cur, "name", NULL); + /* Baudouin Chauviere: SDC generation */ + /* Check if property exists */ + if (Prop = FindProperty(Cur, "loop_breaker", FALSE)) { + /* Check if property exists and is true */ + /*if (0 == strcmp(Prop,"TRUE") || 0 == strcmp(Prop,"true")) {*/ + if (0 == strcmp(Cur->name, "direct")) { + vpr_printf(TIO_MESSAGE_ERROR, + "[Line %d] loop_breaker not supported for '%s'.\n", + Parent->line, Cur->name); + exit(1); + } + //if ( + mode->interconnect[i].loop_breaker_string= my_strdup(Prop); + } + ezxml_set_attr(Cur, "loop_breaker", NULL); + /* END */ + /* Process delay and capacitance annotations */ num_annotations = 0; num_annotations += CountChildren(Cur, "delay_constant", 0); @@ -1366,7 +1420,7 @@ static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) { num_annotations += CountChildren(Cur, "C_constant", 0); num_annotations += CountChildren(Cur, "C_matrix", 0); num_annotations += CountChildren(Cur, "pack_pattern", 0); - /* Xifan TANG: FPGA-SPICE, mode select description */ + /* Xifan TANG: FPGA-SPICE, mode select description for multi-mode CLB */ num_annotations += CountChildren(Cur, "mode_select", 0); /* END FPGA-SPICE, mode select description */ @@ -1448,31 +1502,43 @@ static void ProcessMode(INOUTP ezxml_t Parent, t_mode * mode, * The mode should herit the define_spice_model from its parent */ if (do_spice) { - if (0 == strcmp(mode->name, mode->parent_pb_type->idle_mode_name)) { - if (NULL == mode->parent_pb_type->parent_mode) { - mode->define_idle_mode = 1; + if (0 == strcmp(mode->name, mode->parent_pb_type->idle_mode_name)) { + if (NULL == mode->parent_pb_type->parent_mode) { + mode->define_idle_mode = 1; + } else { + mode->define_idle_mode = mode->parent_pb_type->parent_mode->define_idle_mode; + } } else { - mode->define_idle_mode = mode->parent_pb_type->parent_mode->define_idle_mode; + mode->define_idle_mode = 0; } - } else { - mode->define_idle_mode = 0; - } - /* For physical design mode */ - if (0 == strcmp(mode->name, mode->parent_pb_type->physical_mode_name)) { - if (NULL == mode->parent_pb_type->parent_mode) { - mode->define_physical_mode = 1; + /* For physical design mode + * This is different from idle mode: + * If the parent is not a physical mode, then this is definitely not a physical mode + */ + if (NULL == mode->parent_pb_type->physical_mode_name) { + mode->define_physical_mode = 0; } else { - mode->define_physical_mode = mode->parent_pb_type->parent_mode->define_physical_mode; + if (0 == strcmp(mode->name, mode->parent_pb_type->physical_mode_name)) { + if (NULL == mode->parent_pb_type->parent_mode) { + mode->define_physical_mode = 1; + } else { + mode->define_physical_mode = mode->parent_pb_type->parent_mode->define_physical_mode; + } + } else { + mode->define_physical_mode = 0; + } } - } else { - mode->define_physical_mode = 0; - } } /* Spice Model Support: Xifan TANG * More option: specify if this mode is available during packing */ - mode->disabled_in_packing = GetBooleanProperty(Parent, "disabled_in_packing", FALSE, FALSE); - ezxml_set_attr(Parent, "disabled_in_packing", NULL); + mode->disabled_in_packing = FALSE; /* Default should be FALSE */ + if (NULL != mode->parent_pb_type->parent_mode) { + /* If the parent mode is disabled in packing, all the child mode should be disabled as well */ + mode->disabled_in_packing = mode->parent_pb_type->parent_mode->disabled_in_packing; + } + /* Override if the user specify */ + mode->disabled_in_packing = GetBooleanProperty(Parent, "disabled_in_packing", FALSE, mode->disabled_in_packing); /* END */ mode->num_pb_type_children = CountChildren(Parent, "pb_type", 0); @@ -2220,7 +2286,10 @@ void ProcessLutClass(INOUTP t_pb_type *lut_pb_type) { lut_pb_type->modes[0].mode_power = (t_mode_power*) my_calloc(1, sizeof(t_mode_power)); /* Xifan TANG: LUT default idle mode */ - lut_pb_type->modes[0].define_idle_mode = 1; + lut_pb_type->modes[0].define_idle_mode = 0; + /* Xifan TANG: LUT default physical mode: special for LUT: mode 1 should never to be true */ + lut_pb_type->modes[0].define_physical_mode = FALSE; + /* END */ /* Process interconnect */ /* TODO: add timing annotations to route-through */ @@ -2310,7 +2379,8 @@ void ProcessLutClass(INOUTP t_pb_type *lut_pb_type) { lut_pb_type->modes[1].pb_type_children); /* Xifan TANG: LUT default idle mode */ - lut_pb_type->modes[1].define_idle_mode = 0; + lut_pb_type->modes[1].define_idle_mode = 1; + lut_pb_type->modes[1].define_physical_mode = lut_pb_type->parent_mode->define_physical_mode; /* moved annotations to child so delete old annotations */ for (i = 0; i < lut_pb_type->num_annotations; i++) { for (j = 0; j < lut_pb_type->annotations[i].num_value_prop_pairs; j++) { @@ -2452,6 +2522,7 @@ static void ProcessMemoryClass(INOUTP t_pb_type *mem_pb_type) { /* Xifan TANG: Memory default idle mode */ mem_pb_type->modes[0].define_idle_mode = 1; + mem_pb_type->modes[0].define_physical_mode = mem_pb_type->parent_mode->define_physical_mode; /* Process interconnect */ i_inter = 0; @@ -2758,7 +2829,18 @@ void XmlReadArch(INP const char *ArchFile, INP boolean timing_enabled, /* Xifan TANG: HSPICE Support*/ Next = FindElement(Cur,"spice_settings", arch->read_xml_spice); // Not mandatory options but we will check it later if (Next) { - ProcessSpiceSettings(Next,arch->spice); + /* This information still needs to be read, even if it is just + * thrown away. + */ + /* Allocate */ + if (TRUE == arch->read_xml_spice) { + vpr_printf(TIO_MESSAGE_INFO, "Parsing XML syntax for FPGA X2P...\n"); + ProcessSpiceSettings(Next,arch->spice); + } else { + t_spice* spice_fake = (t_spice*) my_calloc(1, sizeof(t_spice)); + ProcessSpiceSettings(Next, spice_fake); + free(spice_fake); + } FreeNode(Next); } /* end */ @@ -3056,9 +3138,9 @@ static void ProcessSegments(INOUTP ezxml_t Parent, (*Segs)[i].Rmetal = GetFloatProperty(Node, "Rmetal", timing_enabled, 0); (*Segs)[i].Cmetal = GetFloatProperty(Node, "Cmetal", timing_enabled, 0); /* Xifan TANG: SPICE Model Support*/ - (*Segs)[i].spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", FALSE)); + (*Segs)[i].spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", FALSE)); (*Segs)[i].spice_model = NULL; - ezxml_set_attr(Node, "circuit_model_name", NULL); + ezxml_set_attr(Node, "spice_model_name", NULL); /* Get Power info */ /* (*Segs)[i].Cmetal_per_m = GetFloatProperty(Node, "Cmetal_per_m", FALSE, @@ -3334,9 +3416,9 @@ static void ProcessSwitches(INOUTP ezxml_t Parent, FALSE, 1); /* Xifan TANG: Spice Model Support */ - (*Switches)[i].spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", FALSE)); + (*Switches)[i].spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", FALSE)); (*Switches)[i].spice_model = NULL; - ezxml_set_attr(Node, "circuit_model_name", NULL); + ezxml_set_attr(Node, "spice_model_name", NULL); /* Xifan TANG : Read in MUX structure*/ /* Default, we use tree */ structure_type = FindProperty(Node, "structure", FALSE); @@ -3449,9 +3531,9 @@ static void ProcessDirects(INOUTP ezxml_t Parent, OUTP t_direct_inf **Directs, /* Spice Model Support: Xifan TANG * We should have a spice_model_name for this direct connection */ - (*Directs)[i].spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", FALSE)); + (*Directs)[i].spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", FALSE)); (*Directs)[i].spice_model = NULL; - ezxml_set_attr(Node,"circuit_model_name",NULL); + ezxml_set_attr(Node,"spice_model_name",NULL); (*Directs)[i].line = Node->line; diff --git a/vpr7_x2p/libarchfpga/read_xml_spice.c b/vpr7_x2p/libarchfpga/read_xml_spice.c index 490c4f8f1..4ad60afb4 100644 --- a/vpr7_x2p/libarchfpga/read_xml_spice.c +++ b/vpr7_x2p/libarchfpga/read_xml_spice.c @@ -451,8 +451,8 @@ static void ProcessSpiceModelBuffer(ezxml_t Node, read_spice_model = FALSE; } - buffer->spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", read_spice_model)); - ezxml_set_attr(Node, "circuit_model_name", NULL); + buffer->spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", read_spice_model)); + ezxml_set_attr(Node, "spice_model_name", NULL); /*Find Type*/ Prop = my_strdup(FindProperty(Node, "topology", read_buf_info)); @@ -475,9 +475,9 @@ static void ProcessSpiceModelBuffer(ezxml_t Node, if (0 == strcmp(Prop,"on")) { buffer->tapered_buf = 1; /* Try to dig more properites ...*/ - buffer->tap_buf_level = GetIntProperty(Node, "tap_drive_level", TRUE, 1); + buffer->tap_buf_level = GetIntProperty(Node, "tap_buf_level", TRUE, 1); buffer->f_per_stage = GetIntProperty(Node, "f_per_stage", FALSE, 4); - ezxml_set_attr(Node, "tap_drive_level", NULL); + ezxml_set_attr(Node, "tap_buf_level", NULL); ezxml_set_attr(Node, "f_per_stage", NULL); } else if (0 == strcmp(FindProperty(Node,"tapered",TRUE),"off")) { buffer->tapered_buf = 0; @@ -493,6 +493,10 @@ static void ProcessSpiceModelBuffer(ezxml_t Node, buffer->size = GetFloatProperty(Node, "size", read_buf_info, 0.); ezxml_set_attr(Node, "size", NULL); + /* Read location map */ + buffer->location_map = my_strdup(FindProperty(Node, "location_map", FALSE)); + ezxml_set_attr(Node, "location_map", NULL); + return; } @@ -521,8 +525,151 @@ static void ProcessSpiceModelPassGateLogic(ezxml_t Node, return; } +static void ProcessSpiceModelRRAM(ezxml_t Node, + t_spice_model_rram* rram_info) { + rram_info->ron = GetFloatProperty(Node,"ron",TRUE,0); + ezxml_set_attr(Node, "ron", NULL); + + rram_info->roff = GetFloatProperty(Node,"roff",TRUE,0); + ezxml_set_attr(Node, "roff", NULL); + + rram_info->wprog_set_nmos = GetFloatProperty(Node,"wprog_set_nmos",TRUE,0); + ezxml_set_attr(Node, "wprog_set_nmos", NULL); + + rram_info->wprog_set_pmos = GetFloatProperty(Node,"wprog_set_pmos",TRUE,0); + ezxml_set_attr(Node, "wprog_set_nmos", NULL); + + rram_info->wprog_reset_nmos = GetFloatProperty(Node,"wprog_reset_nmos",TRUE,0); + ezxml_set_attr(Node, "wprog_reset_nmos", NULL); + + rram_info->wprog_reset_pmos = GetFloatProperty(Node,"wprog_reset_pmos",TRUE,0); + ezxml_set_attr(Node, "wprog_reset_pmos", NULL); + + return; +} + +static void ProcessSpiceModelMUX(ezxml_t Node, + t_spice_model* spice_model, + t_spice_model_mux* mux_info) { + /* Default: tree, no const_inputs */ + mux_info->structure = SPICE_MODEL_STRUCTURE_TREE; + mux_info->add_const_input = FALSE; + mux_info->const_input_val = 0; + + if (0 == strcmp(FindProperty(Node,"structure",TRUE),"tree")) { + mux_info->structure = SPICE_MODEL_STRUCTURE_TREE; + } else if (0 == strcmp(FindProperty(Node,"structure",TRUE),"one-level")) { + mux_info->structure = SPICE_MODEL_STRUCTURE_ONELEVEL; + } else if (0 == strcmp(FindProperty(Node,"structure",TRUE),"multi-level")) { + mux_info->structure = SPICE_MODEL_STRUCTURE_MULTILEVEL; + /* New Structure: crossbar + } else if (0 == strcmp(FindProperty(Node,"structure",TRUE),"crossbar")) { + spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_CROSSBAR; + */ + } else { + /* Set default to RRAM MUX */ + if (SPICE_MODEL_DESIGN_RRAM == spice_model->design_tech) { + mux_info->structure = SPICE_MODEL_STRUCTURE_ONELEVEL; + } else { + /* Set default to SRAM MUX */ + mux_info->structure = SPICE_MODEL_STRUCTURE_TREE; + } + } + /* Parse the const inputs */ + mux_info->add_const_input = GetBooleanProperty(Node, "add_const_input", FALSE, FALSE); + mux_info->const_input_val = GetIntProperty(Node, "const_input_val", FALSE, 0); + + ezxml_set_attr(Node, "structure", NULL); + ezxml_set_attr(Node, "add_const_input", NULL); + ezxml_set_attr(Node, "const_input_val", NULL); + + if (SPICE_MODEL_STRUCTURE_MULTILEVEL == mux_info->structure) { + mux_info->mux_num_level = GetIntProperty(Node,"num_level",TRUE,1); + /* For num_level == 1, auto convert to one-level structure */ + if (1 == mux_info->mux_num_level) { + mux_info->structure = SPICE_MODEL_STRUCTURE_ONELEVEL; + vpr_printf(TIO_MESSAGE_INFO,"[LINE%d] Automatically convert structure of spice model(%s) to one-level.\n", + Node->line, spice_model->name); + } + } else if (SPICE_MODEL_STRUCTURE_ONELEVEL == mux_info->structure) { + /* Set mux_num_level for other structure: one-level and tree */ + mux_info->mux_num_level = 1; + } + ezxml_set_attr(Node, "num_level", NULL); + /* Specify if should use the advanced 4T1R MUX design */ + mux_info->advanced_rram_design = GetBooleanProperty(Node,"advanced_rram_design", FALSE, FALSE); + ezxml_set_attr(Node, "advanced_rram_design", NULL); + + return; +} + +static void ProcessSpiceModelLUT(ezxml_t Node, + t_spice_model_lut* lut_info) { + lut_info->frac_lut = GetBooleanProperty(Node,"fracturable_lut", FALSE, FALSE); + + return; +} + +static void ProcessSpiceModelGate(ezxml_t Node, + t_spice_model_gate* gate_info) { + if (0 == strcmp(FindProperty(Node,"topology",TRUE),"AND")) { + gate_info->type = SPICE_MODEL_GATE_AND; + } else if (0 == strcmp(FindProperty(Node,"topology",TRUE),"OR")) { + gate_info->type = SPICE_MODEL_GATE_OR; + } else { + vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid topology of gates. Should be [AND|OR].\n", + Node->line); + exit(1); + } + ezxml_set_attr(Node, "topology", NULL); + + return; +} + +static void ProcessSpiceModelPortLutOutputMask(ezxml_t Node, + t_spice_model_port* port) { + + const char* Prop = NULL; + int ipin; + char* Prop_cpy = NULL; + char* pch = NULL; + + port->lut_output_mask = (int*) my_malloc (sizeof(int) * port->size); + + Prop = FindProperty(Node, "lut_output_mask", FALSE); + + if (NULL == Prop) { + /* give a default value */ + for (ipin = 0; ipin < port->size; ipin++) { + port->lut_output_mask[ipin] = ipin; + } + } else { + /* decode the output_maski, split the string by "," */ + ipin = 0; + Prop_cpy = my_strdup(Prop); + pch = strtok(Prop_cpy, ","); + while (NULL != pch) { + port->lut_output_mask[ipin] = my_atoi(pch); + ipin++; + pch = strtok(NULL, ","); + } + /* Error out, fail to match the port size*/ + if (ipin != port->size) { + vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid lut_output_mask(%s): Fail to match the port size (%d).\n", + Node->line, Prop, port->size); + exit(1); + } + } + + ezxml_set_attr(Node, "lut_output_mask", NULL); + + return; +} + + static void ProcessSpiceModelPort(ezxml_t Node, t_spice_model_port* port) { + if (0 == strcmp(FindProperty(Node,"type",TRUE),"input")) { port->type = SPICE_MODEL_PORT_INPUT; } else if (0 == strcmp(FindProperty(Node,"type",TRUE),"output")) { @@ -548,9 +695,19 @@ static void ProcessSpiceModelPort(ezxml_t Node, } ezxml_set_attr(Node, "type", NULL); /* Assign prefix and size*/ - port->prefix = my_strdup(FindProperty(Node,"prefix",TRUE)); + port->prefix = my_strdup(FindProperty(Node, "prefix", TRUE)); ezxml_set_attr(Node, "prefix", NULL); - port->size = GetIntProperty(Node,"size",TRUE,1); + /* Assign port name in the std library + * Ff not found, it will be by default the same as prefix */ + port->lib_name = my_strdup(FindProperty(Node, "lib_name", FALSE)); + ezxml_set_attr(Node, "lib_name", NULL); + if (NULL == port->lib_name) { + port->lib_name = my_strdup(port->prefix); + } + /* Create an inverter prefix to ease the mapping to standard cells */ + port->inv_prefix = my_strdup(FindProperty(Node, "inv_prefix", FALSE)); + ezxml_set_attr(Node, "inv_prefix", NULL); + port->size = GetIntProperty(Node, "size", TRUE, 1); ezxml_set_attr(Node, "size", NULL); /* See if this is a mode selector. @@ -564,6 +721,17 @@ static void ProcessSpiceModelPort(ezxml_t Node, port->default_val = GetIntProperty(Node, "default_val", FALSE, 0); ezxml_set_attr(Node, "default_val", NULL); + /* Tri-state map */ + port->tri_state_map = my_strdup(FindProperty(Node, "tri_state_map", FALSE)); + ezxml_set_attr(Node, "tri_state_map", NULL); + + /* fracturable LUT: define at which level the output should be fractured */ + port->lut_frac_level = GetIntProperty(Node, "lut_frac_level", FALSE, -1); + ezxml_set_attr(Node, "lut_frac_level", NULL); + + /* Output mast of a fracturable LUT, which is to identify which intermediate LUT output will be connected to outputs */ + ProcessSpiceModelPortLutOutputMask(Node, port); + /* See if this is a global signal * We assume that global signals are shared by all the SPICE Model/blocks. * We need to check if other SPICE model has the same port name @@ -584,51 +752,49 @@ static void ProcessSpiceModelPort(ezxml_t Node, ezxml_set_attr(Node, "is_config_enable", NULL); /* Check if this port is linked to another spice_model*/ - port->spice_model_name = my_strdup(FindProperty(Node,"circuit_model_name",FALSE)); - ezxml_set_attr(Node, "circuit_model_name", NULL); + port->spice_model_name = my_strdup(FindProperty(Node,"spice_model_name",FALSE)); + ezxml_set_attr(Node, "spice_model_name", NULL); /* For BL/WL, BLB/WLB ports, we need to get the spice_model for inverters */ if ((SPICE_MODEL_PORT_BL == port->type) ||(SPICE_MODEL_PORT_WL == port->type) ||(SPICE_MODEL_PORT_BLB == port->type) ||(SPICE_MODEL_PORT_WLB == port->type)) { - port->inv_spice_model_name = my_strdup(FindProperty(Node, "inv_circuit_model_name", FALSE)); - ezxml_set_attr(Node, "inv_circuit_model_name", NULL); + port->inv_spice_model_name = my_strdup(FindProperty(Node, "inv_spice_model_name", FALSE)); + ezxml_set_attr(Node, "inv_spice_model_name", NULL); } return; } - static - void ProcessSpiceModelDelayInfo(ezxml_t Node, - t_spice_model_delay_info* cur_delay_info) { - char* delay_str = NULL; +static +void ProcessSpiceModelDelayInfo(ezxml_t Node, + t_spice_model_delay_info* cur_delay_info) { + /* Find the type */ + if (0 == strcmp(FindProperty(Node, "type", TRUE), "rise")) { + cur_delay_info->type = SPICE_MODEL_DELAY_RISE; + } else if (0 == strcmp(FindProperty(Node, "type", TRUE), "fall")) { + cur_delay_info->type = SPICE_MODEL_DELAY_FALL; + } else { + vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid type of delay_info. Should be [rise|fall].\n", + Node->line); + exit(1); + } + ezxml_set_attr(Node, "type", NULL); - /* Find the type */ - if (0 == strcmp(FindProperty(Node, "type", TRUE), "rise")) { - cur_delay_info->type = SPICE_MODEL_DELAY_RISE; - } else if (0 == strcmp(FindProperty(Node, "type", TRUE), "fall")) { - cur_delay_info->type = SPICE_MODEL_DELAY_FALL; - } else { - vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid type of delay_info. Should be [rise|fall].\n", - Node->line); - exit(1); - } - ezxml_set_attr(Node, "type", NULL); + /* Find the input and output ports */ + cur_delay_info->in_port_name = my_strdup(FindProperty(Node, "in_port", TRUE)); + ezxml_set_attr(Node, "in_port", NULL); - /* Find the input and output ports */ - cur_delay_info->in_port_name = my_strdup(FindProperty(Node, "in_port", TRUE)); - ezxml_set_attr(Node, "in_port", NULL); + cur_delay_info->out_port_name = my_strdup(FindProperty(Node, "out_port", TRUE)); + ezxml_set_attr(Node, "out_port", NULL); - cur_delay_info->out_port_name = my_strdup(FindProperty(Node, "out_port", TRUE)); - ezxml_set_attr(Node, "out_port", NULL); + /* Find delay matrix */ + cur_delay_info->value = my_strdup(Node->txt); + ezxml_set_txt(Node, ""); - /* Find delay matrix */ - cur_delay_info->value = my_strdup(Node->txt); - ezxml_set_txt(Node, ""); - - return; - } + return; +} static void ProcessSpiceModelWireParam(ezxml_t Parent, t_spice_model_wire_param* wire_param) { @@ -667,8 +833,6 @@ static void ProcessSpiceModel(ezxml_t Parent, spice_model->type = SPICE_MODEL_CHAN_WIRE; } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"wire")) { spice_model->type = SPICE_MODEL_WIRE; - } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"hard_logic")) { - spice_model->type = SPICE_MODEL_HARDLOGIC; } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"lut")) { spice_model->type = SPICE_MODEL_LUT; } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"ff")) { @@ -681,16 +845,14 @@ static void ProcessSpiceModel(ezxml_t Parent, spice_model->type = SPICE_MODEL_SCFF; } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"iopad")) { spice_model->type = SPICE_MODEL_IOPAD; - } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"wire_vdd")) { - spice_model->type = SPICE_MODEL_VDD; - } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"wire_gnd")) { - spice_model->type = SPICE_MODEL_GND; } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"inv_buf")) { spice_model->type = SPICE_MODEL_INVBUF; } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"pass_gate")) { spice_model->type = SPICE_MODEL_PASSGATE; + } else if (0 == strcmp(FindProperty(Parent,"type",TRUE),"gate")) { + spice_model->type = SPICE_MODEL_GATE; } else { - vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid type of spice model(%s). Should be [mux|lut|ff|io|sram|hard_logic|sff].\n", + vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid type of spice model(%s). Should be [chan_wire|wire|mux|lut|ff|sram|hard_logic|sff|iopad|inv_buf|pass_gate|gate].\n", Parent->line, FindProperty(Parent, "type", TRUE)); exit(1); } @@ -719,6 +881,10 @@ static void ProcessSpiceModel(ezxml_t Parent, /* Find a verilog_netlist path if we can*/ spice_model->dump_structural_verilog = GetBooleanProperty(Parent,"dump_structural_verilog", FALSE, FALSE); ezxml_set_attr(Parent, "dump_structural_verilog", NULL); + + /* Find a verilog_netlist path if we can*/ + spice_model->dump_explicit_port_map = GetBooleanProperty(Parent,"dump_explicit_port_map", FALSE, FALSE); + ezxml_set_attr(Parent, "dump_explicit_port_map", NULL); /* Check the design technology settings*/ Node = ezxml_child(Parent, "design_technology"); @@ -748,80 +914,64 @@ static void ProcessSpiceModel(ezxml_t Parent, } } else if (0 == strcmp(FindProperty(Node,"type",TRUE),"rram")) { spice_model->design_tech = SPICE_MODEL_DESIGN_RRAM; - /* RRAM tech. We need more properties*/ - spice_model->design_tech_info.ron = GetFloatProperty(Node,"ron",TRUE,0); - ezxml_set_attr(Node, "ron", NULL); - spice_model->design_tech_info.roff = GetFloatProperty(Node,"roff",TRUE,0); - ezxml_set_attr(Node, "roff", NULL); - spice_model->design_tech_info.wprog_set_nmos = GetFloatProperty(Node,"wprog_set_nmos",TRUE,0); - ezxml_set_attr(Node, "wprog_set_nmos", NULL); - spice_model->design_tech_info.wprog_set_pmos = GetFloatProperty(Node,"wprog_set_pmos",TRUE,0); - ezxml_set_attr(Node, "wprog_set_nmos", NULL); - spice_model->design_tech_info.wprog_reset_nmos = GetFloatProperty(Node,"wprog_reset_nmos",TRUE,0); - ezxml_set_attr(Node, "wprog_reset_nmos", NULL); - spice_model->design_tech_info.wprog_reset_pmos = GetFloatProperty(Node,"wprog_reset_pmos",TRUE,0); - ezxml_set_attr(Node, "wprog_reset_pmos", NULL); + /* Malloc RRAM info */ + spice_model->design_tech_info.rram_info = (t_spice_model_rram*)my_malloc(sizeof(t_spice_model_rram)); + /* Fill information */ + ProcessSpiceModelRRAM(Node, spice_model->design_tech_info.rram_info); } else { vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] Invalid value for design_technology in spice model(%s). Should be [cmos|rram].\n", Node->line,spice_model->name); exit(1); } ezxml_set_attr(Node, "type", NULL); + /* Read in the structure if defined */ + spice_model->design_tech_info.mux_info = NULL; if (SPICE_MODEL_MUX == spice_model->type) { - if (0 == strcmp(FindProperty(Node,"structure",TRUE),"tree")) { - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_TREE; - } else if (0 == strcmp(FindProperty(Node,"structure",TRUE),"one-level")) { - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_ONELEVEL; - } else if (0 == strcmp(FindProperty(Node,"structure",TRUE),"multi-level")) { - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_MULTILEVEL; - /* New Structure: crossbar - } else if (0 == strcmp(FindProperty(Node,"structure",TRUE),"crossbar")) { - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_CROSSBAR; - */ - } else { - /* Set default to RRAM MUX */ - if (SPICE_MODEL_DESIGN_RRAM == spice_model->design_tech) { - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_ONELEVEL; - } else { - /* Set default to SRAM MUX */ - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_TREE; - } - } - } else { - /* Default: tree */ - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_TREE; + /* Malloc */ + spice_model->design_tech_info.mux_info = (t_spice_model_mux*)my_malloc(sizeof(t_spice_model_mux)); + /* Fill information */ + ProcessSpiceModelMUX(Node, spice_model, spice_model->design_tech_info.mux_info); } - ezxml_set_attr(Node, "structure", NULL); - if (SPICE_MODEL_STRUCTURE_MULTILEVEL == spice_model->design_tech_info.structure) { - spice_model->design_tech_info.mux_num_level = GetIntProperty(Node,"num_level",TRUE,1); - /* For num_level == 1, auto convert to one-level structure */ - if (1 == spice_model->design_tech_info.mux_num_level) { - spice_model->design_tech_info.structure = SPICE_MODEL_STRUCTURE_ONELEVEL; - vpr_printf(TIO_MESSAGE_INFO,"[LINE%d] Automatically convert structure of spice model(%s) to one-level.\n", - Node->line, spice_model->name); - } - } else if (SPICE_MODEL_STRUCTURE_ONELEVEL == spice_model->design_tech_info.structure) { - /* Set mux_num_level for other structure: one-level and tree */ - spice_model->design_tech_info.mux_num_level = 1; + + /* If this is a LUT, more options are available */ + spice_model->design_tech_info.lut_info = NULL; + if (SPICE_MODEL_LUT == spice_model->type) { + /* Malloc */ + spice_model->design_tech_info.lut_info = (t_spice_model_lut*)my_malloc(sizeof(t_spice_model_lut)); + /* Fill information */ + ProcessSpiceModelLUT(Node, spice_model->design_tech_info.lut_info); + /* Malloc */ + spice_model->design_tech_info.mux_info = (t_spice_model_mux*)my_malloc(sizeof(t_spice_model_mux)); + /* Fill information */ + /* Default: tree, no const_inputs */ + spice_model->design_tech_info.mux_info->structure = SPICE_MODEL_STRUCTURE_TREE; + spice_model->design_tech_info.mux_info->add_const_input = FALSE; + spice_model->design_tech_info.mux_info->const_input_val = 0; } - ezxml_set_attr(Node, "num_level", NULL); - /* Specify if should use the advanced 4T1R MUX design */ - spice_model->design_tech_info.advanced_rram_design = GetBooleanProperty(Node,"advanced_rram_design", FALSE, FALSE); - ezxml_set_attr(Node, "advanced_rram_design", NULL); - FreeNode(Node); + ezxml_set_attr(Node, "fracturable_lut", NULL); + + + spice_model->design_tech_info.gate_info = NULL; + if (SPICE_MODEL_GATE == spice_model->type) { + /* Malloc */ + spice_model->design_tech_info.gate_info = (t_spice_model_gate*)my_calloc(1, sizeof(t_spice_model_gate)); + /* Fill information */ + ProcessSpiceModelGate(Node, spice_model->design_tech_info.gate_info); + } } else { vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] design_technology is expected in spice_model(%s).\n", Node->line,spice_model->name); exit(1); } + FreeNode(Node); /* LUT input_buffers */ Node = ezxml_child(Parent, "lut_input_buffer"); spice_model->lut_input_buffer = NULL; if (Node) { /* Malloc the lut_input_buffer */ - spice_model->lut_input_buffer = (t_spice_model_buffer*)my_malloc(sizeof(t_spice_model_buffer)); + spice_model->lut_input_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer)); ProcessSpiceModelBuffer(Node,spice_model->lut_input_buffer); FreeNode(Node); } else if (SPICE_MODEL_LUT == spice_model->type) { @@ -829,6 +979,37 @@ static void ProcessSpiceModel(ezxml_t Parent, Parent->line, spice_model->name); exit(1); } + + /* LUT input_buffers */ + Node = ezxml_child(Parent, "lut_input_inverter"); + spice_model->lut_input_inverter = NULL; + if (Node) { + /* Malloc the lut_input_buffer */ + spice_model->lut_input_inverter = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer)); + ProcessSpiceModelBuffer(Node,spice_model->lut_input_inverter); + FreeNode(Node); + } else if (SPICE_MODEL_LUT == spice_model->type) { + vpr_printf(TIO_MESSAGE_ERROR,"[LINE %d] lut_input_inverter is expected in spice_model(%s).\n", + Parent->line, spice_model->name); + exit(1); + } + + /* LUT intermediate buffers */ + Node = ezxml_child(Parent, "lut_intermediate_buffer"); + spice_model->lut_intermediate_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer)); + if (Node) { + /* Malloc the lut_input_buffer */ + ProcessSpiceModelBuffer(Node,spice_model->lut_intermediate_buffer); + FreeNode(Node); + } else if ((SPICE_MODEL_LUT == spice_model->type) + || (SPICE_MODEL_MUX == spice_model->type)) { + /* Assign default values */ + spice_model->lut_intermediate_buffer->exist = 0; + spice_model->lut_intermediate_buffer->spice_model = NULL; + spice_model->lut_intermediate_buffer->location_map = NULL; + } + + /* Input Buffers*/ Node = ezxml_child(Parent, "input_buffer"); spice_model->input_buffer = NULL; @@ -861,8 +1042,8 @@ static void ProcessSpiceModel(ezxml_t Parent, if (Node) { spice_model->pass_gate_logic = (t_spice_model_pass_gate_logic*)my_malloc(sizeof(t_spice_model_pass_gate_logic)); /* Find spice_model_name */ - spice_model->pass_gate_logic->spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", TRUE)); - ezxml_set_attr(Node, "circuit_model_name", NULL); + spice_model->pass_gate_logic->spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", TRUE)); + ezxml_set_attr(Node, "spice_model_name", NULL); FreeNode(Node); } else if ((SPICE_MODEL_MUX == spice_model->type) ||(SPICE_MODEL_LUT == spice_model->type)) { @@ -897,16 +1078,16 @@ static void ProcessSpiceModel(ezxml_t Parent, FreeNode(Node); } - /* Find delay info */ - spice_model->num_delay_info = CountChildren(Parent, "delay_matrix", 0); - /*Alloc*/ - spice_model->delay_info = (t_spice_model_delay_info*) my_malloc(spice_model->num_delay_info * sizeof(t_spice_model_delay_info)); - /* Assign each found spice model*/ - for (i = 0; i < spice_model->num_delay_info; i++) { - Cur = FindFirstElement(Parent, "delay_matrix", TRUE); - ProcessSpiceModelDelayInfo(Cur, &(spice_model->delay_info[i])); - FreeNode(Cur); - } + /* Find delay info */ + spice_model->num_delay_info = CountChildren(Parent, "delay_matrix", 0); + /*Alloc*/ + spice_model->delay_info = (t_spice_model_delay_info*) my_malloc(spice_model->num_delay_info * sizeof(t_spice_model_delay_info)); + /* Assign each found spice model*/ + for (i = 0; i < spice_model->num_delay_info; i++) { + Cur = FindFirstElement(Parent, "delay_matrix", TRUE); + ProcessSpiceModelDelayInfo(Cur, &(spice_model->delay_info[i])); + FreeNode(Cur); + } /* Initialize the counter*/ spice_model->cnt = 0; @@ -925,9 +1106,9 @@ void ProcessSpiceSRAMOrganization(INOUTP ezxml_t Node, return; } - cur_sram_inf_orgz->spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", required)); + cur_sram_inf_orgz->spice_model_name = my_strdup(FindProperty(Node, "spice_model_name", required)); cur_sram_inf_orgz->spice_model = NULL; - ezxml_set_attr(Node, "circuit_model_name", NULL); + ezxml_set_attr(Node, "spice_model_name", NULL); /* read organization type*/ Prop = FindProperty(Node, "organization", required); @@ -935,7 +1116,7 @@ void ProcessSpiceSRAMOrganization(INOUTP ezxml_t Node, cur_sram_inf_orgz->type = SPICE_SRAM_STANDALONE; /* Default */ } else if (0 == strcmp("scan-chain", Prop)) { cur_sram_inf_orgz->type = SPICE_SRAM_SCAN_CHAIN; - } else if (0 == strcmp("memory_bank", Prop)) { + } else if (0 == strcmp("memory-bank", Prop)) { cur_sram_inf_orgz->type = SPICE_SRAM_MEMORY_BANK; } else if (0 == strcmp("standalone", Prop)) { cur_sram_inf_orgz->type = SPICE_SRAM_STANDALONE; @@ -1094,24 +1275,24 @@ static void check_spice_models(int num_spice_model, } /* Check the I/O transistors are defined when RRAM MUX is selected */ if (SPICE_MODEL_DESIGN_RRAM == spice_models[i].design_tech) { - if (!(0. < spice_models[i].design_tech_info.wprog_set_nmos)) { + if (!(0. < spice_models[i].design_tech_info.rram_info->wprog_set_nmos)) { vpr_printf(TIO_MESSAGE_ERROR, "wprog_set_nmos(%g) should be >0 for a RRAM MUX SPICE model (%s)!\n", - spice_models[i].design_tech_info.wprog_set_nmos, spice_models[i].name); + spice_models[i].design_tech_info.rram_info->wprog_set_nmos, spice_models[i].name); exit(1); } - if (!(0. < spice_models[i].design_tech_info.wprog_set_pmos)) { + if (!(0. < spice_models[i].design_tech_info.rram_info->wprog_set_pmos)) { vpr_printf(TIO_MESSAGE_ERROR, "wprog_set_pmos(%g) should be >0 for a RRAM MUX SPICE model (%s)!\n", - spice_models[i].design_tech_info.wprog_set_pmos, spice_models[i].name); + spice_models[i].design_tech_info.rram_info->wprog_set_pmos, spice_models[i].name); exit(1); } - if (!(0. < spice_models[i].design_tech_info.wprog_reset_nmos)) { + if (!(0. < spice_models[i].design_tech_info.rram_info->wprog_reset_nmos)) { vpr_printf(TIO_MESSAGE_ERROR, "wprog_reset_nmos(%g) should be >0 for a RRAM MUX SPICE model (%s)!\n", - spice_models[i].design_tech_info.wprog_reset_nmos, spice_models[i].name); + spice_models[i].design_tech_info.rram_info->wprog_reset_nmos, spice_models[i].name); exit(1); } - if (!(0. < spice_models[i].design_tech_info.wprog_reset_pmos)) { + if (!(0. < spice_models[i].design_tech_info.rram_info->wprog_reset_pmos)) { vpr_printf(TIO_MESSAGE_ERROR, "wprog_reset_pmos(%g) should be >0 for a RRAM MUX SPICE model (%s)!\n", - spice_models[i].design_tech_info.wprog_reset_pmos, spice_models[i].name); + spice_models[i].design_tech_info.rram_info->wprog_reset_pmos, spice_models[i].name); exit(1); } } @@ -1154,6 +1335,28 @@ static void check_spice_models(int num_spice_model, exit(1); } } + /* Check scan-chain dff has input and output, clock ports*/ + if (SPICE_MODEL_SCFF == spice_models[i].type) { + has_sram = 1; + has_clock_port = 0; + has_in_port = 0; + has_out_port = 0; + for (j = 0; j < spice_models[i].num_port; j++) { + if (SPICE_MODEL_PORT_INPUT == spice_models[i].ports[j].type) { + has_in_port = 1; + } else if (SPICE_MODEL_PORT_OUTPUT == spice_models[i].ports[j].type) { + has_out_port = 1; + } else if (SPICE_MODEL_PORT_CLOCK == spice_models[i].ports[j].type) { + has_clock_port = 1; + } + } + /* Check if we have two ports*/ + if ((0 == has_in_port)||(0 == has_out_port)||(0 == has_clock_port)) { + vpr_printf(TIO_MESSAGE_ERROR,"FF Spice model(%s) does not have input|output|clock port\n",spice_models[i].name); + exit(1); + } + } + /* Check lut has input and output, clock ports*/ if (SPICE_MODEL_LUT == spice_models[i].type) { has_sram_port = 0; @@ -1301,14 +1504,14 @@ void ProcessSpiceSettings(ezxml_t Parent, ProcessSpiceTechLibTransistors(Parent, &(spice->tech_lib)); /* module spice models*/ - Node = FindElement(Parent, "module_circuit_models", FALSE); + Node = FindElement(Parent, "module_spice_models", FALSE); if (Node) { - spice->num_spice_model = CountChildren(Node, "circuit_model", 1); + spice->num_spice_model = CountChildren(Node, "spice_model", 1); /*Alloc*/ spice->spice_models = (t_spice_model*)my_malloc(spice->num_spice_model*sizeof(t_spice_model)); /* Assign each found spice model*/ for (imodel = 0; imodel < spice->num_spice_model; imodel++) { - Cur = FindFirstElement(Node, "circuit_model", TRUE); + Cur = FindFirstElement(Node, "spice_model", TRUE); ProcessSpiceModel(Cur, &(spice->spice_models[imodel])); FreeNode(Cur); } diff --git a/vpr7_x2p/tech/PTM_130nm/130nm.pm b/vpr7_x2p/tech/PTM_130nm/130nm.pm deleted file mode 100644 index bcb5d7a86..000000000 --- a/vpr7_x2p/tech/PTM_130nm/130nm.pm +++ /dev/null @@ -1,145 +0,0 @@ -* Beta Version released on 2/22/06 - -* PTM 130nm NMOS - -.model nmos nmos level = 54 - -+version = 4.0 binunit = 1 paramchk= 1 mobmod = 0 -+capmod = 2 igcmod = 1 igbmod = 1 geomod = 1 -+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1 -+permod = 1 acnqsmod= 0 trnqsmod= 0 - -+tnom = 27 toxe = 2.25e-9 toxp = 1.6e-9 toxm = 2.25e-9 -+dtox = 0.65e-9 epsrox = 3.9 wint = 5e-009 lint = 10.5e-009 -+ll = 0 wl = 0 lln = 1 wln = 1 -+lw = 0 ww = 0 lwn = 1 wwn = 1 -+lwl = 0 wwl = 0 xpart = 0 toxref = 2.25e-9 -+xl = -60e-9 -+vth0 = 0.3782 k1 = 0.4 k2 = 0.01 k3 = 0 -+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2 -+dvt2 = -0.032 dvt0w = 0 dvt1w = 0 dvt2w = 0 -+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1.2e-010 -+dvtp1 = 0.1 lpe0 = 0 lpeb = 0 xj = 3.92e-008 -+ngate = 2e+020 ndep = 1.54e+018 nsd = 2e+020 phin = 0 -+cdsc = 0.0002 cdscb = 0 cdscd = 0 cit = 0 -+voff = -0.13 nfactor = 1.5 eta0 = 0.0092 etab = 0 -+vfb = -0.55 u0 = 0.05928 ua = 6e-010 ub = 1.2e-018 -+uc = 0 vsat = 100370 a0 = 1 ags = 1e-020 -+a1 = 0 a2 = 1 b0 = 0 b1 = 0 -+keta = 0.04 dwg = 0 dwb = 0 pclm = 0.06 -+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = -0.005 drout = 0.5 -+pvag = 1e-020 delta = 0.01 pscbe1 = 8.14e+008 pscbe2 = 1e-007 -+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2.3e+006 -+rsh = 5 rdsw = 200 rsw = 100 rdw = 100 -+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0 -+prwb = 6.8e-011 wr = 1 alpha0 = 0.074 alpha1 = 0.005 -+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002 -+egidl = 0.8 - -+aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002 -+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004 -+eigbinv = 1.1 nigbinv = 3 aigc = 0.012 bigc = 0.0028 -+cigc = 0.002 aigsd = 0.012 bigsd = 0.0028 cigsd = 0.002 -+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1 - -+xrcrg1 = 12 xrcrg2 = 5 -+cgso = 2.4e-010 cgdo = 2.4e-010 cgbo = 2.56e-011 cgdl = 2.653e-10 -+cgsl = 2.653e-10 ckappas = 0.03 ckappad = 0.03 acde = 1 -+moin = 15 noff = 0.9 voffcv = 0.02 - -+kt1 = -0.11 kt1l = 0 kt2 = 0.022 ute = -1.5 -+ua1 = 4.31e-009 ub1 = 7.61e-018 uc1 = -5.6e-011 prt = 0 -+at = 33000 - -+fnoimod = 1 tnoimod = 0 - -+jss = 0.0001 jsws = 1e-011 jswgs = 1e-010 njs = 1 -+ijthsfwd= 0.01 ijthsrev= 0.001 bvs = 10 xjbvs = 1 -+jsd = 0.0001 jswd = 1e-011 jswgd = 1e-010 njd = 1 -+ijthdfwd= 0.01 ijthdrev= 0.001 bvd = 10 xjbvd = 1 -+pbs = 1 cjs = 0.0005 mjs = 0.5 pbsws = 1 -+cjsws = 5e-010 mjsws = 0.33 pbswgs = 1 cjswgs = 3e-010 -+mjswgs = 0.33 pbd = 1 cjd = 0.0005 mjd = 0.5 -+pbswd = 1 cjswd = 5e-010 mjswd = 0.33 pbswgd = 1 -+cjswgd = 5e-010 mjswgd = 0.33 tpb = 0.005 tcj = 0.001 -+tpbsw = 0.005 tcjsw = 0.001 tpbswg = 0.005 tcjswg = 0.001 -+xtis = 3 xtid = 3 - -+dmcg = 0e-006 dmci = 0e-006 dmdg = 0e-006 dmcgt = 0e-007 -+dwj = 0.0e-008 xgw = 0e-007 xgl = 0e-008 - -+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15 -+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1 - -* PTM 130nm PMOS - -.model pmos pmos level = 54 - -+version = 4.0 binunit = 1 paramchk= 1 mobmod = 0 -+capmod = 2 igcmod = 1 igbmod = 1 geomod = 1 -+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1 -+permod = 1 acnqsmod= 0 trnqsmod= 0 - -+tnom = 27 toxe = 2.35e-009 toxp = 1.6e-009 toxm = 2.35e-009 -+dtox = 0.75e-9 epsrox = 3.9 wint = 5e-009 lint = 10.5e-009 -+ll = 0 wl = 0 lln = 1 wln = 1 -+lw = 0 ww = 0 lwn = 1 wwn = 1 -+lwl = 0 wwl = 0 xpart = 0 toxref = 2.35e-009 -+xl = -60e-9 -+vth0 = -0.321 k1 = 0.4 k2 = -0.01 k3 = 0 -+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2 -+dvt2 = -0.032 dvt0w = 0 dvt1w = 0 dvt2w = 0 -+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-009 -+dvtp1 = 0.05 lpe0 = 0 lpeb = 0 xj = 3.92e-008 -+ngate = 2e+020 ndep = 1.14e+018 nsd = 2e+020 phin = 0 -+cdsc = 0.000258 cdscb = 0 cdscd = 6.1e-008 cit = 0 -+voff = -0.126 nfactor = 1.5 eta0 = 0.0092 etab = 0 -+vfb = 0.55 u0 = 0.00835 ua = 2.0e-009 ub = 0.5e-018 -+uc = -3e-011 vsat = 70000 a0 = 1.0 ags = 1e-020 -+a1 = 0 a2 = 1 b0 = -1e-020 b1 = 0 -+keta = -0.047 dwg = 0 dwb = 0 pclm = 0.12 -+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = 3.4e-008 drout = 0.56 -+pvag = 1e-020 delta = 0.01 pscbe1 = 8.14e+008 pscbe2 = 9.58e-007 -+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2.3e+006 -+rsh = 5 rdsw = 240 rsw = 120 rdw = 120 -+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 3.22e-008 -+prwb = 6.8e-011 wr = 1 alpha0 = 0.074 alpha1 = 0.005 -+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002 -+egidl = 0.8 - -+aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002 -+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004 -+eigbinv = 1.1 nigbinv = 3 aigc = 0.69 bigc = 0.0012 -+cigc = 0.0008 aigsd = 0.0087 bigsd = 0.0012 cigsd = 0.0008 -+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1 - -+xrcrg1 = 12 xrcrg2 = 5 -+cgso = 2.4e-010 cgdo = 2.4e-010 cgbo = 2.56e-011 cgdl = 2.653e-10 -+cgsl = 2.653e-10 ckappas = 0.03 ckappad = 0.03 acde = 1 -+moin = 15 noff = 0.9 voffcv = 0.02 - -+kt1 = -0.11 kt1l = 0 kt2 = 0.022 ute = -1.5 -+ua1 = 4.31e-009 ub1 = 7.61e-018 uc1 = -5.6e-011 prt = 0 -+at = 33000 - -+fnoimod = 1 tnoimod = 0 - -+jss = 0.0001 jsws = 1e-011 jswgs = 1e-010 njs = 1 -+ijthsfwd= 0.01 ijthsrev= 0.001 bvs = 10 xjbvs = 1 -+jsd = 0.0001 jswd = 1e-011 jswgd = 1e-010 njd = 1 -+ijthdfwd= 0.01 ijthdrev= 0.001 bvd = 10 xjbvd = 1 -+pbs = 1 cjs = 0.0005 mjs = 0.5 pbsws = 1 -+cjsws = 5e-010 mjsws = 0.33 pbswgs = 1 cjswgs = 3e-010 -+mjswgs = 0.33 pbd = 1 cjd = 0.0005 mjd = 0.5 -+pbswd = 1 cjswd = 5e-010 mjswd = 0.33 pbswgd = 1 -+cjswgd = 5e-010 mjswgd = 0.33 tpb = 0.005 tcj = 0.001 -+tpbsw = 0.005 tcjsw = 0.001 tpbswg = 0.005 tcjswg = 0.001 -+xtis = 3 xtid = 3 - -+dmcg = 0e-006 dmci = 0e-006 dmdg = 0e-006 dmcgt = 0e-007 -+dwj = 0.0e-008 xgw = 0e-007 xgl = 0e-008 - -+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15 -+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1 - - diff --git a/vpr7_x2p/tech/PTM_130nm/130nm.xml b/vpr7_x2p/tech/PTM_130nm/130nm.xml deleted file mode 100644 index a4695daa6..000000000 --- a/vpr7_x2p/tech/PTM_130nm/130nm.xml +++ /dev/null @@ -1,7493 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/tech/PTM_130nm/readme.txt b/vpr7_x2p/tech/PTM_130nm/readme.txt deleted file mode 100644 index 0e0116d35..000000000 --- a/vpr7_x2p/tech/PTM_130nm/readme.txt +++ /dev/null @@ -1,17 +0,0 @@ -This technology file was generated using the Nano-CMOS tool from http://ptm.asu.edu/ - -The following default parameters were used: - -NMOS -Leff=49 nm 10% -Vth=0.18 V 30mV -Vdd=1.3 V -Tox=1.6 nm -Rdsw=200 Ohm - -PMOS -Leff=49 nm 10% -Vth=-0.18 V 30mV -Vdd=1.3 V -Tox=1.6 nm -Rdsw=240 Ohm \ No newline at end of file diff --git a/vpr7_x2p/tech/PTM_22nm/22nm.pm b/vpr7_x2p/tech/PTM_22nm/22nm.pm deleted file mode 100644 index 6e4cd7b81..000000000 --- a/vpr7_x2p/tech/PTM_22nm/22nm.pm +++ /dev/null @@ -1,140 +0,0 @@ -* PTM High Performance 22nm Metal Gate / High-K / Strained-Si -* nominal Vdd = 0.8V - -.model nmos nmos level = 54 - -+version = 4.0 binunit = 1 paramchk= 1 mobmod = 0 -+capmod = 2 igcmod = 1 igbmod = 1 geomod = 1 -+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1 -+permod = 1 acnqsmod= 0 trnqsmod= 0 - -+tnom = 27 toxe = 1.05e-009 toxp = 8e-010 toxm = 1.05e-009 -+dtox = 2.5e-010 epsrox = 3.9 wint = 5e-009 lint = 2e-009 -+ll = 0 wl = 0 lln = 1 wln = 1 -+lw = 0 ww = 0 lwn = 1 wwn = 1 -+lwl = 0 wwl = 0 xpart = 0 toxref = 1.05e-009 -+xl = -9e-9 - -+vth0 = 0.50308 k1 = 0.4 k2 = 0 k3 = 0 -+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2 -+dvt2 = 0 dvt0w = 0 dvt1w = 0 dvt2w = 0 -+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-011 -+dvtp1 = 0.1 lpe0 = 0 lpeb = 0 xj = 7.2e-009 -+ngate = 1e+023 ndep = 5.5e+018 nsd = 2e+020 phin = 0 -+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0 -+voff = -0.13 nfactor = 2.3 eta0 = 0.004 etab = 0 -+vfb = -0.55 u0 = 0.04 ua = 6e-010 ub = 1.2e-018 -+uc = 0 vsat = 250000 a0 = 1 ags = 0 -+a1 = 0 a2 = 1 b0 = 0 b1 = 0 -+keta = 0.04 dwg = 0 dwb = 0 pclm = 0.02 -+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = -0.005 drout = 0.5 -+pvag = 1e-020 delta = 0.01 pscbe1 = 8.14e+008 pscbe2 = 1e-007 -+fprout = 0.2 pdits = 0.01 pditsd = 0.23 pditsl = 2300000 -+rsh = 5 rdsw = 145 rsw = 75 rdw = 75 -+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0 -+prwb = 0 wr = 1 alpha0 = 0.074 alpha1 = 0.005 -+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002 -+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002 -+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004 -+eigbinv = 1.1 nigbinv = 3 aigc = 0.0213 bigc = 0.0025889 -+cigc = 0.002 aigsd = 0.0213 bigsd = 0.0025889 cigsd = 0.002 -+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1 -+xrcrg1 = 12 xrcrg2 = 5 - -+cgso = 6.5e-011 cgdo = 6.5e-011 cgbo = 2.56e-011 cgdl = 2.653e-010 -+cgsl = 2.653e-010 ckappas = 0.03 ckappad = 0.03 acde = 1 -+moin = 15 noff = 0.9 voffcv = 0.02 - -+kt1 = -0.11 kt1l = 0 kt2 = 0.022 ute = -1.5 -+ua1 = 4.31e-009 ub1 = 7.61e-018 uc1 = -5.6e-011 prt = 0 -+at = 33000 - -+fnoimod = 1 tnoimod = 0 - -+jss = 0.0001 jsws = 1e-011 jswgs = 1e-010 njs = 1 -+ijthsfwd= 0.01 ijthsrev= 0.001 bvs = 10 xjbvs = 1 -+jsd = 0.0001 jswd = 1e-011 jswgd = 1e-010 njd = 1 -+ijthdfwd= 0.01 ijthdrev= 0.001 bvd = 10 xjbvd = 1 -+pbs = 1 cjs = 0.0005 mjs = 0.5 pbsws = 1 -+cjsws = 5e-010 mjsws = 0.33 pbswgs = 1 cjswgs = 3e-010 -+mjswgs = 0.33 pbd = 1 cjd = 0.0005 mjd = 0.5 -+pbswd = 1 cjswd = 5e-010 mjswd = 0.33 pbswgd = 1 -+cjswgd = 5e-010 mjswgd = 0.33 tpb = 0.005 tcj = 0.001 -+tpbsw = 0.005 tcjsw = 0.001 tpbswg = 0.005 tcjswg = 0.001 -+xtis = 3 xtid = 3 - -+dmcg = 0 dmci = 0 dmdg = 0 dmcgt = 0 -+dwj = 0 xgw = 0 xgl = 0 - -+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15 -+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1 - - - -.model pmos pmos level = 54 - -+version = 4.0 binunit = 1 paramchk= 1 mobmod = 0 -+capmod = 2 igcmod = 1 igbmod = 1 geomod = 1 -+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1 -+permod = 1 acnqsmod= 0 trnqsmod= 0 - -+tnom = 27 toxe = 1.1e-009 toxp = 8e-010 toxm = 1.1e-009 -+dtox = 3e-010 epsrox = 3.9 wint = 5e-009 lint = 2e-009 -+ll = 0 wl = 0 lln = 1 wln = 1 -+lw = 0 ww = 0 lwn = 1 wwn = 1 -+lwl = 0 wwl = 0 xpart = 0 toxref = 1.1e-009 -+xl = -9e-9 - -+vth0 = -0.4606 k1 = 0.4 k2 = -0.01 k3 = 0 -+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2 -+dvt2 = -0.032 dvt0w = 0 dvt1w = 0 dvt2w = 0 -+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-011 -+dvtp1 = 0.05 lpe0 = 0 lpeb = 0 xj = 7.2e-009 -+ngate = 1e+023 ndep = 4.4e+018 nsd = 2e+020 phin = 0 -+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0 -+voff = -0.126 nfactor = 2.1 eta0 = 0.0038 etab = 0 -+vfb = 0.55 u0 = 0.0095 ua = 2e-009 ub = 5e-019 -+uc = 0 vsat = 210000 a0 = 1 ags = 1e-020 -+a1 = 0 a2 = 1 b0 = 0 b1 = 0 -+keta = -0.047 dwg = 0 dwb = 0 pclm = 0.12 -+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = 3.4e-008 drout = 0.56 -+pvag = 1e-020 delta = 0.01 pscbe1 = 8.14e+008 pscbe2 = 9.58e-007 -+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2300000 -+rsh = 5 rdsw = 145 rsw = 72.5 rdw = 72.5 -+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0 -+prwb = 0 wr = 1 alpha0 = 0.074 alpha1 = 0.005 -+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002 -+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002 -+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004 -+eigbinv = 1.1 nigbinv = 3 aigc = 0.0213 bigc = 0.0025889 -+cigc = 0.002 aigsd = 0.0213 bigsd = 0.0025889 cigsd = 0.002 -+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1 -+xrcrg1 = 12 xrcrg2 = 5 - -+cgso = 6.5e-011 cgdo = 6.5e-011 cgbo = 2.56e-011 cgdl = 2.653e-010 -+cgsl = 2.653e-010 ckappas = 0.03 ckappad = 0.03 acde = 1 -+moin = 15 noff = 0.9 voffcv = 0.02 - -+kt1 = -0.11 kt1l = 0 kt2 = 0.022 ute = -1.5 -+ua1 = 4.31e-009 ub1 = 7.61e-018 uc1 = -5.6e-011 prt = 0 -+at = 33000 - -+fnoimod = 1 tnoimod = 0 - -+jss = 0.0001 jsws = 1e-011 jswgs = 1e-010 njs = 1 -+ijthsfwd= 0.01 ijthsrev= 0.001 bvs = 10 xjbvs = 1 -+jsd = 0.0001 jswd = 1e-011 jswgd = 1e-010 njd = 1 -+ijthdfwd= 0.01 ijthdrev= 0.001 bvd = 10 xjbvd = 1 -+pbs = 1 cjs = 0.0005 mjs = 0.5 pbsws = 1 -+cjsws = 5e-010 mjsws = 0.33 pbswgs = 1 cjswgs = 3e-010 -+mjswgs = 0.33 pbd = 1 cjd = 0.0005 mjd = 0.5 -+pbswd = 1 cjswd = 5e-010 mjswd = 0.33 pbswgd = 1 -+cjswgd = 5e-010 mjswgd = 0.33 tpb = 0.005 tcj = 0.001 -+tpbsw = 0.005 tcjsw = 0.001 tpbswg = 0.005 tcjswg = 0.001 -+xtis = 3 xtid = 3 - -+dmcg = 0 dmci = 0 dmdg = 0 dmcgt = 0 -+dwj = 0 xgw = 0 xgl = 0 - -+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15 -+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1 diff --git a/vpr7_x2p/tech/PTM_22nm/22nm.xml b/vpr7_x2p/tech/PTM_22nm/22nm.xml deleted file mode 100644 index 11adf783a..000000000 --- a/vpr7_x2p/tech/PTM_22nm/22nm.xml +++ /dev/null @@ -1,7493 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/tech/PTM_22nm/readme.txt b/vpr7_x2p/tech/PTM_22nm/readme.txt deleted file mode 100644 index 85bb26a91..000000000 --- a/vpr7_x2p/tech/PTM_22nm/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -This technology file was obtained here: -http://ptm.asu.edu/modelcard/LP/22nm_LP.pm diff --git a/vpr7_x2p/tech/PTM_45nm/45nm.pm b/vpr7_x2p/tech/PTM_45nm/45nm.pm deleted file mode 100644 index 21187b41e..000000000 --- a/vpr7_x2p/tech/PTM_45nm/45nm.pm +++ /dev/null @@ -1,141 +0,0 @@ -* PTM High Performance 45nm Metal Gate / High-K / Strained-Si -* nominal Vdd = 1.0V - -.model nmos nmos level = 54 - -+version = 4.0 binunit = 1 paramchk= 1 mobmod = 0 -+capmod = 2 igcmod = 1 igbmod = 1 geomod = 1 -+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1 -+permod = 1 acnqsmod= 0 trnqsmod= 0 - -+tnom = 27 toxe = 1.25e-009 toxp = 1e-009 toxm = 1.25e-009 -+dtox = 2.5e-010 epsrox = 3.9 wint = 5e-009 lint = 3.75e-009 -+ll = 0 wl = 0 lln = 1 wln = 1 -+lw = 0 ww = 0 lwn = 1 wwn = 1 -+lwl = 0 wwl = 0 xpart = 0 toxref = 1.25e-009 -+xl = -20e-9 - -+vth0 = 0.46893 k1 = 0.4 k2 = 0 k3 = 0 -+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2 -+dvt2 = 0 dvt0w = 0 dvt1w = 0 dvt2w = 0 -+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-010 -+dvtp1 = 0.1 lpe0 = 0 lpeb = 0 xj = 1.4e-008 -+ngate = 1e+023 ndep = 3.24e+018 nsd = 2e+020 phin = 0 -+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0 -+voff = -0.13 nfactor = 2.22 eta0 = 0.0055 etab = 0 -+vfb = -0.55 u0 = 0.054 ua = 6e-010 ub = 1.2e-018 -+uc = 0 vsat = 170000 a0 = 1 ags = 0 -+a1 = 0 a2 = 1 b0 = 0 b1 = 0 -+keta = 0.04 dwg = 0 dwb = 0 pclm = 0.02 -+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = -0.005 drout = 0.5 -+pvag = 1e-020 delta = 0.01 pscbe1 = 8.14e+008 pscbe2 = 1e-007 -+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2300000 -+rsh = 5 rdsw = 155 rsw = 80 rdw = 80 -+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0 -+prwb = 0 wr = 1 alpha0 = 0.074 alpha1 = 0.005 -+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002 -+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002 -+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004 -+eigbinv = 1.1 nigbinv = 3 aigc = 0.02 bigc = 0.0025 -+cigc = 0.002 aigsd = 0.02 bigsd = 0.0025 cigsd = 0.002 -+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1 -+xrcrg1 = 12 xrcrg2 = 5 - -+cgso = 1.1e-010 cgdo = 1.1e-010 cgbo = 2.56e-011 cgdl = 2.653e-010 -+cgsl = 2.653e-010 ckappas = 0.03 ckappad = 0.03 acde = 1 -+moin = 15 noff = 0.9 voffcv = 0.02 - -+kt1 = -0.11 kt1l = 0 kt2 = 0.022 ute = -1.5 -+ua1 = 4.31e-009 ub1 = 7.61e-018 uc1 = -5.6e-011 prt = 0 -+at = 33000 - -+fnoimod = 1 tnoimod = 0 - -+jss = 0.0001 jsws = 1e-011 jswgs = 1e-010 njs = 1 -+ijthsfwd= 0.01 ijthsrev= 0.001 bvs = 10 xjbvs = 1 -+jsd = 0.0001 jswd = 1e-011 jswgd = 1e-010 njd = 1 -+ijthdfwd= 0.01 ijthdrev= 0.001 bvd = 10 xjbvd = 1 -+pbs = 1 cjs = 0.0005 mjs = 0.5 pbsws = 1 -+cjsws = 5e-010 mjsws = 0.33 pbswgs = 1 cjswgs = 3e-010 -+mjswgs = 0.33 pbd = 1 cjd = 0.0005 mjd = 0.5 -+pbswd = 1 cjswd = 5e-010 mjswd = 0.33 pbswgd = 1 -+cjswgd = 5e-010 mjswgd = 0.33 tpb = 0.005 tcj = 0.001 -+tpbsw = 0.005 tcjsw = 0.001 tpbswg = 0.005 tcjswg = 0.001 -+xtis = 3 xtid = 3 - -+dmcg = 0 dmci = 0 dmdg = 0 dmcgt = 0 -+dwj = 0 xgw = 0 xgl = 0 - -+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15 -+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1 - - - -.model pmos pmos level = 54 - -+version = 4.0 binunit = 1 paramchk= 1 mobmod = 0 -+capmod = 2 igcmod = 1 igbmod = 1 geomod = 1 -+diomod = 1 rdsmod = 0 rbodymod= 1 rgatemod= 1 -+permod = 1 acnqsmod= 0 trnqsmod= 0 - -+tnom = 27 toxe = 1.3e-009 toxp = 1e-009 toxm = 1.3e-009 -+dtox = 3e-010 epsrox = 3.9 wint = 5e-009 lint = 3.75e-009 -+ll = 0 wl = 0 lln = 1 wln = 1 -+lw = 0 ww = 0 lwn = 1 wwn = 1 -+lwl = 0 wwl = 0 xpart = 0 toxref = 1.3e-009 -+xl = -20e-9 - -+vth0 = -0.49158 k1 = 0.4 k2 = -0.01 k3 = 0 -+k3b = 0 w0 = 2.5e-006 dvt0 = 1 dvt1 = 2 -+dvt2 = -0.032 dvt0w = 0 dvt1w = 0 dvt2w = 0 -+dsub = 0.1 minv = 0.05 voffl = 0 dvtp0 = 1e-011 -+dvtp1 = 0.05 lpe0 = 0 lpeb = 0 xj = 1.4e-008 -+ngate = 1e+023 ndep = 2.44e+018 nsd = 2e+020 phin = 0 -+cdsc = 0 cdscb = 0 cdscd = 0 cit = 0 -+voff = -0.126 nfactor = 2.1 eta0 = 0.0055 etab = 0 -+vfb = 0.55 u0 = 0.02 ua = 2e-009 ub = 5e-019 -+uc = 0 vsat = 150000 a0 = 1 ags = 1e-020 -+a1 = 0 a2 = 1 b0 = 0 b1 = 0 -+keta = -0.047 dwg = 0 dwb = 0 pclm = 0.12 -+pdiblc1 = 0.001 pdiblc2 = 0.001 pdiblcb = 3.4e-008 drout = 0.56 -+pvag = 1e-020 delta = 0.01 pscbe1 = 8.14e+008 pscbe2 = 9.58e-007 -+fprout = 0.2 pdits = 0.08 pditsd = 0.23 pditsl = 2300000 -+rsh = 5 rdsw = 155 rsw = 75 rdw = 75 -+rdswmin = 0 rdwmin = 0 rswmin = 0 prwg = 0 -+prwb = 0 wr = 1 alpha0 = 0.074 alpha1 = 0.005 -+beta0 = 30 agidl = 0.0002 bgidl = 2.1e+009 cgidl = 0.0002 -+egidl = 0.8 aigbacc = 0.012 bigbacc = 0.0028 cigbacc = 0.002 -+nigbacc = 1 aigbinv = 0.014 bigbinv = 0.004 cigbinv = 0.004 -+eigbinv = 1.1 nigbinv = 3 aigc = 0.010687 bigc = 0.0012607 -+cigc = 0.0008 aigsd = 0.010687 bigsd = 0.0012607 cigsd = 0.0008 -+nigc = 1 poxedge = 1 pigcd = 1 ntox = 1 -+xrcrg1 = 12 xrcrg2 = 5 - -+cgso = 1.1e-010 cgdo = 1.1e-010 cgbo = 2.56e-011 cgdl = 2.653e-010 -+cgsl = 2.653e-010 ckappas = 0.03 ckappad = 0.03 acde = 1 -+moin = 15 noff = 0.9 voffcv = 0.02 - -+kt1 = -0.11 kt1l = 0 kt2 = 0.022 ute = -1.5 -+ua1 = 4.31e-009 ub1 = 7.61e-018 uc1 = -5.6e-011 prt = 0 -+at = 33000 - -+fnoimod = 1 tnoimod = 0 - -+jss = 0.0001 jsws = 1e-011 jswgs = 1e-010 njs = 1 -+ijthsfwd= 0.01 ijthsrev= 0.001 bvs = 10 xjbvs = 1 -+jsd = 0.0001 jswd = 1e-011 jswgd = 1e-010 njd = 1 -+ijthdfwd= 0.01 ijthdrev= 0.001 bvd = 10 xjbvd = 1 -+pbs = 1 cjs = 0.0005 mjs = 0.5 pbsws = 1 -+cjsws = 5e-010 mjsws = 0.33 pbswgs = 1 cjswgs = 3e-010 -+mjswgs = 0.33 pbd = 1 cjd = 0.0005 mjd = 0.5 -+pbswd = 1 cjswd = 5e-010 mjswd = 0.33 pbswgd = 1 -+cjswgd = 5e-010 mjswgd = 0.33 tpb = 0.005 tcj = 0.001 -+tpbsw = 0.005 tcjsw = 0.001 tpbswg = 0.005 tcjswg = 0.001 -+xtis = 3 xtid = 3 - -+dmcg = 0 dmci = 0 dmdg = 0 dmcgt = 0 -+dwj = 0 xgw = 0 xgl = 0 - -+rshg = 0.4 gbmin = 1e-010 rbpb = 5 rbpd = 15 -+rbps = 15 rbdb = 15 rbsb = 15 ngcon = 1 - diff --git a/vpr7_x2p/tech/PTM_45nm/45nm.xml b/vpr7_x2p/tech/PTM_45nm/45nm.xml deleted file mode 100644 index 570f921ba..000000000 --- a/vpr7_x2p/tech/PTM_45nm/45nm.xml +++ /dev/null @@ -1,7493 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/tech/PTM_45nm/readme.txt b/vpr7_x2p/tech/PTM_45nm/readme.txt deleted file mode 100644 index 9f6450906..000000000 --- a/vpr7_x2p/tech/PTM_45nm/readme.txt +++ /dev/null @@ -1,17 +0,0 @@ -This technology file was generated using the Nano-CMOS tool from http://ptm.asu.edu/ - -The following default parameters were used: - -NMOS -Leff=17.5 nm 10% -Vth=0.18 V 30mV -Vdd=1 V -Tox=1.1 nm -Rdsw=155 Ohm - -PMOS -Leff=17.5 nm 10% -Vth=-0.18 V 30mV -Vdd=1 V -Tox=1.1 nm -Rdsw=155 Ohm \ No newline at end of file diff --git a/vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml b/vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml deleted file mode 100644 index 9ee90ce4b..000000000 --- a/vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml +++ /dev/null @@ -1,1453 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - - - - - 10e-12 0e-12 0e-12 - - - 10e-12 0e-12 0e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - 1 1 1 - 1 1 - - - - 1 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - clb.clk - clb.I[19:0] clb.O[4:0] - clb.I[39:20] clb.O[9:5] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_template.xml b/vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_template.xml deleted file mode 100644 index f056d3b9b..000000000 --- a/vpr7_x2p/vpr/ARCH/k6_N10_scan_chain_template.xml +++ /dev/null @@ -1,1453 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - - - - - 10e-12 0e-12 0e-12 - - - 10e-12 0e-12 0e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - 1 1 1 - 1 1 - - - - 1 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - clb.clk - clb.I[19:0] clb.O[4:0] - clb.I[39:20] clb.O[9:5] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/vpr/ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml b/vpr7_x2p/vpr/ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml deleted file mode 100644 index fb5192145..000000000 --- a/vpr7_x2p/vpr/ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml +++ /dev/null @@ -1,882 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - - - - - - - - - - - - - - - 10e-12 0e-12 0e-12 - - - 10e-12 0e-12 0e-12 - - - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - 1 1 1 - 1 1 - - - - 1 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 235e-12 - 235e-12 - 235e-12 - 235e-12 - 235e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 195e-12 - 195e-12 - 195e-12 - 195e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 261e-12 - 261e-12 - 261e-12 - 261e-12 - 261e-12 - 261e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/vpr/ARCH/k6_N10_sram_ptm45nm_TT.xml b/vpr7_x2p/vpr/ARCH/k6_N10_sram_ptm45nm_TT.xml deleted file mode 100644 index 5b9b4727a..000000000 --- a/vpr7_x2p/vpr/ARCH/k6_N10_sram_ptm45nm_TT.xml +++ /dev/null @@ -1,1452 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - 10e-12 - - - 10e-12 - - - - - - - - - - - - 10e-12 0e-12 0e-12 - - - 10e-12 0e-12 0e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - 1 1 1 - 1 1 - - - - 1 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - clb.clk - clb.I[19:0] clb.O[4:0] - clb.I[39:20] clb.O[9:5] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vpr7_x2p/vpr/Circuits/fifo_1bit.act b/vpr7_x2p/vpr/Circuits/fifo_1bit.act deleted file mode 100644 index 1ff453717..000000000 --- a/vpr7_x2p/vpr/Circuits/fifo_1bit.act +++ /dev/null @@ -1,67 +0,0 @@ -rst 0.001 0.206600 -clk 0.486400 0.198400 -data_in 0.5 0.2 -int_reg[0] 0.257400 0.190800 -int_reg[1] 0.202800 0.149200 -int_reg[2] 0.160800 0.115200 -int_reg[3] 0.130400 0.090800 -int_reg[4] 0.106200 0.072000 -int_reg[5] 0.085800 0.056400 -int_reg[6] 0.070200 0.048000 -int_reg[7] 0.055800 0.039200 -int_reg[8] 0.043600 0.031600 -int_reg[9] 0.033400 0.023200 -int_reg[10] 0.026000 0.016800 -int_reg[11] 0.021400 0.014800 -int_reg[12] 0.016400 0.010000 -int_reg[13] 0.013600 0.007600 -int_reg[14] 0.011800 0.006400 -int_reg[15] 0.010200 0.005600 -int_reg[16] 0.008400 0.004800 -int_reg[17] 0.006800 0.004400 -int_reg[18] 0.005200 0.004000 -int_reg[19] 0.003600 0.002800 -int_reg[20] 0.002400 0.002000 -int_reg[21] 0.001400 0.000800 -int_reg[22] 0.001000 0.000400 -int_reg[23] 0.000800 0.000400 -int_reg[24] 0.000600 0.000400 -int_reg[25] 0.000400 0.000400 -int_reg[26] 0.000200 0.000400 -int_reg[27] 0.000000 0.000000 -int_reg[28] 0.000000 0.000000 -int_reg[29] 0.000000 0.000000 -int_reg[30] 0.000000 0.000000 -data_out 0.000000 0.000000 -n64 0.021400 0.003732 -n69 0.016400 0.004289 -n74 0.013600 0.004355 -n79 0.011800 0.004449 -n84 0.010200 0.004579 -n89 0.008400 0.004751 -n94 0.006800 0.004964 -n99 0.005200 0.005218 -n104 0.003600 0.005473 -n109 0.002400 0.005561 -n114 0.001400 0.005648 -n119 0.001000 0.005609 -n124 0.000800 0.005610 -n129 0.000600 0.005652 -n134 0.000400 0.005695 -n139 0.000200 0.005737 -n144 0.000000 0.005779 -n149 0.000000 0.005738 -n154 0.000000 0.005738 -n159 0.000000 0.005738 -n164 0.000000 0.005738 -n9 0.257400 0.049974 -n14 0.202800 0.087932 -n19 0.160800 0.092067 -n24 0.130400 0.094679 -n29 0.106200 0.096468 -n34 0.085800 0.097926 -n39 0.070200 0.099152 -n44 0.055800 0.000744 -n49 0.043600 0.002005 -n54 0.033400 0.003037 -n59 0.026000 0.003481 diff --git a/vpr7_x2p/vpr/Circuits/fifo_1bit.blif b/vpr7_x2p/vpr/Circuits/fifo_1bit.blif deleted file mode 100644 index 19500b7e9..000000000 --- a/vpr7_x2p/vpr/Circuits/fifo_1bit.blif +++ /dev/null @@ -1,103 +0,0 @@ -# Benchmark "fifo_1bit" written by ABC on Wed Dec 12 14:34:26 2018 -.model fifo_1bit -.inputs rst clk data_in -.outputs data_out - -.latch n9 int_reg[0] re clk 0 -.latch n14 int_reg[1] re clk 0 -.latch n19 int_reg[2] re clk 0 -.latch n24 int_reg[3] re clk 0 -.latch n29 int_reg[4] re clk 0 -.latch n34 int_reg[5] re clk 0 -.latch n39 int_reg[6] re clk 0 -.latch n44 int_reg[7] re clk 0 -.latch n49 int_reg[8] re clk 0 -.latch n54 int_reg[9] re clk 0 -.latch n59 int_reg[10] re clk 0 -.latch n64 int_reg[11] re clk 0 -.latch n69 int_reg[12] re clk 0 -.latch n74 int_reg[13] re clk 0 -.latch n79 int_reg[14] re clk 0 -.latch n84 int_reg[15] re clk 0 -.latch n89 int_reg[16] re clk 0 -.latch n94 int_reg[17] re clk 0 -.latch n99 int_reg[18] re clk 0 -.latch n104 int_reg[19] re clk 0 -.latch n109 int_reg[20] re clk 0 -.latch n114 int_reg[21] re clk 0 -.latch n119 int_reg[22] re clk 0 -.latch n124 int_reg[23] re clk 0 -.latch n129 int_reg[24] re clk 0 -.latch n134 int_reg[25] re clk 0 -.latch n139 int_reg[26] re clk 0 -.latch n144 int_reg[27] re clk 0 -.latch n149 int_reg[28] re clk 0 -.latch n154 int_reg[29] re clk 0 -.latch n159 int_reg[30] re clk 0 -.latch n164 data_out re clk 0 - -.names int_reg[10] rst n64 -10 1 -.names int_reg[11] rst n69 -10 1 -.names int_reg[12] rst n74 -10 1 -.names int_reg[13] rst n79 -10 1 -.names int_reg[14] rst n84 -10 1 -.names int_reg[15] rst n89 -10 1 -.names int_reg[16] rst n94 -10 1 -.names int_reg[17] rst n99 -10 1 -.names int_reg[18] rst n104 -10 1 -.names int_reg[19] rst n109 -10 1 -.names int_reg[20] rst n114 -10 1 -.names int_reg[21] rst n119 -10 1 -.names int_reg[22] rst n124 -10 1 -.names int_reg[23] rst n129 -10 1 -.names int_reg[24] rst n134 -10 1 -.names int_reg[25] rst n139 -10 1 -.names int_reg[26] rst n144 -10 1 -.names int_reg[27] rst n149 -10 1 -.names int_reg[28] rst n154 -10 1 -.names int_reg[29] rst n159 -10 1 -.names int_reg[30] rst n164 -10 1 -.names data_in rst n9 -10 1 -.names int_reg[0] rst n14 -10 1 -.names int_reg[1] rst n19 -10 1 -.names int_reg[2] rst n24 -10 1 -.names int_reg[3] rst n29 -10 1 -.names int_reg[4] rst n34 -10 1 -.names int_reg[5] rst n39 -10 1 -.names int_reg[6] rst n44 -10 1 -.names int_reg[7] rst n49 -10 1 -.names int_reg[8] rst n54 -10 1 -.names int_reg[9] rst n59 -10 1 -.end diff --git a/vpr7_x2p/vpr/Circuits/fifo_1bit.v b/vpr7_x2p/vpr/Circuits/fifo_1bit.v deleted file mode 100644 index b8abb0493..000000000 --- a/vpr7_x2p/vpr/Circuits/fifo_1bit.v +++ /dev/null @@ -1,32 +0,0 @@ -/////////////////////////////// -// // -// fifo_1bit benchmark // -// // -/////////////////////////////// - -module fifo_1bit( - rst, - clk, - data_in, - data_out ); - - input rst; - input clk; - input data_in; - output data_out; - - reg[31:0] int_reg; - - assign data_out = int_reg[31]; - - always@(posedge clk or posedge rst) begin - if(rst) begin - int_reg <= 32'h00; - end - else begin - int_reg[0] <= data_in; - int_reg[32:1] = int_reg[31:0]; - end - end - -endmodule diff --git a/vpr7_x2p/vpr/Circuits/fifo_1bit.ys b/vpr7_x2p/vpr/Circuits/fifo_1bit.ys deleted file mode 100644 index f6553d9ba..000000000 --- a/vpr7_x2p/vpr/Circuits/fifo_1bit.ys +++ /dev/null @@ -1,19 +0,0 @@ -#read design -read_verilog -nolatches ../vpr7_x2p/vpr/Circuits/fifo_1bit.v - -# synth -hierarchy -top fifo_1bit -proc - -# Tech map -techmap -D NO_LUT -map ./techlibs/common/adff2dff.v -synth -top fifo_1bit -flatten -clean - -abc -lut 6 - -synth -run check - -opt_clean -purge -write_blif ../vpr7_x2p/vpr/Circuits/fifo_1bit.blif - diff --git a/vpr7_x2p/vpr/Circuits/pip_add.act b/vpr7_x2p/vpr/Circuits/pip_add.act deleted file mode 100644 index efd0108ef..000000000 --- a/vpr7_x2p/vpr/Circuits/pip_add.act +++ /dev/null @@ -1,146 +0,0 @@ -rst 0.001 0.2 -clk 0.506200 0.198800 -a_0 0.507000 0.197200 -a_1 0.502800 0.201000 -a_2 0.498400 0.196600 -a_3 0.510600 0.196600 -a_4 0.514000 0.208000 -a_5 0.517000 0.198400 -a_6 0.491200 0.201400 -a_7 0.516000 0.196400 -b_0 0.502800 0.209400 -b_1 0.490800 0.193600 -b_2 0.508000 0.194200 -b_3 0.464000 0.200600 -b_4 0.492200 0.204200 -b_5 0.505200 0.188600 -b_6 0.496400 0.193400 -b_7 0.513600 0.193000 -cin 0.499400 0.208200 -reg0_a[0] 0.238400 0.176800 -reg0_a[1] 0.246200 0.176000 -reg0_a[2] 0.225800 0.172000 -reg0_a[3] 0.233600 0.175200 -reg0_a[4] 0.241200 0.174400 -reg0_a[5] 0.241400 0.170000 -reg0_a[6] 0.236200 0.171200 -reg0_a[7] 0.244800 0.175200 -reg1_a[0] 0.185400 0.133600 -reg1_a[1] 0.194400 0.138400 -reg1_a[2] 0.177200 0.139600 -reg1_a[3] 0.183600 0.137600 -reg1_a[4] 0.191200 0.140800 -reg1_a[5] 0.191800 0.132000 -reg1_a[6] 0.189200 0.137600 -reg1_a[7] 0.192800 0.140800 -reg2_a[0] 0.148600 0.108000 -reg2_a[1] 0.154800 0.113200 -reg2_a[2] 0.138600 0.111600 -reg2_a[3] 0.145400 0.110800 -reg2_a[4] 0.149200 0.113200 -reg2_a[5] 0.153200 0.108800 -reg2_a[6] 0.151600 0.111600 -reg2_a[7] 0.152200 0.116000 -reg0_b[0] 0.236800 0.178800 -reg0_b[1] 0.233800 0.163200 -reg0_b[2] 0.243600 0.167600 -reg0_b[3] 0.215600 0.173200 -reg0_b[4] 0.226400 0.169200 -reg0_b[5] 0.240000 0.174800 -reg0_b[6] 0.224800 0.177600 -reg0_b[7] 0.245000 0.173200 -reg1_b[0] 0.188000 0.140800 -reg1_b[1] 0.185800 0.130800 -reg1_b[2] 0.193800 0.135200 -reg1_b[3] 0.165600 0.134000 -reg1_b[4] 0.180600 0.134400 -reg1_b[5] 0.188400 0.139600 -reg1_b[6] 0.174200 0.134400 -reg1_b[7] 0.193400 0.136000 -reg2_b[0] 0.149200 0.115200 -reg2_b[1] 0.145600 0.103200 -reg2_b[2] 0.151600 0.107200 -reg2_b[3] 0.128000 0.102800 -reg2_b[4] 0.142200 0.108400 -reg2_b[5] 0.147400 0.110400 -reg2_b[6] 0.138400 0.106800 -reg2_b[7] 0.152600 0.105600 -reg0_cin 0.224800 0.178400 -reg1_cin 0.174400 0.140000 -reg2_cin 0.137400 0.109200 -cout 0.119200 0.105600 -sumout_0 0.111400 0.121200 -sumout_1 0.115800 0.124000 -sumout_2 0.115600 0.126000 -sumout_3 0.115200 0.128000 -sumout_4 0.115800 0.128000 -sumout_5 0.107800 0.119200 -sumout_6 0.117000 0.129200 -sumout_7 0.115200 0.132400 -n340 0.117000 0.060696 -n212_1 0.849800 0.107643 -n213 0.062800 0.025828 -n214 0.850000 0.007413 -n215 0.138200 0.024548 -n216 0.076600 0.000554 -n344 0.115200 0.059006 -n218 0.852400 0.025645 -n57 0.238400 0.039829 -n62 0.246200 0.040694 -n67 0.225800 0.040876 -n72 0.233600 0.039321 -n77 0.241200 0.039861 -n82 0.241400 0.038668 -n87 0.236200 0.042234 -n92 0.244800 0.038625 -n97 0.185400 0.078023 -n102 0.194400 0.076567 -n107 0.177200 0.079580 -n112 0.183600 0.078646 -n117 0.191200 0.077219 -n122 0.191800 0.076600 -n127 0.189200 0.077659 -n132 0.192800 0.076702 -n137 0.148600 0.081354 -n142 0.154800 0.080450 -n147 0.138600 0.083670 -n152 0.145400 0.082242 -n157 0.149200 0.081352 -n162 0.153200 0.080003 -n167 0.151600 0.081252 -n172 0.152200 0.081070 -n177 0.236800 0.041425 -n182 0.233800 0.041591 -n187 0.243600 0.039443 -n192 0.215600 0.045786 -n197 0.226400 0.042352 -n202 0.240000 0.039313 -n207 0.224800 0.040852 -n212 0.245000 0.038637 -n217 0.188000 0.078569 -n222 0.185800 0.077003 -n227 0.193800 0.075904 -n232 0.165600 0.081545 -n237 0.180600 0.079096 -n242 0.188400 0.077479 -n247 0.174200 0.080515 -n252 0.193400 0.076404 -n257 0.149200 0.081918 -n262 0.145600 0.080884 -n267 0.151600 0.080104 -n272 0.128000 0.084941 -n277 0.142200 0.082317 -n282 0.147400 0.081677 -n287 0.138400 0.083456 -n292 0.152600 0.080287 -n297 0.224800 0.041763 -n302 0.174400 0.080624 -n307 0.137400 0.084229 -n312 0.119200 0.071604 -n316 0.111400 0.060180 -n320 0.115800 0.033704 -n324 0.115600 0.059988 -n328 0.115200 0.062886 -n275 0.853600 0.140779 -n336 0.107800 0.062509 -n332 0.115800 0.006673 diff --git a/vpr7_x2p/vpr/Circuits/pip_add.blif b/vpr7_x2p/vpr/Circuits/pip_add.blif deleted file mode 100644 index e8e6939f4..000000000 --- a/vpr7_x2p/vpr/Circuits/pip_add.blif +++ /dev/null @@ -1,264 +0,0 @@ -# Benchmark "pip_add" written by ABC on Fri Dec 7 14:18:10 2018 -.model pip_add -.inputs rst clk a_0 a_1 a_2 a_3 a_4 a_5 a_6 a_7 b_0 b_1 b_2 b_3 b_4 b_5 b_6 \ - b_7 cin -.outputs sumout_0 sumout_1 sumout_2 sumout_3 sumout_4 sumout_5 sumout_6 \ - sumout_7 cout - -.latch n57 reg0_a[0] re clk 0 -.latch n62 reg0_a[1] re clk 0 -.latch n67 reg0_a[2] re clk 0 -.latch n72 reg0_a[3] re clk 0 -.latch n77 reg0_a[4] re clk 0 -.latch n82 reg0_a[5] re clk 0 -.latch n87 reg0_a[6] re clk 0 -.latch n92 reg0_a[7] re clk 0 -.latch n97 reg1_a[0] re clk 0 -.latch n102 reg1_a[1] re clk 0 -.latch n107 reg1_a[2] re clk 0 -.latch n112 reg1_a[3] re clk 0 -.latch n117 reg1_a[4] re clk 0 -.latch n122 reg1_a[5] re clk 0 -.latch n127 reg1_a[6] re clk 0 -.latch n132 reg1_a[7] re clk 0 -.latch n137 reg2_a[0] re clk 0 -.latch n142 reg2_a[1] re clk 0 -.latch n147 reg2_a[2] re clk 0 -.latch n152 reg2_a[3] re clk 0 -.latch n157 reg2_a[4] re clk 0 -.latch n162 reg2_a[5] re clk 0 -.latch n167 reg2_a[6] re clk 0 -.latch n172 reg2_a[7] re clk 0 -.latch n177 reg0_b[0] re clk 0 -.latch n182 reg0_b[1] re clk 0 -.latch n187 reg0_b[2] re clk 0 -.latch n192 reg0_b[3] re clk 0 -.latch n197 reg0_b[4] re clk 0 -.latch n202 reg0_b[5] re clk 0 -.latch n207 reg0_b[6] re clk 0 -.latch n212 reg0_b[7] re clk 0 -.latch n217 reg1_b[0] re clk 0 -.latch n222 reg1_b[1] re clk 0 -.latch n227 reg1_b[2] re clk 0 -.latch n232 reg1_b[3] re clk 0 -.latch n237 reg1_b[4] re clk 0 -.latch n242 reg1_b[5] re clk 0 -.latch n247 reg1_b[6] re clk 0 -.latch n252 reg1_b[7] re clk 0 -.latch n257 reg2_b[0] re clk 0 -.latch n262 reg2_b[1] re clk 0 -.latch n267 reg2_b[2] re clk 0 -.latch n272 reg2_b[3] re clk 0 -.latch n277 reg2_b[4] re clk 0 -.latch n282 reg2_b[5] re clk 0 -.latch n287 reg2_b[6] re clk 0 -.latch n292 reg2_b[7] re clk 0 -.latch n297 reg0_cin re clk 0 -.latch n302 reg1_cin re clk 0 -.latch n307 reg2_cin re clk 0 -.latch n312 cout re clk 0 -.latch n316 sumout_0 re clk 0 -.latch n320 sumout_1 re clk 0 -.latch n324 sumout_2 re clk 0 -.latch n328 sumout_3 re clk 0 -.latch n332 sumout_4 re clk 0 -.latch n336 sumout_5 re clk 0 -.latch n340 sumout_6 re clk 0 -.latch n344 sumout_7 re clk 0 - -.names reg2_a[6] reg2_b[6] n212_1 rst n340 -0000 1 -0110 1 -1010 1 -1100 1 -.names n216 n213 reg2_a[5] reg2_b[5] n212_1 -000- 1 -00-0 1 ---00 1 -.names n215 reg2_a[2] reg2_b[2] reg2_a[3] reg2_b[3] n214 n213 -1111-- 1 -111-1- 1 -11-1-0 1 -11--10 1 -1-11-0 1 -1-1-10 1 -1--11- 1 -.names reg2_a[1] reg2_cin reg2_a[0] reg2_b[0] reg2_b[1] n214 -000-- 1 -00-0- 1 -0-00- 1 -0---0 1 --00-0 1 --0-00 1 ---000 1 -.names reg2_a[4] reg2_b[4] n215 -01 1 -10 1 -.names reg2_a[4] reg2_b[4] n216 -11 1 -.names reg2_a[7] reg2_b[7] n218 rst n344 -0000 1 -0110 1 -1010 1 -1100 1 -.names n213 n216 reg2_a[6] reg2_a[5] reg2_b[5] reg2_b[6] n218 -0000-- 1 -000-0- 1 -00-0-0 1 -00--00 1 ---000- 1 ---0--0 1 ----000 1 -.names a_0 rst n57 -10 1 -.names a_1 rst n62 -10 1 -.names a_2 rst n67 -10 1 -.names a_3 rst n72 -10 1 -.names a_4 rst n77 -10 1 -.names a_5 rst n82 -10 1 -.names a_6 rst n87 -10 1 -.names a_7 rst n92 -10 1 -.names reg0_a[0] rst n97 -10 1 -.names reg0_a[1] rst n102 -10 1 -.names reg0_a[2] rst n107 -10 1 -.names reg0_a[3] rst n112 -10 1 -.names reg0_a[4] rst n117 -10 1 -.names reg0_a[5] rst n122 -10 1 -.names reg0_a[6] rst n127 -10 1 -.names reg0_a[7] rst n132 -10 1 -.names reg1_a[0] rst n137 -10 1 -.names reg1_a[1] rst n142 -10 1 -.names reg1_a[2] rst n147 -10 1 -.names reg1_a[3] rst n152 -10 1 -.names reg1_a[4] rst n157 -10 1 -.names reg1_a[5] rst n162 -10 1 -.names reg1_a[6] rst n167 -10 1 -.names reg1_a[7] rst n172 -10 1 -.names b_0 rst n177 -10 1 -.names b_1 rst n182 -10 1 -.names b_2 rst n187 -10 1 -.names b_3 rst n192 -10 1 -.names b_4 rst n197 -10 1 -.names b_5 rst n202 -10 1 -.names b_6 rst n207 -10 1 -.names b_7 rst n212 -10 1 -.names reg0_b[0] rst n217 -10 1 -.names reg0_b[1] rst n222 -10 1 -.names reg0_b[2] rst n227 -10 1 -.names reg0_b[3] rst n232 -10 1 -.names reg0_b[4] rst n237 -10 1 -.names reg0_b[5] rst n242 -10 1 -.names reg0_b[6] rst n247 -10 1 -.names reg0_b[7] rst n252 -10 1 -.names reg1_b[0] rst n257 -10 1 -.names reg1_b[1] rst n262 -10 1 -.names reg1_b[2] rst n267 -10 1 -.names reg1_b[3] rst n272 -10 1 -.names reg1_b[4] rst n277 -10 1 -.names reg1_b[5] rst n282 -10 1 -.names reg1_b[6] rst n287 -10 1 -.names reg1_b[7] rst n292 -10 1 -.names cin rst n297 -10 1 -.names reg0_cin rst n302 -10 1 -.names reg1_cin rst n307 -10 1 -.names rst reg2_a[7] reg2_b[7] n218 n312 -011- 1 -01-0 1 -0-10 1 -.names reg2_cin reg2_a[0] reg2_b[0] rst n316 -0010 1 -0100 1 -1000 1 -1110 1 -.names reg2_a[1] reg2_b[1] rst reg2_cin reg2_a[0] reg2_b[0] n320 -00011- 1 -0001-1 1 -000-11 1 -01000- 1 -0100-0 1 -010-00 1 -10000- 1 -1000-0 1 -100-00 1 -11011- 1 -1101-1 1 -110-11 1 -.names reg2_a[2] reg2_b[2] n214 rst n324 -0000 1 -0110 1 -1010 1 -1100 1 -.names reg2_a[3] reg2_b[3] n275 rst n328 -0000 1 -0110 1 -1010 1 -1100 1 -.names reg2_a[2] reg2_b[2] n214 n275 -00- 1 -0-1 1 --01 1 -.names reg2_a[5] reg2_b[5] rst n216 n213 n336 -0001- 1 -000-1 1 -01000 1 -10000 1 -1101- 1 -110-1 1 -.names n215 rst reg2_a[3] reg2_b[3] n275 n332 -0011- 1 -001-0 1 -00-10 1 -1000- 1 -100-1 1 -10-01 1 -.end diff --git a/vpr7_x2p/vpr/Circuits/pip_add.v b/vpr7_x2p/vpr/Circuits/pip_add.v deleted file mode 100644 index 8b2b11b12..000000000 --- a/vpr7_x2p/vpr/Circuits/pip_add.v +++ /dev/null @@ -1,142 +0,0 @@ -//////////////////////////////////////// -// // -// Pipelined adder benchmark // -// // -//////////////////////////////////////// - -module pip_add( - rst, - clk, - a_0, - a_1, - a_2, - a_3, - a_4, - a_5, - a_6, - a_7, - b_0, - b_1, - b_2, - b_3, - b_4, - b_5, - b_6, - b_7, - cin, - sumout_0, - sumout_1, - sumout_2, - sumout_3, - sumout_4, - sumout_5, - sumout_6, - sumout_7, - cout); - - input rst; - input clk; - input a_0; - input a_1; - input a_2; - input a_3; - input a_4; - input a_5; - input a_6; - input a_7; - input b_0; - input b_1; - input b_2; - input b_3; - input b_4; - input b_5; - input b_6; - input b_7; - input cin; - output sumout_0; - output sumout_1; - output sumout_2; - output sumout_3; - output sumout_4; - output sumout_5; - output sumout_6; - output sumout_7; - output reg cout; - - reg[7:0] reg0_a; - reg[7:0] reg0_b; - reg[7:0] reg1_a; - reg[7:0] reg1_b; - reg[7:0] reg2_a; - reg[7:0] reg2_b; - reg reg0_cin; - reg reg1_cin; - reg reg2_cin; - wire[8:0] int_sum; - wire int_cout; - wire[7:0] a; - wire[7:0] b; - reg[7:0] sumout; - - assign a = {a_7, a_6, a_5, a_4, a_3, a_2, a_1, a_0}; - assign b = {b_7, b_6, b_5, b_4, b_3, b_2, b_1, b_0}; - assign int_sum = reg2_a + reg2_b + reg2_cin; - assign int_cout = int_sum[8] || 1'b0; - assign sumout_0 = sumout[0]; - assign sumout_1 = sumout[1]; - assign sumout_2 = sumout[2]; - assign sumout_3 = sumout[3]; - assign sumout_4 = sumout[4]; - assign sumout_5 = sumout[5]; - assign sumout_6 = sumout[6]; - assign sumout_7 = sumout[7]; - - always@(posedge clk or posedge rst) begin - if(rst) begin - reg0_a <= 8'h00; - reg0_b <= 8'h00; - reg0_cin <= 1'b0; - end - else begin - reg0_a <= a; - reg0_b <= b; - reg0_cin <= cin; - end - end - always@(posedge clk or posedge rst) begin - if(rst) begin - reg1_a <= 8'h00; - reg1_b <= 8'h00; - reg1_cin <= 1'b0; - end - else begin - reg1_a <= reg0_a; - reg1_b <= reg0_b; - reg1_cin <= reg0_cin; - end - end - always@(posedge clk or posedge rst) begin - if(rst) begin - reg2_a <= 8'h00; - reg2_b <= 8'h00; - reg2_cin <= 1'b0; - end - else begin - reg2_a <= reg1_a; - reg2_b <= reg1_b; - reg2_cin <= reg1_cin; - end - end - - always@(posedge clk or posedge rst) begin - if(rst) begin - sumout <= 8'h00; - cout <= 1'b0; - end - else begin - sumout <= int_sum[7:0]; - cout <= int_cout; - end - end - -endmodule diff --git a/vpr7_x2p/vpr/Circuits/s298_prevpr.act b/vpr7_x2p/vpr/Circuits/s298_prevpr.act deleted file mode 100644 index 56542574b..000000000 --- a/vpr7_x2p/vpr/Circuits/s298_prevpr.act +++ /dev/null @@ -1,42 +0,0 @@ -G0 0.515200 0.186400 -G1 0.514800 0.193600 -G2 0.486200 0.195800 -clk 0.490200 0.198400 -G10 0.267600 0.534800 -G11 0.222000 0.243600 -G12 0.166600 0.110400 -G13 0.043600 0.050400 -G14 0.181000 0.214400 -G15 0.047800 0.016000 -G16 0.012800 0.018400 -G17 0.880200 0.057600 -G18 0.925000 0.038400 -G19 0.046400 0.081200 -G20 0.033600 0.066400 -G21 0.044800 0.043200 -G22 0.193800 0.272200 -G23 0.212000 0.292800 -n21 0.267600 0.136672 -n26 0.222000 0.010724 -n31 0.166600 0.005271 -n36 0.043600 0.088128 -n41 0.181000 0.010995 -n57 0.679400 0.039608 -n46 0.047800 0.000597 -n59 0.941600 0.000356 -n51 0.012800 0.001040 -n56 0.880200 0.082925 -n61 0.925000 0.075430 -n66_1 0.046400 0.002953 -n64 0.047600 0.072462 -n71 0.033600 0.005766 -n66 0.099400 0.025568 -n76 0.044800 0.001108 -n81 0.193800 0.038591 -n86 0.212000 0.041397 -G117 0.924800 0.035520 -G132 0.033600 0.002231 -G66 0.012800 0.000236 -G118 0.046400 0.003768 -G133 0.044800 0.001935 -G67 0.880000 0.050700 diff --git a/vpr7_x2p/vpr/Circuits/s298_prevpr.blif b/vpr7_x2p/vpr/Circuits/s298_prevpr.blif deleted file mode 100644 index 92852723b..000000000 --- a/vpr7_x2p/vpr/Circuits/s298_prevpr.blif +++ /dev/null @@ -1,104 +0,0 @@ -# Benchmark "s298.bench" written by ABC on Thu Jul 26 11:12:10 2018 -.model s298.bench -.inputs G0 G1 G2 clk -.outputs G117 G132 G66 G118 G133 G67 - -.latch n21 G10 re clk 0 -.latch n26 G11 re clk 0 -.latch n31 G12 re clk 0 -.latch n36 G13 re clk 0 -.latch n41 G14 re clk 0 -.latch n46 G15 re clk 0 -.latch n51 G16 re clk 0 -.latch n56 G17 re clk 0 -.latch n61 G18 re clk 0 -.latch n66_1 G19 re clk 0 -.latch n71 G20 re clk 0 -.latch n76 G21 re clk 0 -.latch n81 G22 re clk 0 -.latch n86 G23 re clk 0 - -.names G0 G10 n21 -00 1 -.names G0 G10 G11 G12 G13 n26 -001-- 1 -0101- 1 -010-0 1 -.names G0 G10 G11 G12 n31 -00-1 1 -0110 1 -0-01 1 -.names G0 G10 G11 G12 G13 n36 -00--1 1 -01110 1 -0-011 1 -0-101 1 -.names G0 G10 G13 G14 G23 n57 n41 -00-10- 1 -0110-1 1 -0-010- 1 -0--01- 1 -0--100 1 -.names G11 G12 n57 -00 1 -.names G0 n59 n46 -00 1 -.names G11 G12 G13 G14 G15 G22 n59 -1010-0 1 -1---0- 1 --1--0- 1 ---0-0- 1 ----10- 1 -----00 1 -.names G12 G13 G14 G16 n59 n51 -1-111 1 --10-1 1 --1-11 1 -.names G11 G12 G13 G14 G17 n59 n56 -0-00-1 1 -100--1 1 --1-111 1 ---1111 1 -.names G11 G12 G13 G14 G18 n59 n61 -100--1 1 --1-111 1 ---00-1 1 ---1111 1 -.names G10 n59 n64 n66_1 -00- 1 --11 1 -.names G11 G12 G13 G14 G19 n64 -0001- 1 --1-11 1 ---10- 1 ---1-1 1 -.names G10 G12 G13 G20 n59 n66 n71 -0---0- 1 --00-11 1 ----111 1 -.names G11 G12 G13 G14 n66 -100- 0 ----0 0 -.names G11 G12 G13 G14 G21 n59 n76 -1100-1 1 --1-111 1 ---1111 1 -.names G0 G2 G22 n81 -001 1 -010 1 -.names G0 G1 G23 n86 -001 1 -010 1 -.names G18 G117 -1 1 -.names G20 G132 -1 1 -.names G16 G66 -1 1 -.names G19 G118 -1 1 -.names G21 G133 -1 1 -.names G17 G67 -1 1 -.end diff --git a/vpr7_x2p/vpr/Circuits/sync_4bits_add.act b/vpr7_x2p/vpr/Circuits/sync_4bits_add.act deleted file mode 100644 index 552c806f1..000000000 --- a/vpr7_x2p/vpr/Circuits/sync_4bits_add.act +++ /dev/null @@ -1,40 +0,0 @@ -clk 0.511800 0.202800 -rst 0.00001 0.198000 -a0 0.465000 0.196200 -a1 0.476000 0.196200 -a2 0.480800 0.203200 -a3 0.523200 0.203400 -b0 0.502800 0.211200 -b1 0.479200 0.208400 -b2 0.495200 0.197000 -b3 0.521000 0.204800 -cin 0.490400 0.194600 -reg_b[3] 0.250800 0.189200 -reg_cin 0.241600 0.168200 -cout 0.197600 0.171000 -sumout0 0.197400 0.197200 -sumout1 0.195200 0.205800 -sumout2 0.202000 0.213000 -sumout3 0.191600 0.207600 -reg_a[0] 0.229800 0.171000 -reg_a[1] 0.236000 0.170200 -reg_a[2] 0.230000 0.174400 -reg_a[3] 0.258400 0.179800 -reg_b[0] 0.250600 0.180400 -reg_b[1] 0.238600 0.177800 -reg_b[2] 0.248000 0.177400 -n83 0.250600 0.044471 -n88 0.238600 0.047498 -n93 0.248000 0.044135 -n33 0.250800 0.041399 -n38 0.241600 0.044556 -n43 0.197600 0.011311 -n67 0.767600 0.013393 -n47 0.197400 0.040388 -n51 0.195200 0.019975 -n55 0.202000 0.042318 -n59 0.191600 0.007901 -n63 0.229800 0.048269 -n68 0.236000 0.046714 -n73 0.230000 0.046748 -n78 0.258400 0.040977 diff --git a/vpr7_x2p/vpr/Circuits/sync_4bits_add.blif b/vpr7_x2p/vpr/Circuits/sync_4bits_add.blif deleted file mode 100644 index f099a798b..000000000 --- a/vpr7_x2p/vpr/Circuits/sync_4bits_add.blif +++ /dev/null @@ -1,91 +0,0 @@ -# Benchmark "sync_4bits_add" written by ABC on Sat Dec 22 05:55:54 2018 -.model sync_4bits_add -.inputs clk rst a0 a1 a2 a3 b0 b1 b2 b3 cin -.outputs sumout0 sumout1 sumout2 sumout3 cout - -.latch n33 reg_b[3] re clk 0 -.latch n38 reg_cin re clk 0 -.latch n43 cout re clk 0 -.latch n47 sumout0 re clk 0 -.latch n51 sumout1 re clk 0 -.latch n55 sumout2 re clk 0 -.latch n59 sumout3 re clk 0 -.latch n63 reg_a[0] re clk 0 -.latch n68 reg_a[1] re clk 0 -.latch n73 reg_a[2] re clk 0 -.latch n78 reg_a[3] re clk 0 -.latch n83 reg_b[0] re clk 0 -.latch n88 reg_b[1] re clk 0 -.latch n93 reg_b[2] re clk 0 - -.names b0 rst n83 -10 1 -.names b1 rst n88 -10 1 -.names b2 rst n93 -10 1 -.names b3 rst n33 -10 1 -.names cin rst n38 -10 1 -.names rst reg_b[2] reg_a[2] reg_b[3] reg_a[3] n67 n43 -0111-- 1 -011-1- 1 -01-1-0 1 -01--10 1 -0-11-0 1 -0-1-10 1 -0--11- 1 -.names reg_b[1] reg_cin reg_b[0] reg_a[0] reg_a[1] n67 -000-- 1 -00-0- 1 -0-00- 1 -0---0 1 --00-0 1 --0-00 1 ---000 1 -.names reg_cin reg_b[0] reg_a[0] rst n47 -0010 1 -0100 1 -1000 1 -1110 1 -.names reg_b[1] reg_a[1] rst reg_cin reg_b[0] reg_a[0] n51 -00011- 1 -0001-1 1 -000-11 1 -01000- 1 -0100-0 1 -010-00 1 -10000- 1 -1000-0 1 -100-00 1 -11011- 1 -1101-1 1 -110-11 1 -.names reg_b[2] reg_a[2] n67 rst n55 -0000 1 -0110 1 -1010 1 -1100 1 -.names reg_b[3] reg_a[3] rst reg_b[2] reg_a[2] n67 n59 -00011- 1 -0001-0 1 -000-10 1 -01000- 1 -0100-1 1 -010-01 1 -10000- 1 -1000-1 1 -100-01 1 -11011- 1 -1101-0 1 -110-10 1 -.names a0 rst n63 -10 1 -.names a1 rst n68 -10 1 -.names a2 rst n73 -10 1 -.names a3 rst n78 -10 1 -.end diff --git a/vpr7_x2p/vpr/Circuits/sync_4bits_add.v b/vpr7_x2p/vpr/Circuits/sync_4bits_add.v deleted file mode 100644 index adf440bee..000000000 --- a/vpr7_x2p/vpr/Circuits/sync_4bits_add.v +++ /dev/null @@ -1,90 +0,0 @@ -//////////////////////////////////////// -// // -// Synchronized adder benchmark // -// // -//////////////////////////////////////// - -module sync_4bits_add( - clk, - rst, - a0, - a1, - a2, - a3, - b0, - b1, - b2, - b3, - cin, - sumout0, - sumout1, - sumout2, - sumout3, - cout); - - input clk; - input rst; - input a0; - input a1; - input a2; - input a3; - input b0; - input b1; - input b2; - input b3; - input cin; - output sumout0; - output sumout1; - output sumout2; - output sumout3; - output reg cout; - - wire[3:0] a; - wire[3:0] b; - reg[3:0] sumout; - - reg[3:0] reg_a; - reg[3:0] reg_b; - reg reg_cin; - wire[4:0] int_sum; - - assign a[3] = a3; - assign a[2] = a2; - assign a[1] = a1; - assign a[0] = a0; - assign b[3] = b3; - assign b[2] = b2; - assign b[1] = b1; - assign b[0] = b0; - assign sumout3 = sumout[3]; - assign sumout2 = sumout[2]; - assign sumout1 = sumout[1]; - assign sumout0 = sumout[0]; - - assign int_sum = reg_a + reg_b + reg_cin; - - always@(posedge clk or posedge rst) begin - if(rst) begin - reg_a <= 4'h0; - reg_b <= 4'h0; - reg_cin <= 1'h0; - end - else begin - reg_a <= a; - reg_b <= b; - reg_cin <= cin; - end - end - - always@(posedge clk or posedge rst) begin - if(rst) begin - sumout <= 4'h0; - cout <= 1'h0; - end - else begin - sumout <= int_sum[3:0]; - cout <= int_sum[4]; - end - end - -endmodule diff --git a/vpr7_x2p/vpr/Makefile b/vpr7_x2p/vpr/Makefile index 837b9e7f0..25193d245 100755 --- a/vpr7_x2p/vpr/Makefile +++ b/vpr7_x2p/vpr/Makefile @@ -7,7 +7,7 @@ # Please note that a Mac can run the graphics if the X11 library is installed. -ENABLE_GRAPHICS = true +ENABLE_GRAPHICS = false # can be true or false export BUILD_TYPE = debug @@ -23,11 +23,12 @@ OPTIMIZATION_LEVEL_FOR_RELEASE_BUILD = -O3 CC = $(COMPILER) LIB_DIR = -L. -LIB = -lm -lvpr -FPGA_SPICE_SRC_DIR = SRC/fpga_spice +LIB = -lm -lvpr -lreadline +SHELL_LIB = -lm -lvpr_shell -lreadline +FPGA_SPICE_SRC_DIR = SRC/fpga_x2p SRC_DIR = SRC OBJ_DIR = OBJ -OTHER_DIR = -ISRC/util -ISRC/timing -ISRC/pack -ISRC/place -ISRC/base -ISRC/route -ISRC/power -ISRC/mrfpga -ISRC/fpga_spice/base -ISRC/fpga_spice/spice -ISRC/fpga_spice/verilog -ISRC/fpga_spice/clb_pin_remap -I../libarchfpga -I../printhandler/SRC/TIO_InputOutputHandlers +OTHER_DIR = -ISRC/util -ISRC/timing -ISRC/pack -ISRC/place -ISRC/base -ISRC/route -ISRC/power -ISRC/mrfpga -ISRC/fpga_spice -I$(FPGA_SPICE_SRC_DIR)/base -I$(FPGA_SPICE_SRC_DIR)/bitstream -I$(FPGA_SPICE_SRC_DIR)/bitstream -I$(FPGA_SPICE_SRC_DIR)/clb_pin_remap -I$(FPGA_SPICE_SRC_DIR)/spice -I$(FPGA_SPICE_SRC_DIR)/verilog -I$(FPGA_SPICE_SRC_DIR)/router -I../libarchfpga -I../printhandler/SRC/TIO_InputOutputHandlers -I$(FPGA_SPICE_SRC_DIR)/shell WARN_FLAGS = -Wall -Wpointer-arith -Wcast-qual -D__USE_FIXED_PROTOTYPES__ -ansi -pedantic -Wshadow -Wcast-align -D_POSIX_SOURCE -Wno-write-strings @@ -41,8 +42,6 @@ UNAME := $(shell uname) # determine build env ifeq ($(UNAME), Darwin) MAC_OS = true - # Disable graphic in MacOS - ENABLE_GRAPHICS = false else MAC_OS = false endif @@ -79,6 +78,12 @@ DEP := $(OBJ:.o=.d) $(EXE): $(OBJ) Makefile libvpr.a | notify $(CC) $(FLAGS) OBJ/main.o -o $(EXE) $(LIB_DIR) $(LIB) +SHELL_EXE = vpr_shell + +# cmd-shell interface main +$(SHELL_EXE): $(OBJ) Makefile libvpr_shell.a | notify + $(CC) $(FLAGS) OBJ/shell_main.o -o $(SHELL_EXE) $(LIB_DIR) $(SHELL_LIB) + # if graphics enabled but libx11-dev is not installed, notify the user notify: @ $(PACKAGENOTIFICATION) @@ -96,6 +101,11 @@ libvpr.a: $(OBJ) Makefile libarchfpga @ ar rcs $@ $(OBJ) @ ar d $@ main.o +libvpr_shell.a: $(OBJ) Makefile libarchfpga + @ cp ../libarchfpga/libarchfpga.a $@ + @ ar rcs $@ $(OBJ) + @ ar d $@ shell_main.o + # Enable a second round of expansion so that we may include # the target directory as a prerequisite of the object file. .SECONDEXPANSION: @@ -104,7 +114,7 @@ libvpr.a: $(OBJ) Makefile libarchfpga # timestamp check. Every write to the directory updates the timestamp thus # without this, all but the last file written to a directory would appear # to be out of date. -$(OBJ): OBJ/%.o:$(SRC_DIR)/%.c | $$(dir $$@D) +$(OBJ): OBJ/%.o:$(SRC_DIR)/%.c | $$(dir $$@D) $(CC) $(FLAGS) -MD -MP -I$(OTHER_DIR) -ISRC/util -c $< -o $@ # Silently create target directories as need @@ -113,8 +123,16 @@ $(OBJ_DIRS): -include $(DEP) +.PHONY: all vpr shell_vpr + +all: $(EXE) $(SHELL_EXE) + +vpr: $(EXE) + +shell_vpr: $(SHELL_EXE) + clean: - rm -f $(EXE) $(OBJ) $(DEP) libvpr.a + rm -f $(SHELL_EXE) $(EXE) $(OBJ) $(DEP) libvpr.a libvpr_shell.a cd ../libarchfpga && make clean clean_coverage: clean diff --git a/vpr7_x2p/vpr/SRC/base/OptionTokens.c b/vpr7_x2p/vpr/SRC/base/OptionTokens.c index 357bd7d07..d96645aac 100644 --- a/vpr7_x2p/vpr/SRC/base/OptionTokens.c +++ b/vpr7_x2p/vpr/SRC/base/OptionTokens.c @@ -57,40 +57,47 @@ struct s_TokenPair OptionBaseTokenList[] = { { "power_output_file", OT_POWER_OUT_FILE }, /* Output file for power results */ { "power", OT_POWER }, /* Run power estimation? */ { "tech_properties", OT_CMOS_TECH_BEHAVIOR_FILE }, /* Technology properties */ + /* General FPGA_X2P: FPGA-SPICE/Verilog/Bitstream Options */ + { "fpga_x2p_rename_illegal_port", OT_FPGA_X2P_RENAME_ILLEGAL_PORT }, /* Xifan TANG: rename illegal port names */ + { "fpga_x2p_signal_density_weight", OT_FPGA_X2P_SIGNAL_DENSITY_WEIGHT }, /* The weight of signal density */ + { "fpga_x2p_sim_window_size", OT_FPGA_X2P_SIM_WINDOW_SIZE }, /* Window size in determining number of clock cycles in simulation */ /* Xifan TANG: FPGA SPICE Support */ { "fpga_spice", OT_FPGA_SPICE },/* Xifan TANG: SPICE Model Support, turn on the functionality*/ - { "fpga_spice_rename_illegal_port", OT_FPGA_SPICE_RENAME_ILLEGAL_PORT }, /* Xifan TANG: rename illegal port names */ - { "fpga_spice_signal_density_weight", OT_FPGA_SPICE_SIGNAL_DENSITY_WEIGHT }, /* The weight of signal density */ - { "fpga_spice_sim_window_size", OT_FPGA_SPICE_SIM_WINDOW_SIZE }, /* Window size in determining number of clock cycles in simulation */ - { "fpga_spice_sim_mt_num", OT_FPGA_SPICE_SIM_MT_NUM }, /* number of multi-thread used in simulation */ - { "fpga_spice_dir", OT_SPICE_DIR },/* Xifan TANG: SPICE Model Support, directory of spice netlists*/ - { "fpga_spice_print_top_testbench", OT_SPICE_PRINT_TOP_TESTBENCH }, /* Print the SPICE TOP Testbench for MUXes */ - { "fpga_spice_print_pb_mux_testbench", OT_SPICE_PRINT_PB_MUX_TESTBENCH }, /* Print the SPICE Testbench for MUXes */ - { "fpga_spice_print_cb_mux_testbench", OT_SPICE_PRINT_CB_MUX_TESTBENCH }, /* Print the SPICE Testbench for MUXes */ - { "fpga_spice_print_sb_mux_testbench", OT_SPICE_PRINT_SB_MUX_TESTBENCH }, /* Print the SPICE Testbench for MUXes */ - { "fpga_spice_print_cb_testbench", OT_SPICE_PRINT_CB_TESTBENCH }, /* Print the SPICE Testbench for CBs */ - { "fpga_spice_print_sb_testbench", OT_SPICE_PRINT_SB_TESTBENCH }, /* Print the SPICE Testbench for SBs */ - { "fpga_spice_print_grid_testbench", OT_SPICE_PRINT_GRID_TESTBENCH }, /* Print the SPICE Testbench for Grids */ - { "fpga_spice_print_lut_testbench", OT_SPICE_PRINT_LUT_TESTBENCH }, /* Print the SPICE Testbench for Grids */ - { "fpga_spice_print_hardlogic_testbench", OT_SPICE_PRINT_HARDLOGIC_TESTBENCH }, /* Print the SPICE Testbench for Grids */ + { "fpga_spice_dir", OT_FPGA_SPICE_DIR },/* Xifan TANG: SPICE Model Support, directory of spice netlists*/ + { "fpga_spice_print_top_testbench", OT_FPGA_SPICE_PRINT_TOP_TESTBENCH }, /* Print the SPICE TOP Testbench for MUXes */ + { "fpga_spice_print_pb_mux_testbench", OT_FPGA_SPICE_PRINT_PB_MUX_TESTBENCH }, /* Print the SPICE Testbench for MUXes */ + { "fpga_spice_print_cb_mux_testbench", OT_FPGA_SPICE_PRINT_CB_MUX_TESTBENCH }, /* Print the SPICE Testbench for MUXes */ + { "fpga_spice_print_sb_mux_testbench", OT_FPGA_SPICE_PRINT_SB_MUX_TESTBENCH }, /* Print the SPICE Testbench for MUXes */ + { "fpga_spice_print_cb_testbench", OT_FPGA_SPICE_PRINT_CB_TESTBENCH }, /* Print the SPICE Testbench for CBs */ + { "fpga_spice_print_sb_testbench", OT_FPGA_SPICE_PRINT_SB_TESTBENCH }, /* Print the SPICE Testbench for SBs */ + { "fpga_spice_print_grid_testbench", OT_FPGA_SPICE_PRINT_GRID_TESTBENCH }, /* Print the SPICE Testbench for Grids */ + { "fpga_spice_print_lut_testbench", OT_FPGA_SPICE_PRINT_LUT_TESTBENCH }, /* Print the SPICE Testbench for Grids */ + { "fpga_spice_print_hardlogic_testbench", OT_FPGA_SPICE_PRINT_HARDLOGIC_TESTBENCH }, /* Print the SPICE Testbench for Grids */ + { "fpga_spice_print_io_testbench", OT_FPGA_SPICE_PRINT_IO_TESTBENCH }, /* Print the SPICE Testbench for Grids */ { "fpga_spice_leakage_only", OT_FPGA_SPICE_LEAKAGE_ONLY }, /* Only simulate leakage power in FPGA SPICE */ - { "fpga_spice_parasitic_net_estimation_off", OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION_OFF }, /* Xifan TANG: turn off the parasitic net estimation*/ - { "fpga_spice_testbench_load_extraction_off", OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION_OFF }, /* Xifan TANG: turn off the parasitic net estimation*/ - - + { "fpga_spice_parasitic_net_estimation", OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION}, /* Xifan TANG: turn on/off the parasitic net estimation*/ + { "fpga_spice_testbench_load_extraction", OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION}, /* Xifan TANG: turn on/off the parasitic net estimation*/ + { "fpga_spice_simulator_path", OT_FPGA_SPICE_SIMULATOR_PATH}, /* Specify simulator path for SPICE netlists */ + { "fpga_spice_sim_mt_num", OT_FPGA_SPICE_SIM_MT_NUM }, /* number of multi-thread used in simulation */ /* Xifan TANG: Synthsizable Verilog */ { "fpga_verilog", OT_FPGA_VERILOG_SYN }, { "fpga_verilog_dir", OT_FPGA_VERILOG_SYN_DIR }, - { "fpga_verilog_print_top_testbench", OT_FPGA_VERILOG_SYN_PRINT_TOP_TB }, - { "fpga_verilog_print_top_auto_testbench", OT_FPGA_VERILOG_SYN_PRINT_TOP_AUTO_TB }, - { "fpga_verilog_print_input_blif_testbench", OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TB }, - { "fpga_verilog_print_input_blif_testbench", OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TB }, - { "fpga_verilog_tb_serial_config_mode", OT_FPGA_VERILOG_SYN_TB_SERIAL_CONFIG_MODE }, + { "fpga_verilog_print_top_testbench", OT_FPGA_VERILOG_SYN_PRINT_TOP_TESTBENCH }, + { "fpga_verilog_print_autocheck_top_testbench", OT_FPGA_VERILOG_SYN_PRINT_AUTOCHECK_TOP_TESTBENCH }, + { "fpga_verilog_print_input_blif_testbench", OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TESTBENCH }, + { "fpga_verilog_print_formal_verification_top_netlist", OT_FPGA_VERILOG_SYN_PRINT_FORMAL_VERIFICATION_TOP_NETLIST }, { "fpga_verilog_include_timing", OT_FPGA_VERILOG_SYN_INCLUDE_TIMING }, /* Include timing constraints in Verilog netlists */ - { "fpga_verilog_init_sim", OT_FPGA_VERILOG_INIT_SIM }, /* Allow simulation initialization */ - { "fpga_verilog_print_modelsim_autodeck", OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK }, /* Allow simulation script generation */ - { "fpga_verilog_modelsim_ini_path", OT_FPGA_VERILOG_SYN_MODELSIM_INI_PATH }, /* Specify the simulator path for Verilog netlists */ - /* mrFPGA: Xifan TANG */ + { "fpga_verilog_include_signal_init", OT_FPGA_VERILOG_SYN_INCLUDE_SIGNAL_INIT }, /* Include signal initialization in Verilog netlists */ + { "fpga_verilog_include_icarus_simulator", OT_FPGA_VERILOG_SYN_INCLUDE_ICARUS_SIMULATOR }, /* Include/activate Icarus required functions in Verilog netlists */ + { "fpga_verilog_print_modelsim_autodeck", OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK }, /* Generate autodeck scripts for modelsim */ + { "fpga_verilog_print_user_defined_template", OT_FPGA_VERILOG_SYN_PRINT_USER_DEFINED_TEMPLATE }, /* Specify the simulator path for Verilog netlists */ + { "fpga_verilog_print_report_timing_tcl", OT_FPGA_VERILOG_SYN_PRINT_REPORT_TIMING_TCL }, /* Specify the simulator path for Verilog netlists */ + { "fpga_verilog_report_timing_rpt_path", OT_FPGA_VERILOG_SYN_REPORT_TIMING_RPT_PATH }, /* Specify the simulator path for Verilog netlists */ + { "fpga_verilog_print_sdc_pnr", OT_FPGA_VERILOG_SYN_PRINT_SDC_PNR }, /* Specify the simulator path for Verilog netlists */ + { "fpga_verilog_print_sdc_analysis", OT_FPGA_VERILOG_SYN_PRINT_SDC_ANALYSIS }, /* Specify the simulator path for Verilog netlists */ + /* Xifan Tang: Bitstream generator */ + { "fpga_bitstream_generator", OT_FPGA_BITSTREAM_GENERATOR }, /* turn on bitstream generator, and specify the output file */ + { "fpga_bitstream_output_file", OT_FPGA_BITSTREAM_OUTPUT_FILE }, /* turn on bitstream generator, and specify the output file */ /* mrFPGA: Xifan TANG */ {"show_sram", OT_SHOW_SRAM}, {"show_pass_trans", OT_SHOW_PASS_TRANS}, diff --git a/vpr7_x2p/vpr/SRC/base/OptionTokens.h b/vpr7_x2p/vpr/SRC/base/OptionTokens.h index be5e6e7a3..af7392806 100644 --- a/vpr7_x2p/vpr/SRC/base/OptionTokens.h +++ b/vpr7_x2p/vpr/SRC/base/OptionTokens.h @@ -74,36 +74,47 @@ enum e_OptionBaseToken { OT_ACTIVITY_FILE, OT_POWER_OUT_FILE, OT_CMOS_TECH_BEHAVIOR_FILE, + /* General FPGA_X2P: FPGA-SPICE/Verilog/Bitstream Options */ + OT_FPGA_X2P_RENAME_ILLEGAL_PORT, + OT_FPGA_X2P_SIGNAL_DENSITY_WEIGHT, /* The weight of signal density in determining number of clock cycles in simulation */ + OT_FPGA_X2P_SIM_WINDOW_SIZE, /* Window size in determining number of clock cycles in simulation */ /* Xifan TANG: FPGA SPICE Support */ OT_FPGA_SPICE, /* Xifan TANG: FPGA SPICE Model Support */ - OT_FPGA_SPICE_RENAME_ILLEGAL_PORT, - OT_FPGA_SPICE_SIGNAL_DENSITY_WEIGHT, /* The weight of signal density in determining number of clock cycles in simulation */ - OT_FPGA_SPICE_SIM_WINDOW_SIZE, /* Window size in determining number of clock cycles in simulation */ - OT_FPGA_SPICE_SIM_MT_NUM, /* number of multi-thread used in simulation */ - OT_SPICE_DIR, /* Xifan TANG: FPGA SPICE Model Support */ - OT_SPICE_PRINT_TOP_TESTBENCH, /* Xifan TANG: Print Top-level SPICE Testbench */ - OT_SPICE_PRINT_PB_MUX_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for MUXes */ - OT_SPICE_PRINT_CB_MUX_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for MUXes */ - OT_SPICE_PRINT_SB_MUX_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for MUXes */ - OT_SPICE_PRINT_CB_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for CBs */ - OT_SPICE_PRINT_SB_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for SBs */ - OT_SPICE_PRINT_GRID_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for Grids */ - OT_SPICE_PRINT_LUT_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for LUTs */ - OT_SPICE_PRINT_HARDLOGIC_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for hard logic s */ + OT_FPGA_SPICE_DIR, /* Xifan TANG: FPGA SPICE Model Support */ + OT_FPGA_SPICE_PRINT_TOP_TESTBENCH, /* Xifan TANG: Print Top-level SPICE Testbench */ + OT_FPGA_SPICE_PRINT_PB_MUX_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for MUXes */ + OT_FPGA_SPICE_PRINT_CB_MUX_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for MUXes */ + OT_FPGA_SPICE_PRINT_SB_MUX_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for MUXes */ + OT_FPGA_SPICE_PRINT_CB_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for CBs */ + OT_FPGA_SPICE_PRINT_SB_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for SBs */ + OT_FPGA_SPICE_PRINT_GRID_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for Grids */ + OT_FPGA_SPICE_PRINT_LUT_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for LUTs */ + OT_FPGA_SPICE_PRINT_HARDLOGIC_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for hard logic s */ + OT_FPGA_SPICE_PRINT_IO_TESTBENCH, /* Xifan TANG: Print SPICE Testbench for hard logic s */ OT_FPGA_SPICE_LEAKAGE_ONLY, /* Xifan TANG: Print SPICE Testbench for MUXes */ - OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION_OFF, /* Xifan TANG: turn off the parasitic net estimation*/ - OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION_OFF, /* Xifan TANG: turn off the testbench load extraction */ + OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION, /* Xifan TANG: turn on/off the parasitic net estimation*/ + OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION, /* Xifan TANG: turn on/off the testbench load extraction */ + OT_FPGA_SPICE_SIMULATOR_PATH, + OT_FPGA_SPICE_SIM_MT_NUM, /* number of multi-thread used in simulation */ /* Xifan TANG: Verilog Generation */ OT_FPGA_VERILOG_SYN, /* Xifan TANG: Synthesizable Verilog Dump */ OT_FPGA_VERILOG_SYN_DIR, /* Xifan TANG: Synthesizable Verilog Dump */ - OT_FPGA_VERILOG_SYN_PRINT_TOP_TB, /* Xifan TANG: Synthesizable Verilog Dump */ - OT_FPGA_VERILOG_SYN_PRINT_TOP_AUTO_TB, /* Xifan TANG: Synthesizable Verilog Dump */ - OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TB, /* Xifan TANG: Synthesizable Verilog Dump */ - OT_FPGA_VERILOG_SYN_TB_SERIAL_CONFIG_MODE, /* Xifan TANG: Synthesizable Verilog Dump */ - OT_FPGA_VERILOG_SYN_INCLUDE_TIMING, /* Include timing constraint in Verilog*/ - OT_FPGA_VERILOG_INIT_SIM, /* AA: to allow initialization in simulation */ - OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK, // To allow modelsim script generation - OT_FPGA_VERILOG_SYN_MODELSIM_INI_PATH, // To set modelsim script path + OT_FPGA_VERILOG_SYN_PRINT_TOP_TESTBENCH, /* Xifan Tang: Synthesizable Verilog, turn on option: output testbench for top-level netlist */ + OT_FPGA_VERILOG_SYN_PRINT_AUTOCHECK_TOP_TESTBENCH, /* Xifan Tang: Synthesizable Verilog, turn on option: output testbench for top-level netlist */ + OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TESTBENCH, /* Xifan Tang: Synthesizable Verilog, turn on option: output testbench for the orignial input blif */ + OT_FPGA_VERILOG_SYN_PRINT_FORMAL_VERIFICATION_TOP_NETLIST, /* Xifan Tang: Synthesizable Verilog, turn on option: output netlists in a compact way */ + OT_FPGA_VERILOG_SYN_INCLUDE_TIMING, /* Xifan TANG: Include timing constraints in Verilog */ + OT_FPGA_VERILOG_SYN_INCLUDE_SIGNAL_INIT, /* Xifan TANG: Include timing constraints in Verilog */ + OT_FPGA_VERILOG_SYN_INCLUDE_ICARUS_SIMULATOR, + OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK, + OT_FPGA_VERILOG_SYN_PRINT_USER_DEFINED_TEMPLATE, + OT_FPGA_VERILOG_SYN_PRINT_REPORT_TIMING_TCL, + OT_FPGA_VERILOG_SYN_REPORT_TIMING_RPT_PATH, + OT_FPGA_VERILOG_SYN_PRINT_SDC_PNR, + OT_FPGA_VERILOG_SYN_PRINT_SDC_ANALYSIS, + /* Xifan Tang: Bitstream generator */ + OT_FPGA_BITSTREAM_GENERATOR, + OT_FPGA_BITSTREAM_OUTPUT_FILE, /* mrFPGA: Xifan TANG */ OT_SHOW_SRAM, OT_SHOW_PASS_TRANS, diff --git a/vpr7_x2p/vpr/SRC/base/ReadOptions.c b/vpr7_x2p/vpr/SRC/base/ReadOptions.c index d9dc26ba3..6d3697e69 100644 --- a/vpr7_x2p/vpr/SRC/base/ReadOptions.c +++ b/vpr7_x2p/vpr/SRC/base/ReadOptions.c @@ -474,64 +474,84 @@ ProcessOption(INP char **Args, INOUTP t_options * Options) { case OT_CMOS_TECH_BEHAVIOR_FILE: return ReadString(Args, &Options->CmosTechFile); + /* Xifan Tang: FPGA X2P Options*/ + case OT_FPGA_X2P_RENAME_ILLEGAL_PORT: + return Args; + case OT_FPGA_X2P_SIGNAL_DENSITY_WEIGHT: + return ReadFloat(Args, &Options->fpga_spice_signal_density_weight); + case OT_FPGA_X2P_SIM_WINDOW_SIZE: + return ReadFloat(Args, &Options->fpga_spice_sim_window_size); /* Xifan TANG: FPGA SPICE Model Options*/ case OT_FPGA_SPICE: return Args; - case OT_SPICE_DIR: + case OT_FPGA_SPICE_DIR: return ReadString(Args, &Options->spice_dir); - case OT_SPICE_PRINT_TOP_TESTBENCH: + case OT_FPGA_SPICE_PRINT_TOP_TESTBENCH: return Args; - case OT_SPICE_PRINT_PB_MUX_TESTBENCH: + case OT_FPGA_SPICE_PRINT_PB_MUX_TESTBENCH: return Args; - case OT_SPICE_PRINT_CB_MUX_TESTBENCH: + case OT_FPGA_SPICE_PRINT_CB_MUX_TESTBENCH: return Args; - case OT_SPICE_PRINT_SB_MUX_TESTBENCH: + case OT_FPGA_SPICE_PRINT_SB_MUX_TESTBENCH: return Args; - case OT_SPICE_PRINT_CB_TESTBENCH: + case OT_FPGA_SPICE_PRINT_CB_TESTBENCH: return Args; - case OT_SPICE_PRINT_SB_TESTBENCH: + case OT_FPGA_SPICE_PRINT_SB_TESTBENCH: return Args; - case OT_SPICE_PRINT_GRID_TESTBENCH: + case OT_FPGA_SPICE_PRINT_GRID_TESTBENCH: return Args; - case OT_SPICE_PRINT_LUT_TESTBENCH: + case OT_FPGA_SPICE_PRINT_LUT_TESTBENCH: return Args; - case OT_SPICE_PRINT_HARDLOGIC_TESTBENCH: + case OT_FPGA_SPICE_PRINT_HARDLOGIC_TESTBENCH: + return Args; + case OT_FPGA_SPICE_PRINT_IO_TESTBENCH: return Args; case OT_FPGA_SPICE_LEAKAGE_ONLY: return Args; - case OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION_OFF: - return Args; - case OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION_OFF: - return Args; + case OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION: + return ReadOnOff(Args, &Options->fpga_spice_parasitic_net_estimation); + case OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION: + return ReadOnOff(Args, &Options->fpga_spice_testbench_load_extraction); + case OT_FPGA_SPICE_SIM_MT_NUM: + return ReadInt(Args, &Options->fpga_spice_sim_mt_num); + case OT_FPGA_SPICE_SIMULATOR_PATH: + return ReadString(Args, &Options->fpga_spice_simulator_path); /* Xifan TANG: Synthesizable Verilog */ case OT_FPGA_VERILOG_SYN: return Args; case OT_FPGA_VERILOG_SYN_DIR: - return ReadString(Args, &Options->syn_verilog_dir); - case OT_FPGA_VERILOG_SYN_PRINT_TOP_TB: + return ReadString(Args, &Options->fpga_syn_verilog_dir); + case OT_FPGA_VERILOG_SYN_PRINT_TOP_TESTBENCH: return Args; - case OT_FPGA_VERILOG_SYN_PRINT_TOP_AUTO_TB: - return ReadString(Args, &Options->verilog_benchmark_path); - case OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TB: + case OT_FPGA_VERILOG_SYN_PRINT_AUTOCHECK_TOP_TESTBENCH: + return ReadString(Args, &Options->fpga_verilog_reference_benchmark_file); + case OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TESTBENCH: return Args; - case OT_FPGA_VERILOG_SYN_TB_SERIAL_CONFIG_MODE: - return Args; - case OT_FPGA_SPICE_RENAME_ILLEGAL_PORT: + case OT_FPGA_VERILOG_SYN_PRINT_FORMAL_VERIFICATION_TOP_NETLIST: return Args; case OT_FPGA_VERILOG_SYN_INCLUDE_TIMING: return Args; - case OT_FPGA_VERILOG_INIT_SIM: + case OT_FPGA_VERILOG_SYN_INCLUDE_SIGNAL_INIT: + return Args; + case OT_FPGA_VERILOG_SYN_INCLUDE_ICARUS_SIMULATOR: return Args; case OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK: - return Args; - case OT_FPGA_VERILOG_SYN_MODELSIM_INI_PATH: return ReadString(Args, &Options->fpga_verilog_modelsim_ini_path); - case OT_FPGA_SPICE_SIGNAL_DENSITY_WEIGHT: - return ReadFloat(Args, &Options->signal_density_weight); - case OT_FPGA_SPICE_SIM_WINDOW_SIZE: - return ReadFloat(Args, &Options->sim_window_size); - case OT_FPGA_SPICE_SIM_MT_NUM: - return ReadInt(Args, &Options->spice_sim_mt_num); + case OT_FPGA_VERILOG_SYN_PRINT_USER_DEFINED_TEMPLATE: + return Args; + case OT_FPGA_VERILOG_SYN_PRINT_REPORT_TIMING_TCL: + return Args; + case OT_FPGA_VERILOG_SYN_REPORT_TIMING_RPT_PATH: + return ReadString(Args, &Options->fpga_verilog_report_timing_path); + case OT_FPGA_VERILOG_SYN_PRINT_SDC_PNR: + return Args; + case OT_FPGA_VERILOG_SYN_PRINT_SDC_ANALYSIS: + return Args; + /* Xifan TANG: Bitstream generator */ + case OT_FPGA_BITSTREAM_GENERATOR: + return Args; + case OT_FPGA_BITSTREAM_OUTPUT_FILE: + return ReadString(Args, &Options->fpga_bitstream_file); /* mrFPGA: Xifan TANG */ case OT_SHOW_SRAM: case OT_SHOW_PASS_TRANS: diff --git a/vpr7_x2p/vpr/SRC/base/ReadOptions.h b/vpr7_x2p/vpr/SRC/base/ReadOptions.h index 15ae6cebe..bf7f41382 100644 --- a/vpr7_x2p/vpr/SRC/base/ReadOptions.h +++ b/vpr7_x2p/vpr/SRC/base/ReadOptions.h @@ -91,16 +91,23 @@ struct s_options { /* Last read settings file */ int read_settings; + /* Xifan TANG: signal weight in FPGA_SPICE simulation */ + float fpga_spice_signal_density_weight; + float fpga_spice_sim_window_size; + /* Xifan TANG: SPICE Support*/ char* spice_dir; + boolean fpga_spice_parasitic_net_estimation; + boolean fpga_spice_testbench_load_extraction; + int fpga_spice_sim_mt_num; + char* fpga_spice_simulator_path; /* Xifan TANG: Synthesizable Verilog */ - char* syn_verilog_dir; - char* verilog_benchmark_path; + char* fpga_syn_verilog_dir; + char* fpga_verilog_reference_benchmark_file; char* fpga_verilog_modelsim_ini_path; - /* Xifan TANG: signal weight in FPGA_SPICE simulation */ - float signal_density_weight; - float sim_window_size; - int spice_sim_mt_num; + char* fpga_verilog_report_timing_path; + /* Xifan TANG: Bitstream generator */ + char* fpga_bitstream_file; }; enum e_echo_files { diff --git a/vpr7_x2p/vpr/SRC/base/SetupVPR.c b/vpr7_x2p/vpr/SRC/base/SetupVPR.c index 90f48284e..304ec022a 100644 --- a/vpr7_x2p/vpr/SRC/base/SetupVPR.c +++ b/vpr7_x2p/vpr/SRC/base/SetupVPR.c @@ -48,14 +48,18 @@ static void SetupSpiceOpts(t_options Options, static void SetupSynVerilogOpts(t_options Options, t_syn_verilog_opts* syn_verilog_opts, t_arch* arch); + +/* Xifan TANG: Bitstream Generator */ +static void SetupBitstreamGenOpts(t_options Options, + t_bitstream_gen_opts* bitstream_gen_opts, + t_arch* arch); + /* Xifan TANG: FPGA-SPICE Tool suites Options Setup */ static void SetupFpgaSpiceOpts(t_options Options, t_fpga_spice_opts* fpga_spice_opts, t_arch* arch); /* end */ /* Xifan Tang: Parse CLB to CLB direct connections */ -static void alloc_and_init_globals_clb_to_clb_directs(int num_directs, - t_direct_inf* directs); /* mrFPGA */ static void SetupSwitches_mrFPGA(INP t_arch Arch, @@ -67,6 +71,77 @@ static void set_max_pins_per_side(); static void hack_switch_to_rram(struct s_det_routing_arch *det_routing_arch); /* end */ +void VPRSetupArch(t_arch* arch, + t_det_routing_arch* RoutingArch, + t_segment_inf ** Segments, + /*Xifan TANG: Switch Segment Pattern Support*/ + t_swseg_pattern_inf** swseg_patterns, + t_model** user_models, + t_model** library_models) { + int i, j; + + (*user_models) = arch->models; + (*library_models) = arch->model_library; + + /* TODO: this is inelegant, I should be populating this information in XmlReadArch */ + EMPTY_TYPE = NULL; + FILL_TYPE = NULL; + IO_TYPE = NULL; + for (i = 0; i < num_types; i++) { + if (strcmp(type_descriptors[i].name, "") == 0) { + EMPTY_TYPE = &type_descriptors[i]; + } else if (strcmp(type_descriptors[i].name, "io") == 0) { + IO_TYPE = &type_descriptors[i]; + } else { + for (j = 0; j < type_descriptors[i].num_grid_loc_def; j++) { + if (type_descriptors[i].grid_loc_def[j].grid_loc_type == FILL) { + assert(FILL_TYPE == NULL); + FILL_TYPE = &type_descriptors[i]; + } + } + } + } + assert(EMPTY_TYPE != NULL && FILL_TYPE != NULL && IO_TYPE != NULL); + + *Segments = arch->Segments; + RoutingArch->num_segment = arch->num_segments; + /*Xifan TANG: Switch Segment Pattern Support*/ + (*swseg_patterns) = arch->swseg_patterns; + RoutingArch->num_swseg_pattern = arch->num_swseg_pattern; + /* END */ + + /* mrFPGA */ + sync_arch_mrfpga_globals(arch->arch_mrfpga); + if (is_mrFPGA) { + SetupSwitches_mrFPGA(*arch, RoutingArch, + arch->Switches, arch->num_switches, arch->Segments); + /* Xifan TANG: added by bjxiao */ + set_max_pins_per_side(); + hack_switch_to_rram(RoutingArch); + } else { + /* Normal Setup VPR switches */ + // Xifan TANG: Add Connection Blocks Switches + SetupSwitches(*arch, RoutingArch, + arch->Switches, arch->num_switches); + } + /* END */ + + /* end */ + if(!is_mrFPGA && is_stack) { + add_wire_to_switch(RoutingArch); + } + /* end */ + /* Xifan TANG: mrFPGA */ + if (is_junction) { + setup_junction_switch(RoutingArch); + } + /* end */ + + SetupRoutingArch(*arch, RoutingArch); + + return; +} + /* Sets VPR parameters and defaults. Does not do any error checking * as this should have been done by the various input checkers */ void SetupVPR(INP t_options *Options, INP boolean TimingEnabled, @@ -84,7 +159,7 @@ void SetupVPR(INP t_options *Options, INP boolean TimingEnabled, /*Xifan TANG: Switch Segment Pattern Support*/ t_swseg_pattern_inf** swseg_patterns, t_fpga_spice_opts* fpga_spice_opts) { - int i, j, len; + int len; len = strlen(Options->CircuitName) + 6; /* circuit_name.blif/0*/ if (Options->out_file_prefix != NULL ) { @@ -210,62 +285,8 @@ void SetupVPR(INP t_options *Options, INP boolean TimingEnabled, &num_types); } - *user_models = Arch->models; - *library_models = Arch->model_library; + VPRSetupArch(Arch, RoutingArch, Segments, swseg_patterns, user_models, library_models); - /* TODO: this is inelegant, I should be populating this information in XmlReadArch */ - EMPTY_TYPE = NULL; - FILL_TYPE = NULL; - IO_TYPE = NULL; - for (i = 0; i < num_types; i++) { - if (strcmp(type_descriptors[i].name, "") == 0) { - EMPTY_TYPE = &type_descriptors[i]; - } else if (strcmp(type_descriptors[i].name, "io") == 0) { - IO_TYPE = &type_descriptors[i]; - } else { - for (j = 0; j < type_descriptors[i].num_grid_loc_def; j++) { - if (type_descriptors[i].grid_loc_def[j].grid_loc_type == FILL) { - assert(FILL_TYPE == NULL); - FILL_TYPE = &type_descriptors[i]; - } - } - } - } - assert(EMPTY_TYPE != NULL && FILL_TYPE != NULL && IO_TYPE != NULL); - - *Segments = Arch->Segments; - RoutingArch->num_segment = Arch->num_segments; - /*Xifan TANG: Switch Segment Pattern Support*/ - (*swseg_patterns) = Arch->swseg_patterns; - RoutingArch->num_swseg_pattern = Arch->num_swseg_pattern; - /* END */ - - /* mrFPGA */ - sync_arch_mrfpga_globals(Arch->arch_mrfpga); - if (is_mrFPGA) { - SetupSwitches_mrFPGA(*Arch, RoutingArch, Arch->Switches, Arch->num_switches, Arch->Segments); - /* Xifan TANG: added by bjxiao */ - set_max_pins_per_side(); - hack_switch_to_rram(RoutingArch); - } else { - /* Normal Setup VPR switches */ - // Xifan TANG: Add Connection Blocks Switches - SetupSwitches(*Arch, RoutingArch, Arch->Switches, Arch->num_switches); - } - /* END */ - - /* end */ - if(!is_mrFPGA && is_stack) { - add_wire_to_switch(RoutingArch); - } - /* end */ - /* Xifan TANG: mrFPGA */ - if (is_junction) { - setup_junction_switch(RoutingArch); - } - /* end */ - - SetupRoutingArch(*Arch, RoutingArch); SetupTiming(*Options, *Arch, TimingEnabled, *Operation, *PlacerOpts, *RouterOpts, Timing); SetupPackerOpts(*Options, TimingEnabled, *Arch, Options->NetFile, @@ -960,18 +981,19 @@ static void SetupSpiceOpts(t_options Options, t_arch* arch) { /* Initialize */ spice_opts->do_spice = FALSE; - spice_opts->spice_print_top_testbench = FALSE; - spice_opts->spice_print_pb_mux_testbench = FALSE; - spice_opts->spice_print_cb_mux_testbench = FALSE; - spice_opts->spice_print_sb_mux_testbench = FALSE; - spice_opts->spice_print_cb_testbench = FALSE; - spice_opts->spice_print_sb_testbench = FALSE; - spice_opts->spice_print_lut_testbench = FALSE; - spice_opts->spice_print_hardlogic_testbench = FALSE; - spice_opts->spice_print_grid_testbench = FALSE; + spice_opts->fpga_spice_print_top_testbench = FALSE; + spice_opts->fpga_spice_print_pb_mux_testbench = FALSE; + spice_opts->fpga_spice_print_cb_mux_testbench = FALSE; + spice_opts->fpga_spice_print_sb_mux_testbench = FALSE; + spice_opts->fpga_spice_print_cb_testbench = FALSE; + spice_opts->fpga_spice_print_sb_testbench = FALSE; + spice_opts->fpga_spice_print_lut_testbench = FALSE; + spice_opts->fpga_spice_print_hardlogic_testbench = FALSE; + spice_opts->fpga_spice_print_io_testbench = FALSE; + spice_opts->fpga_spice_print_grid_testbench = FALSE; spice_opts->fpga_spice_leakage_only = FALSE; - spice_opts->fpga_spice_parasitic_net_estimation_off = FALSE; - spice_opts->fpga_spice_testbench_load_extraction_off = FALSE; + spice_opts->fpga_spice_parasitic_net_estimation = TRUE; + spice_opts->fpga_spice_testbench_load_extraction = TRUE; /* Turn on the spice option if it is selected*/ if (Options.Count[OT_FPGA_SPICE]) { @@ -980,65 +1002,74 @@ static void SetupSpiceOpts(t_options Options, /* TODO: this could be more flexible*/ spice_opts->include_dir = "include/"; spice_opts->subckt_dir = "subckt/"; - if (Options.Count[OT_SPICE_PRINT_TOP_TESTBENCH]) { - spice_opts->spice_print_top_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_TOP_TESTBENCH]) { + spice_opts->fpga_spice_print_top_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_PB_MUX_TESTBENCH]) { - spice_opts->spice_print_pb_mux_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_PB_MUX_TESTBENCH]) { + spice_opts->fpga_spice_print_pb_mux_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_CB_MUX_TESTBENCH]) { - spice_opts->spice_print_cb_mux_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_CB_MUX_TESTBENCH]) { + spice_opts->fpga_spice_print_cb_mux_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_SB_MUX_TESTBENCH]) { - spice_opts->spice_print_sb_mux_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_SB_MUX_TESTBENCH]) { + spice_opts->fpga_spice_print_sb_mux_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_CB_TESTBENCH]) { - spice_opts->spice_print_cb_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_CB_TESTBENCH]) { + spice_opts->fpga_spice_print_cb_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_SB_TESTBENCH]) { - spice_opts->spice_print_sb_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_SB_TESTBENCH]) { + spice_opts->fpga_spice_print_sb_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_GRID_TESTBENCH]) { - spice_opts->spice_print_grid_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_GRID_TESTBENCH]) { + spice_opts->fpga_spice_print_grid_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_LUT_TESTBENCH]) { - spice_opts->spice_print_lut_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_LUT_TESTBENCH]) { + spice_opts->fpga_spice_print_lut_testbench = TRUE; } - if (Options.Count[OT_SPICE_PRINT_HARDLOGIC_TESTBENCH]) { - spice_opts->spice_print_hardlogic_testbench = TRUE; + if (Options.Count[OT_FPGA_SPICE_PRINT_HARDLOGIC_TESTBENCH]) { + spice_opts->fpga_spice_print_hardlogic_testbench = TRUE; + } + if (Options.Count[OT_FPGA_SPICE_PRINT_IO_TESTBENCH]) { + spice_opts->fpga_spice_print_io_testbench = TRUE; } if (Options.Count[OT_FPGA_SPICE_LEAKAGE_ONLY]) { spice_opts->fpga_spice_leakage_only = TRUE; } - if (Options.Count[OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION_OFF]) { - spice_opts->fpga_spice_parasitic_net_estimation_off = TRUE; + if (Options.Count[OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION]) { + spice_opts->fpga_spice_parasitic_net_estimation = Options.fpga_spice_parasitic_net_estimation; } - if (Options.Count[OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION_OFF]) { - spice_opts->fpga_spice_testbench_load_extraction_off = TRUE; + if (Options.Count[OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION]) { + spice_opts->fpga_spice_testbench_load_extraction = Options.fpga_spice_testbench_load_extraction; } } /* Set default options */ if ((TRUE == spice_opts->do_spice) - &&(FALSE == spice_opts->spice_print_top_testbench) - &&(FALSE == spice_opts->spice_print_grid_testbench) - &&(FALSE == spice_opts->spice_print_pb_mux_testbench) - &&(FALSE == spice_opts->spice_print_cb_mux_testbench) - &&(FALSE == spice_opts->spice_print_sb_mux_testbench) - &&(FALSE == spice_opts->spice_print_cb_testbench) - &&(FALSE == spice_opts->spice_print_sb_testbench) - &&(FALSE == spice_opts->spice_print_lut_testbench) - &&(FALSE == spice_opts->spice_print_hardlogic_testbench)) { - spice_opts->spice_print_pb_mux_testbench = TRUE; - spice_opts->spice_print_cb_mux_testbench = TRUE; - spice_opts->spice_print_sb_mux_testbench = TRUE; - spice_opts->spice_print_lut_testbench = TRUE; - spice_opts->spice_print_hardlogic_testbench = TRUE; + &&(FALSE == spice_opts->fpga_spice_print_top_testbench) + &&(FALSE == spice_opts->fpga_spice_print_grid_testbench) + &&(FALSE == spice_opts->fpga_spice_print_pb_mux_testbench) + &&(FALSE == spice_opts->fpga_spice_print_cb_mux_testbench) + &&(FALSE == spice_opts->fpga_spice_print_sb_mux_testbench) + &&(FALSE == spice_opts->fpga_spice_print_cb_testbench) + &&(FALSE == spice_opts->fpga_spice_print_sb_testbench) + &&(FALSE == spice_opts->fpga_spice_print_lut_testbench) + &&(FALSE == spice_opts->fpga_spice_print_hardlogic_testbench)) { + spice_opts->fpga_spice_print_pb_mux_testbench = TRUE; + spice_opts->fpga_spice_print_cb_mux_testbench = TRUE; + spice_opts->fpga_spice_print_sb_mux_testbench = TRUE; + spice_opts->fpga_spice_print_lut_testbench = TRUE; + spice_opts->fpga_spice_print_hardlogic_testbench = TRUE; } /* Assign the number of mt in SPICE simulation */ - spice_opts->spice_sim_multi_thread_num = 8; + spice_opts->fpga_spice_sim_multi_thread_num = 8; if (Options.Count[OT_FPGA_SPICE_SIM_MT_NUM]) { - spice_opts->spice_sim_multi_thread_num = Options.spice_sim_mt_num; + spice_opts->fpga_spice_sim_multi_thread_num = Options.fpga_spice_sim_mt_num; + } + + /* Assign path of SPICE simulator */ + spice_opts->simulator_path = NULL; + if (Options.Count[OT_FPGA_SPICE_SIMULATOR_PATH]) { + spice_opts->simulator_path = my_strdup(Options.fpga_spice_simulator_path); } /* If spice option is selected*/ @@ -1056,16 +1087,20 @@ static void SetupSynVerilogOpts(t_options Options, /* Initialize */ syn_verilog_opts->dump_syn_verilog = FALSE; syn_verilog_opts->syn_verilog_dump_dir = NULL; - syn_verilog_opts->tb_serial_config_mode = FALSE; - syn_verilog_opts->print_top_tb = FALSE; - syn_verilog_opts->print_top_auto_tb = FALSE; - syn_verilog_opts->print_input_blif_tb = FALSE; + syn_verilog_opts->print_top_testbench = FALSE; + syn_verilog_opts->print_autocheck_top_testbench = FALSE; + syn_verilog_opts->reference_verilog_benchmark_file = NULL; + syn_verilog_opts->print_input_blif_testbench = FALSE; syn_verilog_opts->include_timing = FALSE; - syn_verilog_opts->init_sim = FALSE; + syn_verilog_opts->include_signal_init = FALSE; syn_verilog_opts->print_modelsim_autodeck = FALSE; + syn_verilog_opts->print_formal_verification_top_netlist= FALSE; syn_verilog_opts->modelsim_ini_path = NULL; - - + syn_verilog_opts->print_user_defined_template = FALSE; + syn_verilog_opts->print_report_timing_tcl = FALSE; + syn_verilog_opts->print_sdc_pnr = FALSE; + syn_verilog_opts->print_sdc_analysis = FALSE; + syn_verilog_opts->include_icarus_simulator = FALSE; /* Turn on Syn_verilog options */ if (Options.Count[OT_FPGA_VERILOG_SYN]) { @@ -1075,40 +1110,61 @@ static void SetupSynVerilogOpts(t_options Options, } if (Options.Count[OT_FPGA_VERILOG_SYN_DIR]) { - syn_verilog_opts->syn_verilog_dump_dir = my_strdup(Options.syn_verilog_dir); + syn_verilog_opts->syn_verilog_dump_dir = my_strdup(Options.fpga_syn_verilog_dir); } - if (Options.Count[OT_FPGA_VERILOG_SYN_TB_SERIAL_CONFIG_MODE]) { - syn_verilog_opts->tb_serial_config_mode = TRUE; + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_TOP_TESTBENCH]) { + syn_verilog_opts->print_top_testbench = TRUE; } - if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_TOP_TB]) { - syn_verilog_opts->print_top_tb = TRUE; + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_AUTOCHECK_TOP_TESTBENCH]) { + syn_verilog_opts->print_autocheck_top_testbench = TRUE; + syn_verilog_opts->reference_verilog_benchmark_file = my_strdup(Options.fpga_verilog_reference_benchmark_file); } - if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_TOP_AUTO_TB]) { - syn_verilog_opts->print_top_auto_tb = TRUE; - syn_verilog_opts->verilog_benchmark_file = my_strdup(Options.verilog_benchmark_path); + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TESTBENCH]) { + syn_verilog_opts->print_input_blif_testbench = TRUE; } - if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TB]) { - syn_verilog_opts->print_input_blif_tb = TRUE; + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_FORMAL_VERIFICATION_TOP_NETLIST]) { + syn_verilog_opts->print_formal_verification_top_netlist = TRUE; } if (Options.Count[OT_FPGA_VERILOG_SYN_INCLUDE_TIMING]) { syn_verilog_opts->include_timing = TRUE; } - if (Options.Count[OT_FPGA_VERILOG_INIT_SIM]) { - syn_verilog_opts->init_sim = TRUE; + if (Options.Count[OT_FPGA_VERILOG_SYN_INCLUDE_SIGNAL_INIT]) { + syn_verilog_opts->include_signal_init = TRUE; + } + + if (Options.Count[OT_FPGA_VERILOG_SYN_INCLUDE_ICARUS_SIMULATOR]) { + syn_verilog_opts->include_icarus_simulator = TRUE; } if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK]) { syn_verilog_opts->print_modelsim_autodeck = TRUE; + syn_verilog_opts->modelsim_ini_path = my_strdup(Options.fpga_verilog_modelsim_ini_path); } - if (Options.Count[OT_FPGA_VERILOG_SYN_MODELSIM_INI_PATH]) { - syn_verilog_opts->modelsim_ini_path = my_strdup(Options.fpga_verilog_modelsim_ini_path); + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_USER_DEFINED_TEMPLATE]) { + syn_verilog_opts->print_user_defined_template = TRUE; + } + + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_REPORT_TIMING_TCL]) { + syn_verilog_opts->print_report_timing_tcl = TRUE; + } + + if (Options.Count[OT_FPGA_VERILOG_SYN_REPORT_TIMING_RPT_PATH]) { + syn_verilog_opts->report_timing_path = my_strdup(Options.fpga_verilog_report_timing_path); + } + + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_SDC_PNR]) { + syn_verilog_opts->print_sdc_pnr = TRUE; + } + + if (Options.Count[OT_FPGA_VERILOG_SYN_PRINT_SDC_ANALYSIS]) { + syn_verilog_opts->print_sdc_analysis = TRUE; } /* SynVerilog needs the input from spice modeling */ @@ -1120,6 +1176,35 @@ static void SetupSynVerilogOpts(t_options Options, return; } +/*Xifan TANG: Bitstream Generator */ +static void SetupBitstreamGenOpts(t_options Options, + t_bitstream_gen_opts* bitstream_gen_opts, + t_arch* arch) { + + /* Initialize */ + bitstream_gen_opts->gen_bitstream = FALSE; + bitstream_gen_opts->bitstream_output_file = NULL; + + /* Turn on Bitstream Generator options */ + if (Options.Count[OT_FPGA_BITSTREAM_GENERATOR]) { + bitstream_gen_opts->gen_bitstream = TRUE; + } else { + return; + } + + if (Options.Count[OT_FPGA_BITSTREAM_OUTPUT_FILE]) { + bitstream_gen_opts->bitstream_output_file = my_strdup(Options.fpga_bitstream_file); + } + + /* SynVerilog needs the input from spice modeling */ + if (FALSE == arch->read_xml_spice) { + arch->read_xml_spice = bitstream_gen_opts->gen_bitstream; + arch->spice = (t_spice*)my_malloc(sizeof(t_spice)); + } + + return; +} + static void SetupFpgaSpiceOpts(t_options Options, t_fpga_spice_opts* fpga_spice_opts, t_arch* Arch) { @@ -1129,40 +1214,46 @@ static void SetupFpgaSpiceOpts(t_options Options, /* Xifan TANG: Synthesizable Verilog Dumping*/ SetupSynVerilogOpts(Options, &(fpga_spice_opts->SynVerilogOpts), Arch); - /* Decide if we need to read activity file */ - fpga_spice_opts->read_act_file = FALSE; + /* Xifan TANG: Bitstream generator */ + SetupBitstreamGenOpts(Options, &(fpga_spice_opts->BitstreamGenOpts), Arch); /* Decide if we need to rename illegal port names */ fpga_spice_opts->rename_illegal_port = FALSE; - if (Options.Count[OT_FPGA_SPICE_RENAME_ILLEGAL_PORT]) { + if (Options.Count[OT_FPGA_X2P_RENAME_ILLEGAL_PORT]) { fpga_spice_opts->rename_illegal_port = TRUE; } /* Assign the weight of signal density */ fpga_spice_opts->signal_density_weight = 1.; - if (Options.Count[OT_FPGA_SPICE_SIGNAL_DENSITY_WEIGHT]) { - fpga_spice_opts->signal_density_weight = Options.signal_density_weight; + if (Options.Count[OT_FPGA_X2P_SIGNAL_DENSITY_WEIGHT]) { + fpga_spice_opts->signal_density_weight = Options.fpga_spice_signal_density_weight; } /* Assign the weight of signal density */ fpga_spice_opts->sim_window_size = 0.5; - if (Options.Count[OT_FPGA_SPICE_SIM_WINDOW_SIZE]) { - fpga_spice_opts->sim_window_size = Options.sim_window_size; + if (Options.Count[OT_FPGA_X2P_SIM_WINDOW_SIZE]) { + fpga_spice_opts->sim_window_size = Options.fpga_spice_sim_window_size; } /* Decide if we need to do FPGA-SPICE */ fpga_spice_opts->do_fpga_spice = FALSE; + if (( TRUE == fpga_spice_opts->SpiceOpts.do_spice) + ||(TRUE == fpga_spice_opts->SynVerilogOpts.dump_syn_verilog) + ||(TRUE == fpga_spice_opts->BitstreamGenOpts.gen_bitstream)) { + fpga_spice_opts->do_fpga_spice = TRUE; + } + + /* Decide if we need to read activity file */ + fpga_spice_opts->read_act_file = FALSE; if (( TRUE == fpga_spice_opts->SpiceOpts.do_spice) ||(TRUE == fpga_spice_opts->SynVerilogOpts.dump_syn_verilog)) { fpga_spice_opts->read_act_file = TRUE; - fpga_spice_opts->do_fpga_spice = TRUE; } return; } /* Initialize the global variables for clb to clb directs */ -static void alloc_and_init_globals_clb_to_clb_directs(int num_directs, t_direct_inf* directs) { num_clb2clb_directs = num_directs; diff --git a/vpr7_x2p/vpr/SRC/base/SetupVPR.h b/vpr7_x2p/vpr/SRC/base/SetupVPR.h index 47b2c5e7e..9ed3c23eb 100644 --- a/vpr7_x2p/vpr/SRC/base/SetupVPR.h +++ b/vpr7_x2p/vpr/SRC/base/SetupVPR.h @@ -2,6 +2,15 @@ #define SETUPVPR_H +void VPRSetupArch(t_arch* arch, + t_det_routing_arch* RoutingArch, + t_segment_inf ** Segments, + t_swseg_pattern_inf** swseg_patterns, + t_model** user_models, + t_model** library_models); + +void alloc_and_init_globals_clb_to_clb_directs(int num_directs, + t_direct_inf* directs); void SetupVPR(INP t_options *Options, INP boolean TimingEnabled, diff --git a/vpr7_x2p/vpr/SRC/base/read_blif.c b/vpr7_x2p/vpr/SRC/base/read_blif.c index cabea82e9..8e982725d 100644 --- a/vpr7_x2p/vpr/SRC/base/read_blif.c +++ b/vpr7_x2p/vpr/SRC/base/read_blif.c @@ -523,7 +523,7 @@ static void add_latch(int doall, INP t_model *latch_model) { logical_block[num_logical_blocks - 1].trigger_type = my_strdup(saved_names[2]); /* Store the initial value */ logical_block[num_logical_blocks - 1].init_val = my_atoi(saved_names[4]); - /* Identify clocks */ + /* Add clock identification */ logical_block[logical_block[num_logical_blocks - 1].clock_net].is_clock = TRUE; /*END*/ diff --git a/vpr7_x2p/vpr/SRC/base/read_netlist.c b/vpr7_x2p/vpr/SRC/base/read_netlist.c index 592b8a8a6..146500fe9 100644 --- a/vpr7_x2p/vpr/SRC/base/read_netlist.c +++ b/vpr7_x2p/vpr/SRC/base/read_netlist.c @@ -962,8 +962,10 @@ static int count_sinks_internal_cb_rr_graph_net_nums( for (i = 0; i < cur_rr_node->num_edges; i++) { if (&rr_graph[rr_graph[cur_rr_node->edges[i]].prev_node] == cur_rr_node) { + if (!(rr_graph[cur_rr_node->edges[i]].net_num == OPEN || rr_graph[cur_rr_node->edges[i]].net_num == cur_rr_node->net_num)) { assert( rr_graph[cur_rr_node->edges[i]].net_num == OPEN || rr_graph[cur_rr_node->edges[i]].net_num == cur_rr_node->net_num); + } count += count_sinks_internal_cb_rr_graph_net_nums( &rr_graph[cur_rr_node->edges[i]], rr_graph); } diff --git a/vpr7_x2p/vpr/SRC/base/verilog_writer.c b/vpr7_x2p/vpr/SRC/base/verilog_writer.c index a24f8d204..e1e6e97e5 100644 --- a/vpr7_x2p/vpr/SRC/base/verilog_writer.c +++ b/vpr7_x2p/vpr/SRC/base/verilog_writer.c @@ -37,7 +37,7 @@ Second - instantiate_top_level() module is called. This function will will trave Third - instantiate_SDF_header() is a short function that will just write the top level declarations in the SDF file. -Fourth - All the wires in the design are instantiated. This is done in the way demonstrated bellow: +Fourth - All the wires in the design are instantiated. This is done in the way demonstrated below: Traverse through all primitives diff --git a/vpr7_x2p/vpr/SRC/base/vpr_api.c b/vpr7_x2p/vpr/SRC/base/vpr_api.c index da76bd033..24fa4ed77 100644 --- a/vpr7_x2p/vpr/SRC/base/vpr_api.c +++ b/vpr7_x2p/vpr/SRC/base/vpr_api.c @@ -65,136 +65,168 @@ static void clay_logical_equivalence_handling(const t_arch *arch); static void clay_lut_input_rebalancing(int iblock, t_pb *pb); static void clay_reload_ble_locations(int iblock); static void resync_pb_graph_nodes_in_pb(t_pb_graph_node *pb_graph_node, - t_pb *pb); + t_pb *pb); /* Local subroutines end */ /* Display general VPR information */ void vpr_print_title(void) { - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, "VPR FPGA Placement and Routing.\n"); - vpr_printf(TIO_MESSAGE_INFO, "Version: Version " VPR_VERSION "\n"); - vpr_printf(TIO_MESSAGE_INFO, "Compiled: " __DATE__ ".\n"); - vpr_printf(TIO_MESSAGE_INFO, "University of Toronto\n"); - vpr_printf(TIO_MESSAGE_INFO, "vpr@eecg.utoronto.ca\n"); - vpr_printf(TIO_MESSAGE_INFO, "Enhancements: mrFPGA, RRAM, SWSEG, FPGA-SPICE by Xifan TANG, EPFL-LSI, U. of Utah-LNIS \n"); - vpr_printf(TIO_MESSAGE_INFO, "Enhancements: OPIN_TO_CB, CLB_PIN_REMAP by Xifan TANG, EPFL-LSI, U. of Utah-LNIS\n"); - vpr_printf(TIO_MESSAGE_INFO, "Enhancements: Synthesizable Verilog Support by Xifan TANG, EPFL-LSI, U. of Utah-LNIS\n"); - vpr_printf(TIO_MESSAGE_INFO, "xifan.tang@utah.edu\n"); - vpr_printf(TIO_MESSAGE_INFO, "This is free open source code under MIT license.\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "VPR FPGA Placement and Routing.\n"); + vpr_printf(TIO_MESSAGE_INFO, "Version: Version " VPR_VERSION "\n"); + vpr_printf(TIO_MESSAGE_INFO, "Compiled: " __DATE__ ".\n"); + vpr_printf(TIO_MESSAGE_INFO, "University of Toronto\n"); + vpr_printf(TIO_MESSAGE_INFO, "vpr@eecg.utoronto.ca\n"); + vpr_printf(TIO_MESSAGE_INFO, "Enhancements: mrFPGA, RRAM, SWSEG, FPGA-SPICE by Xifan TANG, EPFL-LSI, Univ. of Utah-LNIS \n"); + vpr_printf(TIO_MESSAGE_INFO, "Enhancements: Synthesizable Verilog Support by Xifan TANG, EPFL-LSI, Univ. of Utah-LNIS\n"); + vpr_printf(TIO_MESSAGE_INFO, "Enhancements: Bitstream Generator Support by Xifan TANG, EPFL-LSI, Univ. of Utah-LNIS\n"); + vpr_printf(TIO_MESSAGE_INFO, "Enhancements: OPIN_TO_CB, CLB_PIN_REMAP by Xifan TANG, EPFL-LSI, Univ. of Utah-LNIS\n"); + vpr_printf(TIO_MESSAGE_INFO, "xifan.tang@utah.edu\n"); + vpr_printf(TIO_MESSAGE_INFO, "This is free open source code under MIT license.\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); } /* Display help screen */ void vpr_print_usage(void) { - vpr_printf(TIO_MESSAGE_INFO, - "Usage: vpr fpga_architecture.xml circuit_name [Options ...]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, - "General Options: [--nodisp] [--auto ] [--pack]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--place] [--route] [--timing_analyze_only_with_net_delay ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--fast] [--full_stats] [--timing_analysis on | off] [--outfile_prefix ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--blif_file ][--net_file ][--place_file ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--route_file ][--sdc_file ][--echo_file on | off]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, "Packer Options:\n"); - /* vpr_printf(TIO_MESSAGE_INFO, "\t[-global_clocks on|off]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[-hill_climbing on|off]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[-sweep_hanging_nets_and_inputs on|off]\n"); */ - vpr_printf(TIO_MESSAGE_INFO, "\t[--timing_driven_clustering on|off]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--cluster_seed_type timing|max_inputs] [--alpha_clustering ] [--beta_clustering ]\n"); - /* vpr_printf(TIO_MESSAGE_INFO, "\t[-recompute_timing_after ] [-cluster_block_delay ]\n"); */ - vpr_printf(TIO_MESSAGE_INFO, "\t[--allow_unrelated_clustering on|off]\n"); - /* vpr_printf(TIO_MESSAGE_INFO, "\t[-allow_early_exit on|off]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[-intra_cluster_net_delay ] \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[-inter_cluster_net_delay ] \n"); */ - vpr_printf(TIO_MESSAGE_INFO, - "\t[--connection_driven_clustering on|off] \n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, "Placer Options:\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--place_algorithm bounding_box | net_timing_driven | path_timing_driven]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--init_t ] [--exit_t ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--alpha_t ] [--inner_num ] [--seed ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--place_cost_exp ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--place_chan_width ] \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--fix_pins random | ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--enable_timing_computations on | off]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--block_dist ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--place_clb_pin_remap]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, - "Placement Options Valid Only for Timing-Driven Placement:\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--timing_tradeoff ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--recompute_crit_iter ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--inner_loop_recompute_divider ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--td_place_exp_first ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--td_place_exp_last ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, - "Router Options: [-max_router_iterations ] [-bb_factor ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--initial_pres_fac ] [--pres_fac_mult ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--acc_fac ] [--first_iter_pres_fac ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--bend_cost ] [--route_type global | detailed]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--verify_binary_search] [--route_chan_width ]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--router_algorithm breadth_first | timing_driven]\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--base_cost_type intrinsic_delay | delay_normalized | demand_only]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, - "Routing options valid only for timing-driven routing:\n"); - vpr_printf(TIO_MESSAGE_INFO, - "\t[--astar_fac ] [--max_criticality ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t[--criticality_exp ]\n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, "Power Options:\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--power\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--power_output_file \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--activity_file \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--tech_properties \n"); - vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, + "Usage: vpr fpga_architecture.xml circuit_name [Options ...]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, + "General Options: [--nodisp] [--auto ] [--pack]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--place] [--route] [--timing_analyze_only_with_net_delay ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--fast] [--full_stats] [--timing_analysis on | off] [--outfile_prefix ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--blif_file ][--net_file ][--place_file ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--route_file ][--sdc_file ][--echo_file on | off]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "Packer Options:\n"); + /* vpr_printf(TIO_MESSAGE_INFO, "\t[-global_clocks on|off]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[-hill_climbing on|off]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[-sweep_hanging_nets_and_inputs on|off]\n"); */ + vpr_printf(TIO_MESSAGE_INFO, "\t[--timing_driven_clustering on|off]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--cluster_seed_type timing|max_inputs] [--alpha_clustering ] [--beta_clustering ]\n"); + /* vpr_printf(TIO_MESSAGE_INFO, "\t[-recompute_timing_after ] [-cluster_block_delay ]\n"); */ + vpr_printf(TIO_MESSAGE_INFO, "\t[--allow_unrelated_clustering on|off]\n"); + /* vpr_printf(TIO_MESSAGE_INFO, "\t[-allow_early_exit on|off]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[-intra_cluster_net_delay ] \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[-inter_cluster_net_delay ] \n"); */ + vpr_printf(TIO_MESSAGE_INFO, + "\t[--connection_driven_clustering on|off] \n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "Placer Options:\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--place_algorithm bounding_box | net_timing_driven | path_timing_driven]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--init_t ] [--exit_t ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--alpha_t ] [--inner_num ] [--seed ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--place_cost_exp ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--place_chan_width ] \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--fix_pins random | ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--enable_timing_computations on | off]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--block_dist ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--place_clb_pin_remap]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, + "Placement Options Valid Only for Timing-Driven Placement:\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--timing_tradeoff ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--recompute_crit_iter ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--inner_loop_recompute_divider ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--td_place_exp_first ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--td_place_exp_last ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, + "Router Options: [-max_router_iterations ] [-bb_factor ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--initial_pres_fac ] [--pres_fac_mult ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--acc_fac ] [--first_iter_pres_fac ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--bend_cost ] [--route_type global | detailed]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--verify_binary_search] [--route_chan_width ]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--router_algorithm breadth_first | timing_driven]\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--base_cost_type intrinsic_delay | delay_normalized | demand_only]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, + "Routing options valid only for timing-driven routing:\n"); + vpr_printf(TIO_MESSAGE_INFO, + "\t[--astar_fac ] [--max_criticality ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t[--criticality_exp ]\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "Power Options:\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--power\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--power_output_file \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--activity_file \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--tech_properties \n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); /* Xifan TANG: FPGA-SPICE Support*/ - vpr_printf(TIO_MESSAGE_INFO, "FPGA-SPICE tool suite Options:\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_rename_illegal_port\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_signal_density_weight \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_sim_window_size \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_leakage_only\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_parasitic_net_estimation_off\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_testbench_load_extraction_off\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_sim_mt_num\n"); - vpr_printf(TIO_MESSAGE_INFO, "SPICE Support Options:\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_dir \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_top_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_lut_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_hardlogic_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_pb_mux_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_cb_mux_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_sb_mux_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_cb_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_sb_testbench\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_grid_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "FPGA-X2P (from XML to Product/Prototype) tool suite Options:\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_x2p_rename_illegal_port\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_x2p_signal_density_weight \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_x2p_sim_window_size \n"); + vpr_printf(TIO_MESSAGE_INFO, "SPICE Support Options:\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_dir \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_top_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_lut_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_hardlogic_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_io_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_pb_mux_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_cb_mux_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_sb_mux_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_cb_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_sb_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_print_grid_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_leakage_only\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_parasitic_net_estimation \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_testbench_load_extraction \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_sim_mt_num \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_spice_simulator_path \n"); /* Xifan TANG: Synthesizable Verilog Dump*/ - vpr_printf(TIO_MESSAGE_INFO, "Synthesizable Verilog Generator Options:\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_dir \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_include_timing\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_init_sim\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_modelsim_autodeck\n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_modelsim_ini_path \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_top_testbench \n"); - vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_top_auto_testbench \n"); + vpr_printf(TIO_MESSAGE_INFO, "Synthesizable Verilog Generator Options:\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_dir \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_top_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_autocheck_top_testbench \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_input_blif_testbench\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_formal_verification_top_netlist\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_include_timing\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_include_signal_init\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_include_icarus_simulator\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_modelsim_autodeck \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_user_defined_template\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_report_timing_tcl\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_report_timing_rpt_path \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_sdc_pnr\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_verilog_print_sdc_analysis\n"); + /* Xifan Tang: Bitstream generator */ + vpr_printf(TIO_MESSAGE_INFO, "Bitstream Generator Options:\n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_bitstream_generator \n"); + vpr_printf(TIO_MESSAGE_INFO, "\t--fpga_bitstream_output_file \n"); +} + +void vpr_init_file_handler() { + char* pszLogFileName = "vpr_stdout.log"; + unsigned char enableTimeStamps = 1; + unsigned long maxWarningCount = 100000; + unsigned long maxErrorCount = 1000; + + if (PrintHandlerExists() == 1) { + has_printhandler_pre_vpr = TRUE; + } else { + has_printhandler_pre_vpr = FALSE; + } + if (has_printhandler_pre_vpr == FALSE) { + PrintHandlerNew(pszLogFileName); + PrintHandlerInit(enableTimeStamps, maxWarningCount, maxErrorCount); + } + return; } /* Initialize VPR @@ -204,79 +236,68 @@ void vpr_print_usage(void) { 4. Sanity check all three */ void vpr_init(INP int argc, INP char **argv, OUTP t_options *options, - OUTP t_vpr_setup *vpr_setup, OUTP t_arch *arch) { - char* pszLogFileName = "vpr_stdout.log"; - unsigned char enableTimeStamps = 1; - unsigned long maxWarningCount = 100000; - unsigned long maxErrorCount = 1000; + OUTP t_vpr_setup *vpr_setup, OUTP t_arch *arch) { - if (PrintHandlerExists() == 1) { - has_printhandler_pre_vpr = TRUE; - } else { - has_printhandler_pre_vpr = FALSE; - } - if (has_printhandler_pre_vpr == FALSE) { - PrintHandlerNew(pszLogFileName); - PrintHandlerInit(enableTimeStamps, maxWarningCount, maxErrorCount); - } + /* Initialize file handler */ + vpr_init_file_handler(); - /* Print title message */ - vpr_print_title(); + /* Print title message */ + vpr_print_title(); - /* Print usage message if no args */ - if (argc < 3) { - vpr_print_usage(); - exit(1); - } + /* Print usage message if no args */ + if (argc < 3) { + vpr_print_usage(); + exit(1); + } - memset(options, 0, sizeof(t_options)); - memset(vpr_setup, 0, sizeof(t_vpr_setup)); - memset(arch, 0, sizeof(t_arch)); + memset(options, 0, sizeof(t_options)); + memset(vpr_setup, 0, sizeof(t_vpr_setup)); + memset(arch, 0, sizeof(t_arch)); - /* Read in user options */ - ReadOptions(argc, argv, options); - /* Timing option priorities */ - vpr_setup->TimingEnabled = IsTimingEnabled(options); - /* Determine whether echo is on or off */ - setEchoEnabled(IsEchoEnabled(options)); - SetPostSynthesisOption(IsPostSynthesisEnabled(options)); - vpr_setup->constant_net_delay = options->constant_net_delay; + /* Read in user options */ + ReadOptions(argc, argv, options); + /* Timing option priorities */ + vpr_setup->TimingEnabled = IsTimingEnabled(options); + /* Determine whether echo is on or off */ + setEchoEnabled(IsEchoEnabled(options)); + SetPostSynthesisOption(IsPostSynthesisEnabled(options)); + vpr_setup->constant_net_delay = options->constant_net_delay; - /* Read in arch and circuit */ - SetupVPR(options, vpr_setup->TimingEnabled, TRUE, &vpr_setup->FileNameOpts, - arch, &vpr_setup->Operation, &vpr_setup->user_models, - &vpr_setup->library_models, &vpr_setup->PackerOpts, - &vpr_setup->PlacerOpts, &vpr_setup->AnnealSched, - &vpr_setup->RouterOpts, &vpr_setup->RoutingArch, - &vpr_setup->Segments, &vpr_setup->Timing, &vpr_setup->ShowGraphics, - &vpr_setup->GraphPause, &vpr_setup->PowerOpts, - /*Xifan TANG: Switch Segment Pattern Support*/ - &vpr_setup->swseg_patterns, &vpr_setup->FPGA_SPICE_Opts); + /* Read in arch and circuit */ + SetupVPR(options, vpr_setup->TimingEnabled, TRUE, &vpr_setup->FileNameOpts, + arch, &vpr_setup->Operation, &vpr_setup->user_models, + &vpr_setup->library_models, &vpr_setup->PackerOpts, + &vpr_setup->PlacerOpts, &vpr_setup->AnnealSched, + &vpr_setup->RouterOpts, &vpr_setup->RoutingArch, + &vpr_setup->Segments, &vpr_setup->Timing, &vpr_setup->ShowGraphics, + &vpr_setup->GraphPause, &vpr_setup->PowerOpts, + /*Xifan TANG: Switch Segment Pattern Support*/ + &vpr_setup->swseg_patterns, &vpr_setup->FPGA_SPICE_Opts); - /* Check inputs are reasonable */ - CheckOptions(*options, vpr_setup->TimingEnabled); - CheckArch(*arch, vpr_setup->TimingEnabled); + /* Check inputs are reasonable */ + CheckOptions(*options, vpr_setup->TimingEnabled); + CheckArch(*arch, vpr_setup->TimingEnabled); - /* Verify settings don't conflict or otherwise not make sense */ - CheckSetup(vpr_setup->Operation, vpr_setup->PlacerOpts, - vpr_setup->AnnealSched, vpr_setup->RouterOpts, - vpr_setup->RoutingArch, vpr_setup->Segments, vpr_setup->Timing, - arch->Chans); + /* Verify settings don't conflict or otherwise not make sense */ + CheckSetup(vpr_setup->Operation, vpr_setup->PlacerOpts, + vpr_setup->AnnealSched, vpr_setup->RouterOpts, + vpr_setup->RoutingArch, vpr_setup->Segments, vpr_setup->Timing, + arch->Chans); - /* flush any messages to user still in stdout that hasn't gotten displayed */ - fflush(stdout); + /* flush any messages to user still in stdout that hasn't gotten displayed */ + fflush(stdout); - /* Read blif file and sweep unused components */ - read_and_process_blif(vpr_setup->PackerOpts.blif_file_name, - vpr_setup->PackerOpts.sweep_hanging_nets_and_inputs, - vpr_setup->user_models, vpr_setup->library_models, + /* Read blif file and sweep unused components */ + read_and_process_blif(vpr_setup->PackerOpts.blif_file_name, + vpr_setup->PackerOpts.sweep_hanging_nets_and_inputs, + vpr_setup->user_models, vpr_setup->library_models, /* Xifan TANG: we need activity in spice modeling */ - (boolean)(vpr_setup->PowerOpts.do_power + (boolean)(vpr_setup->PowerOpts.do_power | vpr_setup->FPGA_SPICE_Opts.read_act_file), vpr_setup->FileNameOpts.ActFile); - fflush(stdout); + fflush(stdout); - ShowSetup(*options, *vpr_setup); + ShowSetup(*options, *vpr_setup); } /* @@ -284,59 +305,59 @@ void vpr_init(INP int argc, INP char **argv, OUTP t_options *options, * Allocs globals: chan_width_x, chan_width_y, grid * Depends on num_clbs, pins_per_clb */ void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) { - int *num_instances_type, *num_blocks_type; - int i; - int current, high, low; - boolean fit; + int *num_instances_type, *num_blocks_type; + int i; + int current, high, low; + boolean fit; /* Xifan TANG: consider marco length in fitting */ int imacro, max_len_chain_blocks; int num_pl_macros; t_pl_macro* pl_macros; - /* Read in netlist file for placement and routing */ - if (vpr_setup.FileNameOpts.NetFile) { - read_netlist(vpr_setup.FileNameOpts.NetFile, &Arch, &num_blocks, &block, - &num_nets, &clb_net); - /* This is done so that all blocks have subblocks and can be treated the same */ - check_netlist(); - } + /* Read in netlist file for placement and routing */ + if (vpr_setup.FileNameOpts.NetFile) { + read_netlist(vpr_setup.FileNameOpts.NetFile, &Arch, &num_blocks, &block, + &num_nets, &clb_net); + /* This is done so that all blocks have subblocks and can be treated the same */ + check_netlist(); + } - /* Output the current settings to console. */ - printClusteredNetlistStats(); + /* Output the current settings to console. */ + printClusteredNetlistStats(); - if (vpr_setup.Operation == TIMING_ANALYSIS_ONLY) { - do_constant_net_delay_timing_analysis(vpr_setup.Timing, - vpr_setup.constant_net_delay); - } else { - current = nint((float)sqrt((float)num_blocks)); /* current is the value of the smaller side of the FPGA */ - low = 1; - high = -1; + if (vpr_setup.Operation == TIMING_ANALYSIS_ONLY) { + do_constant_net_delay_timing_analysis(vpr_setup.Timing, + vpr_setup.constant_net_delay); + } else { + current = nint((float)sqrt((float)num_blocks)); /* current is the value of the smaller side of the FPGA */ + low = 1; + high = -1; - num_instances_type = (int*) my_calloc(num_types, sizeof(int)); - num_blocks_type = (int*) my_calloc(num_types, sizeof(int)); + num_instances_type = (int*) my_calloc(num_types, sizeof(int)); + num_blocks_type = (int*) my_calloc(num_types, sizeof(int)); - for (i = 0; i < num_blocks; i++) { - num_blocks_type[block[i].type->index]++; - } + for (i = 0; i < num_blocks; i++) { + num_blocks_type[block[i].type->index]++; + } - if (Arch.clb_grid.IsAuto) { - /* Auto-size FPGA, perform a binary search */ - while (high == -1 || low < high) { - /* Generate grid */ - if (Arch.clb_grid.Aspect >= 1.0) { - ny = current; - nx = nint(current * Arch.clb_grid.Aspect); - } else { - nx = current; - ny = nint(current / Arch.clb_grid.Aspect); - } + if (Arch.clb_grid.IsAuto) { + /* Auto-size FPGA, perform a binary search */ + while (high == -1 || low < high) { + /* Generate grid */ + if (Arch.clb_grid.Aspect >= 1.0) { + ny = current; + nx = nint(current * Arch.clb_grid.Aspect); + } else { + nx = current; + ny = nint(current / Arch.clb_grid.Aspect); + } #if DEBUG - vpr_printf(TIO_MESSAGE_INFO, - "Auto-sizing FPGA at x = %d y = %d\n", nx, ny); + vpr_printf(TIO_MESSAGE_INFO, + "Auto-sizing FPGA at x = %d y = %d\n", nx, ny); #endif - alloc_and_load_grid(num_instances_type); - freeGrid(); + alloc_and_load_grid(num_instances_type); + freeGrid(); /* Xifan TANG: We need consider the length of carry-chain CLBs into account! */ num_pl_macros = alloc_and_load_placement_macros(Arch.Directs, Arch.num_directs, &pl_macros); @@ -344,19 +365,19 @@ void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) { max_len_chain_blocks = max_len_pl_macros(num_pl_macros, pl_macros); /* Free all the allocated structs */ free_placement_macros_structs(); - for (imacro = 0; imacro < num_pl_macros; imacro ++) { - free(pl_macros[imacro].members); + for (imacro = 0; imacro < num_pl_macros; imacro ++) { + free(pl_macros[imacro].members); } - free(pl_macros); + free(pl_macros); - /* Test if netlist fits in grid */ - fit = TRUE; - for (i = 0; i < num_types; i++) { - if (num_blocks_type[i] > num_instances_type[i]) { - fit = FALSE; - break; - } - } + /* Test if netlist fits in grid */ + fit = TRUE; + for (i = 0; i < num_types; i++) { + if (num_blocks_type[i] > num_instances_type[i]) { + fit = FALSE; + break; + } + } /* If the length of macros is longer than ny - 2, fitting should fail. * Note: carry-chain logic blocks are placed only vertically in FPGA. */ @@ -366,47 +387,47 @@ void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) { max_len_chain_blocks, ny); } - /* get next value */ - if (!fit) { - /* increase size of max */ - if (high == -1) { - current = current * 2; - if (current > MAX_SHORT) { - vpr_printf(TIO_MESSAGE_ERROR, - "FPGA required is too large for current architecture settings.\n"); - exit(1); - } - } else { - if (low == current) - current++; - low = current; - current = low + ((high - low) / 2); - } - } else { - high = current; - current = low + ((high - low) / 2); - } - } - /* Generate grid */ - if (Arch.clb_grid.Aspect >= 1.0) { - ny = current; - nx = nint(current * Arch.clb_grid.Aspect); - } else { - nx = current; - ny = nint(current / Arch.clb_grid.Aspect); - } - alloc_and_load_grid(num_instances_type); - vpr_printf(TIO_MESSAGE_INFO, "FPGA auto-sized to x = %d y = %d\n", - nx, ny); - } else { - nx = Arch.clb_grid.W; - ny = Arch.clb_grid.H; - alloc_and_load_grid(num_instances_type); - } + /* get next value */ + if (!fit) { + /* increase size of max */ + if (high == -1) { + current = current * 2; + if (current > MAX_SHORT) { + vpr_printf(TIO_MESSAGE_ERROR, + "FPGA required is too large for current architecture settings.\n"); + exit(1); + } + } else { + if (low == current) + current++; + low = current; + current = low + ((high - low) / 2); + } + } else { + high = current; + current = low + ((high - low) / 2); + } + } + /* Generate grid */ + if (Arch.clb_grid.Aspect >= 1.0) { + ny = current; + nx = nint(current * Arch.clb_grid.Aspect); + } else { + nx = current; + ny = nint(current / Arch.clb_grid.Aspect); + } + alloc_and_load_grid(num_instances_type); + vpr_printf(TIO_MESSAGE_INFO, "FPGA auto-sized to x = %d y = %d\n", + nx, ny); + } else { + nx = Arch.clb_grid.W; + ny = Arch.clb_grid.H; + alloc_and_load_grid(num_instances_type); + } - vpr_printf(TIO_MESSAGE_INFO, - "The circuit will be mapped into a %d x %d array of clbs.\n", - nx, ny); + vpr_printf(TIO_MESSAGE_INFO, + "The circuit will be mapped into a %d x %d array of clbs.\n", + nx, ny); /* Xifan TANG: We need consider the length of carry-chain CLBs into account! */ num_pl_macros = alloc_and_load_placement_macros(Arch.Directs, Arch.num_directs, &pl_macros); @@ -419,14 +440,14 @@ void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) { } free(pl_macros); - /* Test if netlist fits in grid */ - fit = TRUE; - for (i = 0; i < num_types; i++) { - if (num_blocks_type[i] > num_instances_type[i]) { - fit = FALSE; - break; - } - } + /* Test if netlist fits in grid */ + fit = TRUE; + for (i = 0; i < num_types; i++) { + if (num_blocks_type[i] > num_instances_type[i]) { + fit = FALSE; + break; + } + } /* If the length of macros is longer than ny - 2, fitting should fail. * Note: carry-chain logic blocks are placed only vertically in FPGA. @@ -437,457 +458,457 @@ void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) { max_len_chain_blocks, ny); } - if (!fit) { - vpr_printf(TIO_MESSAGE_ERROR, - "Not enough physical locations for type %s, number of blocks is %d but number of locations is %d.\n", - type_descriptors[i].name, num_blocks_type[i], - num_instances_type[i]); - exit(1); - } + if (!fit) { + vpr_printf(TIO_MESSAGE_ERROR, + "Not enough physical locations for type %s, number of blocks is %d but number of locations is %d.\n", + type_descriptors[i].name, num_blocks_type[i], + num_instances_type[i]); + exit(1); + } - vpr_printf(TIO_MESSAGE_INFO, "\n"); - vpr_printf(TIO_MESSAGE_INFO, "Resource usage...\n"); - for (i = 0; i < num_types; i++) { - vpr_printf(TIO_MESSAGE_INFO, - "\tNetlist %d\tblocks of type: %s\n", - num_blocks_type[i], type_descriptors[i].name); - vpr_printf(TIO_MESSAGE_INFO, - "\tArchitecture %d\tblocks of type: %s\n", - num_instances_type[i], type_descriptors[i].name); - } - vpr_printf(TIO_MESSAGE_INFO, "\n"); - chan_width_x = (int *) my_malloc((ny + 1) * sizeof(int)); - chan_width_y = (int *) my_malloc((nx + 1) * sizeof(int)); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "Resource usage...\n"); + for (i = 0; i < num_types; i++) { + vpr_printf(TIO_MESSAGE_INFO, + "\tNetlist %d\tblocks of type: %s\n", + num_blocks_type[i], type_descriptors[i].name); + vpr_printf(TIO_MESSAGE_INFO, + "\tArchitecture %d\tblocks of type: %s\n", + num_instances_type[i], type_descriptors[i].name); + } + vpr_printf(TIO_MESSAGE_INFO, "\n"); + chan_width_x = (int *) my_malloc((ny + 1) * sizeof(int)); + chan_width_y = (int *) my_malloc((nx + 1) * sizeof(int)); - free(num_blocks_type); - free(num_instances_type); - } + free(num_blocks_type); + free(num_instances_type); + } } void vpr_pack(INP t_vpr_setup vpr_setup, INP t_arch arch) { - clock_t begin, end; - float inter_cluster_delay = UNDEFINED, Tdel_opin_switch, Tdel_wire_switch, - Tdel_wtoi_switch, R_opin_switch, R_wire_switch, R_wtoi_switch, - Cout_opin_switch, Cout_wire_switch, Cout_wtoi_switch, - opin_switch_del, wire_switch_del, wtoi_switch_del, Rmetal, Cmetal, - first_wire_seg_delay, second_wire_seg_delay; - begin = clock(); - vpr_printf(TIO_MESSAGE_INFO, "Initialize packing.\n"); + clock_t begin, end; + float inter_cluster_delay = UNDEFINED, Tdel_opin_switch, Tdel_wire_switch, + Tdel_wtoi_switch, R_opin_switch, R_wire_switch, R_wtoi_switch, + Cout_opin_switch, Cout_wire_switch, Cout_wtoi_switch, + opin_switch_del, wire_switch_del, wtoi_switch_del, Rmetal, Cmetal, + first_wire_seg_delay, second_wire_seg_delay; + begin = clock(); + vpr_printf(TIO_MESSAGE_INFO, "Initialize packing.\n"); - /* If needed, estimate inter-cluster delay. Assume the average routing hop goes out of - a block through an opin switch to a length-4 wire, then through a wire switch to another - length-4 wire, then through a wire-to-ipin-switch into another block. */ + /* If needed, estimate inter-cluster delay. Assume the average routing hop goes out of + a block through an opin switch to a length-4 wire, then through a wire switch to another + length-4 wire, then through a wire-to-ipin-switch into another block. */ - if (vpr_setup.PackerOpts.timing_driven - && vpr_setup.PackerOpts.auto_compute_inter_cluster_net_delay) { - opin_switch_del = get_switch_info(arch.Segments[0].opin_switch, - Tdel_opin_switch, R_opin_switch, Cout_opin_switch); - wire_switch_del = get_switch_info(arch.Segments[0].wire_switch, - Tdel_wire_switch, R_wire_switch, Cout_wire_switch); - wtoi_switch_del = get_switch_info( - vpr_setup.RoutingArch.wire_to_ipin_switch, Tdel_wtoi_switch, - R_wtoi_switch, Cout_wtoi_switch); /* wire-to-ipin switch */ - Rmetal = arch.Segments[0].Rmetal; - Cmetal = arch.Segments[0].Cmetal; + if (vpr_setup.PackerOpts.timing_driven + && vpr_setup.PackerOpts.auto_compute_inter_cluster_net_delay) { + opin_switch_del = get_switch_info(arch.Segments[0].opin_switch, + Tdel_opin_switch, R_opin_switch, Cout_opin_switch); + wire_switch_del = get_switch_info(arch.Segments[0].wire_switch, + Tdel_wire_switch, R_wire_switch, Cout_wire_switch); + wtoi_switch_del = get_switch_info( + vpr_setup.RoutingArch.wire_to_ipin_switch, Tdel_wtoi_switch, + R_wtoi_switch, Cout_wtoi_switch); /* wire-to-ipin switch */ + Rmetal = arch.Segments[0].Rmetal; + Cmetal = arch.Segments[0].Cmetal; - /* The delay of a wire with its driving switch is the switch delay plus the - product of the equivalent resistance and capacitance experienced by the wire. */ + /* The delay of a wire with its driving switch is the switch delay plus the + product of the equivalent resistance and capacitance experienced by the wire. */ #define WIRE_SEGMENT_LENGTH 4 - first_wire_seg_delay = opin_switch_del - + (R_opin_switch + Rmetal * WIRE_SEGMENT_LENGTH / 2) - * (Cout_opin_switch + Cmetal * WIRE_SEGMENT_LENGTH); - second_wire_seg_delay = wire_switch_del - + (R_wire_switch + Rmetal * WIRE_SEGMENT_LENGTH / 2) - * (Cout_wire_switch + Cmetal * WIRE_SEGMENT_LENGTH); - inter_cluster_delay = 4 - * (first_wire_seg_delay + second_wire_seg_delay - + wtoi_switch_del); /* multiply by 4 to get a more conservative estimate */ - } + first_wire_seg_delay = opin_switch_del + + (R_opin_switch + Rmetal * WIRE_SEGMENT_LENGTH / 2) + * (Cout_opin_switch + Cmetal * WIRE_SEGMENT_LENGTH); + second_wire_seg_delay = wire_switch_del + + (R_wire_switch + Rmetal * WIRE_SEGMENT_LENGTH / 2) + * (Cout_wire_switch + Cmetal * WIRE_SEGMENT_LENGTH); + inter_cluster_delay = 4 + * (first_wire_seg_delay + second_wire_seg_delay + + wtoi_switch_del); /* multiply by 4 to get a more conservative estimate */ + } - try_pack(&vpr_setup.PackerOpts, &arch, vpr_setup.user_models, - vpr_setup.library_models, vpr_setup.Timing, inter_cluster_delay); - end = clock(); + try_pack(&vpr_setup.PackerOpts, &arch, vpr_setup.user_models, + vpr_setup.library_models, vpr_setup.Timing, inter_cluster_delay); + end = clock(); #ifdef CLOCKS_PER_SEC - vpr_printf(TIO_MESSAGE_INFO, "Packing took %g seconds.\n", - (float) (end - begin) / CLOCKS_PER_SEC); - vpr_printf(TIO_MESSAGE_INFO, "Packing completed.\n"); + vpr_printf(TIO_MESSAGE_INFO, "Packing took %g seconds.\n", + (float) (end - begin) / CLOCKS_PER_SEC); + vpr_printf(TIO_MESSAGE_INFO, "Packing completed.\n"); #else - vpr_printf(TIO_MESSAGE_INFO, "Packing took %g seconds.\n", (float)(end - begin) / CLK_PER_SEC); + vpr_printf(TIO_MESSAGE_INFO, "Packing took %g seconds.\n", (float)(end - begin) / CLK_PER_SEC); #endif /* Xifan TANG: print the run time of packing placement */ - vpr_printf(TIO_MESSAGE_INFO, "Packing routing took %g seconds.\n", pack_route_time); - fflush(stdout); + vpr_printf(TIO_MESSAGE_INFO, "Packing routing took %g seconds.\n", pack_route_time); + fflush(stdout); } void vpr_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch arch) { - /* Startup X graphics */ - set_graphics_state(vpr_setup.ShowGraphics, vpr_setup.GraphPause, - vpr_setup.RouterOpts.route_type); - if (vpr_setup.ShowGraphics) { - init_graphics("VPR: Versatile Place and Route for FPGAs", WHITE); - alloc_draw_structs(); - } + /* Startup X graphics */ + set_graphics_state(vpr_setup.ShowGraphics, vpr_setup.GraphPause, + vpr_setup.RouterOpts.route_type); + if (vpr_setup.ShowGraphics) { + init_graphics("VPR: Versatile Place and Route for FPGAs", WHITE); + alloc_draw_structs(); + } - /* Do placement and routing */ - place_and_route(vpr_setup.Operation, vpr_setup.PlacerOpts, - vpr_setup.FileNameOpts.PlaceFile, vpr_setup.FileNameOpts.NetFile, - vpr_setup.FileNameOpts.ArchFile, vpr_setup.FileNameOpts.RouteFile, - vpr_setup.AnnealSched, vpr_setup.RouterOpts, vpr_setup.RoutingArch, - vpr_setup.Segments, vpr_setup.Timing, arch.Chans, arch.models, - arch.Directs, arch.num_directs, arch.sram_inf.area, + /* Do placement and routing */ + place_and_route(vpr_setup.Operation, vpr_setup.PlacerOpts, + vpr_setup.FileNameOpts.PlaceFile, vpr_setup.FileNameOpts.NetFile, + vpr_setup.FileNameOpts.ArchFile, vpr_setup.FileNameOpts.RouteFile, + vpr_setup.AnnealSched, vpr_setup.RouterOpts, vpr_setup.RoutingArch, + vpr_setup.Segments, vpr_setup.Timing, arch.Chans, arch.models, + arch.Directs, arch.num_directs, arch.sram_inf.area, /*Xifan TANG: Switch Segment Pattern Support*/ vpr_setup.swseg_patterns); - fflush(stdout); + fflush(stdout); - /* Close down X Display */ - if (vpr_setup.ShowGraphics) - close_graphics(); - free_draw_structs(); + /* Close down X Display */ + if (vpr_setup.ShowGraphics) + close_graphics(); + free_draw_structs(); } /* Free architecture data structures */ void free_arch(t_arch* Arch) { - int i; - t_model *model, *prev; - t_model_ports *port, *prev_port; - struct s_linked_vptr *vptr, *vptr_prev; + int i; + t_model *model, *prev; + t_model_ports *port, *prev_port; + struct s_linked_vptr *vptr, *vptr_prev; - freeGrid(); - free(chan_width_x); - chan_width_x = NULL; - free(chan_width_y); - chan_width_y = NULL; + freeGrid(); + free(chan_width_x); + chan_width_x = NULL; + free(chan_width_y); + chan_width_y = NULL; - for (i = 0; i < Arch->num_switches; i++) { - if (Arch->Switches->name != NULL) { - free(Arch->Switches[i].name); - } - } - free(Arch->Switches); - free(switch_inf); - for (i = 0; i < Arch->num_segments; i++) { - if (Arch->Segments->cb != NULL) { - free(Arch->Segments[i].cb); - } - if (Arch->Segments->sb != NULL) { - free(Arch->Segments[i].sb); - } - } - free(Arch->Segments); - model = Arch->models; - while (model) { - port = model->inputs; - while (port) { - prev_port = port; - port = port->next; - free(prev_port->name); - free(prev_port); - } - port = model->outputs; - while (port) { - prev_port = port; - port = port->next; - free(prev_port->name); - free(prev_port); - } - vptr = model->pb_types; - while (vptr) { - vptr_prev = vptr; - vptr = vptr->next; - free(vptr_prev); - } - prev = model; + for (i = 0; i < Arch->num_switches; i++) { + if (Arch->Switches->name != NULL) { + free(Arch->Switches[i].name); + } + } + free(Arch->Switches); + free(switch_inf); + for (i = 0; i < Arch->num_segments; i++) { + if (Arch->Segments->cb != NULL) { + free(Arch->Segments[i].cb); + } + if (Arch->Segments->sb != NULL) { + free(Arch->Segments[i].sb); + } + } + free(Arch->Segments); + model = Arch->models; + while (model) { + port = model->inputs; + while (port) { + prev_port = port; + port = port->next; + free(prev_port->name); + free(prev_port); + } + port = model->outputs; + while (port) { + prev_port = port; + port = port->next; + free(prev_port->name); + free(prev_port); + } + vptr = model->pb_types; + while (vptr) { + vptr_prev = vptr; + vptr = vptr->next; + free(vptr_prev); + } + prev = model; - model = model->next; - if (prev->instances) - free(prev->instances); - free(prev->name); - free(prev); - } + model = model->next; + if (prev->instances) + free(prev->instances); + free(prev->name); + free(prev); + } - for (i = 0; i < 4; i++) { - vptr = Arch->model_library[i].pb_types; - while (vptr) { - vptr_prev = vptr; - vptr = vptr->next; - free(vptr_prev); - } - } + for (i = 0; i < 4; i++) { + vptr = Arch->model_library[i].pb_types; + while (vptr) { + vptr_prev = vptr; + vptr = vptr->next; + free(vptr_prev); + } + } - for (i = 0; i < Arch->num_directs; i++) { - free(Arch->Directs[i].name); - free(Arch->Directs[i].from_pin); - free(Arch->Directs[i].to_pin); - } - free(Arch->Directs); + for (i = 0; i < Arch->num_directs; i++) { + free(Arch->Directs[i].name); + free(Arch->Directs[i].from_pin); + free(Arch->Directs[i].to_pin); + } + free(Arch->Directs); - free(Arch->model_library[0].name); - free(Arch->model_library[0].outputs->name); - free(Arch->model_library[0].outputs); - free(Arch->model_library[1].inputs->name); - free(Arch->model_library[1].inputs); - free(Arch->model_library[1].name); - free(Arch->model_library[2].name); - free(Arch->model_library[2].inputs[0].name); - free(Arch->model_library[2].inputs[1].name); - free(Arch->model_library[2].inputs); - free(Arch->model_library[2].outputs->name); - free(Arch->model_library[2].outputs); - free(Arch->model_library[3].name); - free(Arch->model_library[3].inputs->name); - free(Arch->model_library[3].inputs); - free(Arch->model_library[3].outputs->name); - free(Arch->model_library[3].outputs); - free(Arch->model_library); + free(Arch->model_library[0].name); + free(Arch->model_library[0].outputs->name); + free(Arch->model_library[0].outputs); + free(Arch->model_library[1].inputs->name); + free(Arch->model_library[1].inputs); + free(Arch->model_library[1].name); + free(Arch->model_library[2].name); + free(Arch->model_library[2].inputs[0].name); + free(Arch->model_library[2].inputs[1].name); + free(Arch->model_library[2].inputs); + free(Arch->model_library[2].outputs->name); + free(Arch->model_library[2].outputs); + free(Arch->model_library[3].name); + free(Arch->model_library[3].inputs->name); + free(Arch->model_library[3].inputs); + free(Arch->model_library[3].outputs->name); + free(Arch->model_library[3].outputs); + free(Arch->model_library); - if (Arch->clocks) { - free(Arch->clocks->clock_inf); - } + if (Arch->clocks) { + free(Arch->clocks->clock_inf); + } - free_complex_block_types(); - free_chunk_memory_trace(); + free_complex_block_types(); + free_chunk_memory_trace(); } void free_options(t_options *options) { - free(options->ArchFile); - free(options->CircuitName); - if (options->ActFile) - free(options->ActFile); - if (options->BlifFile) - free(options->BlifFile); - if (options->NetFile) - free(options->NetFile); - if (options->PlaceFile) - free(options->PlaceFile); - if (options->PowerFile) - free(options->PowerFile); - if (options->CmosTechFile) - free(options->CmosTechFile); - if (options->RouteFile) - free(options->RouteFile); - if (options->out_file_prefix) - free(options->out_file_prefix); - if (options->PinFile) - free(options->PinFile); + free(options->ArchFile); + free(options->CircuitName); + if (options->ActFile) + free(options->ActFile); + if (options->BlifFile) + free(options->BlifFile); + if (options->NetFile) + free(options->NetFile); + if (options->PlaceFile) + free(options->PlaceFile); + if (options->PowerFile) + free(options->PowerFile); + if (options->CmosTechFile) + free(options->CmosTechFile); + if (options->RouteFile) + free(options->RouteFile); + if (options->out_file_prefix) + free(options->out_file_prefix); + if (options->PinFile) + free(options->PinFile); } static void free_complex_block_types(void) { - int i, j, k, m; + int i, j, k, m; - free_all_pb_graph_nodes(); + free_all_pb_graph_nodes(); - for (i = 0; i < num_types; i++) { - if (&type_descriptors[i] == EMPTY_TYPE) { - continue; - } - free(type_descriptors[i].name); - for (j = 0; j < type_descriptors[i].height; j++) { - for (k = 0; k < 4; k++) { - for (m = 0; - m < type_descriptors[i].num_pin_loc_assignments[j][k]; - m++) { - if (type_descriptors[i].pin_loc_assignments[j][k][m]) - free(type_descriptors[i].pin_loc_assignments[j][k][m]); - } - free(type_descriptors[i].pinloc[j][k]); - free(type_descriptors[i].pin_loc_assignments[j][k]); - } - free(type_descriptors[i].pinloc[j]); - free(type_descriptors[i].pin_loc_assignments[j]); - free(type_descriptors[i].num_pin_loc_assignments[j]); - } - for (j = 0; j < type_descriptors[i].num_class; j++) { - free(type_descriptors[i].class_inf[j].pinlist); - } - free(type_descriptors[i].pinloc); - free(type_descriptors[i].pin_loc_assignments); - free(type_descriptors[i].num_pin_loc_assignments); - free(type_descriptors[i].pin_height); - free(type_descriptors[i].class_inf); - free(type_descriptors[i].is_global_pin); - free(type_descriptors[i].pin_class); - free(type_descriptors[i].grid_loc_def); - free(type_descriptors[i].is_Fc_frac); - free(type_descriptors[i].is_Fc_full_flex); - free(type_descriptors[i].Fc); - free_pb_type(type_descriptors[i].pb_type); - free(type_descriptors[i].pb_type); - } - free(type_descriptors); + for (i = 0; i < num_types; i++) { + if (&type_descriptors[i] == EMPTY_TYPE) { + continue; + } + free(type_descriptors[i].name); + for (j = 0; j < type_descriptors[i].height; j++) { + for (k = 0; k < 4; k++) { + for (m = 0; + m < type_descriptors[i].num_pin_loc_assignments[j][k]; + m++) { + if (type_descriptors[i].pin_loc_assignments[j][k][m]) + free(type_descriptors[i].pin_loc_assignments[j][k][m]); + } + free(type_descriptors[i].pinloc[j][k]); + free(type_descriptors[i].pin_loc_assignments[j][k]); + } + free(type_descriptors[i].pinloc[j]); + free(type_descriptors[i].pin_loc_assignments[j]); + free(type_descriptors[i].num_pin_loc_assignments[j]); + } + for (j = 0; j < type_descriptors[i].num_class; j++) { + free(type_descriptors[i].class_inf[j].pinlist); + } + free(type_descriptors[i].pinloc); + free(type_descriptors[i].pin_loc_assignments); + free(type_descriptors[i].num_pin_loc_assignments); + free(type_descriptors[i].pin_height); + free(type_descriptors[i].class_inf); + free(type_descriptors[i].is_global_pin); + free(type_descriptors[i].pin_class); + free(type_descriptors[i].grid_loc_def); + free(type_descriptors[i].is_Fc_frac); + free(type_descriptors[i].is_Fc_full_flex); + free(type_descriptors[i].Fc); + free_pb_type(type_descriptors[i].pb_type); + free(type_descriptors[i].pb_type); + } + free(type_descriptors); } static void free_pb_type(t_pb_type *pb_type) { - int i, j, k, m; + int i, j, k, m; - free(pb_type->name); - if (pb_type->blif_model) - free(pb_type->blif_model); + free(pb_type->name); + if (pb_type->blif_model) + free(pb_type->blif_model); - for (i = 0; i < pb_type->num_modes; i++) { - for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { - free_pb_type(&pb_type->modes[i].pb_type_children[j]); - } - free(pb_type->modes[i].pb_type_children); - free(pb_type->modes[i].name); - for (j = 0; j < pb_type->modes[i].num_interconnect; j++) { - free(pb_type->modes[i].interconnect[j].input_string); - free(pb_type->modes[i].interconnect[j].output_string); - free(pb_type->modes[i].interconnect[j].name); + for (i = 0; i < pb_type->num_modes; i++) { + for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { + free_pb_type(&pb_type->modes[i].pb_type_children[j]); + } + free(pb_type->modes[i].pb_type_children); + free(pb_type->modes[i].name); + for (j = 0; j < pb_type->modes[i].num_interconnect; j++) { + free(pb_type->modes[i].interconnect[j].input_string); + free(pb_type->modes[i].interconnect[j].output_string); + free(pb_type->modes[i].interconnect[j].name); - for (k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; - k++) { - if (pb_type->modes[i].interconnect[j].annotations[k].clock) - free( - pb_type->modes[i].interconnect[j].annotations[k].clock); - if (pb_type->modes[i].interconnect[j].annotations[k].input_pins) { - free( - pb_type->modes[i].interconnect[j].annotations[k].input_pins); - } - if (pb_type->modes[i].interconnect[j].annotations[k].output_pins) { - free( - pb_type->modes[i].interconnect[j].annotations[k].output_pins); - } - for (m = 0; - m - < pb_type->modes[i].interconnect[j].annotations[k].num_value_prop_pairs; - m++) { - free( - pb_type->modes[i].interconnect[j].annotations[k].value[m]); - } - free(pb_type->modes[i].interconnect[j].annotations[k].prop); - free(pb_type->modes[i].interconnect[j].annotations[k].value); - } - free(pb_type->modes[i].interconnect[j].annotations); - if (pb_type->modes[i].interconnect[j].interconnect_power) - free(pb_type->modes[i].interconnect[j].interconnect_power); - } - if (pb_type->modes[i].interconnect) - free(pb_type->modes[i].interconnect); - if (pb_type->modes[i].mode_power) - free(pb_type->modes[i].mode_power); - } - if (pb_type->modes) - free(pb_type->modes); + for (k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; + k++) { + if (pb_type->modes[i].interconnect[j].annotations[k].clock) + free( + pb_type->modes[i].interconnect[j].annotations[k].clock); + if (pb_type->modes[i].interconnect[j].annotations[k].input_pins) { + free( + pb_type->modes[i].interconnect[j].annotations[k].input_pins); + } + if (pb_type->modes[i].interconnect[j].annotations[k].output_pins) { + free( + pb_type->modes[i].interconnect[j].annotations[k].output_pins); + } + for (m = 0; + m + < pb_type->modes[i].interconnect[j].annotations[k].num_value_prop_pairs; + m++) { + free( + pb_type->modes[i].interconnect[j].annotations[k].value[m]); + } + free(pb_type->modes[i].interconnect[j].annotations[k].prop); + free(pb_type->modes[i].interconnect[j].annotations[k].value); + } + free(pb_type->modes[i].interconnect[j].annotations); + if (pb_type->modes[i].interconnect[j].interconnect_power) + free(pb_type->modes[i].interconnect[j].interconnect_power); + } + if (pb_type->modes[i].interconnect) + free(pb_type->modes[i].interconnect); + if (pb_type->modes[i].mode_power) + free(pb_type->modes[i].mode_power); + } + if (pb_type->modes) + free(pb_type->modes); - for (i = 0; i < pb_type->num_annotations; i++) { - for (j = 0; j < pb_type->annotations[i].num_value_prop_pairs; j++) { - free(pb_type->annotations[i].value[j]); - } - free(pb_type->annotations[i].value); - free(pb_type->annotations[i].prop); - if (pb_type->annotations[i].input_pins) { - free(pb_type->annotations[i].input_pins); - } - if (pb_type->annotations[i].output_pins) { - free(pb_type->annotations[i].output_pins); - } - if (pb_type->annotations[i].clock) { - free(pb_type->annotations[i].clock); - } - } - if (pb_type->num_annotations > 0) { - free(pb_type->annotations); - } + for (i = 0; i < pb_type->num_annotations; i++) { + for (j = 0; j < pb_type->annotations[i].num_value_prop_pairs; j++) { + free(pb_type->annotations[i].value[j]); + } + free(pb_type->annotations[i].value); + free(pb_type->annotations[i].prop); + if (pb_type->annotations[i].input_pins) { + free(pb_type->annotations[i].input_pins); + } + if (pb_type->annotations[i].output_pins) { + free(pb_type->annotations[i].output_pins); + } + if (pb_type->annotations[i].clock) { + free(pb_type->annotations[i].clock); + } + } + if (pb_type->num_annotations > 0) { + free(pb_type->annotations); + } - if (pb_type->pb_type_power) { - free(pb_type->pb_type_power); - } + if (pb_type->pb_type_power) { + free(pb_type->pb_type_power); + } - for (i = 0; i < pb_type->num_ports; i++) { - free(pb_type->ports[i].name); - if (pb_type->ports[i].port_class) { - free(pb_type->ports[i].port_class); - } - if (pb_type->ports[i].port_power) { - free(pb_type->ports[i].port_power); - } - } - free(pb_type->ports); + for (i = 0; i < pb_type->num_ports; i++) { + free(pb_type->ports[i].name); + if (pb_type->ports[i].port_class) { + free(pb_type->ports[i].port_class); + } + if (pb_type->ports[i].port_power) { + free(pb_type->ports[i].port_power); + } + } + free(pb_type->ports); } void free_circuit() { - int i; - struct s_linked_vptr *p_io_removed; + int i; + struct s_linked_vptr *p_io_removed; - /* Free netlist reference tables for nets */ - free(clb_to_vpack_net_mapping); - free(vpack_to_clb_net_mapping); - clb_to_vpack_net_mapping = NULL; - vpack_to_clb_net_mapping = NULL; + /* Free netlist reference tables for nets */ + free(clb_to_vpack_net_mapping); + free(vpack_to_clb_net_mapping); + clb_to_vpack_net_mapping = NULL; + vpack_to_clb_net_mapping = NULL; - /* Free logical blocks and nets */ - if (logical_block != NULL) { - free_logical_blocks(); - free_logical_nets(); - } + /* Free logical blocks and nets */ + if (logical_block != NULL) { + free_logical_blocks(); + free_logical_nets(); + } - if (clb_net != NULL) { - for (i = 0; i < num_nets; i++) { - free(clb_net[i].name); - free(clb_net[i].node_block); - free(clb_net[i].node_block_pin); - free(clb_net[i].node_block_port); - } - } - free(clb_net); - clb_net = NULL; + if (clb_net != NULL) { + for (i = 0; i < num_nets; i++) { + free(clb_net[i].name); + free(clb_net[i].node_block); + free(clb_net[i].node_block_pin); + free(clb_net[i].node_block_port); + } + } + free(clb_net); + clb_net = NULL; - if (block != NULL) { - for (i = 0; i < num_blocks; i++) { - if (block[i].pb != NULL) { - free_cb(block[i].pb); - free(block[i].pb); - } - free(block[i].nets); - free(block[i].name); - } - } - free(block); - block = NULL; + if (block != NULL) { + for (i = 0; i < num_blocks; i++) { + if (block[i].pb != NULL) { + free_cb(block[i].pb); + free(block[i].pb); + } + free(block[i].nets); + free(block[i].name); + } + } + free(block); + block = NULL; - free(blif_circuit_name); - free(default_output_name); - blif_circuit_name = NULL; + free(blif_circuit_name); + free(default_output_name); + blif_circuit_name = NULL; - p_io_removed = circuit_p_io_removed; - while (p_io_removed != NULL) { - circuit_p_io_removed = p_io_removed->next; - free(p_io_removed->data_vptr); - free(p_io_removed); - p_io_removed = circuit_p_io_removed; - } + p_io_removed = circuit_p_io_removed; + while (p_io_removed != NULL) { + circuit_p_io_removed = p_io_removed->next; + free(p_io_removed->data_vptr); + free(p_io_removed); + p_io_removed = circuit_p_io_removed; + } } void vpr_free_vpr_data_structures(INOUTP t_arch Arch, INOUTP t_options options, - INOUTP t_vpr_setup vpr_setup) { + INOUTP t_vpr_setup vpr_setup) { - if (vpr_setup.Timing.SDCFile != NULL) { - free(vpr_setup.Timing.SDCFile); - vpr_setup.Timing.SDCFile = NULL; - } + if (vpr_setup.Timing.SDCFile != NULL) { + free(vpr_setup.Timing.SDCFile); + vpr_setup.Timing.SDCFile = NULL; + } - free_options(&options); - free_circuit(); - free_arch(&Arch); - free_echo_file_info(); - free_output_file_names(); - free_timing_stats(); - free_sdc_related_structs(); + free_options(&options); + free_circuit(); + free_arch(&Arch); + free_echo_file_info(); + free_output_file_names(); + free_timing_stats(); + free_sdc_related_structs(); } void vpr_free_all(INOUTP t_arch Arch, INOUTP t_options options, - INOUTP t_vpr_setup vpr_setup) { - free_rr_graph(); - if (vpr_setup.RouterOpts.doRouting) { - free_route_structs(); - } - free_trace_structs(); - vpr_free_vpr_data_structures(Arch, options, vpr_setup); - if (has_printhandler_pre_vpr == FALSE) { - PrintHandlerDelete(); - } + INOUTP t_vpr_setup vpr_setup) { + free_rr_graph(); + if (vpr_setup.RouterOpts.doRouting) { + free_route_structs(); + } + free_trace_structs(); + vpr_free_vpr_data_structures(Arch, options, vpr_setup); + if (has_printhandler_pre_vpr == FALSE) { + PrintHandlerDelete(); + } } /**************************************************************************************************** @@ -896,628 +917,628 @@ void vpr_free_all(INOUTP t_arch Arch, INOUTP t_options options, ****************************************************************************************************/ /* Read in user options */ void vpr_read_options(INP int argc, INP char **argv, OUTP t_options * options) { - ReadOptions(argc, argv, options); + ReadOptions(argc, argv, options); } /* Read in arch and circuit */ void vpr_setup_vpr(INP t_options *Options, INP boolean TimingEnabled, - INP boolean readArchFile, OUTP struct s_file_name_opts *FileNameOpts, - INOUTP t_arch * Arch, OUTP enum e_operation *Operation, - OUTP t_model ** user_models, OUTP t_model ** library_models, - OUTP struct s_packer_opts *PackerOpts, - OUTP struct s_placer_opts *PlacerOpts, - OUTP struct s_annealing_sched *AnnealSched, - OUTP struct s_router_opts *RouterOpts, - OUTP struct s_det_routing_arch *RoutingArch, - OUTP t_segment_inf ** Segments, OUTP t_timing_inf * Timing, - OUTP boolean * ShowGraphics, OUTP int *GraphPause, - t_power_opts * PowerOpts, + INP boolean readArchFile, OUTP struct s_file_name_opts *FileNameOpts, + INOUTP t_arch * Arch, OUTP enum e_operation *Operation, + OUTP t_model ** user_models, OUTP t_model ** library_models, + OUTP struct s_packer_opts *PackerOpts, + OUTP struct s_placer_opts *PlacerOpts, + OUTP struct s_annealing_sched *AnnealSched, + OUTP struct s_router_opts *RouterOpts, + OUTP struct s_det_routing_arch *RoutingArch, + OUTP t_segment_inf ** Segments, OUTP t_timing_inf * Timing, + OUTP boolean * ShowGraphics, OUTP int *GraphPause, + t_power_opts * PowerOpts, /*Xifan TANG: Switch Segment Pattern Support*/ OUTP t_swseg_pattern_inf** swseg_patterns, /* Xifan TANG: FPGA-SPICE Tool Suites Support*/ OUTP t_fpga_spice_opts* FPGA_SPICE_Opts) { - SetupVPR(Options, TimingEnabled, readArchFile, FileNameOpts, Arch, - Operation, user_models, library_models, PackerOpts, PlacerOpts, - AnnealSched, RouterOpts, RoutingArch, Segments, Timing, - ShowGraphics, GraphPause, PowerOpts, swseg_patterns, FPGA_SPICE_Opts); + SetupVPR(Options, TimingEnabled, readArchFile, FileNameOpts, Arch, + Operation, user_models, library_models, PackerOpts, PlacerOpts, + AnnealSched, RouterOpts, RoutingArch, Segments, Timing, + ShowGraphics, GraphPause, PowerOpts, swseg_patterns, FPGA_SPICE_Opts); } /* Check inputs are reasonable */ void vpr_check_options(INP t_options Options, INP boolean TimingEnabled) { - CheckOptions(Options, TimingEnabled); + CheckOptions(Options, TimingEnabled); } void vpr_check_arch(INP t_arch Arch, INP boolean TimingEnabled) { - CheckArch(Arch, TimingEnabled); + CheckArch(Arch, TimingEnabled); } /* Verify settings don't conflict or otherwise not make sense */ void vpr_check_setup(INP enum e_operation Operation, - INP struct s_placer_opts PlacerOpts, - INP struct s_annealing_sched AnnealSched, - INP struct s_router_opts RouterOpts, - INP struct s_det_routing_arch RoutingArch, INP t_segment_inf * Segments, - INP t_timing_inf Timing, INP t_chan_width_dist Chans) { - CheckSetup(Operation, PlacerOpts, AnnealSched, RouterOpts, RoutingArch, - Segments, Timing, Chans); + INP struct s_placer_opts PlacerOpts, + INP struct s_annealing_sched AnnealSched, + INP struct s_router_opts RouterOpts, + INP struct s_det_routing_arch RoutingArch, INP t_segment_inf * Segments, + INP t_timing_inf Timing, INP t_chan_width_dist Chans) { + CheckSetup(Operation, PlacerOpts, AnnealSched, RouterOpts, RoutingArch, + Segments, Timing, Chans); } /* Read blif file and sweep unused components */ void vpr_read_and_process_blif(INP char *blif_file, - INP boolean sweep_hanging_nets_and_inputs, INP t_model *user_models, - INP t_model *library_models, boolean read_activity_file, - char * activity_file) { - read_and_process_blif(blif_file, sweep_hanging_nets_and_inputs, user_models, - library_models, read_activity_file, activity_file); + INP boolean sweep_hanging_nets_and_inputs, INP t_model *user_models, + INP t_model *library_models, boolean read_activity_file, + char * activity_file) { + read_and_process_blif(blif_file, sweep_hanging_nets_and_inputs, user_models, + library_models, read_activity_file, activity_file); } /* Show current setup */ void vpr_show_setup(INP t_options options, INP t_vpr_setup vpr_setup) { - ShowSetup(options, vpr_setup); + ShowSetup(options, vpr_setup); } /* Output file names management */ void vpr_alloc_and_load_output_file_names(const char* default_name) { - alloc_and_load_output_file_names(default_name); + alloc_and_load_output_file_names(default_name); } void vpr_set_output_file_name(enum e_output_files ename, const char *name, - const char* default_name) { - setOutputFileName(ename, name, default_name); + const char* default_name) { + setOutputFileName(ename, name, default_name); } char *vpr_get_output_file_name(enum e_output_files ename) { - return getOutputFileName(ename); + return getOutputFileName(ename); } /* logical equivalence scrambles the packed netlist indices with the actual indices, need to resync then re-output clustered netlist, this code assumes I'm dealing with a TI CLAY v1 architecture */ /* Returns a trace array [0..num_logical_nets-1] with the final routing of the circuit from the logical_block netlist, index of the trace array corresponds to the index of a vpack_net */ t_trace* vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture( - INP const t_arch *arch) { - t_trace *trace; + INP const t_arch *arch) { + t_trace *trace; - /* Map post-routed traces to clb_nets and block */ - resync_post_route_netlist(); + /* Map post-routed traces to clb_nets and block */ + resync_post_route_netlist(); - /* Resolve logically equivalent inputs */ - clay_logical_equivalence_handling(arch); + /* Resolve logically equivalent inputs */ + clay_logical_equivalence_handling(arch); - /* Finalize traceback */ - trace = alloc_and_load_final_routing_trace(); - if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_COMPLETE_NET_TRACE)) { - print_complete_net_trace(trace, - getEchoFileName(E_ECHO_COMPLETE_NET_TRACE)); - } - return trace; + /* Finalize traceback */ + trace = alloc_and_load_final_routing_trace(); + if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_COMPLETE_NET_TRACE)) { + print_complete_net_trace(trace, + getEchoFileName(E_ECHO_COMPLETE_NET_TRACE)); + } + return trace; } /* reload intra cluster nets to complex block */ static void reload_intra_cluster_nets(t_pb *pb) { - int i, j; - const t_pb_type* pb_type; - pb_type = pb->pb_graph_node->pb_type; - if (pb_type->blif_model != NULL) { - setup_intracluster_routing_for_logical_block(pb->logical_block, - pb->pb_graph_node); - } else if (pb->child_pbs != NULL) { - set_pb_graph_mode(pb->pb_graph_node, pb->mode, 1); - for (i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) { - for (j = 0; j < pb_type->modes[pb->mode].pb_type_children[i].num_pb; - j++) { - if (pb->child_pbs[i] != NULL) { - if (pb->child_pbs[i][j].name != NULL) { - reload_intra_cluster_nets(&pb->child_pbs[i][j]); - } - } - } - } - } + int i, j; + const t_pb_type* pb_type; + pb_type = pb->pb_graph_node->pb_type; + if (pb_type->blif_model != NULL) { + setup_intracluster_routing_for_logical_block(pb->logical_block, + pb->pb_graph_node); + } else if (pb->child_pbs != NULL) { + set_pb_graph_mode(pb->pb_graph_node, pb->mode, 1); + for (i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) { + for (j = 0; j < pb_type->modes[pb->mode].pb_type_children[i].num_pb; + j++) { + if (pb->child_pbs[i] != NULL) { + if (pb->child_pbs[i][j].name != NULL) { + reload_intra_cluster_nets(&pb->child_pbs[i][j]); + } + } + } + } + } } /* Determine trace from logical_block output to logical_block inputs Algorithm traverses intra-block routing, goes to inter-block routing, then returns to intra-block routing */ static t_trace *alloc_and_load_final_routing_trace() { - int i; - int iblock; - t_trace* final_routing_trace; - t_pb_graph_pin *pin; + int i; + int iblock; + t_trace* final_routing_trace; + t_pb_graph_pin *pin; - final_routing_trace = (t_trace*) my_calloc(num_logical_nets, - sizeof(t_trace)); - for (i = 0; i < num_logical_nets; i++) { - iblock = logical_block[vpack_net[i].node_block[0]].clb_index; + final_routing_trace = (t_trace*) my_calloc(num_logical_nets, + sizeof(t_trace)); + for (i = 0; i < num_logical_nets; i++) { + iblock = logical_block[vpack_net[i].node_block[0]].clb_index; - final_routing_trace[i].iblock = iblock; - final_routing_trace[i].iswitch = OPEN; - final_routing_trace[i].index = OPEN; - final_routing_trace[i].next = NULL; + final_routing_trace[i].iblock = iblock; + final_routing_trace[i].iswitch = OPEN; + final_routing_trace[i].index = OPEN; + final_routing_trace[i].next = NULL; - pin = get_pb_graph_node_pin_from_vpack_net(i, 0); - if (!pin) - continue; - final_routing_trace[i].index = pin->pin_count_in_cluster; + pin = get_pb_graph_node_pin_from_vpack_net(i, 0); + if (!pin) + continue; + final_routing_trace[i].index = pin->pin_count_in_cluster; - expand_routing_trace(&final_routing_trace[i], i); - } + expand_routing_trace(&final_routing_trace[i], i); + } - return final_routing_trace; + return final_routing_trace; } /* Given a routing trace, expand until full trace is complete returns pointer to last terminal trace */ static t_trace *expand_routing_trace(t_trace *trace, int ivpack_net) { - int i, iblock, inode, ipin, inet; - int gridx, gridy; - t_trace *current, *new_trace, *inter_cb_trace; - t_rr_node *local_rr_graph; - boolean success; - t_pb_graph_pin *pb_graph_pin; + int i, iblock, inode, ipin, inet; + int gridx, gridy; + t_trace *current, *new_trace, *inter_cb_trace; + t_rr_node *local_rr_graph; + boolean success; + t_pb_graph_pin *pb_graph_pin; - iblock = trace->iblock; - inode = trace->index; - local_rr_graph = block[iblock].pb->rr_graph; - current = trace; + iblock = trace->iblock; + inode = trace->index; + local_rr_graph = block[iblock].pb->rr_graph; + current = trace; - if (local_rr_graph[inode].pb_graph_pin->num_output_edges == 0) { - if (local_rr_graph[inode].pb_graph_pin->port->type == OUT_PORT) { - /* connection to outside cb */ - if (vpack_net[ivpack_net].is_global) { - inet = vpack_to_clb_net_mapping[ivpack_net]; - if (inet != OPEN) { - for (ipin = 1; ipin <= clb_net[inet].num_sinks; ipin++) { - pb_graph_pin = get_pb_graph_node_pin_from_clb_net(inet, - ipin); - new_trace = (t_trace*) my_calloc(1, sizeof(t_trace)); - new_trace->iblock = clb_net[inet].node_block[ipin]; - new_trace->index = pb_graph_pin->pin_count_in_cluster; - new_trace->iswitch = OPEN; - new_trace->num_siblings = 0; - new_trace->next = NULL; - current->next = new_trace; - current = expand_routing_trace(new_trace, ivpack_net); - } - } - } else { - inter_cb_trace = - trace_head[vpack_to_clb_net_mapping[ivpack_net]]; - if (inter_cb_trace != NULL) { - inter_cb_trace = inter_cb_trace->next; /* skip source and go right to opin */ - } - while (inter_cb_trace != NULL) { - /* continue traversing inter cb trace */ - if (rr_node[inter_cb_trace->index].type != SINK) { - new_trace = (t_trace*) my_calloc(1, sizeof(t_trace)); - new_trace->iblock = OPEN; - new_trace->index = inter_cb_trace->index; - new_trace->iswitch = inter_cb_trace->iswitch; - new_trace->num_siblings = 0; - new_trace->next = NULL; - current->next = new_trace; - if (rr_node[inter_cb_trace->index].type == IPIN) { - current = current->next; - gridx = rr_node[new_trace->index].xlow; - gridy = rr_node[new_trace->index].ylow; - gridy = gridy - grid[gridx][gridy].offset; - new_trace = (t_trace*) my_calloc(1, - sizeof(t_trace)); - new_trace->iblock = - grid[gridx][gridy].blocks[rr_node[inter_cb_trace->index].z]; - new_trace->index = - rr_node[inter_cb_trace->index].pb_graph_pin->pin_count_in_cluster; - new_trace->iswitch = OPEN; - new_trace->num_siblings = 0; - new_trace->next = NULL; - current->next = new_trace; - current = expand_routing_trace(new_trace, - ivpack_net); - } else { - current = current->next; - } - } - inter_cb_trace = inter_cb_trace->next; - } - } - } - } else { - /* connection to another intra-cluster pin */ - current = trace; - success = FALSE; - for (i = 0; i < local_rr_graph[inode].num_edges; i++) { - if (local_rr_graph[local_rr_graph[inode].edges[i]].prev_node - == inode) { - if (success == FALSE) { - success = TRUE; - } else { - current->next = (t_trace*) my_calloc(1, sizeof(t_trace)); - current = current->next; - current->iblock = trace->iblock; - current->index = trace->index; - current->iswitch = trace->iswitch; - current->next = NULL; - } - new_trace = (t_trace*) my_calloc(1, sizeof(t_trace)); - new_trace->iblock = trace->iblock; - new_trace->index = local_rr_graph[inode].edges[i]; - new_trace->iswitch = OPEN; - new_trace->num_siblings = 0; - new_trace->next = NULL; - current->next = new_trace; - current = expand_routing_trace(new_trace, ivpack_net); - } - } - assert(success); - } - return current; + if (local_rr_graph[inode].pb_graph_pin->num_output_edges == 0) { + if (local_rr_graph[inode].pb_graph_pin->port->type == OUT_PORT) { + /* connection to outside cb */ + if (vpack_net[ivpack_net].is_global) { + inet = vpack_to_clb_net_mapping[ivpack_net]; + if (inet != OPEN) { + for (ipin = 1; ipin <= clb_net[inet].num_sinks; ipin++) { + pb_graph_pin = get_pb_graph_node_pin_from_clb_net(inet, + ipin); + new_trace = (t_trace*) my_calloc(1, sizeof(t_trace)); + new_trace->iblock = clb_net[inet].node_block[ipin]; + new_trace->index = pb_graph_pin->pin_count_in_cluster; + new_trace->iswitch = OPEN; + new_trace->num_siblings = 0; + new_trace->next = NULL; + current->next = new_trace; + current = expand_routing_trace(new_trace, ivpack_net); + } + } + } else { + inter_cb_trace = + trace_head[vpack_to_clb_net_mapping[ivpack_net]]; + if (inter_cb_trace != NULL) { + inter_cb_trace = inter_cb_trace->next; /* skip source and go right to opin */ + } + while (inter_cb_trace != NULL) { + /* continue traversing inter cb trace */ + if (rr_node[inter_cb_trace->index].type != SINK) { + new_trace = (t_trace*) my_calloc(1, sizeof(t_trace)); + new_trace->iblock = OPEN; + new_trace->index = inter_cb_trace->index; + new_trace->iswitch = inter_cb_trace->iswitch; + new_trace->num_siblings = 0; + new_trace->next = NULL; + current->next = new_trace; + if (rr_node[inter_cb_trace->index].type == IPIN) { + current = current->next; + gridx = rr_node[new_trace->index].xlow; + gridy = rr_node[new_trace->index].ylow; + gridy = gridy - grid[gridx][gridy].offset; + new_trace = (t_trace*) my_calloc(1, + sizeof(t_trace)); + new_trace->iblock = + grid[gridx][gridy].blocks[rr_node[inter_cb_trace->index].z]; + new_trace->index = + rr_node[inter_cb_trace->index].pb_graph_pin->pin_count_in_cluster; + new_trace->iswitch = OPEN; + new_trace->num_siblings = 0; + new_trace->next = NULL; + current->next = new_trace; + current = expand_routing_trace(new_trace, + ivpack_net); + } else { + current = current->next; + } + } + inter_cb_trace = inter_cb_trace->next; + } + } + } + } else { + /* connection to another intra-cluster pin */ + current = trace; + success = FALSE; + for (i = 0; i < local_rr_graph[inode].num_edges; i++) { + if (local_rr_graph[local_rr_graph[inode].edges[i]].prev_node + == inode) { + if (success == FALSE) { + success = TRUE; + } else { + current->next = (t_trace*) my_calloc(1, sizeof(t_trace)); + current = current->next; + current->iblock = trace->iblock; + current->index = trace->index; + current->iswitch = trace->iswitch; + current->next = NULL; + } + new_trace = (t_trace*) my_calloc(1, sizeof(t_trace)); + new_trace->iblock = trace->iblock; + new_trace->index = local_rr_graph[inode].edges[i]; + new_trace->iswitch = OPEN; + new_trace->num_siblings = 0; + new_trace->next = NULL; + current->next = new_trace; + current = expand_routing_trace(new_trace, ivpack_net); + } + } + assert(success); + } + return current; } static void print_complete_net_trace(t_trace* trace, const char *file_name) { - FILE *fp; - int iblock, inode, iprev_block; - t_trace *current; - t_rr_node *local_rr_graph; - const char *name_type[] = { "SOURCE", "SINK", "IPIN", "OPIN", "CHANX", - "CHANY", "INTRA_CLUSTER_EDGE" }; - int i; + FILE *fp; + int iblock, inode, iprev_block; + t_trace *current; + t_rr_node *local_rr_graph; + const char *name_type[] = { "SOURCE", "SINK", "IPIN", "OPIN", "CHANX", + "CHANY", "INTRA_CLUSTER_EDGE" }; + int i; - fp = my_fopen(file_name, "w", 0); + fp = my_fopen(file_name, "w", 0); - for (i = 0; i < num_logical_nets; i++) { - current = &trace[i]; - iprev_block = OPEN; + for (i = 0; i < num_logical_nets; i++) { + current = &trace[i]; + iprev_block = OPEN; - fprintf(fp, "Net %s (%d)\n\n", vpack_net[i].name, i); - while (current != NULL) { - iblock = current->iblock; - inode = current->index; - if (iblock != OPEN) { - if (iprev_block != iblock) { - iprev_block = iblock; - fprintf(fp, "Block %s (%d) (%d, %d, %d):\n", - block[iblock].name, iblock, block[iblock].x, - block[iblock].y, block[iblock].z); - } - local_rr_graph = block[iblock].pb->rr_graph; - fprintf(fp, "\tNode:\t%d\t%s[%d].%s[%d]", inode, - local_rr_graph[inode].pb_graph_pin->parent_node->pb_type->name, - local_rr_graph[inode].pb_graph_pin->parent_node->placement_index, - local_rr_graph[inode].pb_graph_pin->port->name, - local_rr_graph[inode].pb_graph_pin->pin_number); - } else { - fprintf(fp, "Node:\t%d\t%6s (%d,%d) ", inode, - name_type[(int) rr_node[inode].type], - rr_node[inode].xlow, rr_node[inode].ylow); + fprintf(fp, "Net %s (%d)\n\n", vpack_net[i].name, i); + while (current != NULL) { + iblock = current->iblock; + inode = current->index; + if (iblock != OPEN) { + if (iprev_block != iblock) { + iprev_block = iblock; + fprintf(fp, "Block %s (%d) (%d, %d, %d):\n", + block[iblock].name, iblock, block[iblock].x, + block[iblock].y, block[iblock].z); + } + local_rr_graph = block[iblock].pb->rr_graph; + fprintf(fp, "\tNode:\t%d\t%s[%d].%s[%d]", inode, + local_rr_graph[inode].pb_graph_pin->parent_node->pb_type->name, + local_rr_graph[inode].pb_graph_pin->parent_node->placement_index, + local_rr_graph[inode].pb_graph_pin->port->name, + local_rr_graph[inode].pb_graph_pin->pin_number); + } else { + fprintf(fp, "Node:\t%d\t%6s (%d,%d) ", inode, + name_type[(int) rr_node[inode].type], + rr_node[inode].xlow, rr_node[inode].ylow); - if ((rr_node[inode].xlow != rr_node[inode].xhigh) - || (rr_node[inode].ylow != rr_node[inode].yhigh)) - fprintf(fp, "to (%d,%d) ", rr_node[inode].xhigh, - rr_node[inode].yhigh); + if ((rr_node[inode].xlow != rr_node[inode].xhigh) + || (rr_node[inode].ylow != rr_node[inode].yhigh)) + fprintf(fp, "to (%d,%d) ", rr_node[inode].xhigh, + rr_node[inode].yhigh); - switch (rr_node[inode].type) { + switch (rr_node[inode].type) { - case IPIN: - case OPIN: - if (grid[rr_node[inode].xlow][rr_node[inode].ylow].type - == IO_TYPE) { - fprintf(fp, " Pad: "); - } else { /* IO Pad. */ - fprintf(fp, " Pin: "); - } - break; + case IPIN: + case OPIN: + if (grid[rr_node[inode].xlow][rr_node[inode].ylow].type + == IO_TYPE) { + fprintf(fp, " Pad: "); + } else { /* IO Pad. */ + fprintf(fp, " Pin: "); + } + break; - case CHANX: - case CHANY: - fprintf(fp, " Track: "); - break; + case CHANX: + case CHANY: + fprintf(fp, " Track: "); + break; - case SOURCE: - case SINK: - if (grid[rr_node[inode].xlow][rr_node[inode].ylow].type - == IO_TYPE) { - fprintf(fp, " Pad: "); - } else { /* IO Pad. */ - fprintf(fp, " Class: "); - } - break; + case SOURCE: + case SINK: + if (grid[rr_node[inode].xlow][rr_node[inode].ylow].type + == IO_TYPE) { + fprintf(fp, " Pad: "); + } else { /* IO Pad. */ + fprintf(fp, " Class: "); + } + break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "in print_route: Unexpected traceback element type: %d (%s).\n", - rr_node[inode].type, - name_type[rr_node[inode].type]); - exit(1); - break; - } + default: + vpr_printf(TIO_MESSAGE_ERROR, + "in print_route: Unexpected traceback element type: %d (%s).\n", + rr_node[inode].type, + name_type[rr_node[inode].type]); + exit(1); + break; + } - fprintf(fp, "%d ", rr_node[inode].ptc_num); + fprintf(fp, "%d ", rr_node[inode].ptc_num); - /* Uncomment line below if you're debugging and want to see the switch types * - * used in the routing. */ - /* fprintf (fp, "Switch: %d", tptr->iswitch); */ + /* Uncomment line below if you're debugging and want to see the switch types * + * used in the routing. */ + /* fprintf (fp, "Switch: %d", tptr->iswitch); */ - fprintf(fp, "\n"); - } - current = current->next; - } - fprintf(fp, "\n"); - } - fclose(fp); + fprintf(fp, "\n"); + } + current = current->next; + } + fprintf(fp, "\n"); + } + fclose(fp); } void resync_post_route_netlist() { - int i, j, iblock; - int gridx, gridy; - t_trace *trace; - for (i = 0; i < num_blocks; i++) { - for (j = 0; j < block[i].type->num_pins; j++) { - if (block[i].nets[j] != OPEN - && clb_net[block[i].nets[j]].is_global == FALSE) - block[i].nets[j] = OPEN; - } - } - for (i = 0; i < num_nets; i++) { - if (clb_net[i].is_global == TRUE) - continue; - j = 0; - trace = trace_head[i]; - while (trace != NULL) { - if (rr_node[trace->index].type == OPIN && j == 0) { - gridx = rr_node[trace->index].xlow; - gridy = rr_node[trace->index].ylow; - gridy = gridy - grid[gridx][gridy].offset; - iblock = grid[gridx][gridy].blocks[rr_node[trace->index].z]; - assert(clb_net[i].node_block[j] == iblock); - clb_net[i].node_block_pin[j] = rr_node[trace->index].ptc_num; - block[iblock].nets[rr_node[trace->index].ptc_num] = i; - j++; - } else if (rr_node[trace->index].type == IPIN) { - gridx = rr_node[trace->index].xlow; - gridy = rr_node[trace->index].ylow; - gridy = gridy - grid[gridx][gridy].offset; - iblock = grid[gridx][gridy].blocks[rr_node[trace->index].z]; - clb_net[i].node_block[j] = iblock; - clb_net[i].node_block_pin[j] = rr_node[trace->index].ptc_num; - block[iblock].nets[rr_node[trace->index].ptc_num] = i; - j++; - } - trace = trace->next; - } - assert(j == clb_net[i].num_sinks + 1); - } + int i, j, iblock; + int gridx, gridy; + t_trace *trace; + for (i = 0; i < num_blocks; i++) { + for (j = 0; j < block[i].type->num_pins; j++) { + if (block[i].nets[j] != OPEN + && clb_net[block[i].nets[j]].is_global == FALSE) + block[i].nets[j] = OPEN; + } + } + for (i = 0; i < num_nets; i++) { + if (clb_net[i].is_global == TRUE) + continue; + j = 0; + trace = trace_head[i]; + while (trace != NULL) { + if (rr_node[trace->index].type == OPIN && j == 0) { + gridx = rr_node[trace->index].xlow; + gridy = rr_node[trace->index].ylow; + gridy = gridy - grid[gridx][gridy].offset; + iblock = grid[gridx][gridy].blocks[rr_node[trace->index].z]; + assert(clb_net[i].node_block[j] == iblock); + clb_net[i].node_block_pin[j] = rr_node[trace->index].ptc_num; + block[iblock].nets[rr_node[trace->index].ptc_num] = i; + j++; + } else if (rr_node[trace->index].type == IPIN) { + gridx = rr_node[trace->index].xlow; + gridy = rr_node[trace->index].ylow; + gridy = gridy - grid[gridx][gridy].offset; + iblock = grid[gridx][gridy].blocks[rr_node[trace->index].z]; + clb_net[i].node_block[j] = iblock; + clb_net[i].node_block_pin[j] = rr_node[trace->index].ptc_num; + block[iblock].nets[rr_node[trace->index].ptc_num] = i; + j++; + } + trace = trace->next; + } + assert(j == clb_net[i].num_sinks + 1); + } } static void clay_logical_equivalence_handling(const t_arch *arch) { - t_trace **saved_ext_rr_trace_head, **saved_ext_rr_trace_tail; - t_rr_node *saved_ext_rr_node; - int num_ext_rr_node, num_ext_nets; - int i, j; + t_trace **saved_ext_rr_trace_head, **saved_ext_rr_trace_tail; + t_rr_node *saved_ext_rr_node; + int num_ext_rr_node, num_ext_nets; + int i, j; - for (i = 0; i < num_blocks; i++) { - clay_reload_ble_locations(i); - } + for (i = 0; i < num_blocks; i++) { + clay_reload_ble_locations(i); + } - /* Resolve logically equivalent inputs */ - saved_ext_rr_trace_head = trace_head; - saved_ext_rr_trace_tail = trace_tail; - saved_ext_rr_node = rr_node; - num_ext_rr_node = num_rr_nodes; - num_ext_nets = num_nets; - num_rr_nodes = 0; - rr_node = NULL; - trace_head = NULL; - trace_tail = NULL; - free_rr_graph(); /* free all data structures associated with rr_graph */ + /* Resolve logically equivalent inputs */ + saved_ext_rr_trace_head = trace_head; + saved_ext_rr_trace_tail = trace_tail; + saved_ext_rr_node = rr_node; + num_ext_rr_node = num_rr_nodes; + num_ext_nets = num_nets; + num_rr_nodes = 0; + rr_node = NULL; + trace_head = NULL; + trace_tail = NULL; + free_rr_graph(); /* free all data structures associated with rr_graph */ - alloc_and_load_cluster_legality_checker(); - for (i = 0; i < num_blocks; i++) { - /* Regenerate rr_graph (note, can be more runtime efficient but this allows for more code reuse) - */ - rr_node = block[i].pb->rr_graph; - num_rr_nodes = block[i].pb->pb_graph_node->total_pb_pins; - free_legalizer_for_cluster(&block[i], TRUE); - alloc_and_load_legalizer_for_cluster(&block[i], i, arch); - reload_intra_cluster_nets(block[i].pb); - reload_ext_net_rr_terminal_cluster(); - force_post_place_route_cb_input_pins(i); + alloc_and_load_cluster_legality_checker(); + for (i = 0; i < num_blocks; i++) { + /* Regenerate rr_graph (note, can be more runtime efficient but this allows for more code reuse) + */ + rr_node = block[i].pb->rr_graph; + num_rr_nodes = block[i].pb->pb_graph_node->total_pb_pins; + free_legalizer_for_cluster(&block[i], TRUE); + alloc_and_load_legalizer_for_cluster(&block[i], i, arch); + reload_intra_cluster_nets(block[i].pb); + reload_ext_net_rr_terminal_cluster(); + force_post_place_route_cb_input_pins(i); #ifdef HACK_LUT_PIN_SWAPPING - /* Resolve rebalancing of LUT inputs */ - clay_lut_input_rebalancing(i, block[i].pb); + /* Resolve rebalancing of LUT inputs */ + clay_lut_input_rebalancing(i, block[i].pb); #endif - /* reset rr_graph */ - for (j = 0; j < num_rr_nodes; j++) { - rr_node[j].occ = 0; - rr_node[j].prev_edge = OPEN; - rr_node[j].prev_node = OPEN; - } - if (try_breadth_first_route_cluster() == FALSE) { - vpr_printf(TIO_MESSAGE_ERROR, - "Failed to resync post routed solution with clustered netlist.\n"); - vpr_printf(TIO_MESSAGE_ERROR, "Cannot recover from error.\n"); - exit(1); - } - save_cluster_solution(); - reset_legalizer_for_cluster(&block[i]); - free_legalizer_for_cluster(&block[i], FALSE); - } - free_cluster_legality_checker(); + /* reset rr_graph */ + for (j = 0; j < num_rr_nodes; j++) { + rr_node[j].occ = 0; + rr_node[j].prev_edge = OPEN; + rr_node[j].prev_node = OPEN; + } + if (try_breadth_first_route_cluster() == FALSE) { + vpr_printf(TIO_MESSAGE_ERROR, + "Failed to resync post routed solution with clustered netlist.\n"); + vpr_printf(TIO_MESSAGE_ERROR, "Cannot recover from error.\n"); + exit(1); + } + save_cluster_solution(); + reset_legalizer_for_cluster(&block[i]); + free_legalizer_for_cluster(&block[i], FALSE); + } + free_cluster_legality_checker(); - trace_head = saved_ext_rr_trace_head; - trace_tail = saved_ext_rr_trace_tail; - rr_node = saved_ext_rr_node; - num_rr_nodes = num_ext_rr_node; - num_nets = num_ext_nets; + trace_head = saved_ext_rr_trace_head; + trace_tail = saved_ext_rr_trace_tail; + rr_node = saved_ext_rr_node; + num_rr_nodes = num_ext_rr_node; + num_nets = num_ext_nets; } /* Force router to use the LUT inputs designated by the timing engine post the LUT input rebalancing optimization */ static void clay_lut_input_rebalancing(int iblock, t_pb *pb) { - int i, j; - t_rr_node *local_rr_graph; - t_pb_graph_node *lut_wrapper, *lut; - int lut_size; - int *lut_pin_remap; - int snode, input; - t_pb_graph_node *pb_graph_node; + int i, j; + t_rr_node *local_rr_graph; + t_pb_graph_node *lut_wrapper, *lut; + int lut_size; + int *lut_pin_remap; + int snode, input; + t_pb_graph_node *pb_graph_node; - if (pb->name != NULL) { - pb_graph_node = pb->pb_graph_node; - if (pb_graph_node->pb_type->blif_model != NULL) { - lut_pin_remap = pb->lut_pin_remap; - if (lut_pin_remap != NULL) { - local_rr_graph = block[iblock].pb->rr_graph; - lut = pb->pb_graph_node; - lut_wrapper = lut->parent_pb_graph_node; + if (pb->name != NULL) { + pb_graph_node = pb->pb_graph_node; + if (pb_graph_node->pb_type->blif_model != NULL) { + lut_pin_remap = pb->lut_pin_remap; + if (lut_pin_remap != NULL) { + local_rr_graph = block[iblock].pb->rr_graph; + lut = pb->pb_graph_node; + lut_wrapper = lut->parent_pb_graph_node; - /* Ensure that this is actually a LUT */ - assert( - lut->num_input_ports == 1 && lut_wrapper->num_input_ports == 1); - assert( - lut->num_input_pins[0] == lut_wrapper->num_input_pins[0]); - assert( - lut->num_output_ports == 1 && lut_wrapper->num_output_ports == 1); - assert( - lut->num_output_pins[0] == 1 && lut_wrapper->num_output_pins[0] == 1); + /* Ensure that this is actually a LUT */ + assert( + lut->num_input_ports == 1 && lut_wrapper->num_input_ports == 1); + assert( + lut->num_input_pins[0] == lut_wrapper->num_input_pins[0]); + assert( + lut->num_output_ports == 1 && lut_wrapper->num_output_ports == 1); + assert( + lut->num_output_pins[0] == 1 && lut_wrapper->num_output_pins[0] == 1); - lut_size = lut->num_input_pins[0]; - for (i = 0; i < lut_size; i++) { - snode = lut_wrapper->input_pins[0][i].pin_count_in_cluster; - free(local_rr_graph[snode].edges); - local_rr_graph[snode].edges = NULL; - local_rr_graph[snode].num_edges = 0; - } - for (i = 0; i < lut_size; i++) { - input = lut_pin_remap[i]; - if (input != OPEN) { - snode = - lut_wrapper->input_pins[0][i].pin_count_in_cluster; - assert(local_rr_graph[snode].num_edges == 0); - local_rr_graph[snode].num_edges = 1; - local_rr_graph[snode].edges = (int*) my_malloc( - sizeof(int)); - local_rr_graph[snode].edges[0] = - lut->input_pins[0][input].pin_count_in_cluster; - } - } - } - } else if (pb->child_pbs != NULL) { - for (i = 0; - i - < pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children; - i++) { - if (pb->child_pbs[i] != NULL) { - for (j = 0; - j - < pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb; - j++) { - clay_lut_input_rebalancing(iblock, - &pb->child_pbs[i][j]); - } - } - } - } - } + lut_size = lut->num_input_pins[0]; + for (i = 0; i < lut_size; i++) { + snode = lut_wrapper->input_pins[0][i].pin_count_in_cluster; + free(local_rr_graph[snode].edges); + local_rr_graph[snode].edges = NULL; + local_rr_graph[snode].num_edges = 0; + } + for (i = 0; i < lut_size; i++) { + input = lut_pin_remap[i]; + if (input != OPEN) { + snode = + lut_wrapper->input_pins[0][i].pin_count_in_cluster; + assert(local_rr_graph[snode].num_edges == 0); + local_rr_graph[snode].num_edges = 1; + local_rr_graph[snode].edges = (int*) my_malloc( + sizeof(int)); + local_rr_graph[snode].edges[0] = + lut->input_pins[0][input].pin_count_in_cluster; + } + } + } + } else if (pb->child_pbs != NULL) { + for (i = 0; + i + < pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children; + i++) { + if (pb->child_pbs[i] != NULL) { + for (j = 0; + j + < pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb; + j++) { + clay_lut_input_rebalancing(iblock, + &pb->child_pbs[i][j]); + } + } + } + } + } } /* Swaps BLEs to match output logical equivalence solution from routing solution Assumes classical cluster with full crossbar and BLEs, each BLE is a single LUT+FF pair */ static void clay_reload_ble_locations(int iblock) { - int i, mode, ipin, new_loc; - t_pb_graph_node *pb_graph_node; - t_pb_graph_pin *pb_graph_pin; - const t_pb_type *pb_type; - t_trace *trace; - t_rr_node *local_rr_graph; - int inet, ivpack_net; + int i, mode, ipin, new_loc; + t_pb_graph_node *pb_graph_node; + t_pb_graph_pin *pb_graph_pin; + const t_pb_type *pb_type; + t_trace *trace; + t_rr_node *local_rr_graph; + int inet, ivpack_net; - if (block[iblock].type == IO_TYPE) { - return; - } + if (block[iblock].type == IO_TYPE) { + return; + } - pb_graph_node = block[iblock].pb->pb_graph_node; - pb_type = pb_graph_node->pb_type; - mode = block[iblock].pb->mode; - local_rr_graph = block[iblock].pb->rr_graph; + pb_graph_node = block[iblock].pb->pb_graph_node; + pb_type = pb_graph_node->pb_type; + mode = block[iblock].pb->mode; + local_rr_graph = block[iblock].pb->rr_graph; - assert(block[iblock].pb->mode == 0); - assert(pb_type->modes[mode].num_pb_type_children == 1); - assert(pb_type->modes[mode].pb_type_children[0].num_output_pins == 1); + assert(block[iblock].pb->mode == 0); + assert(pb_type->modes[mode].num_pb_type_children == 1); + assert(pb_type->modes[mode].pb_type_children[0].num_output_pins == 1); - t_pb** temp; - temp = (t_pb**) my_calloc(1, sizeof(t_pb*)); - temp[0] = (t_pb*) my_calloc(pb_type->modes[mode].pb_type_children[0].num_pb, - sizeof(t_pb)); + t_pb** temp; + temp = (t_pb**) my_calloc(1, sizeof(t_pb*)); + temp[0] = (t_pb*) my_calloc(pb_type->modes[mode].pb_type_children[0].num_pb, + sizeof(t_pb)); - /* determine new location for BLEs that route out of cluster */ - for (i = 0; i < pb_type->modes[mode].pb_type_children[0].num_pb; i++) { - if (block[iblock].pb->child_pbs[0][i].name != NULL) { - ivpack_net = - local_rr_graph[pb_graph_node->child_pb_graph_nodes[mode][0][i].output_pins[0][0].pin_count_in_cluster].net_num; - inet = vpack_to_clb_net_mapping[ivpack_net]; - if (inet != OPEN) { - ipin = OPEN; - trace = trace_head[inet]; - while (trace) { - if (rr_node[trace->index].type == OPIN) { - ipin = rr_node[trace->index].ptc_num; - break; - } - trace = trace->next; - } - assert(ipin); - pb_graph_pin = get_pb_graph_node_pin_from_block_pin(iblock, - ipin); - new_loc = pb_graph_pin->pin_number; - assert(temp[0][new_loc].name == NULL); - temp[0][new_loc] = block[iblock].pb->child_pbs[0][i]; - } - } - } + /* determine new location for BLEs that route out of cluster */ + for (i = 0; i < pb_type->modes[mode].pb_type_children[0].num_pb; i++) { + if (block[iblock].pb->child_pbs[0][i].name != NULL) { + ivpack_net = + local_rr_graph[pb_graph_node->child_pb_graph_nodes[mode][0][i].output_pins[0][0].pin_count_in_cluster].net_num; + inet = vpack_to_clb_net_mapping[ivpack_net]; + if (inet != OPEN) { + ipin = OPEN; + trace = trace_head[inet]; + while (trace) { + if (rr_node[trace->index].type == OPIN) { + ipin = rr_node[trace->index].ptc_num; + break; + } + trace = trace->next; + } + assert(ipin); + pb_graph_pin = get_pb_graph_node_pin_from_block_pin(iblock, + ipin); + new_loc = pb_graph_pin->pin_number; + assert(temp[0][new_loc].name == NULL); + temp[0][new_loc] = block[iblock].pb->child_pbs[0][i]; + } + } + } - /* determine new location for BLEs that do not route out of cluster */ - new_loc = 0; - for (i = 0; i < pb_type->modes[mode].pb_type_children[0].num_pb; i++) { - if (block[iblock].pb->child_pbs[0][i].name != NULL) { - ivpack_net = - local_rr_graph[pb_graph_node->child_pb_graph_nodes[mode][0][i].output_pins[0][0].pin_count_in_cluster].net_num; - inet = vpack_to_clb_net_mapping[ivpack_net]; - if (inet == OPEN) { - while (temp[0][new_loc].name != NULL) { - new_loc++; - } - temp[0][new_loc] = block[iblock].pb->child_pbs[0][i]; - } - } - } + /* determine new location for BLEs that do not route out of cluster */ + new_loc = 0; + for (i = 0; i < pb_type->modes[mode].pb_type_children[0].num_pb; i++) { + if (block[iblock].pb->child_pbs[0][i].name != NULL) { + ivpack_net = + local_rr_graph[pb_graph_node->child_pb_graph_nodes[mode][0][i].output_pins[0][0].pin_count_in_cluster].net_num; + inet = vpack_to_clb_net_mapping[ivpack_net]; + if (inet == OPEN) { + while (temp[0][new_loc].name != NULL) { + new_loc++; + } + temp[0][new_loc] = block[iblock].pb->child_pbs[0][i]; + } + } + } - free(block[iblock].pb->child_pbs); - block[iblock].pb->child_pbs = temp; - resync_pb_graph_nodes_in_pb(block[iblock].pb->pb_graph_node, - block[iblock].pb); + free(block[iblock].pb->child_pbs); + block[iblock].pb->child_pbs = temp; + resync_pb_graph_nodes_in_pb(block[iblock].pb->pb_graph_node, + block[iblock].pb); } static void resync_pb_graph_nodes_in_pb(t_pb_graph_node *pb_graph_node, - t_pb *pb) { - int i, j; + t_pb *pb) { + int i, j; - if (pb->name == NULL) { - return; - } + if (pb->name == NULL) { + return; + } - assert( - strcmp(pb->pb_graph_node->pb_type->name, pb_graph_node->pb_type->name) == 0); + assert( + strcmp(pb->pb_graph_node->pb_type->name, pb_graph_node->pb_type->name) == 0); - pb->pb_graph_node = pb_graph_node; - if (pb->child_pbs != NULL) { - for (i = 0; - i < pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children; - i++) { - if (pb->child_pbs[i] != NULL) { - for (j = 0; - j - < pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb; - j++) { - resync_pb_graph_nodes_in_pb( - &pb_graph_node->child_pb_graph_nodes[pb->mode][i][j], - &pb->child_pbs[i][j]); - } - } - } - } + pb->pb_graph_node = pb_graph_node; + if (pb->child_pbs != NULL) { + for (i = 0; + i < pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children; + i++) { + if (pb->child_pbs[i] != NULL) { + for (j = 0; + j + < pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb; + j++) { + resync_pb_graph_nodes_in_pb( + &pb_graph_node->child_pb_graph_nodes[pb->mode][i][j], + &pb->child_pbs[i][j]); + } + } + } + } } /* This function performs power estimation, and must be called @@ -1525,60 +1546,61 @@ static void resync_pb_graph_nodes_in_pb(t_pb_graph_node *pb_graph_node, * will not work when running a partial flow (ex. only routing). */ void vpr_power_estimation(t_vpr_setup vpr_setup, t_arch Arch) { - e_power_ret_code power_ret_code; - boolean power_error; + e_power_ret_code power_ret_code; + boolean power_error; - /* Ensure we are only using 1 clock */ - //assert(count_netlist_clocks() == 1); + /* Ensure we are only using 1 clock */ + //assert(count_netlist_clocks() == 1); - /* Get the critical path of this clock */ - g_solution_inf.T_crit = get_critical_path_delay() / 1e9; - assert(g_solution_inf.T_crit > 0.); + /* Get the critical path of this clock */ + g_solution_inf.T_crit = get_critical_path_delay() / 1e9; + assert(g_solution_inf.T_crit > 0.); - vpr_printf(TIO_MESSAGE_INFO, "\n\nPower Estimation:\n"); - vpr_printf(TIO_MESSAGE_INFO, "-----------------\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n\nPower Estimation:\n"); + vpr_printf(TIO_MESSAGE_INFO, "-----------------\n"); - vpr_printf(TIO_MESSAGE_INFO, "Initializing power module\n"); + vpr_printf(TIO_MESSAGE_INFO, "Initializing power module\n"); - /* Initialize the power module */ - power_error = power_init(vpr_setup.FileNameOpts.PowerFile, - vpr_setup.FileNameOpts.CmosTechFile, &Arch, &vpr_setup.RoutingArch); - if (power_error) { - vpr_printf(TIO_MESSAGE_ERROR, "Power initialization failed.\n"); - } + /* Initialize the power module */ + power_error = power_init(vpr_setup.FileNameOpts.PowerFile, + vpr_setup.FileNameOpts.CmosTechFile, &Arch, &vpr_setup.RoutingArch); + if (power_error) { + vpr_printf(TIO_MESSAGE_ERROR, "Power initialization failed.\n"); + } - if (!power_error) { - float power_runtime_s; + if (!power_error) { + float power_runtime_s; - vpr_printf(TIO_MESSAGE_INFO, "Running power estimation\n"); + vpr_printf(TIO_MESSAGE_INFO, "Running power estimation\n"); - /* Run power estimation */ - power_ret_code = power_total(&power_runtime_s, vpr_setup, &Arch, - &vpr_setup.RoutingArch); + /* Run power estimation */ + power_ret_code = power_total(&power_runtime_s, vpr_setup, &Arch, + &vpr_setup.RoutingArch); - /* Check for errors/warnings */ - if (power_ret_code == POWER_RET_CODE_ERRORS) { - vpr_printf(TIO_MESSAGE_ERROR, - "Power estimation failed. See power output for error details.\n"); - } else if (power_ret_code == POWER_RET_CODE_WARNINGS) { - vpr_printf(TIO_MESSAGE_WARNING, - "Power estimation completed with warnings. See power output for more details.\n"); - } else if (power_ret_code == POWER_RET_CODE_SUCCESS) { - } - vpr_printf(TIO_MESSAGE_INFO, "Power estimation took %g seconds\n", - power_runtime_s); - } + /* Check for errors/warnings */ + if (power_ret_code == POWER_RET_CODE_ERRORS) { + vpr_printf(TIO_MESSAGE_ERROR, + "Power estimation failed. See power output for error details.\n"); + } else if (power_ret_code == POWER_RET_CODE_WARNINGS) { + vpr_printf(TIO_MESSAGE_WARNING, + "Power estimation completed with warnings. See power output for more details.\n"); + } else if (power_ret_code == POWER_RET_CODE_SUCCESS) { + } + vpr_printf(TIO_MESSAGE_INFO, "Power estimation took %g seconds\n", + power_runtime_s); + } - /* Uninitialize power module */ - if (!power_error) { - vpr_printf(TIO_MESSAGE_INFO, "Uninitializing power module\n"); - power_error = power_uninit(); - if (power_error) { - vpr_printf(TIO_MESSAGE_ERROR, "Power uninitialization failed.\n"); - } else { + /* Uninitialize power module */ + if (!power_error) { + vpr_printf(TIO_MESSAGE_INFO, "Uninitializing power module\n"); + power_error = power_uninit(); + if (power_error) { + vpr_printf(TIO_MESSAGE_ERROR, "Power uninitialization failed.\n"); + } else { - } - } - vpr_printf(TIO_MESSAGE_INFO, "\n"); + } + } + vpr_printf(TIO_MESSAGE_INFO, "\n"); } + diff --git a/vpr7_x2p/vpr/SRC/base/vpr_api.h b/vpr7_x2p/vpr/SRC/base/vpr_api.h index 5ccadb5c6..f81694e49 100644 --- a/vpr7_x2p/vpr/SRC/base/vpr_api.h +++ b/vpr7_x2p/vpr/SRC/base/vpr_api.h @@ -102,6 +102,13 @@ t_trace* vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture( INP const t_arch *arch); /* FPGA-SPICE */ -#include "fpga_spice_api.h" +#include "fpga_x2p_api.h" + +/* mrFPGA : Xifan TANG */ +#include "mrfpga_api.h" +/* END */ + +/* APIs to be call by the interactive shell*/ +void vpr_init_file_handler() ; #endif diff --git a/vpr7_x2p/vpr/SRC/base/vpr_types.h b/vpr7_x2p/vpr/SRC/base/vpr_types.h index f1f21dece..aeea025db 100755 --- a/vpr7_x2p/vpr/SRC/base/vpr_types.h +++ b/vpr7_x2p/vpr/SRC/base/vpr_types.h @@ -201,6 +201,7 @@ typedef struct s_pb { /* Xifan TANG: SPICE model support*/ char* spice_name_tag; + void* phy_pb; /* Xifan TANG: FPGA-SPICE and SynVerilog */ int num_reserved_conf_bits; @@ -248,8 +249,7 @@ typedef struct s_logical_block { /* for Register/flip-flop */ char* trigger_type; int init_val; - /* To identify if this is a clock */ - int is_clock; + boolean is_clock; } t_logical_block; @@ -557,6 +557,7 @@ typedef struct s_grid_tile { /* Stores the bounding box of a net in terms of the minimum and * * maximum coordinates of the blocks forming the net, clipped to * * the region (1..nx, 1..ny). */ +typedef struct s_bb t_bb; struct s_bb { int xmin; int xmax; @@ -598,6 +599,11 @@ struct s_block { int** pin_prefer_side; /* [0..num_pins-1][0..3] */ t_pb *pb; + + /* Xifan TANG: FPGA-SPICE + * pb for physical model + */ + void* phy_pb; boolean isFixed; @@ -616,6 +622,8 @@ struct s_file_name_opts { char *PowerFile; char *CmosTechFile; char *out_file_prefix; + /* For shell-like interface */ + char *SDCFile; }; /* Options for packing @@ -881,7 +889,7 @@ typedef struct s_seg_details { * (UDSD by AY) drivers: How do signals driving a routing track connect to * * the track? * * index: index of the segment type used for this track. */ - +typedef struct s_linked_f_pointer t_linked_f_pointer; struct s_linked_f_pointer { struct s_linked_f_pointer *next; float *fptr; @@ -966,6 +974,7 @@ struct s_rr_node { int* drive_switches; /* Xifan TANG: for parasitic net estimation */ boolean vpack_net_num_changed; + boolean is_parasitic_net; /* Xifan TANG: pb_pin_eq_auto_detect support */ boolean is_in_heap; /* SPECIAL: For switch box muxes */ @@ -973,6 +982,9 @@ struct s_rr_node { t_rr_node** sb_drive_rr_nodes; int* sb_drive_switches; t_pb* pb; + /* BC: Supports SDC for SBs/CBs. PBs use the one inside of the pb_graph*/ + char* name_mux; + int id_path; // int seg_index; /* Valid only for CHANX or CHANY*/ /* END */ @@ -1182,25 +1194,27 @@ struct s_cb { typedef struct s_spice_opts t_spice_opts; struct s_spice_opts { boolean do_spice; - boolean spice_print_top_testbench; - boolean spice_print_grid_testbench; - boolean spice_print_cb_testbench; - boolean spice_print_sb_testbench; - boolean spice_print_pb_mux_testbench; - boolean spice_print_cb_mux_testbench; - boolean spice_print_sb_mux_testbench; - boolean spice_print_lut_testbench; - boolean spice_print_hardlogic_testbench; + boolean fpga_spice_print_top_testbench; + boolean fpga_spice_print_grid_testbench; + boolean fpga_spice_print_cb_testbench; + boolean fpga_spice_print_sb_testbench; + boolean fpga_spice_print_pb_mux_testbench; + boolean fpga_spice_print_cb_mux_testbench; + boolean fpga_spice_print_sb_mux_testbench; + boolean fpga_spice_print_lut_testbench; + boolean fpga_spice_print_hardlogic_testbench; + boolean fpga_spice_print_io_testbench; boolean fpga_spice_leakage_only; - boolean fpga_spice_parasitic_net_estimation_off; - boolean fpga_spice_testbench_load_extraction_off; + boolean fpga_spice_parasitic_net_estimation; + boolean fpga_spice_testbench_load_extraction; /*Xifan TANG: FPGA SPICE Model Support*/ char* spice_dir; char* include_dir; char* subckt_dir; - int spice_sim_multi_thread_num; + int fpga_spice_sim_multi_thread_num; + char* simulator_path; }; /* Xifan TANG: synthesizable verilog dumping */ @@ -1208,15 +1222,28 @@ typedef struct s_syn_verilog_opts t_syn_verilog_opts; struct s_syn_verilog_opts { boolean dump_syn_verilog; char* syn_verilog_dump_dir; - boolean print_top_tb; - boolean print_top_auto_tb; - char* verilog_benchmark_file; - boolean print_input_blif_tb; - boolean tb_serial_config_mode; + boolean print_top_testbench; + boolean print_input_blif_testbench; + boolean print_formal_verification_top_netlist; boolean include_timing; - boolean init_sim; + boolean include_signal_init; + boolean include_icarus_simulator; boolean print_modelsim_autodeck; char* modelsim_ini_path; + char* report_timing_path; + boolean print_user_defined_template; + boolean print_autocheck_top_testbench; + char* reference_verilog_benchmark_file; + boolean print_report_timing_tcl; + boolean print_sdc_pnr; + boolean print_sdc_analysis; +}; + +/* Xifan TANG: bitstream generator */ +typedef struct s_bitstream_gen_opts t_bitstream_gen_opts; +struct s_bitstream_gen_opts { + boolean gen_bitstream; + char* bitstream_output_file; }; typedef struct s_fpga_spice_opts t_fpga_spice_opts; @@ -1226,6 +1253,7 @@ struct s_fpga_spice_opts { boolean rename_illegal_port; /* Rename illegal port names that is not compatible with verilog/SPICE syntax */ t_spice_opts SpiceOpts; /* Xifan TANG: SPICE Support*/ t_syn_verilog_opts SynVerilogOpts; /* Xifan TANG: Synthesizable verilog dumping*/ + t_bitstream_gen_opts BitstreamGenOpts; /* Xifan Bitsteam Generator */ /* Signal Density */ float signal_density_weight; diff --git a/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh b/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh old mode 100644 new mode 100755 index bcfd81a63..c12803ba1 --- a/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh +++ b/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh @@ -1 +1,2 @@ -ctags -R . ../../libarchfpga/include/*.[ch] ../../libarchfpga/fpga_spice_include/*.[ch] ../../libarchfpga/*.[ch] +rm tags +ctags -R shell_main.c main.c ./* ../../libarchfpga/include/*.[ch] ../../libarchfpga/fpga_spice_include/*.[ch] ../../libarchfpga/*.[ch] ../../pcre/SRC/*.[ch] diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.h b/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.h deleted file mode 100644 index 37a3986d8..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.h +++ /dev/null @@ -1,5 +0,0 @@ - - -void vpr_fpga_spice_tool_suites(t_vpr_setup vpr_setup, - t_arch Arch); - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.h b/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.h deleted file mode 100644 index ac43b1881..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.h +++ /dev/null @@ -1,7 +0,0 @@ - -void encode_decoder_addr(int input, - int decoder_size, char* addr); - -void dump_fpga_spice_bitstream(char* bitstream_file_name, - char* circuit_name, - t_sram_orgz_info* cur_sram_orgz_info); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.c b/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.c deleted file mode 100644 index c42c9dc0a..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.c +++ /dev/null @@ -1,7698 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph_util.h" -#include "rr_graph.h" -#include "rr_graph2.h" -#include "vpr_utils.h" - -/* Include SPICE support headers*/ -#include "quicksort.h" -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_timing_utils.h" -#include "token.h" - -enum e_dir_err { - E_DIR_NOT_EXIST, - E_EXIST_BUT_NOT_DIR, - E_DIR_EXIST -}; - -/***** Subroutines *****/ -char* my_gettime() { - time_t current_time; - char* c_time_string; - - /* Obtain current time as seconds elapsed since the Epoch*/ - current_time = time(NULL); - - if (current_time == ((time_t)-1)) { - vpr_printf(TIO_MESSAGE_ERROR,"Failure to compute the current time.\n"); - exit(1); - } - - /* Convert to local time format*/ - c_time_string = ctime(¤t_time); - if (NULL == c_time_string) { - vpr_printf(TIO_MESSAGE_ERROR,"Failure to convert the current time.\n"); - exit(1); - } - /* Return it*/ - return c_time_string; -} - -char* format_dir_path(char* dir_path) { - int len = strlen(dir_path); /* String length without the last "\0"*/ - int i; - char* ret = (char*)my_malloc(sizeof(char)*(len+2)); - - strcpy(ret,dir_path); - /* Replace all the "\" to "/"*/ - for (i=0; i -1; i--) { - if (split_token == local_copy[i]) { - split_pos = i; - break; - } - } - - /* Get the path and prog_name*/ - if (-1 == split_pos) { - /* In this case, the prog_path actually contains only the program name*/ - path = my_strdup("./"); - prog_name = my_strdup(local_copy); - } else if (len == split_pos) { - /* In this case the progrom name is NULL... actually the prog_path is a directory*/ - path = my_strdup(local_copy); - prog_name = NULL; - } else { - /* We have to split it!*/ - local_copy[split_pos] = '\0'; - path = my_strdup(local_copy); - prog_name = my_strdup(local_copy + split_pos + 1); - } - - /*Copy it to the return*/ - (*ret_path) = my_strdup(path); - (*ret_prog_name) = my_strdup(prog_name); - - /* Free useless resources */ - my_free(local_copy); - my_free(path); - my_free(prog_name); - - return 1; -} - -char* chomp_file_name_postfix(char* file_name) { - char* ret = NULL; - char* postfix = NULL; - - split_path_prog_name(file_name, '.', &ret, &postfix); - - my_free(postfix); - - return ret; -} - - -/* Print SRAM bits, typically in a comment line */ -void fprint_commented_sram_bits(FILE* fp, - int num_sram_bits, int* sram_bits) { - int i; - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d]) FileHandle is NULL!\n",__FILE__,__LINE__); - exit(1); - } - - for (i = 0; i < num_sram_bits; i++) { - fprintf(fp, "%d", sram_bits[i]); - } - - return; -} - - -/* With a given spice_model_name, find the spice model and return its pointer - * If we find nothing, return NULL - */ -t_spice_model* find_name_matched_spice_model(char* spice_model_name, - int num_spice_model, - t_spice_model* spice_models) { - t_spice_model* ret = NULL; - int imodel; - int num_found = 0; - - for (imodel = 0; imodel < num_spice_model; imodel++) { - if (0 == strcmp(spice_model_name, spice_models[imodel].name)) { - ret = &(spice_models[imodel]); - num_found++; - } - } - - if (0 == num_found) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d])Fail to find a spice model match name: %s !\n", - __FILE__ ,__LINE__, spice_model_name); - exit(1); - } - - assert(1 == num_found); - - return ret; -} - -/* Get the default spice_model*/ -t_spice_model* get_default_spice_model(enum e_spice_model_type default_spice_model_type, - int num_spice_model, - t_spice_model* spice_models) { - t_spice_model* ret = NULL; - int i; - - for (i = 0; i < num_spice_model; i++) { - /* Find a MUX and it is set as default*/ - if ((default_spice_model_type == spice_models[i].type)&&(1 == spice_models[i].is_default)) { - /* Check if we have multiple default*/ - if (NULL != ret) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d])Both SPICE model(%s and %s) are set as default!\n", - __FILE__, __LINE__, ret->name, spice_models[i].name); - exit(1); - } else { - ret = &(spice_models[i]); - } - } - } - - return ret; -} - -/* Tasks: - * 1. Search the inv_spice_model_name of each ports of a spice_model - * 2. Copy the information from inverter spice model to higher level spice_models - */ -void config_spice_model_port_inv_spice_model(int num_spice_models, - t_spice_model* spice_model) { - int i, iport; - t_spice_model* inv_spice_model = NULL; - - for (i = 0; i < num_spice_models; i++) { - /* By pass inverters and buffers */ - if (SPICE_MODEL_INVBUF == spice_model[i].type) { - continue; - } - for (iport = 0; iport < spice_model[i].num_port; iport++) { - /* Now we bypass non BL/WL ports */ - if ((SPICE_MODEL_PORT_BL != spice_model[i].ports[iport].type) - && (SPICE_MODEL_PORT_BLB != spice_model[i].ports[iport].type) - && (SPICE_MODEL_PORT_WL != spice_model[i].ports[iport].type) - && (SPICE_MODEL_PORT_WLB != spice_model[i].ports[iport].type)) { - continue; - } - if (NULL == spice_model[i].ports[iport].inv_spice_model_name) { - inv_spice_model = get_default_spice_model(SPICE_MODEL_INVBUF, - num_spice_models, spice_model); - } else { - inv_spice_model = find_name_matched_spice_model(spice_model[i].ports[iport].inv_spice_model_name, - num_spice_models, spice_model); - /* We should find a buffer spice_model*/ - if (NULL == inv_spice_model) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find inv_spice_model to the port(name=%s) of spice_model(name=%s)!\n", - __FILE__, __LINE__, spice_model[i].ports[iport].prefix, spice_model[i].name); - exit(1); - } - } - /* Config */ - spice_model[i].ports[iport].inv_spice_model = inv_spice_model; - } - } - return; -} - - /* Find a spice model port by given name */ - t_spice_model_port* find_spice_model_port_by_name(t_spice_model* cur_spice_model, - char* port_name) { - int iport; - t_spice_model_port* port = NULL; - int cnt = 0; - - for (iport = 0; iport < cur_spice_model->num_port; iport++) { - if (0 == strcmp(cur_spice_model->ports[iport].prefix, port_name)) { - port = &(cur_spice_model->ports[iport]); - cnt++; - } - } - - assert ((0 == cnt) || (1 == cnt)); - - return port; - } - - -/* Tasks: - * 1. Search the spice_model_name of input and output buffer and link to the spice_model - * 2. Copy the information from input/output buffer spice model to higher level spice_models - */ -void config_spice_model_input_output_buffers_pass_gate(int num_spice_models, - t_spice_model* spice_model) { - int i; - t_spice_model* buf_spice_model = NULL; - t_spice_model* pgl_spice_model = NULL; - - for (i = 0; i < num_spice_models; i++) { - /* By pass inverters and buffers */ - if (SPICE_MODEL_INVBUF == spice_model[i].type) { - continue; - } - - /* Check if this spice model has input buffers */ - if (1 == spice_model[i].input_buffer->exist) { - buf_spice_model = find_name_matched_spice_model(spice_model[i].input_buffer->spice_model_name, - num_spice_models, spice_model); - /* We should find a buffer spice_model*/ - if (NULL == buf_spice_model) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find inv/buffer spice_model to the input buffer of spice_model(name=%s)!\n", - __FILE__, __LINE__, spice_model[i].name); - exit(1); - } - /* Copy the information from found spice model to current spice model*/ - memcpy(spice_model[i].input_buffer, buf_spice_model->design_tech_info.buffer_info, sizeof(t_spice_model_buffer)); - /* Recover the spice_model_name and exist */ - spice_model[i].input_buffer->exist = 1; - spice_model[i].input_buffer->spice_model_name = my_strdup(buf_spice_model->name); - spice_model[i].input_buffer->spice_model = buf_spice_model; - } - - /* Check if this spice model has output buffers */ - if (1 == spice_model[i].output_buffer->exist) { - buf_spice_model = find_name_matched_spice_model(spice_model[i].output_buffer->spice_model_name, - num_spice_models, spice_model); - /* We should find a buffer spice_model*/ - if (NULL == buf_spice_model) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find inv/buffer spice_model to the output buffer of spice_model(name=%s)!\n", - __FILE__, __LINE__, spice_model[i].name); - exit(1); - } - /* Copy the information from found spice model to current spice model*/ - memcpy(spice_model[i].output_buffer, buf_spice_model->design_tech_info.buffer_info, sizeof(t_spice_model_buffer)); - /* Recover the spice_model_name and exist */ - spice_model[i].output_buffer->exist = 1; - spice_model[i].output_buffer->spice_model_name = my_strdup(buf_spice_model->name); - spice_model[i].output_buffer->spice_model = buf_spice_model; - } - - /* If this spice_model is a LUT, check the lut_input_buffer */ - if (SPICE_MODEL_LUT == spice_model[i].type) { - assert(1 == spice_model[i].lut_input_buffer->exist); - - buf_spice_model = find_name_matched_spice_model(spice_model[i].lut_input_buffer->spice_model_name, - num_spice_models, spice_model); - - /* We should find a buffer spice_model*/ - if (NULL == buf_spice_model) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find inv/buffer spice_model to the lut_input buffer of spice_model(name=%s)!\n", - __FILE__, __LINE__, spice_model[i].name); - exit(1); - } - /* Copy the information from found spice model to current spice model*/ - memcpy(spice_model[i].lut_input_buffer, buf_spice_model->design_tech_info.buffer_info, sizeof(t_spice_model_buffer)); - /* Recover the spice_model_name and exist */ - spice_model[i].lut_input_buffer->exist = 1; - spice_model[i].lut_input_buffer->spice_model_name = my_strdup(buf_spice_model->name); - spice_model[i].lut_input_buffer->spice_model = buf_spice_model; - } - - /* Check pass_gate logic only for LUT and MUX */ - if ((SPICE_MODEL_LUT == spice_model[i].type) - ||(SPICE_MODEL_MUX == spice_model[i].type)) { - pgl_spice_model = find_name_matched_spice_model(spice_model[i].pass_gate_logic->spice_model_name, - num_spice_models, spice_model); - /* We should find a buffer spice_model*/ - if (NULL == pgl_spice_model) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find pass_gate spice_model to the pass_gate_logic of spice_model(name=%s)!\n", - __FILE__, __LINE__, spice_model[i].name); - exit(1); - } - /* Copy the information from found spice model to current spice model*/ - memcpy(spice_model[i].pass_gate_logic, pgl_spice_model->design_tech_info.pass_gate_info, sizeof(t_spice_model_pass_gate_logic)); - /* Recover the spice_model_name */ - spice_model[i].pass_gate_logic->spice_model_name = my_strdup(pgl_spice_model->name); - spice_model[i].pass_gate_logic->spice_model = pgl_spice_model; - } - } - - return; -} - -/* Return the SPICE model ports wanted - * ATTENTION: we use the pointer of spice model here although we don't modify anything of spice_model - * but we have return input ports, whose pointer will be lost if the input is not the pointor of spice_model - * BECAUSE spice_model will be a local copy if it is not a pointer. And it will be set free when this function - * finishes. So the return pointers become invalid ! - */ -t_spice_model_port** find_spice_model_ports(t_spice_model* spice_model, - enum e_spice_model_port_type port_type, - int* port_num, boolean ignore_global_port) { - int iport, cur; - t_spice_model_port** ret = NULL; - - /* Check codes*/ - assert(NULL != port_num); - assert(NULL != spice_model); - - /* Count the number of ports that match*/ - (*port_num) = 0; - for (iport = 0; iport < spice_model->num_port; iport++) { - /* ignore global port if user specified */ - if ((TRUE == ignore_global_port) - &&(TRUE == spice_model->ports[iport].is_global)) { - continue; - } - if (port_type == spice_model->ports[iport].type) { - (*port_num)++; - } - } - - /* Initial the return pointers*/ - ret = (t_spice_model_port**)my_malloc(sizeof(t_spice_model_port*)*(*port_num)); - memset(ret, 0 , sizeof(t_spice_model_port*)*(*port_num)); - - /* Fill the return pointers*/ - cur = 0; - for (iport = 0; iport < spice_model->num_port; iport++) { - /* ignore global port if user specified */ - if ((TRUE == ignore_global_port) - &&(TRUE == spice_model->ports[iport].is_global)) { - continue; - } - if (port_type == spice_model->ports[iport].type) { - ret[cur] = &(spice_model->ports[iport]); - cur++; - } - } - /* Check correctness*/ - assert(cur == (*port_num)); - - return ret; -} - -/* Find the configure done ports */ -t_spice_model_port** find_spice_model_config_done_ports(t_spice_model* spice_model, - enum e_spice_model_port_type port_type, - int* port_num, boolean ignore_global_port) { - int iport, cur; - t_spice_model_port** ret = NULL; - - /* Check codes*/ - assert(NULL != port_num); - assert(NULL != spice_model); - - /* Count the number of ports that match*/ - (*port_num) = 0; - for (iport = 0; iport < spice_model->num_port; iport++) { - /* ignore global port if user specified */ - if ((TRUE == ignore_global_port) - &&(TRUE == spice_model->ports[iport].is_global)) { - continue; - } - if ((port_type == spice_model->ports[iport].type) - &&(TRUE == spice_model->ports[iport].is_config_enable)) { - (*port_num)++; - } - } - - /* Initial the return pointers*/ - ret = (t_spice_model_port**)my_malloc(sizeof(t_spice_model_port*)*(*port_num)); - memset(ret, 0 , sizeof(t_spice_model_port*)*(*port_num)); - - /* Fill the return pointers*/ - cur = 0; - for (iport = 0; iport < spice_model->num_port; iport++) { - /* ignore global port if user specified */ - if ((TRUE == ignore_global_port) - &&(TRUE == spice_model->ports[iport].is_global)) { - continue; - } - if ((port_type == spice_model->ports[iport].type) - &&(TRUE == spice_model->ports[iport].is_config_enable)) { - ret[cur] = &(spice_model->ports[iport]); - cur++; - } - } - /* Check correctness*/ - assert(cur == (*port_num)); - - return ret; -} - -/* Find the transistor in the tech lib*/ -t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib, - e_spice_trans_type trans_type) { - /* If we did not find return NULL*/ - t_spice_transistor_type* ret = NULL; - int i; - - for (i = 0; i < tech_lib.num_transistor_type; i++) { - if (trans_type == tech_lib.transistor_types[i].type) { - ret = &(tech_lib.transistor_types[i]); - break; - } - } - - return ret; -} - -/* Convert a integer to a string*/ -char* my_itoa(int input) { - char* ret = NULL; - int sign = 0; - int len = 0; - int temp = input; - int cur; - char end_of_str; - - /* Identify input number is positive or negative*/ - if (input < 0) { - sign = 1; /* sign will be '-'*/ - len = 1; - temp = 0 - input; - } else if (0 == input) { - sign = 0; - len = 2; - /* Alloc*/ - ret = (char*)my_malloc(sizeof(char)*len); - /* Lets get the end_of_str, the char is dependent on OS*/ - sprintf(ret,"%s","0"); - return ret; - } - /* Identify the length of string*/ - while(temp > 0) { - len++; - temp = temp/10; - } - /* Total length of string should include '\0' at the end*/ - len = len + 1; - /* Alloc*/ - ret = (char*)my_malloc(sizeof(char)*len); - - /*Fill it*/ - temp = input; - /* Lets get the end_of_str, the char is dependent on OS*/ - sprintf(ret,"%s","-"); - end_of_str = ret[1]; - ret[len-1] = end_of_str; - cur = len - 2; - /* Print the number reversely*/ - while(temp > 0) { - ret[cur] = temp%10 + '0'; /* ASIC II base is '0'*/ - cur--; - temp = temp/10; - } - /* Print the sign*/ - if (1 == sign) { - assert(0 == cur); - ret[cur] = '-'; - temp = 0 - input; - } else { - assert(-1 == cur); - } - - return ret; -} - -/* Generate a filename (string) for a grid subckt SPICE netlist, - * with given x and y coordinates - */ -char* fpga_spice_create_one_subckt_filename(char* file_name_prefix, - int subckt_x, int subckt_y, - char* file_name_postfix) { - char* fname = NULL; - - fname = (char*) my_malloc(sizeof(char) * (strlen(file_name_prefix) - + strlen(my_itoa(subckt_x)) + strlen(my_itoa(subckt_y)) - + strlen(file_name_postfix) + 1)); - - sprintf(fname, "%s%d_%d%s", - file_name_prefix, subckt_x, subckt_y, file_name_postfix); - - return fname; -} - - -/* With given spice_model_port, find the pb_type port with same name and type*/ -t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, - t_spice_model_port* spice_model_port) { - int iport; - t_port* ret = NULL; - - /* Search ports */ - for (iport = 0; iport < pb_type->num_ports; iport++) { - /* Match the name and port size*/ - if ((0 == strcmp(pb_type->ports[iport].name, spice_model_port->prefix)) - &&(pb_type->ports[iport].num_pins == spice_model_port->size)) { - /* Match the type*/ - switch (spice_model_port->type) { - case SPICE_MODEL_PORT_INPUT: - if ((IN_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - if (NULL != ret) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", - __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); - exit(1); - } - ret = &(pb_type->ports[iport]); - } - break; - case SPICE_MODEL_PORT_OUTPUT: - if (OUT_PORT == pb_type->ports[iport].type) { - if (NULL != ret) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", - __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); - exit(1); - } - ret = &(pb_type->ports[iport]); - } - break; - case SPICE_MODEL_PORT_CLOCK: - if ((IN_PORT == pb_type->ports[iport].type)&&(1 == pb_type->ports[iport].is_clock)) { - if (NULL != ret) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", - __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); - exit(1); - } - ret = &(pb_type->ports[iport]); - } - break; - case SPICE_MODEL_PORT_INOUT : - if ((INOUT_PORT == pb_type->ports[iport].type)&&(0 == pb_type->ports[iport].is_clock)) { - if (NULL != ret) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", - __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); - exit(1); - } - ret = &(pb_type->ports[iport]); - } - break; - case SPICE_MODEL_PORT_SRAM: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for spice_model_port(%s)!\n", - __FILE__, __LINE__, spice_model_port->prefix); - exit(1); - } - } - } - - return ret; -} - -char* chomp_spice_node_prefix(char* spice_node_prefix) { - int len = 0; - char* ret = NULL; - - if (NULL == spice_node_prefix) { - return NULL; - } - - len = strlen(spice_node_prefix); /* String length without the last "\0"*/ - ret = (char*)my_malloc(sizeof(char)*(len+2)); - - /* Don't do anything when input is NULL*/ - if (NULL == spice_node_prefix) { - my_free(ret); - return NULL; - } - - strcpy(ret,spice_node_prefix); - /* If the path end up with "_" we should remove it*/ - if ('_' == ret[len-1]) { - ret[len-1] = ret[len]; - } - - return ret; -} - -char* format_spice_node_prefix(char* spice_node_prefix) { - int len = strlen(spice_node_prefix); /* String length without the last "\0"*/ - char* ret = (char*)my_malloc(sizeof(char)*(len+2)); - - /* Don't do anything when input is NULL*/ - if (NULL == spice_node_prefix) { - my_free(ret); - return NULL; - } - - strcpy(ret,spice_node_prefix); - /* If the path does not end up with "_" we should complete it*/ - if (ret[len-1] != '_') { - strcat(ret, "_"); - } - return ret; -} - -t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type, - enum e_spice_model_port_type port_type, - int* port_num) { - int iport, cur; - t_port** ret = NULL; - - /* Check codes*/ - assert(NULL != port_num); - assert(NULL != pb_type); - - /* Count the number of ports that match*/ - (*port_num) = 0; - for (iport = 0; iport < pb_type->num_ports; iport++) { - switch (port_type) { - case SPICE_MODEL_PORT_INPUT: /* TODO: support is_non_clock_global*/ - if ((IN_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - (*port_num)++; - } - break; - case SPICE_MODEL_PORT_OUTPUT: - if ((OUT_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - (*port_num)++; - } - break; - case SPICE_MODEL_PORT_INOUT: - if ((INOUT_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - (*port_num)++; - } - break; - case SPICE_MODEL_PORT_CLOCK: - if ((IN_PORT == pb_type->ports[iport].type) - &&(1 == pb_type->ports[iport].is_clock)) { - (*port_num)++; - } - break; - case SPICE_MODEL_PORT_SRAM: - /* Original VPR don't support this*/ - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for port!\n", - __FILE__, __LINE__); - exit(1); - } - } - - /* Initial the return pointers*/ - ret = (t_port**)my_malloc(sizeof(t_port*)*(*port_num)); - memset(ret, 0 , sizeof(t_port*)*(*port_num)); - - /* Fill the return pointers*/ - cur = 0; - - for (iport = 0; iport < pb_type->num_ports; iport++) { - switch (port_type) { - case SPICE_MODEL_PORT_INPUT : /* TODO: support is_non_clock_global*/ - if ((IN_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - ret[cur] = &(pb_type->ports[iport]); - cur++; - } - break; - case SPICE_MODEL_PORT_OUTPUT: - if ((OUT_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - ret[cur] = &(pb_type->ports[iport]); - cur++; - } - break; - case SPICE_MODEL_PORT_INOUT: - if ((INOUT_PORT == pb_type->ports[iport].type) - &&(0 == pb_type->ports[iport].is_clock)) { - ret[cur] = &(pb_type->ports[iport]); - cur++; - } - break; - case SPICE_MODEL_PORT_CLOCK: - if ((IN_PORT == pb_type->ports[iport].type) - &&(1 == pb_type->ports[iport].is_clock)) { - ret[cur] = &(pb_type->ports[iport]); - cur++; - } - break; - case SPICE_MODEL_PORT_SRAM: - /* Original VPR don't support this*/ - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for port!\n", - __FILE__, __LINE__); - exit(1); - } - } - - /* Check correctness*/ - assert(cur == (*port_num)); - - return ret; -} - -/* Given the co-ordinators of grid, - * Find if there is a block mapped into this grid - */ -t_block* search_mapped_block(int x, int y, int z) { - t_block* ret = NULL; - int iblk = 0; - - /*Valid pointors*/ - assert(NULL != grid); - assert((0 < x)||(0 == x)); - assert((x < (nx + 1))||(x == (nx + 1))); - assert((0 < y)||(0 == y)); - assert((x < (ny + 1))||(x == (ny + 1))); - - /* Search all blocks*/ - for (iblk = 0; iblk < num_blocks; iblk++) { - if ((x == block[iblk].x)&&(y == block[iblk].y)&&(z == block[iblk].z)) { - /* Matched cordinators*/ - ret = &(block[iblk]); - /* Check */ - assert(block[iblk].type == grid[x][y].type); - assert(z < grid[x][y].type->capacity); - assert(0 < grid[x][y].usage); - } - } - - return ret; -} - - - - -/* Change the decimal number to binary - * and return a array of integer*/ -int* my_decimal2binary(int decimal, - int* binary_len) { - int* ret = NULL; - int i = 0; - int code = decimal; - - (*binary_len) = 0; - - while (0 < code) { - (*binary_len)++; - code = code/2; - } - - i = (*binary_len) - 1; - while (0 < code) { - ret[i] = code%2; - i--; - code = code/2; - } - - return ret; -} - -/* Determine the number of SRAM bit for a basis subckt of a multiplexer - * In general, the number of SRAM bits should be same as the number of inputs per level - * with one exception: - * When multiplexing structure is tree-like, there should be only 1 SRAM bit - */ -int determine_num_sram_bits_mux_basis_subckt(t_spice_model* mux_spice_model, - int mux_size, - int num_input_per_level, - boolean special_basis) { - int num_sram_bits; - - /* General cases */ - switch (mux_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - num_sram_bits = 1; - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - num_sram_bits = num_input_per_level; - if ((2 == num_sram_bits)&&(2 == mux_size)) { - num_sram_bits = 1; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", - __FILE__, __LINE__, mux_spice_model->name); - exit(1); - } - - /* For special cases: overide the results */ - if (TRUE == special_basis) { - num_sram_bits = num_input_per_level; - } - - return num_sram_bits; -} - -/* Determine the level of multiplexer - */ -int determine_tree_mux_level(int mux_size) { - int level = 0; - - /* Do log2(mux_size), have a basic number*/ - level = (int)(log((double)mux_size)/log(2.)); - /* Fix the error, i.e. mux_size=5, level = 2, we have to complete */ - while (mux_size > pow(2.,(double)level)) { - level++; - } - - return level; -} - -int determine_num_input_basis_multilevel_mux(int mux_size, - int mux_level) { - int num_input_per_unit = 2; - - /* Special Case: mux_size = 2 */ - if (2 == mux_size) { - return mux_size; - } - - if (1 == mux_level) { - return mux_size; - } - - if (2 == mux_level) { - num_input_per_unit = (int)sqrt(mux_size); - while (num_input_per_unit*num_input_per_unit < mux_size) { - num_input_per_unit++; - } - return num_input_per_unit; - } - - assert(2 < mux_level); - - - while(pow((double)num_input_per_unit, (double)mux_level) < mux_size) { - num_input_per_unit++; - } - - if (num_input_per_unit < 2) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Number of inputs of each basis should be at least 2!\n", - __FILE__, __LINE__); - exit(1); - } - - return num_input_per_unit; -} - -/*Determine the number inputs required at the last level*/ -int tree_mux_last_level_input_num(int num_level, - int mux_size) { - int ret = 0; - - ret = (int)(pow(2., (double)num_level)) - mux_size; - - if (0 < ret) { - ret = (int)(2.*(mux_size - pow(2., (double)(num_level-1)))); - } else if (0 > ret) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])num_level(%d) is wrong with mux_size(%d)!\n", - __FILE__, __LINE__, num_level, mux_size); - exit(1); - } else { - ret = mux_size; - } - - return ret; -} - -int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit, - int mux_size) { - int ret = 0; - int num_basis_last_level = (int)(mux_size/num_input_per_unit); - int num_potential_special_inputs = 0; - int num_special_basis = 0; - int num_input_special_basis = 0; - - ret = mux_size - num_basis_last_level * num_input_per_unit; - assert((0 == ret)||(0 < ret)); - - /* Special Case: mux_size = 2 */ - if (2 == mux_size) { - return mux_size; - } - - if (0 < ret) { - /* Check if we need a special basis at last level, - * differ : the number of input of the last-2 level will be used - */ - num_potential_special_inputs = (num_basis_last_level + ret) - pow((double)(num_input_per_unit), (double)(num_level-1)); - /* should be smaller than the num_input_per_unit */ - assert((!(0 > num_potential_special_inputs))&&(num_potential_special_inputs < num_input_per_unit)); - /* We need a speical basis */ - num_special_basis = pow((double)(num_input_per_unit), (double)(num_level-1)) - num_basis_last_level; - if (ret == num_special_basis) { - num_input_special_basis = 0; - } else if (1 == num_special_basis) { - num_input_special_basis = ret; - } else { - assert ( 1 < num_special_basis ); - num_input_special_basis = ret - 1; - } - ret = num_input_special_basis + num_basis_last_level * num_input_per_unit; - } else { - ret = mux_size; - } - - return ret; -} - -int determine_lut_path_id(int lut_size, - int* lut_inputs) { - int path_id = 0; - int i; - - for (i = 0; i < lut_size; i++) { - switch (lut_inputs[i]) { - case 0: - path_id += (int)pow(2., (double)(i)); - break; - case 1: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid sram_bits[%d]!\n", - __FILE__, __LINE__, i); - exit(1); - } - } - - return path_id; -} - -/* Decoding a one-level MUX: - * SPICE/Verilog model declare the sram port sequence as follows: - * sel0, sel1, ... , selN, - * which control the pass-gate logic connected to - * in0, in1, ... , inN - * When decode the SRAM bits, we initialize every bits to zero - * And then set the sel signal corresponding to the input to be 1. - * TODO: previously the decoding is not correct, need to check any bug in SPICE part - */ -int* decode_onelevel_mux_sram_bits(int fan_in, - int mux_level, - int path_id) { - int* ret = (int*)my_malloc(sizeof(int)*fan_in); - int i; - - /* Check */ - assert( (!(0 > path_id)) && (path_id < fan_in) ); - - for (i = 0; i < fan_in; i++) { - ret[i] = 0; - } - ret[path_id] = 1; - /* ret[fan_in - 1 - path_id] = 1; */ - return ret; -} - -int* decode_multilevel_mux_sram_bits(int fan_in, - int mux_level, - int path_id) { - int* ret = NULL; - int i, j, path_differ, temp; - int num_last_level_input, active_mux_level, active_path_id, num_input_basis; - - /* Check */ - assert((0 == path_id)||(0 < path_id)); - assert(path_id < fan_in); - - /* TODO: determine the number of input of basis */ - switch (mux_level) { - case 1: - /* Special: 1-level should be have special care !!! */ - return decode_onelevel_mux_sram_bits(fan_in, mux_level, path_id); - default: - assert(1 < mux_level); - num_input_basis = determine_num_input_basis_multilevel_mux(fan_in, mux_level); - break; - } - - ret = (int*)my_malloc(sizeof(int)*(num_input_basis * mux_level)); - - /* Determine last level input */ - num_last_level_input = multilevel_mux_last_level_input_num(mux_level, num_input_basis, fan_in); - - /* Initialize */ - for (i = 0; i < (num_input_basis*mux_level); i++) { - ret[i] = 0; - } - - /* When last level input number is less than the 2**mux_level, - * There are some input at the level: (mux_level-1) - */ - active_mux_level = mux_level; - active_path_id = path_id; - if (num_last_level_input < fan_in) { - if (path_id > num_last_level_input) { - active_mux_level = mux_level - 1; - active_path_id = (int)pow((double)num_input_basis,(double)(active_mux_level)) - (fan_in - path_id); - } - } else { - assert(num_last_level_input == fan_in); - } - - temp = active_path_id; - for (i = mux_level - 1; i > (mux_level - active_mux_level - 1); i--) { - for (j = 0; j < num_input_basis; j++) { - path_differ = (j + 1) * (int)pow((double)num_input_basis,(double)(i+active_mux_level-mux_level)); - if (temp < path_differ) { - /* This is orignal one for SPICE, but not work for VerilogGen - * I comment it here - ret[i*num_input_basis + j] = 1; - */ - ret[(mux_level - 1 - i)*num_input_basis + j] = 1; - /* Reduce the min. start index of this basis */ - temp -= j * (int)pow((double)num_input_basis,(double)(i+active_mux_level-mux_level)); - break; /* Touch the boundry, stop and move onto the next level */ - } - } - } - - /* Check */ - assert(0 == temp); - - return ret; -} - -/* Decode the configuration to sram_bits - * A path_id is in the range of [0..fan_in-1] - * sram - * input0 -----| - * |----- output - * input1 -----| - * Here, we assume (fix) the mux2to1 pass input0 when sram = 1 (vdd), and pass input1 when sram = 0(gnd) - * To generate the sram bits, we can determine the in each level of MUX, - * the path id is on the upper path(sram = 1) or the lower path (sram = 0), by path_id > 2**mux_level - */ -int* decode_tree_mux_sram_bits(int fan_in, - int mux_level, - int path_id) { - int* ret = (int*)my_malloc(sizeof(int)*mux_level); - int i = 0; - int path_differ = 0; - int temp = 0; - int num_last_level_input = 0; - int active_mux_level = 0; - int active_path_id = 0; - - /* Check */ - assert((0 == path_id)||(0 < path_id)); - assert(path_id < fan_in); - - /* Determine last level input */ - num_last_level_input = tree_mux_last_level_input_num(mux_level, fan_in); - - /* Initialize */ - for (i = 0; i < mux_level; i++) { - ret[i] = 0; - } - - /* When last level input number is less than the 2**mux_level, - * There are some input at the level: (mux_level-1) - */ - active_mux_level = mux_level; - active_path_id = path_id; - if (num_last_level_input < fan_in) { - if (path_id > num_last_level_input) { - active_mux_level = mux_level - 1; - active_path_id = (int)pow(2.,(double)(active_mux_level)) - (fan_in - path_id); - } - } else { - assert(num_last_level_input == fan_in); - } - - temp = active_path_id; - for (i = mux_level - 1; i > (mux_level - active_mux_level - 1); i--) { - path_differ = (int)pow(2.,(double)(i+active_mux_level-mux_level)); - if (temp < path_differ) { - ret[i] = 1; - } else { - temp = temp - path_differ; - ret[i] = 0; - } - } - - /* Check */ - assert(0 == temp); - - return ret; -} - -void decode_cmos_mux_sram_bits(t_spice_model* mux_spice_model, - int mux_size, int path_id, - int* bit_len, int** conf_bits, int* mux_level) { - /* Check */ - assert(NULL != mux_level); - assert(NULL != bit_len); - assert(NULL != conf_bits); - assert((-1 < path_id)&&(path_id < mux_size)); - assert(SPICE_MODEL_MUX == mux_spice_model->type); - assert(SPICE_MODEL_DESIGN_CMOS == mux_spice_model->design_tech); - - /* Initialization */ - (*bit_len) = 0; - (*conf_bits) = NULL; - - /* Special for MUX-2: whatever structure it is, it has always one-level and one configuration bit */ - if (2 == mux_size) { - (*bit_len) = 1; - (*mux_level) = 1; - (*conf_bits) = decode_tree_mux_sram_bits(mux_size, (*mux_level), path_id); - return; - } - /* Other general cases */ - switch (mux_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - (*mux_level) = determine_tree_mux_level(mux_size); - (*bit_len) = (*mux_level); - (*conf_bits) = decode_tree_mux_sram_bits(mux_size, (*mux_level), path_id); - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - (*mux_level) = 1; - (*bit_len) = mux_size; - (*conf_bits) = decode_onelevel_mux_sram_bits(mux_size, (*mux_level), path_id); - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - (*mux_level) = mux_spice_model->design_tech_info.mux_num_level; - (*bit_len) = determine_num_input_basis_multilevel_mux(mux_size, (*mux_level)) * (*mux_level); - (*conf_bits) = decode_multilevel_mux_sram_bits(mux_size, (*mux_level), path_id); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for mux_spice_model (%s)!\n", - __FILE__, __LINE__, mux_spice_model->name); - exit(1); - } - return; -} - - -/** - * Split a string with strtok - * Store each token in a char array - * tokens (char**): - * tokens[i] (char*) : pointer to a string split by delims - */ - -char** my_strtok(char* str, - char* delims, - int* len) -{ - char** ret; - char* result; - int cnt=0; - int* lens; - char* tmp; - - if (NULL == str) - { - printf("Warning: NULL string found in my_strtok!\n"); - return NULL; - } - - tmp = my_strdup(str); - result = strtok(tmp,delims); - /*First scan to determine the size*/ - while(result != NULL) - { - cnt++; - /* strtok split until its buffer is NULL*/ - result = strtok(NULL,delims); - } - //printf("1st scan cnt=%d\n",cnt); - /* Allocate memory*/ - ret = (char**)my_malloc(cnt*sizeof(char*)); - lens = (int*)my_malloc(cnt*sizeof(int)); - /*Second to determine the size of each char*/ - cnt = 0; - memcpy(tmp,str,strlen(str)+1); - result = strtok(tmp,delims); - while(result != NULL) - { - lens[cnt] = strlen(result)+1; - //printf("lens[%d]=%d .",cnt,lens[cnt]); - cnt++; - /* strtok split until its buffer is NULL*/ - result = strtok(NULL,delims); - } - //printf("\n"); - /*Third to allocate and copy each char*/ - cnt = 0; - memcpy(tmp,str,strlen(str)+1); - result = strtok(tmp,delims); - while(result != NULL) - { - //printf("results[%d] = %s ",cnt,result); - ret[cnt] = my_strdup(result); - cnt++; - /* strtok split until its buffer is NULL*/ - result = strtok(NULL,delims); - } - //printf("\n"); - - (*len) = cnt; - - free(tmp); - - return ret; -} - -int get_opposite_side(int side){ - - switch (side) { - case 0: - return 2; - case 1: - return 3; - case 2: - return 0; - case 3: - return 1; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid side index. Should be [0,3].\n", - __FILE__, __LINE__); - exit(1); - } -} - -char* convert_side_index_to_string(int side) { - switch (side) { - case 0: - return "top"; - case 1: - return "right"; - case 2: - return "bottom"; - case 3: - return "left"; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid side index. Should be [0,3].\n", - __FILE__, __LINE__); - exit(1); - } -} - -char* convert_chan_type_to_string(t_rr_type chan_type) { - switch(chan_type) { - case CHANX: - return "chanx"; - break; - case CHANY: - return "chany"; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); - exit(1); - } -} - -char* convert_chan_rr_node_direction_to_string(enum PORTS chan_rr_node_direction) { - switch(chan_rr_node_direction) { - case IN_PORT: - return "in"; - break; - case OUT_PORT: - return "out"; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of port!\n", __FILE__, __LINE__); - exit(1); - } -} - -void init_spice_net_info(t_spice_net_info* spice_net_info) { - if (NULL == spice_net_info) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_net_info!\n", __FILE__, __LINE__); - exit(1); - } - - spice_net_info->density = 0.; - spice_net_info->freq = 0.; - - assert((1 == default_signal_init_value)||(0 == default_signal_init_value)); - spice_net_info->init_val = default_signal_init_value; - spice_net_info->probability = (float)default_signal_init_value; - - spice_net_info->pwl = 0.; - spice_net_info->pwh = 0.; - spice_net_info->slew_rise = 0.; - - return; -} - -t_spice_model* find_iopad_spice_model(int num_spice_model, - t_spice_model* spice_models) { - t_spice_model* ret = NULL; - int imodel; - int num_found = 0; - - for (imodel = 0; imodel < num_spice_model; imodel++) { - if (SPICE_MODEL_IOPAD == spice_models[imodel].type) { - ret = &(spice_models[imodel]); - num_found++; - } - } - - assert(1 == num_found); - - return ret; -} - -/* Check if the grid coorindate given is in the range */ -boolean is_grid_coordinate_in_range(int x_min, - int x_max, - int grid_x) { - /* See if x is in the range */ - if ((x_min > grid_x) - ||(x_max < grid_x)) { - return FALSE; - } - - /* Reach here, means all in the range */ - return TRUE; -} - -char* generate_string_spice_model_type(enum e_spice_model_type spice_model_type) { - char* ret = NULL; - - switch (spice_model_type) { - case SPICE_MODEL_WIRE: - ret = "wire"; - break; - case SPICE_MODEL_MUX: - ret = "Multiplexer"; - break; - case SPICE_MODEL_LUT: - ret = "Look-Up Table"; - break; - case SPICE_MODEL_FF: - ret = "Flip-flop"; - break; - case SPICE_MODEL_SRAM: - ret = "SRAM"; - break; - case SPICE_MODEL_HARDLOGIC: - ret = "hard_logic"; - break; - case SPICE_MODEL_IOPAD: - ret = "iopad"; - break; - case SPICE_MODEL_SCFF: - ret = "Scan-chain Flip-flop"; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); - exit(1); - } - - return ret; -} - -/* Deteremine the side of a io grid */ -int determine_io_grid_side(int x, - int y) { - /* TOP side IO of FPGA */ - if ((ny + 1) == y) { - /* Make sure a valid x, y */ - assert((!(0 > x))&&(x < (nx + 1))); - return BOTTOM; /* Such I/O has only Bottom side pins */ - } else if ((nx + 1) == x) { /* RIGHT side IO of FPGA */ - /* Make sure a valid x, y */ - assert((!(0 > y))&&(y < (ny + 1))); - return LEFT; /* Such I/O has only Left side pins */ - } else if (0 == y) { /* BOTTOM side IO of FPGA */ - /* Make sure a valid x, y */ - assert((!(0 > x))&&(x < (nx + 1))); - return TOP; /* Such I/O has only Top side pins */ - } else if (0 == x) { /* LEFT side IO of FPGA */ - /* Make sure a valid x, y */ - assert((!(0 > y))&&(y < (ny + 1))); - return RIGHT; /* Such I/O has only Right side pins */ - } else { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])I/O Grid is in the center part of FPGA! Currently unsupported!\n", - __FILE__, __LINE__); - exit(1); - } -} - -void find_prev_rr_nodes_with_src(t_rr_node* src_rr_node, - int* num_drive_rr_nodes, - t_rr_node*** drive_rr_nodes, - int** switch_indices) { - int inode, iedge, next_node; - int cur_index, switch_index; - - assert(NULL != src_rr_node); - assert(NULL != num_drive_rr_nodes); - assert(NULL != switch_indices); - - (*num_drive_rr_nodes) = 0; - (*drive_rr_nodes) = NULL; - (*switch_indices) = NULL; - - switch_index = -1; - /* Determine num_drive_rr_node */ - for (inode = 0; inode < num_rr_nodes; inode++) { - for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { - next_node = rr_node[inode].edges[iedge]; - if (src_rr_node == &(rr_node[next_node])) { - /* Get the spice_model */ - if (-1 == switch_index) { - switch_index = rr_node[inode].switches[iedge]; - } else { /* Make sure the switches are the same*/ - assert(switch_index == rr_node[inode].switches[iedge]); - } - (*num_drive_rr_nodes)++; - } - } - } - /* Malloc */ - (*drive_rr_nodes) = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*(*num_drive_rr_nodes)); - (*switch_indices) = (int*)my_malloc(sizeof(int)*(*num_drive_rr_nodes)); - - /* Find all the rr_nodes that drive current_rr_node*/ - cur_index = 0; - for (inode = 0; inode < num_rr_nodes; inode++) { - for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { - next_node = rr_node[inode].edges[iedge]; - if (src_rr_node == &(rr_node[next_node])) { - /* Update drive_rr_nodes list */ - (*drive_rr_nodes)[cur_index] = &(rr_node[inode]); - (*switch_indices)[cur_index] = rr_node[inode].switches[iedge]; - cur_index++; - } - } - } - assert(cur_index == (*num_drive_rr_nodes)); - - return; -} - - -int find_path_id_prev_rr_node(int num_drive_rr_nodes, - t_rr_node** drive_rr_nodes, - t_rr_node* src_rr_node) { - int path_id, inode; - - /* Configuration bits for this MUX*/ - path_id = -1; - for (inode = 0; inode < num_drive_rr_nodes; inode++) { - if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { - path_id = inode; - break; - } - } - assert((-1 != path_id)&&(path_id < src_rr_node->fan_in)); - - return path_id; -} - -int pb_pin_net_num(t_rr_node* pb_rr_graph, - t_pb_graph_pin* pin) { - int net_num = OPEN; - - if (NULL == pb_rr_graph) { - /* Try the temp_net_num in pb_graph_pin */ - net_num = pin->temp_net_num; - } else { - net_num = pb_rr_graph[pin->pin_count_in_cluster].net_num; - } - - return net_num; -} - -float pb_pin_density(t_rr_node* pb_rr_graph, - t_pb_graph_pin* pin) { - float density = 0.; - int net_num; - - if (NULL == pb_rr_graph) { - /* Try the temp_net_num in pb_graph_pin */ - net_num = pin->temp_net_num; - if (OPEN != net_num) { - density = vpack_net[net_num].spice_net_info->density; - } - return density; - } - net_num = pb_rr_graph[pin->pin_count_in_cluster].net_num; - - if (OPEN != net_num) { - density = vpack_net[net_num].spice_net_info->density; - } - - return density; -} - -float pb_pin_probability(t_rr_node* pb_rr_graph, - t_pb_graph_pin* pin) { - float probability = (float)(default_signal_init_value); - int net_num; - - if (NULL == pb_rr_graph) { - /* Try the temp_net_num in pb_graph_pin */ - net_num = pin->temp_net_num; - if (OPEN != net_num) { - probability = vpack_net[net_num].spice_net_info->probability; - } - return probability; - } - net_num = pb_rr_graph[pin->pin_count_in_cluster].net_num; - - if (OPEN != net_num) { - probability = vpack_net[net_num].spice_net_info->probability; - } - - return probability; -} - -int pb_pin_init_value(t_rr_node* pb_rr_graph, - t_pb_graph_pin* pin) { - float init_val = (float)(default_signal_init_value); - int net_num; - - if (NULL == pb_rr_graph) { - /* TODO: we know initialize to vdd could reduce the leakage power od multiplexers! - * But I can this as an option ! - */ - /* Try the temp_net_num in pb_graph_pin */ - net_num = pin->temp_net_num; - if (OPEN != net_num) { - init_val = vpack_net[net_num].spice_net_info->init_val; - } - return init_val; - } - net_num = pb_rr_graph[pin->pin_count_in_cluster].net_num; - - if (OPEN != net_num) { - init_val = vpack_net[net_num].spice_net_info->init_val; - } - - return init_val; -} - -float get_rr_node_net_density(t_rr_node node) { - /* If we found this net is OPEN, we assume it zero-density */ - if (OPEN == node.vpack_net_num) { - return 0.; - } else { - return vpack_net[node.vpack_net_num].spice_net_info->density; - } -} - -float get_rr_node_net_probability(t_rr_node node) { - /* If we found this net is OPEN, we assume it zero-probability */ - if (OPEN == node.vpack_net_num) { - /* TODO: we know initialize to vdd could reduce the leakage power od multiplexers! - * But I can this as an option ! - */ - return (float)(default_signal_init_value); - } else { - return vpack_net[node.vpack_net_num].spice_net_info->probability; - } -} - -int get_rr_node_net_init_value(t_rr_node node) { - /* If we found this net is OPEN, we assume it zero-probability */ - if (OPEN == node.vpack_net_num) { - /* TODO: we know initialize to vdd could reduce the leakage power od multiplexers! - * But I can this as an option ! - */ - return (float)(default_signal_init_value); - } else { - return vpack_net[node.vpack_net_num].spice_net_info->init_val; - } -} - -int find_parent_pb_type_child_index(t_pb_type* parent_pb_type, - int mode_index, - t_pb_type* child_pb_type) { - int i; - - assert(NULL != parent_pb_type); - assert(NULL != child_pb_type); - assert((!(0 > mode_index))&&(mode_index < parent_pb_type->num_modes)); - - for (i = 0; i < parent_pb_type->modes[mode_index].num_pb_type_children; i++) { - if (child_pb_type == &(parent_pb_type->modes[mode_index].pb_type_children[i])) { - assert(0 == strcmp(child_pb_type->name, parent_pb_type->modes[mode_index].pb_type_children[i].name)); - return i; - } - } - - return -1; -} - -/* Rule in generating a unique name: - * name of current pb = _[index] - */ -void gen_spice_name_tag_pb_rec(t_pb* cur_pb, - char* prefix) { - char* prefix_rec = NULL; - int ipb, jpb, mode_index; - - mode_index = cur_pb->mode; - - /* Free previous name_tag if there is */ - /* my_free(cur_pb->spice_name_tag); */ - - /* Generate the name_tag */ - if ((0 < cur_pb->pb_graph_node->pb_type->num_modes) - &&(NULL == cur_pb->pb_graph_node->pb_type->spice_model_name)) { - prefix_rec = (char*)my_malloc(sizeof(char)*(strlen(prefix) + 1 + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 - + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) + 7 + strlen(cur_pb->pb_graph_node->pb_type->modes[mode_index].name) + 2 )); - sprintf(prefix_rec, "%s_%s[%d]_mode[%s]", - prefix, cur_pb->pb_graph_node->pb_type->name, cur_pb->pb_graph_node->placement_index, cur_pb->pb_graph_node->pb_type->modes[mode_index].name); - cur_pb->spice_name_tag = my_strdup(prefix_rec); - } else { - assert((0 == cur_pb->pb_graph_node->pb_type->num_modes) - ||(NULL != cur_pb->pb_graph_node->pb_type->spice_model_name)); - prefix_rec = (char*)my_malloc(sizeof(char)*(strlen(prefix) + 1 + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 - + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) + 2 )); - sprintf(prefix_rec, "%s_%s[%d]", - prefix, cur_pb->pb_graph_node->pb_type->name, cur_pb->pb_graph_node->placement_index); - cur_pb->spice_name_tag = my_strdup(prefix_rec); - } - - /* When reach the leaf, we directly return */ - /* Recursive until reach the leaf */ - if ((0 == cur_pb->pb_graph_node->pb_type->num_modes) - ||(NULL == cur_pb->child_pbs)) { - return; - } - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Refer to pack/output_clustering.c [LINE 392] */ - //if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - /* Try to simplify the name tag... to avoid exceeding the length of SPICE name (up to 1024 chars) */ - /* gen_spice_name_tag_pb_rec(&(cur_pb->child_pbs[ipb][jpb]),prefix); */ - gen_spice_name_tag_pb_rec(&(cur_pb->child_pbs[ipb][jpb]),prefix_rec); - //} - } - } - - my_free(prefix_rec); - - return; -} - - -/* Generate a unique name tag for each pb, - * to identify it in both SPICE netlist and Power Modeling. - */ -void gen_spice_name_tags_all_pbs() { - int iblk; - char* prefix = NULL; - - for (iblk = 0; iblk < num_blocks; iblk++) { - prefix = (char*)my_malloc(sizeof(char)*(5 + strlen(my_itoa(block[iblk].x)) + 2 + strlen(my_itoa(block[iblk].y)) + 2)); - sprintf(prefix, "grid[%d][%d]", block[iblk].x, block[iblk].y); - gen_spice_name_tag_pb_rec(block[iblk].pb, prefix); - my_free(prefix); - } - - return; -} - -/* Make sure the edge has only one input pin and output pin*/ -void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge) { - assert(1 == pb_graph_edge.num_input_pins); - assert(1 == pb_graph_edge.num_output_pins); - - return; -} - -/* Check all the edges for a given pb_graph_pin*/ -void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin) { - int iedge; - - for (iedge = 0; iedge < pb_graph_pin.num_input_edges; iedge++) { - check_pb_graph_edge(*(pb_graph_pin.input_edges[iedge])); - } - - for (iedge = 0; iedge < pb_graph_pin.num_output_edges; iedge++) { - check_pb_graph_edge(*(pb_graph_pin.output_edges[iedge])); - } - - return; -} - -int find_pb_mapped_logical_block_rec(t_pb* cur_pb, - t_spice_model* pb_spice_model, - char* pb_spice_name_tag) { - int logical_block_index = OPEN; - int mode_index, ipb, jpb; - - assert(NULL != cur_pb); - - if ((pb_spice_model == cur_pb->pb_graph_node->pb_type->spice_model) - &&(0 == strcmp(cur_pb->spice_name_tag, pb_spice_name_tag))) { - /* Return the logic block we may find */ - switch (pb_spice_model->type) { - case SPICE_MODEL_LUT : - /* Special for LUT... They have sub modes!!!*/ - assert(NULL != cur_pb->child_pbs); - return cur_pb->child_pbs[0][0].logical_block; - case SPICE_MODEL_FF: - assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model); - return cur_pb->logical_block; - case SPICE_MODEL_HARDLOGIC: - if (NULL != cur_pb->child_pbs) { - return cur_pb->child_pbs[0][0].logical_block; - } else { - assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model); - return cur_pb->logical_block; - } - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid spice model type!\n", - __FILE__, __LINE__); - exit(1); - } - } - - /* Go recursively ... */ - mode_index = cur_pb->mode; - if (0 == cur_pb->pb_graph_node->pb_type->num_modes) { - return logical_block_index; - } - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - logical_block_index = - find_pb_mapped_logical_block_rec(&(cur_pb->child_pbs[ipb][jpb]), pb_spice_model, pb_spice_name_tag); - if (OPEN != logical_block_index) { - return logical_block_index; - } - } - } - } - - return logical_block_index; -} - -int find_grid_mapped_logical_block(int x, int y, - t_spice_model* pb_spice_model, - char* pb_spice_name_tag) { - int logical_block_index = OPEN; - int iblk; - - /* Find the grid usage */ - if (0 == grid[x][y].usage) { - return logical_block_index; - } else { - assert(0 < grid[x][y].usage); - /* search each block */ - for (iblk = 0; iblk < grid[x][y].usage; iblk++) { - /* Get the pb */ - logical_block_index = find_pb_mapped_logical_block_rec(block[grid[x][y].blocks[iblk]].pb, - pb_spice_model, pb_spice_name_tag); - if (OPEN != logical_block_index) { - return logical_block_index; - } - } - } - - return logical_block_index; -} - -void stats_pb_graph_node_port_pin_numbers(t_pb_graph_node* cur_pb_graph_node, - int* num_inputs, - int* num_outputs, - int* num_clock_pins) { - int iport; - - assert(NULL != cur_pb_graph_node); - - (*num_inputs) = 0; - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - (*num_inputs) += cur_pb_graph_node->num_input_pins[iport]; - } - (*num_outputs) = 0; - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - (*num_outputs) += cur_pb_graph_node->num_output_pins[iport]; - } - (*num_clock_pins) = 0; - for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { - (*num_clock_pins) += cur_pb_graph_node->num_clock_pins[iport]; - } - - return; -} - -int recommend_num_sim_clock_cycle(float sim_window_size) { - float avg_density = 0.; - float median_density = 0.; - int recmd_num_sim_clock_cycle = 0; - int inet, jnet; - int net_cnt = 0; - float* density_value = NULL; - int* sort_index = NULL; - int* net_to_sort_index_mapping = NULL; - - float weighted_avg_density = 0.; - float net_weight = 0.; - int weighted_net_cnt = 0; - - /* get the average density of all the nets */ - for (inet = 0; inet < num_logical_nets; inet++) { - assert(NULL != vpack_net[inet].spice_net_info); - if ((FALSE == vpack_net[inet].is_global) - &&(FALSE == vpack_net[inet].is_const_gen) - &&(0. != vpack_net[inet].spice_net_info->density)) { - avg_density += vpack_net[inet].spice_net_info->density; - net_cnt++; - /* Consider the weight of fan-out */ - if (0 == vpack_net[inet].num_sinks) { - net_weight = 1; - } else { - assert( 0 < vpack_net[inet].num_sinks ); - net_weight = vpack_net[inet].num_sinks; - } - weighted_avg_density += vpack_net[inet].spice_net_info->density * net_weight; - weighted_net_cnt += net_weight; - } - } - avg_density = avg_density/net_cnt; - weighted_avg_density = weighted_avg_density/weighted_net_cnt; - - /* Fill the array to be sorted */ - density_value = (float*)my_malloc(sizeof(float)*net_cnt); - sort_index = (int*)my_malloc(sizeof(int)*net_cnt); - net_to_sort_index_mapping = (int*)my_malloc(sizeof(int)*net_cnt); - jnet = 0; - for (inet = 0; inet < num_logical_nets; inet++) { - assert(NULL != vpack_net[inet].spice_net_info); - if ((FALSE == vpack_net[inet].is_global) - &&(FALSE == vpack_net[inet].is_const_gen) - &&(0. != vpack_net[inet].spice_net_info->density)) { - sort_index[jnet] = jnet; - net_to_sort_index_mapping[jnet] = inet; - density_value[jnet] = vpack_net[inet].spice_net_info->density; - jnet++; - } - } - assert(jnet == net_cnt); - /* Sort the density */ - quicksort_float_index(net_cnt, sort_index, density_value); - /* Get the median */ - median_density = vpack_net[sort_index[(int)(0.5*net_cnt)]].spice_net_info->density; - - /* It may be more reasonable to use median - * But, if median density is 0, we use average density - */ - if ((0. == median_density) && (0. == avg_density)) { - recmd_num_sim_clock_cycle = 1; - vpr_printf(TIO_MESSAGE_WARNING, - "All the signal density is zero! No. of clock cycles in simulations are set to be %d!", - recmd_num_sim_clock_cycle); - } else if (0. == avg_density) { - recmd_num_sim_clock_cycle = (int)round(1/median_density); - } else if (0. == median_density) { - recmd_num_sim_clock_cycle = (int)round(1/avg_density); - } else { - /* add a sim window size to balance the weight of average density and median density - * In practice, we find that there could be huge difference between avereage and median values - * For a reasonable number of simulation clock cycles, we do this window size. - */ - recmd_num_sim_clock_cycle = (int)round(1 / (sim_window_size * avg_density + (1 - sim_window_size) * median_density )); - } - - assert( 0 < recmd_num_sim_clock_cycle); - - vpr_printf(TIO_MESSAGE_INFO, "Average net density: %.2f\n", avg_density); - vpr_printf(TIO_MESSAGE_INFO, "Median net density: %.2f\n", median_density); - vpr_printf(TIO_MESSAGE_INFO, "Average net densityi after weighting: %.2f\n", weighted_avg_density); - vpr_printf(TIO_MESSAGE_INFO, "Window size set for Simulation: %.2f\n", sim_window_size); - vpr_printf(TIO_MESSAGE_INFO, "Net density after Window size : %.2f\n", - (sim_window_size * avg_density + (1 - sim_window_size) * median_density)); - vpr_printf(TIO_MESSAGE_INFO, "Recommend no. of clock cycles: %d\n", recmd_num_sim_clock_cycle); - - /* Free */ - my_free(sort_index); - my_free(density_value); - my_free(net_to_sort_index_mapping); - - return recmd_num_sim_clock_cycle; -} - -void auto_select_num_sim_clock_cycle(t_spice* spice, - float sim_window_size) { - int recmd_num_sim_clock_cycle = recommend_num_sim_clock_cycle(sim_window_size); - - /* Auto select number of simulation clock cycles*/ - if (-1 == spice->spice_params.meas_params.sim_num_clock_cycle) { - vpr_printf(TIO_MESSAGE_INFO, "Auto select the no. of clock cycles in simulation: %d\n", recmd_num_sim_clock_cycle); - spice->spice_params.meas_params.sim_num_clock_cycle = recmd_num_sim_clock_cycle; - } else { - vpr_printf(TIO_MESSAGE_INFO, "No. of clock cycles in simulation is forced to be: %d\n", - spice->spice_params.meas_params.sim_num_clock_cycle); - } - - return; -} - -/* Malloc grid_index_low and grid_index_high for a spice_model */ -void alloc_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) { - int ix, iy; - - /* grid_index_low */ - /* x - direction*/ - cur_spice_model->grid_index_low = (int**)my_malloc(sizeof(int*)*(nx + 2)); - /* y - direction*/ - for (ix = 0; ix < (nx + 2); ix++) { - cur_spice_model->grid_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 2)); - } - /* Initialize */ - for (ix = 0; ix < (nx + 2); ix++) { - for (iy = 0; iy < (ny + 2); iy++) { - cur_spice_model->grid_index_low[ix][iy] = 0; - } - } - /* grid_index_high */ - /* x - direction*/ - cur_spice_model->grid_index_high = (int**)my_malloc(sizeof(int*)*(nx + 2)); - /* y - direction*/ - for (ix = 0; ix < (nx + 2); ix++) { - cur_spice_model->grid_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 2)); - } - /* Initialize */ - for (ix = 0; ix < (nx + 2); ix++) { - for (iy = 0; iy < (ny + 2); iy++) { - cur_spice_model->grid_index_high[ix][iy] = 0; - } - } - - return; -} - -void free_one_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) { - int ix; - - for (ix = 0; ix < (nx + 2); ix++) { - my_free(cur_spice_model->grid_index_high[ix]); - my_free(cur_spice_model->grid_index_low[ix]); - } - - my_free(cur_spice_model->grid_index_high); - my_free(cur_spice_model->grid_index_low); - - return; -} - -void free_spice_model_grid_index_low_high(int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - free_one_spice_model_grid_index_low_high(&(spice_model[i])); - } - return; -} - - -void update_one_spice_model_grid_index_low(int x, int y, - t_spice_model* cur_spice_model) { - /* Check */ - assert((!(0 > x))&&(!(x > (nx + 1)))); - assert((!(0 > y))&&(!(y > (ny + 1)))); - assert(NULL != cur_spice_model); - assert(NULL != cur_spice_model->grid_index_low); - assert(NULL != cur_spice_model->grid_index_low[x]); - - /* Assigne the low */ - cur_spice_model->grid_index_low[x][y] = cur_spice_model->cnt; - - return; -} - -void update_spice_models_grid_index_low(int x, int y, - int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - update_one_spice_model_grid_index_low(x, y, &(spice_model[i])); - } - - return; -} - -void update_one_spice_model_grid_index_high(int x, int y, - t_spice_model* cur_spice_model) { - /* Check */ - assert((!(0 > x))&&(!(x > (nx + 1)))); - assert((!(0 > y))&&(!(y > (ny + 1)))); - assert(NULL != cur_spice_model); - assert(NULL != cur_spice_model->grid_index_high); - assert(NULL != cur_spice_model->grid_index_high[x]); - - /* Assigne the low */ - cur_spice_model->grid_index_high[x][y] = cur_spice_model->cnt; - - return; -} - -void update_spice_models_grid_index_high(int x, int y, - int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - update_one_spice_model_grid_index_high(x, y, &(spice_model[i])); - } - - return; -} - -void zero_one_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) { - int ix, iy; - /* Initialize */ - for (ix = 0; ix < (nx + 2); ix++) { - for (iy = 0; iy < (ny + 2); iy++) { - cur_spice_model->grid_index_high[ix][iy] = 0; - cur_spice_model->grid_index_low[ix][iy] = 0; - } - } - return; -} - -void zero_spice_model_grid_index_low_high(int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - zero_one_spice_model_grid_index_low_high(&(spice_model[i])); - } - - return; -} - -char* gen_str_spice_model_structure(enum e_spice_model_structure spice_model_structure) { - switch (spice_model_structure) { - case SPICE_MODEL_STRUCTURE_TREE: - return "tree-like"; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - return "one-level"; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - return "multi-level"; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid spice model structure!\n", - __FILE__, __LINE__); - exit(1); - } -} - -/* Check if the spice model structure is the same with the switch_inf structure */ -boolean check_spice_model_structure_match_switch_inf(t_switch_inf target_switch_inf) { - assert(NULL != target_switch_inf.spice_model); - if (target_switch_inf.structure != target_switch_inf.spice_model->design_tech_info.structure) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Structure in spice_model(%s) is different from switch_inf[%s]!\n", - __FILE__, __LINE__, target_switch_inf.spice_model->name, target_switch_inf.name); - return FALSE; - } - return TRUE; -} - -int find_pb_type_idle_mode_index(t_pb_type cur_pb_type) { - int idle_mode_index = 0; - int imode = 0; - int num_idle_mode = 0; - - /* if we touch the leaf node */ - if (NULL != cur_pb_type.blif_model) { - return 0; - } - - if (0 == cur_pb_type.num_modes) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Intend to find the idle mode while cur_pb_type has 0 modes!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Normal Condition: */ - for (imode = 0; imode < cur_pb_type.num_modes; imode++) { - if (1 == cur_pb_type.modes[imode].define_idle_mode) { - idle_mode_index = imode; - num_idle_mode++; - } - } - - assert(1 == num_idle_mode); - - return idle_mode_index; -} - -/* Find the physical mode index */ -int find_pb_type_physical_mode_index(t_pb_type cur_pb_type) { - int phy_mode_index = 0; - int imode = 0; - int num_phy_mode = 0; - - /* if we touch the leaf node */ - if (NULL != cur_pb_type.blif_model) { - return 0; - } - - if (0 == cur_pb_type.num_modes) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Intend to find the idle mode while cur_pb_type has 0 modes!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Normal Condition: */ - for (imode = 0; imode < cur_pb_type.num_modes; imode++) { - if (1 == cur_pb_type.modes[imode].define_physical_mode) { - phy_mode_index = imode; - num_phy_mode++; - } - } - assert(1 == num_phy_mode); - - return phy_mode_index; -} - -void mark_grid_type_pb_graph_node_pins_temp_net_num(int x, int y) { - int iport, ipin, type_pin_index, class_id, pin_global_rr_node_id; - t_type_ptr type = NULL; - t_pb_graph_node* top_pb_graph_node = NULL; - int mode_index, ipb, jpb; - - /* Assert */ - assert((!(x < 0))&&(x < (nx + 2))); - assert((!(y < 0))&&(y < (ny + 2))); - - type = grid[x][y].type; - - if (EMPTY_TYPE == type) { - return; /* Bypass empty grid */ - } - - top_pb_graph_node = type->pb_graph_head; - /* Input ports */ - for (iport = 0; iport < top_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < top_pb_graph_node->num_input_pins[iport]; ipin++) { - top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; - type_pin_index = top_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - class_id = type->pin_class[type_pin_index]; - assert(RECEIVER == type->class_inf[class_id].type); - /* Find the pb net_num and update OPIN net_num */ - pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); - if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; - continue; - } - top_pb_graph_node->input_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - } - } - /* clock ports */ - for (iport = 0; iport < top_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < top_pb_graph_node->num_clock_pins[iport]; ipin++) { - top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; - type_pin_index = top_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster; - class_id = type->pin_class[type_pin_index]; - assert(RECEIVER == type->class_inf[class_id].type); - /* Find the pb net_num and update OPIN net_num */ - pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); - if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; - continue; - } - top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - } - } - - /* Go recursively ... */ - mode_index = find_pb_type_idle_mode_index(*(top_pb_graph_node->pb_type)); - for (ipb = 0; ipb < top_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < top_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Mark pb_graph_node temp_net_num */ - rec_mark_pb_graph_node_temp_net_num(&(top_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb])); - } - } - - /* Output ports */ - for (iport = 0; iport < top_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < top_pb_graph_node->num_output_pins[iport]; ipin++) { - top_pb_graph_node->output_pins[iport][ipin].temp_net_num = OPEN; - type_pin_index = top_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; - class_id = type->pin_class[type_pin_index]; - assert(DRIVER == type->class_inf[class_id].type); - /* Find the pb net_num and update OPIN net_num */ - pin_global_rr_node_id = get_rr_node_index(x, y, OPIN, type_pin_index, rr_node_indices); - if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - top_pb_graph_node->output_pins[iport][ipin].temp_net_num = OPEN; - continue; - } - top_pb_graph_node->output_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - } - } - - /* Run again to handle feedback loop */ - /* Input ports */ - for (iport = 0; iport < top_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < top_pb_graph_node->num_input_pins[iport]; ipin++) { - top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; - type_pin_index = top_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - class_id = type->pin_class[type_pin_index]; - assert(RECEIVER == type->class_inf[class_id].type); - /* Find the pb net_num and update OPIN net_num */ - pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); - if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; - continue; - } - top_pb_graph_node->input_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - } - } - /* clock ports */ - for (iport = 0; iport < top_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < top_pb_graph_node->num_clock_pins[iport]; ipin++) { - top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; - type_pin_index = top_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster; - class_id = type->pin_class[type_pin_index]; - assert(RECEIVER == type->class_inf[class_id].type); - /* Find the pb net_num and update OPIN net_num */ - pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); - if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; - continue; - } - top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - } - } - - - return; -} - -/* Assign the temp_net_num by considering the first incoming edge that belongs to the correct operating mode */ -void assign_pb_graph_node_pin_temp_net_num_by_mode_index(t_pb_graph_pin* cur_pb_graph_pin, - int mode_index) { - int iedge; - - /* IMPORTANT: I assume by default the index of selected edge is 0 - * Make sure this input edge comes from the default mode - */ - for (iedge = 0; iedge < cur_pb_graph_pin->num_input_edges; iedge++) { - if (mode_index != cur_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode_index) { - continue; - } - cur_pb_graph_pin->temp_net_num = cur_pb_graph_pin->input_edges[iedge]->input_pins[0]->temp_net_num; - break; - } - - return; -} - -void mark_pb_graph_node_input_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, - int mode_index) { - int iport, ipin; - - assert(NULL != cur_pb_graph_node); - - /* Input ports */ - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { - cur_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; - /* IMPORTANT: I assume by default the index of selected edge is 0 - * Make sure this input edge comes from the default mode - */ - assign_pb_graph_node_pin_temp_net_num_by_mode_index(&(cur_pb_graph_node->input_pins[iport][ipin]), mode_index); - } - } - - return; -} - -void mark_pb_graph_node_clock_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, - int mode_index) { - int iport, ipin; - - assert(NULL != cur_pb_graph_node); - - /* Clock ports */ - for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { - cur_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; - assign_pb_graph_node_pin_temp_net_num_by_mode_index(&(cur_pb_graph_node->clock_pins[iport][ipin]), mode_index); - } - } - - return; -} - -void mark_pb_graph_node_output_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, - int mode_index) { - int iport, ipin; - - assert(NULL != cur_pb_graph_node); - - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - cur_pb_graph_node->output_pins[iport][ipin].temp_net_num = OPEN; - /* IMPORTANT: I assume by default the index of selected edge is 0 - * Make sure this input edge comes from the default mode - */ - assign_pb_graph_node_pin_temp_net_num_by_mode_index(&(cur_pb_graph_node->output_pins[iport][ipin]), mode_index); - } - } - - return; -} - -/* Mark temp_net_num in current pb_graph_node from the parent pb_graph_node */ -void rec_mark_pb_graph_node_temp_net_num(t_pb_graph_node* cur_pb_graph_node) { - int mode_index, ipb, jpb; - - assert(NULL != cur_pb_graph_node); - - /* Find the default mode */ - mode_index = find_pb_type_idle_mode_index(*(cur_pb_graph_node->pb_type)); - - mark_pb_graph_node_input_pins_temp_net_num(cur_pb_graph_node, mode_index); - - mark_pb_graph_node_clock_pins_temp_net_num(cur_pb_graph_node, mode_index); - - if (NULL != cur_pb_graph_node->pb_type->spice_model) { - return; - } - - /* Go recursively ... */ - mode_index = find_pb_type_idle_mode_index(*(cur_pb_graph_node->pb_type)); - for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Mark pb_graph_node temp_net_num */ - rec_mark_pb_graph_node_temp_net_num(&(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb])); - } - } - - /* IMPORTANT: update the temp_net of Output ports after recursion is done! - * the outputs of sub pb_graph_node should be updated first - */ - mark_pb_graph_node_output_pins_temp_net_num(cur_pb_graph_node, mode_index); - - /* Do this again to handle feedback loops ! */ - mark_pb_graph_node_input_pins_temp_net_num(cur_pb_graph_node, mode_index); - - mark_pb_graph_node_clock_pins_temp_net_num(cur_pb_graph_node, mode_index); - - return; -} - -void load_one_pb_graph_pin_temp_net_num_from_pb(t_pb* cur_pb, - t_pb_graph_pin* cur_pb_graph_pin) { - int node_index; - t_rr_node* pb_rr_nodes = NULL; - - assert(NULL != cur_pb); - assert(NULL != cur_pb->pb_graph_node); - - /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; - node_index = cur_pb_graph_pin->pin_count_in_cluster; - cur_pb_graph_pin->temp_net_num = pb_rr_nodes[node_index].vpack_net_num; - - return; -} - -/* According to the vpack_net_num in cur_pb - * assign it to the corresponding pb_graph_pins - */ -void load_pb_graph_node_temp_net_num_from_pb(t_pb* cur_pb) { - int iport, ipin; - - assert(NULL != cur_pb); - assert(NULL != cur_pb->pb_graph_node); - - /* Input ports */ - for (iport = 0; iport < cur_pb->pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb->pb_graph_node->num_input_pins[iport]; ipin++) { - load_one_pb_graph_pin_temp_net_num_from_pb(cur_pb, - &(cur_pb->pb_graph_node->input_pins[iport][ipin])); - } - } - - /* Clock ports */ - for (iport = 0; iport < cur_pb->pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < cur_pb->pb_graph_node->num_clock_pins[iport]; ipin++) { - load_one_pb_graph_pin_temp_net_num_from_pb(cur_pb, - &(cur_pb->pb_graph_node->clock_pins[iport][ipin])); - } - } - - /* Output ports */ - for (iport = 0; iport < cur_pb->pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb->pb_graph_node->num_output_pins[iport]; ipin++) { - load_one_pb_graph_pin_temp_net_num_from_pb(cur_pb, - &(cur_pb->pb_graph_node->output_pins[iport][ipin])); - } - } - - return; -} - -/* Recursively traverse the hierachy of a pb, - * store parasitic nets in the temp_net_num of the assoicated pb_graph_node - */ -void rec_mark_one_pb_unused_pb_graph_node_temp_net_num(t_pb* cur_pb) { - int ipb, jpb; - int mode_index; - - /* Check */ - assert(NULL != cur_pb); - - if (NULL != cur_pb->pb_graph_node->pb_type->spice_model) { - return; - } - /* Go recursively ... */ - mode_index = cur_pb->mode; - if (!(0 < cur_pb->pb_graph_node->pb_type->num_modes)) { - return; - } - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - rec_mark_one_pb_unused_pb_graph_node_temp_net_num(&(cur_pb->child_pbs[ipb][jpb])); - } else { - /* Print idle graph_node muxes */ - load_pb_graph_node_temp_net_num_from_pb(cur_pb); - /* We should update the net_num */ - rec_mark_pb_graph_node_temp_net_num(cur_pb->child_pbs[ipb][jpb].pb_graph_node); - } - } - } - - return; -} - -void update_pb_vpack_net_num_from_temp_net_num(t_pb* cur_pb, - t_pb_graph_pin* cur_pb_graph_pin) { - int node_index; - t_rr_node* pb_rr_nodes = NULL; - - assert(NULL != cur_pb); - assert(NULL != cur_pb->pb_graph_node); - - /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; - node_index = cur_pb_graph_pin->pin_count_in_cluster; - - /* Avoid mistakenly modification */ - if (OPEN != pb_rr_nodes[node_index].vpack_net_num) { - return; - } - /* Only modify when original vpack_net_num is open!!! */ - pb_rr_nodes[node_index].vpack_net_num = cur_pb_graph_pin->temp_net_num; - - return; -} - -void update_pb_graph_node_temp_net_num_to_pb(t_pb_graph_node* cur_pb_graph_node, - t_pb* cur_pb) { - int iport, ipin; - t_rr_node* pb_rr_nodes = NULL; - - assert(NULL != cur_pb->pb_graph_node); - assert(NULL != cur_pb); - - pb_rr_nodes = cur_pb->rr_graph; - - /* Input ports */ - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { - update_pb_vpack_net_num_from_temp_net_num(cur_pb, - &(cur_pb_graph_node->input_pins[iport][ipin])); - } - } - - /* Clock ports */ - for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { - update_pb_vpack_net_num_from_temp_net_num(cur_pb, - &(cur_pb_graph_node->clock_pins[iport][ipin])); - } - } - - /* Output ports */ - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - update_pb_vpack_net_num_from_temp_net_num(cur_pb, - &(cur_pb_graph_node->output_pins[iport][ipin])); - } - } - - return; -} - -void rec_load_unused_pb_graph_node_temp_net_num_to_pb(t_pb* cur_pb) { - int ipb, jpb; - int mode_index; - - /* Check */ - assert(NULL != cur_pb); - - if (NULL != cur_pb->pb_graph_node->pb_type->spice_model) { - return; - } - /* Go recursively ... */ - mode_index = cur_pb->mode; - if (!(0 < cur_pb->pb_graph_node->pb_type->num_modes)) { - return; - } - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - rec_load_unused_pb_graph_node_temp_net_num_to_pb(&(cur_pb->child_pbs[ipb][jpb])); - } else { - update_pb_graph_node_temp_net_num_to_pb(cur_pb->child_pbs[ipb][jpb].pb_graph_node, - cur_pb); - } - } - } - - return; -} - -void mark_one_pb_parasitic_nets(t_pb* cur_pb) { - - /* By go recursively, parasitic net num are stored in the temp_net_num in pb_graph_node */ - rec_mark_one_pb_unused_pb_graph_node_temp_net_num(cur_pb); - - /* Load the temp_net_num to vpack_net_num in the current pb! */ - rec_load_unused_pb_graph_node_temp_net_num_to_pb(cur_pb); - - return; -} - -void init_rr_nodes_vpack_net_num_changed(int LL_num_rr_nodes, - t_rr_node* LL_rr_node) { - int inode; - - for (inode = 0; inode < LL_num_rr_nodes; inode++) { - LL_rr_node[inode].vpack_net_num_changed = FALSE; - } - - return; -} - -/* Check if this net is connected to a PI*/ -boolean is_net_pi(t_net* cur_net) { - int src_blk_idx; - - assert(NULL != cur_net); - - src_blk_idx = cur_net->node_block[0]; - if (VPACK_INPAD == logical_block[src_blk_idx].type) { - return TRUE; - } - return FALSE; -} - -int check_consistency_logical_block_net_num(t_logical_block* lgk_blk, - int num_inputs, int* input_net_num) { - int i, iport, ipin, net_eq; - int consistency = 1; - int* input_net_num_mapped = (int*)my_calloc(num_inputs, sizeof(int)); - - for (iport = 0; iport < lgk_blk->pb->pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < lgk_blk->pb->pb_graph_node->num_input_pins[iport]; ipin++) { - if (OPEN == lgk_blk->input_nets[iport][ipin]) { - continue; /* bypass unused pins */ - } - /* Initial net_eq */ - net_eq = 0; - /* Check if this net can be found in the input net_num */ - for (i = 0; i < num_inputs; i++) { - if (1 == input_net_num_mapped[i]) { - continue; - } - if (input_net_num[i] == lgk_blk->input_nets[iport][ipin]) { - net_eq = 1; - input_net_num_mapped[i] = 1; - break; - } - } - if (0 == net_eq) { - consistency = 0; - break; - } - } - if (0 == consistency) { - break; - } - } - - /* Free */ - my_free(input_net_num_mapped); - - return consistency; -} - -/* Determine if this rr_node is driving this switch box (x,y) - * For more than length-1 wire, the fan-in of a des_rr_node in a switch box - * contain all the drivers in the switch boxes that it passes through. - * This function is to identify if the src_rr_node is the driver in this switch box - */ -int rr_node_drive_switch_box(t_rr_node* src_rr_node, - t_rr_node* des_rr_node, - int switch_box_x, - int switch_box_y, - int chan_side) { - - /* Make sure a valid src_rr_node and des_rr_node */ - assert(NULL != src_rr_node); - assert(NULL != des_rr_node); - /* The src_rr_node should be either CHANX or CHANY */ - assert((CHANX == des_rr_node->type)||(CHANY == des_rr_node->type)); - /* Valid switch_box coordinator */ - assert((!(0 > switch_box_x))&&(!(switch_box_x > (nx + 1)))); - assert((!(0 > switch_box_y))&&(!(switch_box_y > (ny + 1)))); - /* Valid des_rr_node coordinator */ - assert((!(switch_box_x < (des_rr_node->xlow - 1)))&&(!(switch_box_x > (des_rr_node->xhigh + 1)))); - assert((!(switch_box_y < (des_rr_node->ylow - 1)))&&(!(switch_box_y > (des_rr_node->yhigh + 1)))); - - /* Check the src_rr_node coordinator */ - switch (chan_side) { - case TOP: - /* Following cases: - * | - * / | \ - */ - /* The destination rr_node only have one condition!!! */ - assert((INC_DIRECTION == des_rr_node->direction)&&(CHANY == des_rr_node->type)); - /* depend on the type of src_rr_node */ - switch (src_rr_node->type) { - case OPIN: - if (((switch_box_y + 1) == src_rr_node->ylow) - &&((switch_box_x == src_rr_node->xlow)||((switch_box_x + 1) == src_rr_node->xlow))) { - return 1; - } - break; - case CHANX: - assert(src_rr_node->ylow == src_rr_node->yhigh); - if ((switch_box_y == src_rr_node->ylow) - &&(!(switch_box_x < (src_rr_node->xlow - 1))) - &&(!(switch_box_x > (src_rr_node->xhigh + 1)))) { - return 1; - } - break; - case CHANY: - assert(src_rr_node->xlow == src_rr_node->xhigh); - if ((switch_box_x == src_rr_node->xlow) - &&(!(switch_box_y < src_rr_node->ylow)) - &&(!(switch_box_y > src_rr_node->yhigh))) { - return 1; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case RIGHT: - /* Following cases: - * \ - * --- ---- - * / - */ - /* The destination rr_node only have one condition!!! */ - assert((INC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type)); - /* depend on the type of src_rr_node */ - switch (src_rr_node->type) { - case OPIN: - if (((switch_box_x + 1) == src_rr_node->xlow) - &&((switch_box_y == src_rr_node->ylow)||((switch_box_y + 1) == src_rr_node->ylow))) { - return 1; - } - break; - case CHANX: - assert(src_rr_node->ylow == src_rr_node->yhigh); - if ((switch_box_y == src_rr_node->ylow) - &&(!(switch_box_x < src_rr_node->xlow))&&(!(switch_box_x > src_rr_node->xhigh))) { - return 1; - } - break; - case CHANY: - assert(src_rr_node->xlow == src_rr_node->xhigh); - if ((switch_box_x == src_rr_node->xlow) - &&(!(switch_box_y < (src_rr_node->ylow - 1))) - &&(!(switch_box_y > (src_rr_node->yhigh + 1)))) { - return 1; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case BOTTOM: - /* Following cases: - * | - * \ | / - * | - */ - /* The destination rr_node only have one condition!!! */ - assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANY == des_rr_node->type)); - /* depend on the type of src_rr_node */ - switch (src_rr_node->type) { - case OPIN: - if ((switch_box_y == src_rr_node->ylow) - &&((switch_box_x == src_rr_node->xlow)||((switch_box_x + 1) == src_rr_node->xlow))) { - return 1; - } - break; - case CHANX: - assert(src_rr_node->ylow == src_rr_node->yhigh); - if ((switch_box_y == src_rr_node->ylow) - &&(!(switch_box_x < (src_rr_node->xlow - 1))) - &&(!(switch_box_x > (src_rr_node->xhigh + 1)))) { - return 1; - } - break; - case CHANY: - assert(src_rr_node->xlow == src_rr_node->xhigh); - if ((switch_box_x == src_rr_node->xlow) - &&(!((switch_box_y + 1) < src_rr_node->ylow)) - &&(!((switch_box_y + 1) > src_rr_node->yhigh))) { - return 1; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case LEFT: - /* Following cases: - * / - * --- ---- - * \ - */ - /* The destination rr_node only have one condition!!! */ - assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type)); - /* depend on the type of src_rr_node */ - switch (src_rr_node->type) { - case OPIN: - if ((switch_box_x == src_rr_node->xlow) - &&((switch_box_y == src_rr_node->ylow)||((switch_box_y + 1) == src_rr_node->ylow))) { - return 1; - } - break; - case CHANX: - assert(src_rr_node->ylow == src_rr_node->yhigh); - if ((switch_box_y == src_rr_node->ylow) - &&(!((switch_box_x + 1) < src_rr_node->xlow)) - &&(!((switch_box_x + 1) > src_rr_node->xhigh))) { - return 1; - } - break; - case CHANY: - assert(src_rr_node->xlow == src_rr_node->xhigh); - if ((switch_box_x == src_rr_node->xlow) - &&(!(switch_box_y < (src_rr_node->ylow - 1))) - &&(!(switch_box_y > (src_rr_node->yhigh + 1)))) { - return 1; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", - __FILE__, __LINE__); - exit(1); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid side!\n", __FILE__, __LINE__); - exit(1); - } - - return 0; -} - -void find_drive_rr_nodes_switch_box(int switch_box_x, - int switch_box_y, - t_rr_node* src_rr_node, - int chan_side, - int return_num_only, - int* num_drive_rr_nodes, - t_rr_node*** drive_rr_nodes, - int* switch_index) { - int cur_index = 0; - //int inode, iedge, next_node; - int inode; - - /* I decide to kill the codes that search all the edges, the running time is huge... */ - /* Determine the num_drive_rr_nodes */ - (*num_drive_rr_nodes) = 0; - (*switch_index) = -1; - - for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) { - if (1 == rr_node_drive_switch_box(src_rr_node->drive_rr_nodes[inode], src_rr_node, - switch_box_x, switch_box_y, chan_side)) { - /* Get the spice_model */ - if (-1 == (*switch_index)) { - (*switch_index) = src_rr_node->drive_switches[inode]; - } else { /* Make sure the switches are the same*/ - assert((*switch_index) == src_rr_node->drive_switches[inode]); - } - (*num_drive_rr_nodes)++; - } - } - - //for (inode = 0; inode < num_rr_nodes; inode++) { - // for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { - // next_node = rr_node[inode].edges[iedge]; - // /* Make sure the coordinator is matched to this switch box*/ - // if ((src_rr_node == &(rr_node[next_node])) - // &&(1 == rr_node_drive_switch_box(&(rr_node[inode]), src_rr_node, switch_box_x, switch_box_y, chan_side))) { - // /* Get the spice_model */ - // if (-1 == (*switch_index)) { - // (*switch_index) = rr_node[inode].switches[iedge]; - // } else { /* Make sure the switches are the same*/ - // assert((*switch_index) == rr_node[inode].switches[iedge]); - // } - // (*num_drive_rr_nodes)++; - // } - // } - //} - - /* Check and malloc*/ - assert((!(0 > (*num_drive_rr_nodes)))&&(!((*num_drive_rr_nodes) > src_rr_node->fan_in))); - if (1 == return_num_only) { - return; - } - (*drive_rr_nodes) = NULL; - if (0 == (*num_drive_rr_nodes)) { - return; - } - (*drive_rr_nodes) = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*(*num_drive_rr_nodes)); - - /* Find all the rr_nodes that drive current_rr_node*/ - cur_index = 0; - (*switch_index) = -1; - - for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) { - if (1 == rr_node_drive_switch_box(src_rr_node->drive_rr_nodes[inode], src_rr_node, - switch_box_x, switch_box_y, chan_side)) { - /* Update drive_rr_nodes list */ - (*drive_rr_nodes)[cur_index] = src_rr_node->drive_rr_nodes[inode]; - /* Get the spice_model */ - if (-1 == (*switch_index)) { - (*switch_index) = src_rr_node->drive_switches[inode]; - } else { /* Make sure the switches are the same*/ - assert((*switch_index) == src_rr_node->drive_switches[inode]); - } - cur_index++; - } - } - //for (inode = 0; inode < num_rr_nodes; inode++) { - // for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { - // next_node = rr_node[inode].edges[iedge]; - // /* Make sure the coordinator is matched to this switch box*/ - // if ((src_rr_node == &(rr_node[next_node])) - // &&(1 == rr_node_drive_switch_box(&(rr_node[inode]), src_rr_node, switch_box_x, switch_box_y, chan_side))) { - // /* Update drive_rr_nodes list */ - // (*drive_rr_nodes)[cur_index] = &(rr_node[inode]); - // /* Get the spice_model */ - // if (-1 == (*switch_index)) { - // (*switch_index) = rr_node[inode].switches[iedge]; - // } else { /* Make sure the switches are the same*/ - // assert((*switch_index) == rr_node[inode].switches[iedge]); - // } - // cur_index++; - // } - // } - //} - /* Verification */ - assert(cur_index == (*num_drive_rr_nodes)); - - return; -} - -/* Count the number of configuration bits of a spice model */ -int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model, - int mux_size) { - int num_sram_bits = 0; - int iport; - int lut_size; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - assert(NULL != cur_spice_model); - - /* Only LUT and MUX requires configuration bits*/ - switch (cur_spice_model->type) { - case SPICE_MODEL_LUT: - /* Determine size of LUT*/ - input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - lut_size = input_ports[0]->size; - num_sram_bits = (int)pow(2.,(double)(lut_size)); - assert(num_sram_bits == sram_ports[0]->size); - assert(1 == output_ports[0]->size); - /* TODO: could be more smart! Use mapped spice_model of SRAM ports! - * Support Non-volatile RRAM-based SRAM */ - switch (cur_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * Number of memory bits is still same as CMOS SRAM - */ - break; - case SPICE_MODEL_DESIGN_CMOS: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - break; - case SPICE_MODEL_MUX: - assert((2 == mux_size)||(2 < mux_size)); - /* Number of configuration bits depends on the MUX structure */ - switch (cur_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - num_sram_bits = determine_tree_mux_level(mux_size); - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - num_sram_bits = mux_size; - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - num_sram_bits = cur_spice_model->design_tech_info.mux_num_level - * determine_num_input_basis_multilevel_mux(mux_size, - cur_spice_model->design_tech_info.mux_num_level); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_sram_bits = 1; - } - /* Also the number of configuration bits depends on the technology*/ - switch (cur_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* 4T1R MUX requires more configuration bits */ - if (SPICE_MODEL_STRUCTURE_TREE == cur_spice_model->design_tech_info.structure) { - /* For tree-structure: we need 3 times more config. bits */ - num_sram_bits = 3 * num_sram_bits; - } else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.structure) { - /* For multi-level structure: we need 1 more config. bits for each level */ - num_sram_bits += cur_spice_model->design_tech_info.mux_num_level; - } else { - num_sram_bits = (num_sram_bits + 1); - } - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_sram_bits = 3; - } - break; - case SPICE_MODEL_DESIGN_CMOS: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - break; - case SPICE_MODEL_WIRE: - case SPICE_MODEL_FF: - case SPICE_MODEL_SRAM: - case SPICE_MODEL_HARDLOGIC: - case SPICE_MODEL_SCFF: - case SPICE_MODEL_VDD: - case SPICE_MODEL_GND: - case SPICE_MODEL_IOPAD: - /* Other block, we just count the number SRAM ports defined by user */ - num_sram_bits = 0; - sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - /* TODO: could be more smart! - * Support Non-volatile RRAM-based SRAM */ - if (0 < num_sram_port) { - assert(NULL != sram_ports); - for (iport = 0; iport < num_sram_port; iport++) { - assert(NULL != sram_ports[iport]->spice_model); - num_sram_bits += sram_ports[iport]->size; - /* TODO: could be more smart! - * Support Non-volatile RRAM-based SRAM */ - switch (cur_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * Number of memory bits is still same as CMOS SRAM - */ - case SPICE_MODEL_DESIGN_CMOS: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - } - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); - exit(1); - } - - return num_sram_bits; -} - -/* For a multiplexer, determine its reserved configuration bits */ -int count_num_reserved_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type) { - int num_reserved_conf_bits = 0; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - /* Check */ - assert(SPICE_MODEL_LUT == cur_spice_model->type); - - /* Determine size of LUT*/ - sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - assert(1 == num_sram_port); - /* TODO: could be more smart! Use mapped spice_model of SRAM ports! - * Support Non-volatile RRAM-based SRAM */ - switch (sram_ports[0]->spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * In memory bank, by intensively share the Bit/Word Lines, - * we only need 1 additional BL and WL for each memory bit. - * Number of memory bits is still same as CMOS SRAM - */ - num_reserved_conf_bits = - count_num_reserved_conf_bits_one_rram_sram_spice_model(sram_ports[0]->spice_model, - cur_sram_orgz_type); - break; - case SPICE_MODEL_DESIGN_CMOS: - num_reserved_conf_bits = 0; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - - /* Free */ - my_free(sram_ports); - - return num_reserved_conf_bits; -} - -/* For a multiplexer, determine its reserved configuration bits */ -int count_num_reserved_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type, - int mux_size) { - int num_reserved_conf_bits = 0; - - /* Check */ - assert(SPICE_MODEL_MUX == cur_spice_model->type); - assert((2 == mux_size)||(2 < mux_size)); - - /* Number of configuration bits depends on the MUX structure */ - switch (cur_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - num_reserved_conf_bits = 2; - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - num_reserved_conf_bits = mux_size; - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - num_reserved_conf_bits = cur_spice_model->design_tech_info.mux_num_level * - determine_num_input_basis_multilevel_mux(mux_size, - cur_spice_model->design_tech_info.mux_num_level); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_reserved_conf_bits = 2; - } - /* Also the number of configuration bits depends on the technology*/ - switch (cur_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - switch (cur_sram_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - /* In memory bank, by intensively share the Bit/Word Lines, - * we only need 1 additional BL and WL for each MUX level. - */ - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_reserved_conf_bits = 2; - } - break; - case SPICE_SRAM_SCAN_CHAIN: - case SPICE_SRAM_STANDALONE: - /* 4T1R MUX requires more configuration bits */ - if (SPICE_MODEL_STRUCTURE_TREE == cur_spice_model->design_tech_info.structure) { - /* For tree-structure: we need 3 times more config. bits */ - num_reserved_conf_bits = 0; - } else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.structure) { - /* For multi-level structure: we need 1 more config. bits for each level */ - num_reserved_conf_bits = 0; - } else { - num_reserved_conf_bits = 0; - } - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_reserved_conf_bits = 0; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case SPICE_MODEL_DESIGN_CMOS: - num_reserved_conf_bits = 0; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - - return num_reserved_conf_bits; -} - -/* For a non-volatile SRAM, we determine its number of reserved conf. bits */ -int count_num_reserved_conf_bits_one_rram_sram_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type) { - int num_reserved_conf_bits = 0; - int num_bl_ports, num_wl_ports; - t_spice_model_port** bl_ports = NULL; - t_spice_model_port** wl_ports = NULL; - - /* Check */ - assert(SPICE_MODEL_SRAM == cur_spice_model->type); - - switch (cur_sram_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - find_bl_wl_ports_spice_model(cur_spice_model, - &num_bl_ports, &bl_ports, - &num_wl_ports, &wl_ports); - assert((1 == num_bl_ports)&&(1 == num_wl_ports)); - assert(bl_ports[0]->size == wl_ports[0]->size); - num_reserved_conf_bits = bl_ports[0]->size - 1; /*TODO: to be more smart: num_bl-1 of SRAM model ?*/ - break; - case SPICE_SRAM_SCAN_CHAIN: - case SPICE_SRAM_STANDALONE: - num_reserved_conf_bits = 0; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Free */ - my_free(bl_ports); - my_free(wl_ports); - - return num_reserved_conf_bits; -} - -int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type, - int mux_size) { - int num_reserved_conf_bits = 0; - int temp_num_reserved_conf_bits = 0; - int iport; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - assert(NULL != cur_spice_model); - - /* Only LUT and MUX requires configuration bits*/ - switch (cur_spice_model->type) { - case SPICE_MODEL_LUT: - num_reserved_conf_bits = - count_num_reserved_conf_bits_one_lut_spice_model(cur_spice_model, - cur_sram_orgz_type); - break; - case SPICE_MODEL_MUX: - num_reserved_conf_bits = - count_num_reserved_conf_bits_one_mux_spice_model(cur_spice_model, - cur_sram_orgz_type, - mux_size); - break; - case SPICE_MODEL_WIRE: - case SPICE_MODEL_FF: - case SPICE_MODEL_SRAM: - case SPICE_MODEL_HARDLOGIC: - case SPICE_MODEL_SCFF: - case SPICE_MODEL_VDD: - case SPICE_MODEL_GND: - case SPICE_MODEL_IOPAD: - /* Other block, we just count the number SRAM ports defined by user */ - num_reserved_conf_bits = 0; - sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - /* TODO: could be more smart! - * Support Non-volatile RRAM-based SRAM */ - if (0 < num_sram_port) { - assert(NULL != sram_ports); - for (iport = 0; iport < num_sram_port; iport++) { - assert(NULL != sram_ports[iport]->spice_model); - /* TODO: could be more smart! - * Support Non-volatile RRAM-based SRAM */ - switch (sram_ports[iport]->spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * Number of memory bits is still same as CMOS SRAM - */ - temp_num_reserved_conf_bits = - count_num_reserved_conf_bits_one_rram_sram_spice_model(sram_ports[iport]->spice_model, - cur_sram_orgz_type); - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - break; - case SPICE_MODEL_DESIGN_CMOS: - num_reserved_conf_bits = 0; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - } - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); - exit(1); - } - - /* Free */ - my_free(sram_ports); - - return num_reserved_conf_bits; -} - - - -/* Count the number of configuration bits of a spice model */ -int count_num_conf_bits_one_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type, - int mux_size) { - int num_conf_bits = 0; - int iport; - int lut_size; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - assert(NULL != cur_spice_model); - - /* Only LUT and MUX requires configuration bits*/ - switch (cur_spice_model->type) { - case SPICE_MODEL_LUT: - /* Determine size of LUT*/ - input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - lut_size = input_ports[0]->size; - num_conf_bits = (int)pow(2.,(double)(lut_size)); - assert(num_conf_bits == sram_ports[0]->size); - assert(1 == output_ports[0]->size); - /* TODO: could be more smart! Use mapped spice_model of SRAM ports! - * Support Non-volatile RRAM-based SRAM */ - switch (sram_ports[0]->spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * In memory bank, by intensively share the Bit/Word Lines, - * we only need 1 additional BL and WL for each memory bit. - * Number of memory bits is still same as CMOS SRAM - */ - switch (cur_sram_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - break; - case SPICE_SRAM_SCAN_CHAIN: - case SPICE_SRAM_STANDALONE: - num_conf_bits = 2 * num_conf_bits; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case SPICE_MODEL_DESIGN_CMOS: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - break; - case SPICE_MODEL_MUX: - assert((2 == mux_size)||(2 < mux_size)); - /* Number of configuration bits depends on the MUX structure */ - switch (cur_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - num_conf_bits = determine_tree_mux_level(mux_size); - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - num_conf_bits = mux_size; - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - num_conf_bits = cur_spice_model->design_tech_info.mux_num_level - * determine_num_input_basis_multilevel_mux(mux_size, - cur_spice_model->design_tech_info.mux_num_level); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_conf_bits = 1; - } - /* Also the number of configuration bits depends on the technology*/ - switch (cur_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - switch (cur_sram_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - /* In memory bank, by intensively share the Bit/Word Lines, - * we only need 1 additional BL and WL for each MUX level. - */ - num_conf_bits = cur_spice_model->design_tech_info.mux_num_level; - /* For 2:1 MUX, whatever structure, there is only one level */ - if (2 == mux_size) { - num_conf_bits = 1; - } - break; - case SPICE_SRAM_SCAN_CHAIN: - case SPICE_SRAM_STANDALONE: - /* Currently we keep the same as CMOS MUX */ - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case SPICE_MODEL_DESIGN_CMOS: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - break; - case SPICE_MODEL_WIRE: - case SPICE_MODEL_FF: - case SPICE_MODEL_SRAM: - case SPICE_MODEL_HARDLOGIC: - case SPICE_MODEL_SCFF: - case SPICE_MODEL_VDD: - case SPICE_MODEL_GND: - case SPICE_MODEL_IOPAD: - /* Other block, we just count the number SRAM ports defined by user */ - num_conf_bits = 0; - sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - /* TODO: could be more smart! - * Support Non-volatile RRAM-based SRAM */ - if (0 < num_sram_port) { - assert(NULL != sram_ports); - for (iport = 0; iport < num_sram_port; iport++) { - assert(NULL != sram_ports[iport]->spice_model); - /* TODO: could be more smart! - * Support Non-volatile RRAM-based SRAM */ - switch (sram_ports[iport]->spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * Number of memory bits is still same as CMOS SRAM - */ - switch (cur_sram_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - num_conf_bits += sram_ports[iport]->size; - break; - case SPICE_SRAM_SCAN_CHAIN: - case SPICE_SRAM_STANDALONE: - num_conf_bits += sram_ports[iport]->size; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", - __FILE__, __LINE__); - exit(1); - } - break; - case SPICE_MODEL_DESIGN_CMOS: - /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, - * Number of memory bits is still same as CMOS SRAM - */ - switch (cur_sram_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - num_conf_bits += sram_ports[iport]->size; - break; - case SPICE_SRAM_SCAN_CHAIN: - case SPICE_SRAM_STANDALONE: - num_conf_bits += sram_ports[iport]->size; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", - __FILE__, __LINE__); - exit(1); - } - - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - } - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); - exit(1); - } - - /* Free */ - my_free(input_ports); - my_free(output_ports); - my_free(sram_ports); - - return num_conf_bits; -} - -int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc, - enum e_sram_orgz cur_sram_orgz_type) { - int fan_in = 0; - enum e_interconnect spice_interc_type = DIRECT_INTERC; - - int num_reserved_conf_bits = 0; - int temp_num_reserved_conf_bits = 0; - - /* 1. identify pin interconnection type, - * 2. Identify the number of fan-in (Consider interconnection edges of only selected mode) - * 3. Select and print the SPICE netlist - */ - if (NULL == cur_interc) { - return num_reserved_conf_bits; - } else { - fan_in = cur_interc->fan_in; - if (0 == fan_in) { - return num_reserved_conf_bits; - } - } - /* Initialize the interconnection type that will be implemented in SPICE netlist*/ - switch (cur_interc->type) { - case DIRECT_INTERC: - assert(cur_interc->fan_out == fan_in); - spice_interc_type = DIRECT_INTERC; - break; - case COMPLETE_INTERC: - if (1 == fan_in) { - spice_interc_type = DIRECT_INTERC; - } else { - assert((2 == fan_in)||(2 < fan_in)); - spice_interc_type = MUX_INTERC; - } - break; - case MUX_INTERC: - assert((2 == fan_in)||(2 < fan_in)); - spice_interc_type = MUX_INTERC; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", - __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); - exit(1); - } - /* This time, (2nd round), count the number of configuration bits, according to interc type*/ - switch (spice_interc_type) { - case DIRECT_INTERC: - /* Check : - * 1. Direct interc has only one fan-in! - */ - assert((cur_interc->fan_out == fan_in) - ||((COMPLETE_INTERC == cur_interc->type)&&(1 == fan_in))); - break; - case COMPLETE_INTERC: - case MUX_INTERC: - /* Check : - * MUX should have at least 2 fan_in - */ - assert((2 == fan_in)||(2 < fan_in)); - assert((1 == cur_interc->fan_out)||(1 < cur_interc->fan_out)); - /* 2. spice_model is a wire */ - assert(NULL != cur_interc->spice_model); - assert(SPICE_MODEL_MUX == cur_interc->spice_model->type); - temp_num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(cur_interc->spice_model, - cur_sram_orgz_type, fan_in); - /* FOR COMPLETE_INTERC: we should consider fan_out number ! */ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", - __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); - exit(1); - } - return num_reserved_conf_bits; -} - - -int count_num_conf_bit_one_interc(t_interconnect* cur_interc, - enum e_sram_orgz cur_sram_orgz_type) { - int fan_in = 0; - enum e_interconnect spice_interc_type = DIRECT_INTERC; - - int num_conf_bits = 0; - - /* 1. identify pin interconnection type, - * 2. Identify the number of fan-in (Consider interconnection edges of only selected mode) - * 3. Select and print the SPICE netlist - */ - if (NULL == cur_interc) { - return num_conf_bits; - } else { - fan_in = cur_interc->fan_in; - if (0 == fan_in) { - return num_conf_bits; - } - } - /* Initialize the interconnection type that will be implemented in SPICE netlist*/ - switch (cur_interc->type) { - case DIRECT_INTERC: - assert(cur_interc->fan_out == fan_in); - spice_interc_type = DIRECT_INTERC; - break; - case COMPLETE_INTERC: - if (1 == fan_in) { - spice_interc_type = DIRECT_INTERC; - } else { - assert((2 == fan_in)||(2 < fan_in)); - spice_interc_type = MUX_INTERC; - } - break; - case MUX_INTERC: - assert((2 == fan_in)||(2 < fan_in)); - spice_interc_type = MUX_INTERC; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", - __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); - exit(1); - } - /* This time, (2nd round), count the number of configuration bits, according to interc type*/ - switch (spice_interc_type) { - case DIRECT_INTERC: - /* Check : - * 1. Direct interc has only one fan-in! - */ - assert((cur_interc->fan_out == fan_in) - ||((COMPLETE_INTERC == cur_interc->type)&&(1 == fan_in))); - break; - case COMPLETE_INTERC: - case MUX_INTERC: - /* Check : - * MUX should have at least 2 fan_in - */ - assert((2 == fan_in)||(2 < fan_in)); - assert((1 == cur_interc->fan_out)||(1 < cur_interc->fan_out)); - /* 2. spice_model is a wire */ - assert(NULL != cur_interc->spice_model); - assert(SPICE_MODEL_MUX == cur_interc->spice_model->type); - num_conf_bits = count_num_conf_bits_one_spice_model(cur_interc->spice_model, - cur_sram_orgz_type, fan_in); - /* FOR COMPLETE_INTERC: we should consider fan_out number ! */ - num_conf_bits = num_conf_bits * cur_interc->fan_out; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", - __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); - exit(1); - } - return num_conf_bits; -} - -/* Count the number of configuration bits of interconnection inside a pb_type in its default mode */ -int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode, - enum e_sram_orgz cur_sram_orgz_type) { - int num_conf_bits = 0; - int jinterc = 0; - - for (jinterc = 0; jinterc < cur_pb_type_mode->num_interconnect; jinterc++) { - num_conf_bits += count_num_conf_bit_one_interc(&(cur_pb_type_mode->interconnect[jinterc]), - cur_sram_orgz_type); - } - - return num_conf_bits; -} - -/* Count the number of configuration bits of interconnection inside a pb_type in its default mode */ -int count_num_reserved_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode, - enum e_sram_orgz cur_sram_orgz_type) { - int num_reserved_conf_bits = 0; - int temp_num_reserved_conf_bits = 0; - int jinterc = 0; - - for (jinterc = 0; jinterc < cur_pb_type_mode->num_interconnect; jinterc++) { - /* num of reserved configuration bits is determined by the largest one */ - temp_num_reserved_conf_bits = - count_num_reserved_conf_bit_one_interc(&(cur_pb_type_mode->interconnect[jinterc]), - cur_sram_orgz_type); - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - } - - return num_reserved_conf_bits; -} - -/* Count the number of configuration bits of a grid (type_descriptor) in default mode */ -int rec_count_num_conf_bits_pb_type_default_mode(t_pb_type* cur_pb_type, - t_sram_orgz_info* cur_sram_orgz_info) { - int mode_index, ipb, jpb; - int sum_num_conf_bits = 0; - int num_reserved_conf_bits = 0; - int temp_num_reserved_conf_bits = 0; - - cur_pb_type->default_mode_num_conf_bits = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - rec_count_num_conf_bits_pb_type_default_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb]), cur_sram_orgz_info); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - sum_num_conf_bits = count_num_conf_bits_one_spice_model(cur_pb_type->spice_model, cur_sram_orgz_info->type, 0); - cur_pb_type->default_mode_num_conf_bits = sum_num_conf_bits; - /* calculate the number of reserved configuration bits */ - cur_pb_type->default_mode_num_reserved_conf_bits = - count_num_reserved_conf_bits_one_spice_model(cur_pb_type->spice_model, - cur_sram_orgz_info->type, 0); - } else { /* Count the sum of configuration bits of all the children pb_types */ - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_conf_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_conf_bits; - temp_num_reserved_conf_bits = - cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_reserved_conf_bits; - /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - } - } - /* Count the number of configuration bits of interconnection */ - sum_num_conf_bits += count_num_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), cur_sram_orgz_info->type); - /* Count the number of reserved_configuration bits of interconnection */ - temp_num_reserved_conf_bits = - count_num_reserved_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), - cur_sram_orgz_info->type); - /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - /* Update the info in pb_type */ - cur_pb_type->default_mode_num_reserved_conf_bits = num_reserved_conf_bits; - cur_pb_type->default_mode_num_conf_bits = sum_num_conf_bits; - } - - return sum_num_conf_bits; -} - -/* Count the number of configuration bits of a grid (type_descriptor) in default mode */ -int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, - t_sram_orgz_info* cur_sram_orgz_info) { - int mode_index, ipb, jpb; - int sum_num_conf_bits = 0; - int num_reserved_conf_bits = 0; - int temp_num_reserved_conf_bits = 0; - - cur_pb_type->physical_mode_num_conf_bits = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - rec_count_num_conf_bits_pb_type_physical_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb]), cur_sram_orgz_info); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - sum_num_conf_bits = count_num_conf_bits_one_spice_model(cur_pb_type->spice_model, cur_sram_orgz_info->type, 0); - cur_pb_type->physical_mode_num_conf_bits = sum_num_conf_bits; - /* calculate the number of reserved configuration bits */ - cur_pb_type->physical_mode_num_reserved_conf_bits = - count_num_reserved_conf_bits_one_spice_model(cur_pb_type->spice_model, - cur_sram_orgz_info->type, 0); - } else { /* Count the sum of configuration bits of all the children pb_types */ - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_conf_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_conf_bits; - temp_num_reserved_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_reserved_conf_bits; - - /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - } - } - /* Count the number of configuration bits of interconnection */ - sum_num_conf_bits += count_num_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), - cur_sram_orgz_info->type); - /* Count the number of reserved_configuration bits of interconnection */ - temp_num_reserved_conf_bits = - count_num_reserved_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), - cur_sram_orgz_info->type); - /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - /* Update the info in pb_type */ - cur_pb_type->physical_mode_num_reserved_conf_bits = num_reserved_conf_bits; - cur_pb_type->physical_mode_num_conf_bits = sum_num_conf_bits; - } - - return sum_num_conf_bits; -} - - -/* Count the number of configuration bits of a pb_graph_node */ -int rec_count_num_conf_bits_pb(t_pb* cur_pb, - t_sram_orgz_info* cur_sram_orgz_info) { - int mode_index, ipb, jpb; - t_pb_type* cur_pb_type = NULL; - t_pb_graph_node* cur_pb_graph_node = NULL; - int sum_num_conf_bits = 0; - int num_reserved_conf_bits = 0; - int temp_num_reserved_conf_bits = 0; - - /* Check cur_pb_graph_node*/ - if (NULL == cur_pb) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb.\n", - __FILE__, __LINE__); - exit(1); - } - cur_pb_graph_node = cur_pb->pb_graph_node; - cur_pb_type = cur_pb_graph_node->pb_type; - mode_index = cur_pb->mode; - - cur_pb->num_conf_bits = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* recursive for the child_pbs*/ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Recursive*/ - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - rec_count_num_conf_bits_pb(&(cur_pb->child_pbs[ipb][jpb]), cur_sram_orgz_info); - } else { - /* Check if this pb has no children, no children mean idle*/ - rec_count_num_conf_bits_pb_type_default_mode(cur_pb->child_pbs[ipb][jpb].pb_graph_node->pb_type, - cur_sram_orgz_info); - } - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - sum_num_conf_bits += count_num_conf_bits_one_spice_model(cur_pb_type->spice_model, - cur_sram_orgz_info->type, 0); - cur_pb->num_conf_bits = sum_num_conf_bits; - /* calculate the number of reserved configuration bits */ - cur_pb->num_reserved_conf_bits = - count_num_reserved_conf_bits_one_spice_model(cur_pb_type->spice_model, - cur_sram_orgz_info->type, 0); - - } else { - /* Definition ends*/ - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* we should make sure this placement index == child_pb_type[jpb]*/ - assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - /* Count in the number of configuration bits of on child pb */ - sum_num_conf_bits += cur_pb->child_pbs[ipb][jpb].num_conf_bits; - temp_num_reserved_conf_bits = cur_pb->child_pbs[ipb][jpb].num_reserved_conf_bits; - } else { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_conf_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_conf_bits; - temp_num_reserved_conf_bits = - cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_reserved_conf_bits; - } - /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - } - } - /* Count the number of configuration bits of interconnection */ - sum_num_conf_bits += count_num_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), - cur_sram_orgz_info->type); - /* Count the number of reserved_configuration bits of interconnection */ - temp_num_reserved_conf_bits = - count_num_reserved_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), - cur_sram_orgz_info->type); - /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ - if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { - num_reserved_conf_bits = temp_num_reserved_conf_bits; - } - /* Update the info in pb_type */ - cur_pb->num_reserved_conf_bits = num_reserved_conf_bits; - cur_pb->num_conf_bits = sum_num_conf_bits; - } - - return sum_num_conf_bits; -} - -/* Initialize the number of configuraion bits for one grid */ -void init_one_grid_num_conf_bits(int ix, int iy, - t_sram_orgz_info* cur_sram_orgz_info) { - t_block* mapped_block = NULL; - int iz; - int cur_block_index = 0; - int capacity; - - /* Check */ - assert((!(0 > ix))&&(!(ix > (nx + 1)))); - assert((!(0 > iy))&&(!(iy > (ny + 1)))); - - if ((NULL == grid[ix][iy].type) - ||(EMPTY_TYPE == grid[ix][iy].type) - ||(0 != grid[ix][iy].offset)) { - /* Empty grid, directly return */ - return; - } - capacity= grid[ix][iy].type->capacity; - assert(0 < capacity); - - /* check capacity and if this has been mapped */ - for (iz = 0; iz < capacity; iz++) { - /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ - mapped_block = search_mapped_block(ix, iy, iz); - rec_count_num_conf_bits_pb_type_physical_mode(grid[ix][iy].type->pb_type, cur_sram_orgz_info); - /* Comments: Grid [x][y]*/ - if (NULL == mapped_block) { - /* Print a consider a idle pb_type ...*/ - rec_count_num_conf_bits_pb_type_default_mode(grid[ix][iy].type->pb_type, cur_sram_orgz_info); - } else { - if (iz == mapped_block->z) { - // assert(mapped_block == &(block[grid[ix][iy].blocks[cur_block_index]])); - cur_block_index++; - } - rec_count_num_conf_bits_pb(mapped_block->pb, cur_sram_orgz_info); - } - } - - assert(cur_block_index == grid[ix][iy].usage); - - return; -} - -/* Initialize the number of configuraion bits for all grids */ -void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info) { - int ix, iy; - - /* Core grid */ - vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of configuration bits of Core grids...\n"); - for (ix = 1; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); - } - } - - /* Consider the IO pads */ - vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of configuration bits of I/O grids...\n"); - /* Left side: x = 0, y = 1 .. ny*/ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); - } - /* Right side : x = nx + 1, y = 1 .. ny*/ - ix = nx + 1; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); - } - /* Bottom side : x = 1 .. nx + 1, y = 0 */ - iy = 0; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); - } - /* Top side : x = 1 .. nx + 1, y = nx + 1 */ - iy = ny + 1; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); - } - - return; -} - -/* Reset the counter of each spice_model to be zero */ -void zero_spice_models_cnt(int num_spice_models, t_spice_model* spice_model) { - int imodel = 0; - - for (imodel = 0; imodel < num_spice_models; imodel++) { - spice_model[imodel].cnt = 0; - } - - return; -} - -void zero_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) { - int ix, iy; - /* Initialize */ - for (ix = 0; ix < (nx + 1); ix++) { - for (iy = 0; iy < (ny + 1); iy++) { - cur_spice_model->sb_index_low[ix][iy] = 0; - cur_spice_model->cbx_index_low[ix][iy] = 0; - cur_spice_model->cby_index_low[ix][iy] = 0; - cur_spice_model->sb_index_high[ix][iy] = 0; - cur_spice_model->cbx_index_high[ix][iy] = 0; - cur_spice_model->cby_index_high[ix][iy] = 0; - } - } - return; -} - -void zero_spice_models_routing_index_low_high(int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - zero_one_spice_model_routing_index_low_high(&(spice_model[i])); - } - - return; -} - -/* Malloc routing_index_low and routing_index_high for a spice_model */ -void alloc_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) { - int ix; - - /* [cbx|cby|sb]_index_low */ - /* x - direction*/ - cur_spice_model->sb_index_low = (int**)my_malloc(sizeof(int*)*(nx + 1)); - cur_spice_model->cbx_index_low = (int**)my_malloc(sizeof(int*)*(nx + 1)); - cur_spice_model->cby_index_low = (int**)my_malloc(sizeof(int*)*(nx + 1)); - /* y - direction*/ - for (ix = 0; ix < (nx + 1); ix++) { - cur_spice_model->sb_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); - cur_spice_model->cbx_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); - cur_spice_model->cby_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); - } - - /* grid_index_high */ - /* x - direction*/ - cur_spice_model->sb_index_high = (int**)my_malloc(sizeof(int*)*(nx + 1)); - cur_spice_model->cbx_index_high = (int**)my_malloc(sizeof(int*)*(nx + 1)); - cur_spice_model->cby_index_high = (int**)my_malloc(sizeof(int*)*(nx + 1)); - /* y - direction*/ - for (ix = 0; ix < (nx + 1); ix++) { - cur_spice_model->sb_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); - cur_spice_model->cbx_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); - cur_spice_model->cby_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); - } - - zero_one_spice_model_routing_index_low_high(cur_spice_model); - - return; -} - -void free_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) { - int ix; - - /* index_high */ - for (ix = 0; ix < (nx + 1); ix++) { - my_free(cur_spice_model->sb_index_low[ix]); - my_free(cur_spice_model->cbx_index_low[ix]); - my_free(cur_spice_model->cby_index_low[ix]); - - my_free(cur_spice_model->sb_index_high[ix]); - my_free(cur_spice_model->cbx_index_high[ix]); - my_free(cur_spice_model->cby_index_high[ix]); - } - my_free(cur_spice_model->sb_index_low); - my_free(cur_spice_model->cbx_index_low); - my_free(cur_spice_model->cby_index_low); - - my_free(cur_spice_model->sb_index_high); - my_free(cur_spice_model->cbx_index_high); - my_free(cur_spice_model->cby_index_high); - - return; -} - -void free_spice_model_routing_index_low_high(int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - free_one_spice_model_routing_index_low_high(&(spice_model[i])); - } - - return; -} - -void update_one_spice_model_routing_index_high(int x, int y, t_rr_type chan_type, - t_spice_model* cur_spice_model) { - /* Check */ - assert((!(0 > x))&&(!(x > (nx + 1)))); - assert((!(0 > y))&&(!(y > (ny + 1)))); - assert(NULL != cur_spice_model); - assert(NULL != cur_spice_model->sb_index_high); - assert(NULL != cur_spice_model->sb_index_high[x]); - assert(NULL != cur_spice_model->cbx_index_high); - assert(NULL != cur_spice_model->cbx_index_high[x]); - assert(NULL != cur_spice_model->cby_index_high); - assert(NULL != cur_spice_model->cby_index_high[x]); - - /* Assigne the low */ - if (CHANX == chan_type) { - cur_spice_model->cbx_index_high[x][y] = cur_spice_model->cnt; - } else if (CHANY == chan_type) { - cur_spice_model->cby_index_high[x][y] = cur_spice_model->cnt; - } else if (SOURCE == chan_type) { - cur_spice_model->sb_index_high[x][y] = cur_spice_model->cnt; - } - - return; -} - -void update_spice_models_routing_index_high(int x, int y, t_rr_type chan_type, - int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - update_one_spice_model_routing_index_high(x, y, chan_type, &(spice_model[i])); - } - - return; -} - -void update_one_spice_model_routing_index_low(int x, int y, t_rr_type chan_type, - t_spice_model* cur_spice_model) { - /* Check */ - assert((!(0 > x))&&(!(x > (nx + 1)))); - assert((!(0 > y))&&(!(y > (ny + 1)))); - assert(NULL != cur_spice_model); - assert(NULL != cur_spice_model->sb_index_low); - assert(NULL != cur_spice_model->sb_index_low[x]); - assert(NULL != cur_spice_model->cbx_index_low); - assert(NULL != cur_spice_model->cbx_index_low[x]); - assert(NULL != cur_spice_model->cby_index_low); - assert(NULL != cur_spice_model->cby_index_low[x]); - - /* Assigne the low */ - if (CHANX == chan_type) { - cur_spice_model->cbx_index_low[x][y] = cur_spice_model->cnt; - } else if (CHANY == chan_type) { - cur_spice_model->cby_index_low[x][y] = cur_spice_model->cnt; - } else if (SOURCE == chan_type) { - cur_spice_model->sb_index_low[x][y] = cur_spice_model->cnt; - } - - return; -} - -void update_spice_models_routing_index_low(int x, int y, t_rr_type chan_type, - int num_spice_models, - t_spice_model* spice_model) { - int i; - - for (i = 0; i < num_spice_models; i++) { - update_one_spice_model_routing_index_low(x, y, chan_type, &(spice_model[i])); - } - - return; -} - -/* Count the number of inpad and outpad of a grid (type_descriptor) in default mode */ -void rec_count_num_iopads_pb_type_physical_mode(t_pb_type* cur_pb_type) { - int mode_index, ipb, jpb; - int sum_num_iopads = 0; - - cur_pb_type->physical_mode_num_iopads = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - rec_count_num_iopads_pb_type_physical_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb])); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { - sum_num_iopads = 1; - cur_pb_type->physical_mode_num_iopads = sum_num_iopads; - } - } else { /* Count the sum of configuration bits of all the children pb_types */ - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_iopads += cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_iopads; - } - } - /* Count the number of configuration bits of interconnection */ - /* Update the info in pb_type */ - cur_pb_type->physical_mode_num_iopads = sum_num_iopads; - } - - return; -} - -/* Count the number of inpad and outpad of a grid (type_descriptor) in default mode */ -void rec_count_num_iopads_pb_type_default_mode(t_pb_type* cur_pb_type) { - int mode_index, ipb, jpb; - int sum_num_iopads = 0; - - cur_pb_type->default_mode_num_iopads = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - rec_count_num_iopads_pb_type_default_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb])); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { - sum_num_iopads = 1; - cur_pb_type->default_mode_num_iopads = sum_num_iopads; - } - } else { /* Count the sum of configuration bits of all the children pb_types */ - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_iopads += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_iopads; - } - } - /* Count the number of configuration bits of interconnection */ - /* Update the info in pb_type */ - cur_pb_type->default_mode_num_iopads = sum_num_iopads; - } - - return; -} - -/* Count the number of configuration bits of a pb_graph_node */ -void rec_count_num_iopads_pb(t_pb* cur_pb) { - int mode_index, ipb, jpb; - t_pb_type* cur_pb_type = NULL; - t_pb_graph_node* cur_pb_graph_node = NULL; - - int sum_num_iopads = 0; - - /* Check cur_pb_graph_node*/ - if (NULL == cur_pb) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb.\n", - __FILE__, __LINE__); - exit(1); - } - cur_pb_graph_node = cur_pb->pb_graph_node; - cur_pb_type = cur_pb_graph_node->pb_type; - mode_index = cur_pb->mode; - - cur_pb->num_iopads = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* recursive for the child_pbs*/ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Recursive*/ - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - rec_count_num_iopads_pb(&(cur_pb->child_pbs[ipb][jpb])); - } else { - /* Check if this pb has no children, no children mean idle*/ - rec_count_num_iopads_pb_type_default_mode(cur_pb->child_pbs[ipb][jpb].pb_graph_node->pb_type); - } - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { - sum_num_iopads = 1; - cur_pb->num_iopads = sum_num_iopads; - } - } else { - /* Definition ends*/ - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* we should make sure this placement index == child_pb_type[jpb]*/ - assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - /* Count in the number of configuration bits of on child pb */ - sum_num_iopads += cur_pb->child_pbs[ipb][jpb].num_iopads; - } else { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_iopads += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_iopads; - } - } - } - /* Count the number of configuration bits of interconnection */ - /* Update the info in pb_type */ - cur_pb->num_iopads = sum_num_iopads; - } - - return; -} - -/* Initialize the number of configuraion bits for one grid */ -void init_one_grid_num_iopads(int ix, int iy) { - t_block* mapped_block = NULL; - int iz; - int cur_block_index = 0; - int capacity; - - /* Check */ - assert((!(0 > ix))&&(!(ix > (nx + 1)))); - assert((!(0 > iy))&&(!(iy > (ny + 1)))); - - if ((NULL == grid[ix][iy].type) - ||(EMPTY_TYPE == grid[ix][iy].type) - ||(0 != grid[ix][iy].offset)) { - /* Empty grid, directly return */ - return; - } - capacity= grid[ix][iy].type->capacity; - assert(0 < capacity); - - /* check capacity and if this has been mapped */ - for (iz = 0; iz < capacity; iz++) { - /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ - mapped_block = search_mapped_block(ix, iy, iz); - rec_count_num_iopads_pb_type_physical_mode(grid[ix][iy].type->pb_type); - /* Comments: Grid [x][y]*/ - if (NULL == mapped_block) { - /* Print a consider a idle pb_type ...*/ - rec_count_num_iopads_pb_type_default_mode(grid[ix][iy].type->pb_type); - } else { - if (iz == mapped_block->z) { - // assert(mapped_block == &(block[grid[ix][iy].blocks[cur_block_index]])); - cur_block_index++; - } - rec_count_num_iopads_pb(mapped_block->pb); - } - } - - assert(cur_block_index == grid[ix][iy].usage); - - return; -} - -/* Initialize the number of configuraion bits for all grids */ -void init_grids_num_iopads() { - int ix, iy; - - /* Core grid */ - vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of I/O pads of Core grids...\n"); - for (ix = 1; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - init_one_grid_num_iopads(ix, iy); - } - } - - /* Consider the IO pads */ - vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of I/O pads of I/O grids...\n"); - /* Left side: x = 0, y = 1 .. ny*/ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_iopads(ix, iy); - } - /* Right side : x = nx + 1, y = 1 .. ny*/ - ix = nx + 1; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_iopads(ix, iy); - } - /* Bottom side : x = 1 .. nx + 1, y = 0 */ - iy = 0; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_iopads(ix, iy); - } - /* Top side : x = 1 .. nx + 1, y = nx + 1 */ - iy = ny + 1; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_iopads(ix, iy); - } - - return; -} - -/* Count the number of mode configuration bits of a grid (type_descriptor) in default mode */ -void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type) { - int mode_index, ipb, jpb; - int sum_num_mode_bits = 0; - - cur_pb_type->default_mode_num_mode_bits = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - rec_count_num_mode_bits_pb_type_default_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb])); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { - sum_num_mode_bits = 1; - cur_pb_type->default_mode_num_mode_bits = sum_num_mode_bits; - } - } else { /* Count the sum of configuration bits of all the children pb_types */ - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_mode_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_mode_bits; - } - } - /* Count the number of configuration bits of interconnection */ - /* Update the info in pb_type */ - cur_pb_type->default_mode_num_mode_bits = sum_num_mode_bits; - } - - return; -} - -/* Count the number of configuration bits of a pb_graph_node */ -void rec_count_num_mode_bits_pb(t_pb* cur_pb) { - int mode_index, ipb, jpb; - t_pb_type* cur_pb_type = NULL; - t_pb_graph_node* cur_pb_graph_node = NULL; - - int sum_num_mode_bits = 0; - - /* Check cur_pb_graph_node*/ - if (NULL == cur_pb) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb.\n", - __FILE__, __LINE__); - exit(1); - } - cur_pb_graph_node = cur_pb->pb_graph_node; - cur_pb_type = cur_pb_graph_node->pb_type; - mode_index = cur_pb->mode; - - cur_pb->num_mode_bits = 0; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* recursive for the child_pbs*/ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Recursive*/ - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - rec_count_num_mode_bits_pb(&(cur_pb->child_pbs[ipb][jpb])); - } else { - /* Check if this pb has no children, no children mean idle*/ - rec_count_num_mode_bits_pb_type_default_mode(cur_pb->child_pbs[ipb][jpb].pb_graph_node->pb_type); - } - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { - sum_num_mode_bits = 1; - cur_pb->num_mode_bits = sum_num_mode_bits; - } - } else { - /* Definition ends*/ - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* we should make sure this placement index == child_pb_type[jpb]*/ - assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - /* Count in the number of configuration bits of on child pb */ - sum_num_mode_bits += cur_pb->child_pbs[ipb][jpb].num_mode_bits; - } else { - /* Count in the number of configuration bits of on child pb_type */ - sum_num_mode_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_mode_bits; - } - } - } - /* Count the number of configuration bits of interconnection */ - /* Update the info in pb_type */ - cur_pb->num_mode_bits = sum_num_mode_bits; - } - - return; -} - -/* Initialize the number of configuraion bits for one grid */ -void init_one_grid_num_mode_bits(int ix, int iy) { - t_block* mapped_block = NULL; - int iz; - int cur_block_index = 0; - int capacity; - - /* Check */ - assert((!(0 > ix))&&(!(ix > (nx + 1)))); - assert((!(0 > iy))&&(!(iy > (ny + 1)))); - - if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) { - /* Empty grid, directly return */ - return; - } - capacity= grid[ix][iy].type->capacity; - assert(0 < capacity); - - /* check capacity and if this has been mapped */ - for (iz = 0; iz < capacity; iz++) { - /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ - mapped_block = search_mapped_block(ix, iy, iz); - /* Comments: Grid [x][y]*/ - if (NULL == mapped_block) { - /* Print a consider a idle pb_type ...*/ - rec_count_num_mode_bits_pb_type_default_mode(grid[ix][iy].type->pb_type); - } else { - if (iz == mapped_block->z) { - // assert(mapped_block == &(block[grid[ix][iy].blocks[cur_block_index]])); - cur_block_index++; - } - rec_count_num_mode_bits_pb(mapped_block->pb); - } - } - - assert(cur_block_index == grid[ix][iy].usage); - - return; -} - -/* Initialize the number of configuraion bits for all grids */ -void init_grids_num_mode_bits() { - int ix, iy; - - /* Core grid */ - vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of mode configuraiton bits of Core grids...\n"); - for (ix = 1; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - init_one_grid_num_mode_bits(ix, iy); - } - } - - /* Consider the IO pads */ - vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of mode configuration bits of I/O grids...\n"); - /* Left side: x = 0, y = 1 .. ny*/ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_mode_bits(ix, iy); - } - /* Right side : x = nx + 1, y = 1 .. ny*/ - ix = nx + 1; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_mode_bits(ix, iy); - } - /* Bottom side : x = 1 .. nx + 1, y = 0 */ - iy = 0; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_mode_bits(ix, iy); - } - /* Top side : x = 1 .. nx + 1, y = nx + 1 */ - iy = ny + 1; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - init_one_grid_num_mode_bits(ix, iy); - } - - return; -} - - -/* Check if this SPICE model defined as SRAM - * contain necessary ports for its functionality - */ -void check_sram_spice_model_ports(t_spice_model* cur_spice_model, - boolean include_bl_wl) { - int num_input_ports; - t_spice_model_port** input_ports = NULL; - int num_output_ports; - t_spice_model_port** output_ports = NULL; - int num_bl_ports; - t_spice_model_port** bl_ports = NULL; - int num_wl_ports; - t_spice_model_port** wl_ports = NULL; - - int iport; - int num_global_ports = 0; - int num_err = 0; - - /* Check the type of SPICE model */ - assert(SPICE_MODEL_SRAM == cur_spice_model->type); - - /* Check if we has 1 input other than global ports */ - input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_ports, TRUE); - num_global_ports = 0; - for (iport = 0; iport < num_input_ports; iport++) { - if (TRUE == input_ports[iport]->is_global) { - num_global_ports++; - } - } - if (1 != (num_input_ports - num_global_ports)) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have only 1 non-global input port!\n", - __FILE__, __LINE__); - num_err++; - if (1 != input_ports[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have an input port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } - /* Check if we has 1 output with size 2 */ - output_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_ports, TRUE); - num_global_ports = 0; - for (iport = 0; iport < num_output_ports; iport++) { - if (TRUE == output_ports[iport]->is_global) { - num_global_ports++; - } - } - if (1 != (num_output_ports - num_global_ports)) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have only 1 non-global output port!\n", - __FILE__, __LINE__); - num_err++; - if (2 != output_ports[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have a output port with size 2!\n", - __FILE__, __LINE__); - num_err++; - } - } - if (FALSE == include_bl_wl) { - if (0 == num_err) { - return; - } else { - exit(1); - } - } - /* If bl and wl are required, check their existence */ - bl_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_BL, &num_bl_ports, TRUE); - if (1 != num_bl_ports) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL with BL and WL should have only 1 BL port!\n", - __FILE__, __LINE__); - num_err++; - exit(1); - if (1 != bl_ports[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have a BL port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } - - wl_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_WL, &num_wl_ports, TRUE); - if (1 != num_wl_ports) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL with WL and WL should have only 1 WL port!\n", - __FILE__, __LINE__); - num_err++; - exit(1); - if (1 != wl_ports[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have a WL port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } - - if (0 < num_err) { - exit(1); - } - - /* Free */ - my_free(input_ports); - my_free(output_ports); - my_free(bl_ports); - my_free(wl_ports); - - return; -} - -void check_ff_spice_model_ports(t_spice_model* cur_spice_model, - boolean is_scff) { - int iport; - int num_input_ports; - t_spice_model_port** input_ports = NULL; - int num_output_ports; - t_spice_model_port** output_ports = NULL; - int num_clock_ports; - t_spice_model_port** clock_ports = NULL; - - int num_err = 0; - - /* Check the type of SPICE model */ - if (FALSE == is_scff) { - assert(SPICE_MODEL_FF == cur_spice_model->type); - } else { - assert(SPICE_MODEL_SCFF == cur_spice_model->type); - } - /* Check if we have D, Set and Reset */ - input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_ports, FALSE); - if (TRUE == is_scff) { - if (1 > num_input_ports) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL should at least have an input port!\n", - __FILE__, __LINE__); - num_err++; - } - for (iport = 0; iport < num_input_ports; iport++) { - if (1 != input_ports[iport]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL: each input port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } - } else { - if (3 != num_input_ports) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) FF SPICE MODEL should have only 3 input port!\n", - __FILE__, __LINE__); - num_err++; - } - for (iport = 0; iport < num_input_ports; iport++) { - if (1 != input_ports[iport]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) FF SPICE MODEL: each input port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } - } - /* Check if we have clock */ - clock_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_CLOCK, &num_clock_ports, FALSE); - if (1 > num_clock_ports) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) [FF|SCFF] SPICE MODEL should have at least 1 clock port!\n", - __FILE__, __LINE__); - num_err++; - } - for (iport = 0; iport < num_clock_ports; iport++) { - if (1 != clock_ports[iport]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) [FF|SCFF] SPICE MODEL: 1 clock port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } - /* Check if we have output */ - output_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_ports, TRUE); - if (FALSE == is_scff) { - if (1 != output_ports[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) FF SPICE MODEL: each output port with size 1!\n", - __FILE__, __LINE__); - num_err++; - } - } else { - if (1 != num_output_ports) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL should have only 1 output port!\n", - __FILE__, __LINE__); - num_err++; - if (2 != output_ports[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL: the output port with size 2!\n", - __FILE__, __LINE__); - num_err++; - } - } - } - /* Error out if required */ - if (0 < num_err) { - exit(1); - } - - /* Free */ - my_free(input_ports); - my_free(output_ports); - my_free(clock_ports); - - return; -} - -/* Free a conf_bit_info */ -void free_conf_bit(t_conf_bit* conf_bit) { - return; -} - -void free_conf_bit_info(t_conf_bit_info* conf_bit_info) { - free_conf_bit(conf_bit_info->sram_bit); - my_free(conf_bit_info->sram_bit); - - free_conf_bit(conf_bit_info->bl); - my_free(conf_bit_info->bl); - - free_conf_bit(conf_bit_info->wl); - my_free(conf_bit_info->wl); - - return; -} - -/* Fill the information into a confbit_info */ -t_conf_bit_info* -alloc_one_conf_bit_info(int index, - t_conf_bit* sram_val, - t_conf_bit* bl_val, t_conf_bit* wl_val, - t_spice_model* parent_spice_model) { - t_conf_bit_info* new_conf_bit_info = (t_conf_bit_info*)my_malloc(sizeof(t_conf_bit_info)); - - /* Check if we have a valid conf_bit_info */ - if (NULL == new_conf_bit_info) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to malloc a new conf_bit_info!\n", - __FILE__, __LINE__); - exit(1); - } - /* Fill the information */ - new_conf_bit_info->index = index; - new_conf_bit_info->sram_bit = sram_val; - new_conf_bit_info->bl = bl_val; - new_conf_bit_info->wl = wl_val; - new_conf_bit_info->parent_spice_model = parent_spice_model; - new_conf_bit_info->parent_spice_model_index = parent_spice_model->cnt; - - return new_conf_bit_info; -} - -/* Add an element to linked-list */ -t_llist* -add_conf_bit_info_to_llist(t_llist* head, int index, - t_conf_bit* sram_val, t_conf_bit* bl_val, t_conf_bit* wl_val, - t_spice_model* parent_spice_model) { - t_llist* temp = NULL; - t_conf_bit_info* new_conf_bit_info = NULL; - - /* if head is NULL, we create a head */ - if (NULL == head) { - temp = create_llist(1); - new_conf_bit_info = alloc_one_conf_bit_info(index, sram_val, bl_val, wl_val, parent_spice_model); - assert(NULL != new_conf_bit_info); - temp->dptr = (void*)new_conf_bit_info; - assert(NULL == temp->next); - return temp; - } else { - /* If head is a valid pointer, we add a new element to the tail of this linked-list */ - temp = insert_llist_node_before_head(head); - new_conf_bit_info = alloc_one_conf_bit_info(index, sram_val, bl_val, wl_val, parent_spice_model); - assert(NULL != new_conf_bit_info); - temp->dptr = (void*)new_conf_bit_info; - return temp; - } -} - -/* add configuration bits of a MUX to linked-list - * when SRAM organization type is scan-chain */ -void -add_mux_scff_conf_bits_to_llist(int mux_size, - t_sram_orgz_info* cur_sram_orgz_info, - int num_mux_sram_bits, int* mux_sram_bits, - t_spice_model* mux_spice_model) { - int ibit, cur_mem_bit; - t_conf_bit** sram_bit = NULL; - - /* Assert*/ - assert(NULL != cur_sram_orgz_info); - assert(NULL != mux_spice_model); - - cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); - - /* Depend on the design technology of mux_spice_model - * Fill the conf_bits information */ - switch (mux_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - case SPICE_MODEL_DESIGN_RRAM: - /* Count how many configuration bits need to program - * Scan-chain needs to know each memory bit whatever it is 0 or 1 - */ - /* Allocate the array */ - sram_bit = (t_conf_bit**)my_malloc(num_mux_sram_bits * sizeof(t_conf_bit*)); - for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { - sram_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - } - /* Fill the array: sram_bit */ - for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { - sram_bit[ibit]->addr = cur_mem_bit + ibit; - sram_bit[ibit]->val = mux_sram_bits[ibit]; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", - __FILE__, __LINE__ ); - exit(1); - } - - /* Fill the linked list */ - for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { - cur_sram_orgz_info->conf_bit_head = - add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, cur_mem_bit + ibit, - sram_bit[ibit], NULL, NULL, - mux_spice_model); - } - - /* Free */ - my_free(sram_bit); - - return; -} - -/* add configuration bits of a MUX to linked-list - * when SRAM organization type is scan-chain */ -void -add_mux_membank_conf_bits_to_llist(int mux_size, - t_sram_orgz_info* cur_sram_orgz_info, - int num_mux_sram_bits, int* mux_sram_bits, - t_spice_model* mux_spice_model) { - int ibit, cur_mem_bit, num_conf_bits, cur_bit, cur_bl, cur_wl; - int ilevel; - int num_bl_enabled, num_wl_enabled; - t_conf_bit** sram_bit = NULL; - t_conf_bit** wl_bit = NULL; - t_conf_bit** bl_bit = NULL; - - /* Assert*/ - assert(NULL != cur_sram_orgz_info); - assert(NULL != mux_spice_model); - - cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); - get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); - - /* Depend on the design technology of mux_spice_model - * Fill the conf_bits information */ - switch (mux_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - /* Count how many configuration bits need to program - * Assume all the SRAMs are zero initially. - * only Configuration to bit 1 requires a programming operation - */ - num_conf_bits = num_mux_sram_bits; - /* Allocate the array */ - bl_bit = (t_conf_bit**)my_malloc(num_mux_sram_bits * sizeof(t_conf_bit*)); - wl_bit = (t_conf_bit**)my_malloc(num_mux_sram_bits * sizeof(t_conf_bit*)); - for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { - bl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - wl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - } - /* SRAMs are typically organized in an array where BLs and WLs are efficiently shared - * Actual BL/WL address in the array is hard to predict here, - * they will be handled in the top_netlist and top_testbench generation - */ - for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { - bl_bit[ibit]->addr = cur_mem_bit + ibit; - bl_bit[ibit]->val = mux_sram_bits[ibit]; - wl_bit[ibit]->addr = cur_mem_bit + ibit; - wl_bit[ibit]->val = 1; /* We always assume WL is the write enable signal of a SRAM */ - } - break; - case SPICE_MODEL_DESIGN_RRAM: - /* Count how many configuration bits need to program - * only BL and WL are both 1 requires a programming operation - * Each level of a MUX requires 1 RRAM to be configured. - * Therefore, the number of configuration bits should be num_mux_levels - */ - num_bl_enabled = 0; - /* Check how many Bit lines are 1 */ - for (ibit = 0; ibit < num_mux_sram_bits/2; ibit++) { - if (1 == mux_sram_bits[ibit]) { - num_bl_enabled++; - } - } - num_wl_enabled = 0; - /* Check how many Word lines are 1 */ - for (ibit = 0; ibit < num_mux_sram_bits/2; ibit++) { - if (1 == mux_sram_bits[ibit + num_mux_sram_bits/2]) { - num_wl_enabled++; - } - } - /* The number of enabled Bit and Word lines should be the same */ - assert(num_bl_enabled == num_wl_enabled); - /* Assign num_conf_bits */ - num_conf_bits = num_bl_enabled; - /* Allocate the array */ - bl_bit = (t_conf_bit**)my_malloc(num_conf_bits * sizeof(t_conf_bit*)); - wl_bit = (t_conf_bit**)my_malloc(num_conf_bits * sizeof(t_conf_bit*)); - for (ibit = 0; ibit < num_conf_bits; ibit++) { - bl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - wl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - } - /* For one-level RRAM MUX: - * There should be only 1 BL and 1 WL whose value is 1 - * First half of mux_sram_bits are BL, the rest are WL - * For multi-level RRAM MUX: - * There could be more than 1 BL and 1 WL whose value is 1 - * We need to divde the mux_sram_bits into small part, - * each part has only 1 BL and 1 WL whose value is 1 - */ - /* Assign bit lines address and values */ - cur_bit = 0; - /* We slice the BL part of array mux_sram_bits to N=num_conf_bits parts */ - for (ilevel = 0; ilevel < num_conf_bits; ilevel++) { - for (ibit = ilevel * num_mux_sram_bits/(2*num_conf_bits); /* Start address of each slice*/ - ibit < (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits); /* End address of each slice*/ - ibit++) { - if (0 == mux_sram_bits[ibit]) { - continue; /* Skip non-zero bits */ - } - assert(1 == mux_sram_bits[ibit]); - if (ibit == (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits) - 1) { - bl_bit[cur_bit]->addr = cur_bl + ilevel; - /* Last conf_bit should use a new BL/WL */ - } else { - /* First part of conf_bit should use reserved BL/WL */ - bl_bit[cur_bit]->addr = ibit; - } - bl_bit[cur_bit]->val = mux_sram_bits[ibit]; - cur_bit++; - } - } - assert(num_conf_bits == cur_bit); - /* Assign Word lines address and values */ - cur_bit = 0; - for (ilevel = 0; ilevel < num_conf_bits; ilevel++) { - for (ibit = num_mux_sram_bits/2 + ilevel * num_mux_sram_bits/(2*num_conf_bits); /* Start address of each slice*/ - ibit < num_mux_sram_bits/2 + (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits); /* End address of each slice*/ - ibit++) { - if (0 == mux_sram_bits[ibit]) { - continue; /* Skip non-zero bits */ - } - assert(1 == mux_sram_bits[ibit]); - if (ibit == num_mux_sram_bits/2 + (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits) - 1) { - wl_bit[cur_bit]->addr = cur_wl + ilevel; - /* Last conf_bit should use a new BL/WL */ - } else { - /* First part of conf_bit should use reserved BL/WL */ - wl_bit[cur_bit]->addr = ibit; - } - wl_bit[cur_bit]->val = mux_sram_bits[ibit]; - cur_bit++; - } - } - assert(num_conf_bits == cur_bit); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", - __FILE__, __LINE__ ); - exit(1); - } - - /* Fill the linked list */ - for (ibit = 0; ibit < num_conf_bits; ibit++) { - cur_sram_orgz_info->conf_bit_head = - add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, cur_mem_bit + ibit, - NULL, bl_bit[ibit], wl_bit[ibit], - mux_spice_model); - } - - /* Free */ - my_free(sram_bit); - my_free(bl_bit); - my_free(wl_bit); - - return; -} - -/* Should we return a value ? */ -void -add_mux_conf_bits_to_llist(int mux_size, - t_sram_orgz_info* cur_sram_orgz_info, - int num_mux_sram_bits, int* mux_sram_bits, - t_spice_model* mux_spice_model) { - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - add_mux_scff_conf_bits_to_llist(mux_size, cur_sram_orgz_info, - num_mux_sram_bits, mux_sram_bits, - mux_spice_model); - break; - case SPICE_SRAM_MEMORY_BANK: - add_mux_membank_conf_bits_to_llist(mux_size, cur_sram_orgz_info, - num_mux_sram_bits, mux_sram_bits, - mux_spice_model); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* Add SCFF configutration bits to a linked list*/ -void -add_sram_scff_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, - int num_sram_bits, int* sram_bits) { - int ibit, cur_mem_bit; - t_conf_bit** sram_bit = NULL; - t_spice_model* cur_sram_spice_model = NULL; - - /* Assert*/ - assert(NULL != cur_sram_orgz_info); - - cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); - - /* Get memory model */ - get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_sram_spice_model); - assert(NULL != cur_sram_spice_model); - - /* Count how many configuration bits need to program - * Scan-chain needs to know each memory bit whatever it is 0 or 1 - */ - /* Allocate the array */ - sram_bit = (t_conf_bit**)my_malloc(num_sram_bits * sizeof(t_conf_bit*)); - for (ibit = 0; ibit < num_sram_bits; ibit++) { - sram_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - } - /* Fill the array: sram_bit */ - for (ibit = 0; ibit < num_sram_bits; ibit++) { - sram_bit[ibit]->addr = cur_mem_bit + ibit; - sram_bit[ibit]->val = sram_bits[ibit]; - } - - /* Fill the linked list */ - for (ibit = 0; ibit < num_sram_bits; ibit++) { - cur_sram_orgz_info->conf_bit_head = - add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, cur_mem_bit + ibit, - sram_bit[ibit], NULL, NULL, - cur_sram_spice_model); - } - - /* Free */ - my_free(sram_bit); - - return; -} - - -/* Add SRAM configuration bits in memory bank organization to a linked list */ -void add_sram_membank_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, - int num_bls, int num_wls, - int* bl_conf_bits, int* wl_conf_bits) { - int ibit, cur_bl, cur_wl, cur_mem_bit; - t_spice_model* cur_sram_spice_model = NULL; - t_conf_bit* bl_bit = NULL; - t_conf_bit* wl_bit = NULL; - int bit_cnt = 0; - - /* Assert*/ - assert(NULL != cur_sram_orgz_info); - - /* Get current counter of sram_spice_model */ - cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); - get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); - - /* Get memory model */ - get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_sram_spice_model); - assert(NULL != cur_sram_spice_model); - - /* Malloc */ - bl_bit = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - wl_bit = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); - - /* Depend on the memory technology, we have different configuration bits */ - switch (cur_sram_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - assert((1 == num_bls)&&(1 == num_wls)); - bl_bit->addr = mem_index; - wl_bit->addr = mem_index; - bl_bit->val = bl_conf_bits[0]; - wl_bit->val = wl_conf_bits[0]; - break; - case SPICE_MODEL_DESIGN_RRAM: - /* Fill information */ - bit_cnt = 0; /* Check counter */ - for (ibit = 0; ibit < num_bls; ibit++) { - /* Bypass zero bit */ - if (0 == bl_conf_bits[ibit]) { - continue; - } - /* Check if this bit is in reserved bls */ - if (ibit == num_bls - 1) { - /* Last bit is always independent */ - bl_bit->addr = mem_index; - bl_bit->val = 1; - } else { - /* Other bits are shared */ - bl_bit->addr = ibit; - bl_bit->val = 1; - } - /* Update check counter */ - bit_cnt++; - } - /* Check */ - assert(1 == bit_cnt); - - bit_cnt = 0; /* Check counter */ - for (ibit = 0; ibit < num_wls; ibit++) { - /* Bypass zero bit */ - if (0 == wl_conf_bits[ibit]) { - continue; - } - /* Check if this bit is in reserved bls */ - if (ibit == num_wls - 1) { - /* Last bit is always independent */ - wl_bit->addr = mem_index; - wl_bit->val = 1; - } else { - /* Other bits are shared */ - wl_bit->addr = ibit; - wl_bit->val = 1; - } - /* Update check counter */ - bit_cnt++; - } - /* Check */ - assert(1 == bit_cnt); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", - __FILE__, __LINE__); - exit(1); - } - - /* Fill the linked list */ - cur_sram_orgz_info->conf_bit_head = - add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, mem_index, - NULL, bl_bit, wl_bit, - cur_sram_spice_model); - - return; -} - -/* Add SRAM configuration bits to a linked list */ -void -add_sram_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, - int num_sram_bits, int* sram_bits) { - int num_bls, num_wls; - int* bl_conf_bits = NULL; - int* wl_conf_bits = NULL; - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - add_sram_scff_conf_bits_to_llist(cur_sram_orgz_info, - num_sram_bits, sram_bits); - break; - case SPICE_SRAM_MEMORY_BANK: - /* Initialize parameters */ - /* Number of BLs should be same as WLs */ - num_bls = num_sram_bits/2; - num_wls = num_sram_bits/2; - /* Convention: first part of Array (sram_bits) is BL configuration bits, - * second part is WL configuration bits. - */ - bl_conf_bits = sram_bits; - wl_conf_bits = sram_bits + num_bls; - add_sram_membank_conf_bits_to_llist(cur_sram_orgz_info, mem_index, - num_bls, num_wls, - bl_conf_bits, wl_conf_bits); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* Find BL and WL ports for a SRAM model. - * And check if the number of BL/WL satisfy the technology needs - */ -void find_bl_wl_ports_spice_model(t_spice_model* cur_spice_model, - int* num_bl_ports, t_spice_model_port*** bl_ports, - int* num_wl_ports, t_spice_model_port*** wl_ports) { - int i; - - /* Check */ - assert(NULL != cur_spice_model); - - /* Find BL ports */ - (*bl_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_BL, num_bl_ports, TRUE); - /* Find WL ports */ - (*wl_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_WL, num_wl_ports, TRUE); - - /* port size of BL/WL should be at least 1 !*/ - assert((*num_bl_ports) == (*num_wl_ports)); - - /* Check the size of BL/WL ports */ - switch (cur_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_RRAM: - /* This check may be too tight */ - for (i = 0; i < (*num_bl_ports); i++) { - assert(0 < (*bl_ports)[i]->size); - } - for (i = 0; i < (*num_wl_ports); i++) { - assert(0 < (*wl_ports)[i]->size); - } - break; - case SPICE_MODEL_DESIGN_CMOS: - for (i = 0; i < (*num_bl_ports); i++) { - assert(0 < (*bl_ports)[i]->size); - } - for (i = 0; i < (*num_wl_ports); i++) { - assert(0 < (*wl_ports)[i]->size); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", - __FILE__, __LINE__, cur_spice_model->name); - exit(1); - } - - return; -} - -/* Find BL and WL ports for a SRAM model. - * And check if the number of BL/WL satisfy the technology needs - */ -void find_blb_wlb_ports_spice_model(t_spice_model* cur_spice_model, - int* num_blb_ports, t_spice_model_port*** blb_ports, - int* num_wlb_ports, t_spice_model_port*** wlb_ports) { - /* Check */ - assert(NULL != cur_spice_model); - - /* Find BL ports */ - (*blb_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_BLB, num_blb_ports, TRUE); - /* Find WL ports */ - (*wlb_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_WLB, num_wlb_ports, TRUE); - - return; -} - -/* Decode mode bits "01..." to a SRAM bits array */ -int* decode_mode_bits(char* mode_bits, int* num_sram_bits) { - int* sram_bits = NULL; - int i; - - assert(NULL != mode_bits); - (*num_sram_bits) = strlen(mode_bits); - - sram_bits = (int*)my_calloc((*num_sram_bits), sizeof(int)); - - for (i = 0; i < (*num_sram_bits); i++) { - switch(mode_bits[i]) { - case '1': - sram_bits[i] = 1; - break; - case '0': - sram_bits[i] = 0; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid mode_bits(%s)!\n", - __FILE__, __LINE__, mode_bits); - exit(1); - } - } - - return sram_bits; -} - -/* For LUTs without SPICE netlist defined, we can create a SPICE netlist - * In this case, we need a MUX - */ -void stats_lut_spice_mux(t_llist** muxes_head, - t_spice_model* spice_model) { - int lut_mux_size = 0; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - - if (NULL == spice_model) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid Spice_model pointer!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Check */ - assert(SPICE_MODEL_LUT == spice_model->type); - - /* Get input ports */ - input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - assert(1 == num_input_port); - lut_mux_size = (int)pow(2.,(double)(input_ports[0]->size)); - - /* MUX size = 2^lut_size */ - check_and_add_mux_to_linked_list(muxes_head, lut_mux_size, spice_model); - - return; -} - -char* complete_truth_table_line(int lut_size, - char* input_truth_table_line) { - char* ret = NULL; - int num_token = 0; - char** tokens = NULL; - int cover_len = 0; - int j; - - /* Due to the size of truth table may be less than the lut size. - * i.e. in LUT-6 architecture, there exists LUT1-6 in technology-mapped netlists - * So, in truth table line, there may be 10- 1 - * In this case, we should complete it by --10- 1 - */ - /*Malloc the completed truth table, lut_size + space + truth_val + '\0'*/ - ret = (char*)my_malloc(sizeof(char)*lut_size + 3); - /* Split one line of truth table line*/ - tokens = my_strtok(input_truth_table_line, " ", &num_token); - /* Check, only 2 tokens*/ - /* Sometimes, the truth table is ' 0' or ' 1', which corresponds to a constant */ - if (1 == num_token) { - /* restore the token[0]*/ - tokens = (char**)realloc(tokens, 2*sizeof(char*)); - tokens[1] = tokens[0]; - tokens[0] = my_strdup("-"); - num_token = 2; - } - - /* In Most cases, there should be 2 tokens. */ - assert(2 == num_token); - if ((0 != strcmp(tokens[1], "1"))&&(0 != strcmp(tokens[1], "0"))) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Last token of truth table line should be [0|1]!\n", - __FILE__, __LINE__); - exit(1); - } - /* Complete the truth table line*/ - cover_len = strlen(tokens[0]); - assert((cover_len < lut_size)||(cover_len == lut_size)); - - /* Copy the original truth table line */ - for (j = 0; j < cover_len; j++) { - ret[j] = tokens[0][j]; - } - /* Add the number of '-' we should add in the back !!! */ - for (j = cover_len; j < lut_size; j++) { - ret[j] = '-'; - } - - /* Copy the original truth table line */ - sprintf(ret + lut_size, " %s", tokens[1]); - - /* Free */ - for (j = 0; j < num_token; j++) { - my_free(tokens[j]); - } - - return ret; -} - -/* For each lut_bit_lines, we should recover the truth table, - * and then set the sram bits to "1" if the truth table defines so. - * Start_point: the position we start decode recursively - */ -void configure_lut_sram_bits_per_line_rec(int** sram_bits, - int lut_size, - char* truth_table_line, - int start_point) { - int i; - int num_sram_bit = (int)pow(2., (double)(lut_size)); - char* temp_line = my_strdup(truth_table_line); - int do_config = 1; - int sram_id = 0; - - /* Check the length of sram bits and truth table line */ - //assert((sizeof(int)*num_sram_bit) == sizeof(*sram_bits)); /*TODO: fix this assert*/ - assert((unsigned)(lut_size + 1 + 1)== strlen(truth_table_line)); /* lut_size + space + '1' */ - /* End of truth_table_line should be "space" and "1" */ - assert((0 == strcmp(" 1", truth_table_line + lut_size))||(0 == strcmp(" 0", truth_table_line + lut_size))); - /* Make sure before start point there is no '-' */ - for (i = 0; i < start_point; i++) { - assert('-' != truth_table_line[i]); - } - - /* Configure sram bits recursively */ - for (i = start_point; i < lut_size; i++) { - if ('-' == truth_table_line[i]) { - do_config = 0; - /* if we find a dont_care, we don't do configure now but recursively*/ - /* '0' branch */ - temp_line[i] = '0'; - configure_lut_sram_bits_per_line_rec(sram_bits, lut_size, temp_line, start_point + 1); - /* '1' branch */ - temp_line[i] = '1'; - configure_lut_sram_bits_per_line_rec(sram_bits, lut_size, temp_line, start_point + 1); - break; - } - } - - /* do_config*/ - if (do_config) { - for (i = 0; i < lut_size; i++) { - /* Should be either '0' or '1' */ - switch (truth_table_line[i]) { - case '0': - /* We assume the 1-lut pass sram1 when input = 0 */ - sram_id += (int)pow(2., (double)(i)); - break; - case '1': - /* We assume the 1-lut pass sram0 when input = 1 */ - break; - case '-': - assert('-' != truth_table_line[i]); /* Make sure there is no dont_care */ - default : - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid truth_table bit(%c), should be [0|1|'-]!\n", - __FILE__, __LINE__, truth_table_line[i]); - exit(1); - } - } - /* Set the sram bit to '1'*/ - assert((-1 < sram_id) && (sram_id < num_sram_bit)); - if (0 == strcmp(" 1", truth_table_line + lut_size)) { - (*sram_bits)[sram_id] = 1; /* on set*/ - } else if (0 == strcmp(" 0", truth_table_line + lut_size)) { - (*sram_bits)[sram_id] = 0; /* off set */ - } else { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid truth_table_line ending(=%s)!\n", - __FILE__, __LINE__, truth_table_line + lut_size); - exit(1); - } - } - - /* Free */ - my_free(temp_line); - - return; -} - -/* Determine if the truth table of a LUT is a on-set or a off-set */ -int determine_lut_truth_table_on_set(int truth_table_len, - char** truth_table) { - int on_set = 0; - int off_set = 0; - int i, tt_line_len; - - for (i = 0; i < truth_table_len; i++) { - tt_line_len = strlen(truth_table[i]); - switch (truth_table[i][tt_line_len - 1]) { - case '1': - on_set = 1; - break; - case '0': - off_set = 1; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid truth_table_line ending(=%c)!\n", - __FILE__, __LINE__, truth_table[i][tt_line_len - 1]); - exit(1); - } - } - - /* Prefer on_set if both are true */ - if (1 == (on_set + off_set)) { - on_set = 1; off_set = 0; - } - - return on_set; -} - - -int* generate_lut_sram_bits(int truth_table_len, - char** truth_table, - int lut_size, - int default_sram_bit_value) { - int num_sram = (int)pow(2.,(double)(lut_size)); - int* ret = (int*)my_malloc(sizeof(int)*num_sram); - char** completed_truth_table = (char**)my_malloc(sizeof(char*)*truth_table_len); - int on_set = 0; - int off_set = 0; - int i; - - /* if No truth_table, do default*/ - if (0 == truth_table_len) { - switch (default_sram_bit_value) { - case 0: - off_set = 0; - on_set = 1; - break; - case 1: - off_set = 1; - on_set = 0; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid default_signal_init_value(=%d)!\n", - __FILE__, __LINE__, default_sram_bit_value); - exit(1); - } - } else { - on_set = determine_lut_truth_table_on_set(truth_table_len, truth_table); - off_set = 1 - on_set; - } - - /* Read in truth table lines, decode one by one */ - for (i = 0; i < truth_table_len; i++) { - /* Complete the truth table line by line*/ - //printf("truth_table[%d] = %s\n", i, truth_table[i]); - completed_truth_table[i] = complete_truth_table_line(lut_size, truth_table[i]); - //printf("Completed_truth_table[%d] = %s\n", i, completed_truth_table[i]); - } - //printf("on_set=%d off_set=%d", on_set, off_set); - assert(1 == (on_set + off_set)); - - if (1 == on_set) { - /* Initial all sram bits to 0*/ - for (i = 0 ; i < num_sram; i++) { - ret[i] = 0; - } - } else if (1 == off_set) { - /* Initial all sram bits to 1*/ - for (i = 0 ; i < num_sram; i++) { - ret[i] = 1; - } - } - - for (i = 0; i < truth_table_len; i++) { - /* Update the truth table, sram_bits */ - configure_lut_sram_bits_per_line_rec(&ret, lut_size, completed_truth_table[i], 0); - } - - /* Free */ - for (i = 0; i < truth_table_len; i++) { - my_free(completed_truth_table[i]); - } - - return ret; -} - -char** assign_lut_truth_table(t_logical_block* mapped_logical_block, - int* truth_table_length) { - char** truth_table = NULL; - t_linked_vptr* head = NULL; - int cur = 0; - - if (NULL == mapped_logical_block) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid mapped_logical_block!\n", - __FILE__, __LINE__); - exit(1); - } - /* Count the lines of truth table*/ - head = mapped_logical_block->truth_table; - while(head) { - (*truth_table_length)++; - head = head->next; - } - /* Allocate truth_tables */ - truth_table = (char**)my_malloc(sizeof(char*)*(*truth_table_length)); - /* Fill truth_tables*/ - cur = 0; - head = mapped_logical_block->truth_table; - while(head) { - truth_table[cur] = my_strdup((char*)head->data_vptr); - head = head->next; - cur++; - } - assert(cur == (*truth_table_length)); - - return truth_table; -} - -/* Get the vpack_net_num of all the input pins of a LUT physical pb */ -void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_block, - int* num_lut_pin, int** lut_pin_net) { - int ipin; - - /* Check */ - assert (NULL == lut_logical_block->model->inputs[0].next); - (*num_lut_pin) = lut_logical_block->model->inputs[0].size; - - /* Allocate */ - (*lut_pin_net) = (int*) my_malloc ((*num_lut_pin) * sizeof(int)); - /* Fill the array */ - for (ipin = 0; ipin < (*num_lut_pin); ipin++) { - (*lut_pin_net)[ipin] = lut_logical_block->input_nets[0][ipin]; - } - - return; -} - -/* Find the vpack_net_num of the outputs of the logical_block */ -void get_logical_block_output_vpack_net_num(t_logical_block* cur_logical_block, - int* num_lb_output_ports, int** num_lb_output_pins, - int*** lb_output_vpack_net_num) { - int iport, ipin; - int num_output_ports = 0; - int* num_output_pins = NULL; - t_model_ports* head = NULL; - int** output_vpack_net_num = NULL; - - assert (NULL != cur_logical_block); - - /* Count how many outputs we have */ - head = cur_logical_block->model->outputs; - while (NULL != head) { - num_output_ports++; - head = head->next; - } - /* Allocate */ - num_output_pins = (int*) my_calloc(num_output_ports, sizeof(int)); - output_vpack_net_num = (int**) my_calloc(num_output_ports, sizeof(int*)); - /* Fill the array */ - iport = 0; - head = cur_logical_block->model->outputs; - while (NULL != head) { - num_output_pins[iport] = head->size; - output_vpack_net_num[iport] = (int*) my_calloc(num_output_pins[iport], sizeof(int)); - /* Fill the array */ - for (ipin = 0; ipin < num_output_pins[iport]; ipin++) { - output_vpack_net_num[iport][ipin] = cur_logical_block->output_nets[iport][ipin]; - } - /* Go to the next */ - head = head->next; - /* Update counter */ - iport++; - } - - assert (iport == num_output_ports); - - /* Assign return values */ - (*num_lb_output_ports) = num_output_ports; - (*num_lb_output_pins) = num_output_pins; - (*lb_output_vpack_net_num) = output_vpack_net_num; - - return; -} - -int get_pb_graph_node_wired_lut_logical_block_index(t_pb_graph_node* cur_pb_graph_node, - t_rr_node* op_pb_rr_graph) { - int iport, ipin; - int wired_lut_lb_index = OPEN; - int num_used_lut_input_pins = 0; - int num_used_lut_output_pins = 0; - int temp_rr_node_index; - int lut_output_vpack_net_num = OPEN; - - num_used_lut_output_pins = 0; - /* Find the used output pin of this LUT and rr_node in the graph */ - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - temp_rr_node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; - if (OPEN != op_pb_rr_graph[temp_rr_node_index].vpack_net_num) { /* TODO: Shit... I do not why the vpack_net_num is not synchronized to the net_num !!! */ - num_used_lut_output_pins++; - lut_output_vpack_net_num = op_pb_rr_graph[temp_rr_node_index].vpack_net_num; - } - } - } - /* Make sure we only have 1 used output pin */ - /* vpr_printf(TIO_MESSAGE_INFO, "Wired LUT num_used_lut_output_pins is %d\n", num_used_lut_output_pins); */ - assert ((1 == num_used_lut_output_pins) - && (OPEN != lut_output_vpack_net_num)); - - num_used_lut_input_pins = 0; - /* Find the used input pin of this LUT and rr_node in the graph */ - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { - temp_rr_node_index = cur_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - if (lut_output_vpack_net_num == op_pb_rr_graph[temp_rr_node_index].vpack_net_num) { - num_used_lut_input_pins++; - } - } - } - /* Make sure we only have 1 used input pin */ - if (1 != num_used_lut_input_pins) { - assert (-1 < num_used_lut_input_pins); - } - - /* vpr_printf(TIO_MESSAGE_INFO, "Wired LUT output vpack_net_num is %d\n", lut_output_vpack_net_num); */ - - /* Find the used output*/ - - /* The logical block is the driver for this vpack_net( node_block[0] )*/ - wired_lut_lb_index = vpack_net[lut_output_vpack_net_num].node_block[0]; - assert (OPEN != wired_lut_lb_index); - - return wired_lut_lb_index; -} - - - -/* Adapt the truth from the actual connection from the input nets of a LUT, - */ -char** assign_post_routing_wired_lut_truth_table(t_logical_block* wired_lut_logical_block, - int lut_size, int* lut_pin_vpack_net_num, - int* truth_table_length) { - int inet, iport; - char** tt = (char**) my_malloc(sizeof(char*)); - int num_lut_output_ports; - int* num_lut_output_pins; - int** lut_output_vpack_net_num; - - /* The output of this mapped block is the wires routed through this LUT */ - /* Find the vpack_net_num of the output of the lut_logical_block */ - get_logical_block_output_vpack_net_num(wired_lut_logical_block, - &num_lut_output_ports, - &num_lut_output_pins, - &lut_output_vpack_net_num); - - /* Check */ - assert ( 1 == num_lut_output_ports); - assert ( 1 == num_lut_output_pins[0]); - assert ( OPEN != lut_output_vpack_net_num[0][0]); - - /* truth_table_length will be always 1*/ - (*truth_table_length) = 1; - - /* Malloc */ - tt[0] = (char*)my_malloc((lut_size + 3) * sizeof(char)); - /* Fill the truth table !!! */ - for (inet = 0; inet < lut_size; inet++) { - /* Find the vpack_num in the lut_input_pin, we fix it to be 1 */ - if (lut_output_vpack_net_num[0][0] == lut_pin_vpack_net_num[inet]) { - tt[0][inet] = '1'; - } else { - /* Otherwise it should be don't care */ - tt[0][inet] = '-'; - } - } - memcpy(tt[0] + lut_size, " 1", 3); - - /* Free */ - my_free(num_lut_output_pins); - for (iport = 0; iport < num_lut_output_ports; iport++) { - my_free(lut_output_vpack_net_num); - } - - return tt; -} - - -/* Provide the truth table of a mapped logical block - * 1. Reorgainze the truth table to be consistent with the mapped nets of a LUT - * 2. Allocate the truth table in a clean char array and return - */ -char** assign_post_routing_lut_truth_table(t_logical_block* mapped_logical_block, - int lut_size, int* lut_pin_vpack_net_num, - int* truth_table_length) { - char** truth_table = NULL; - t_linked_vptr* head = NULL; - int cur = 0; - int inet, jnet; - int* lut_to_lb_net_mapping = NULL; - int num_lb_pin = 0; - int* lb_pin_vpack_net_num = NULL; - int lb_truth_table_size = 0; - - if (NULL == mapped_logical_block) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid mapped_logical_block!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Allocate */ - lut_to_lb_net_mapping = (int*) my_malloc (sizeof(int) * lut_size); - /* Find nets mapped to a logical block */ - get_lut_logical_block_input_pin_vpack_net_num(mapped_logical_block, - &num_lb_pin, &lb_pin_vpack_net_num); - /* Create a pin-to-pin net_num mapping */ - for (inet = 0; inet < lut_size; inet++) { - lut_to_lb_net_mapping[inet] = OPEN; - /* Bypass open nets */ - if (OPEN == lut_pin_vpack_net_num[inet]) { - continue; - } - assert (OPEN != lut_pin_vpack_net_num[inet]); - /* Find the position (offset) of each vpack_net_num in lb_pins */ - for (jnet = 0; jnet < num_lb_pin; jnet++) { - if (lut_pin_vpack_net_num[inet] == lb_pin_vpack_net_num[jnet]) { - lut_to_lb_net_mapping[inet] = jnet; - break; - } - } - /* Not neccesary to find a one, some luts just share part of their pins */ - } - - /* Initialization */ - (*truth_table_length) = 0; - /* Count the lines of truth table*/ - head = mapped_logical_block->truth_table; - while(head) { - (*truth_table_length)++; - head = head->next; - } - /* Allocate truth_tables */ - truth_table = (char**)my_malloc(sizeof(char*)*(*truth_table_length)); - /* Fill truth_tables*/ - cur = 0; - head = mapped_logical_block->truth_table; - while(head) { - /* Handle the truth table pin remapping */ - truth_table[cur] = (char*) my_malloc((lut_size + 3) * sizeof(char)); - /* Initialize */ - lb_truth_table_size = strlen((char*)(head->data_vptr)); - memcpy(truth_table[cur] + lut_size, (char*)(head->data_vptr) + lb_truth_table_size - 2, 3); - /* Add */ - for (inet = 0; inet < lut_size; inet++) { - /* Open net implies a don't care, or some nets are not in the list */ - if ((OPEN == lut_pin_vpack_net_num[inet]) - || (OPEN == lut_to_lb_net_mapping[inet])) { - truth_table[cur][inet] = '-'; - continue; - } - /* Find the desired truth table bit */ - truth_table[cur][inet] = ((char*)(head->data_vptr))[lut_to_lb_net_mapping[inet]]; - } - - head = head->next; - cur++; - } - assert(cur == (*truth_table_length)); - - return truth_table; -} - - -/* Get initial value of a Latch/FF output*/ -int get_ff_output_init_val(t_logical_block* ff_logical_block) { - assert((0 == ff_logical_block->init_val)||(1 == ff_logical_block->init_val)); - - return ff_logical_block->init_val; -} - -/* Get initial value of a mapped LUT output*/ -int get_lut_output_init_val(t_logical_block* lut_logical_block) { - int i; - int* sram_bits = NULL; /* decoded SRAM bits */ - int truth_table_length = 0; - char** truth_table = NULL; - int lut_size = 0; - int input_net_index = OPEN; - int* input_init_val = NULL; - int init_path_id = 0; - int output_init_val = 0; - - t_spice_model* lut_spice_model = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - /* Ensure a valid file handler*/ - if (NULL == lut_logical_block) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid LUT logical block!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Get SPICE model */ - assert((NULL != lut_logical_block->pb) - && ( NULL != lut_logical_block->pb->pb_graph_node) - && ( NULL != lut_logical_block->pb->pb_graph_node->pb_type)); - lut_spice_model = lut_logical_block->pb->pb_graph_node->pb_type->parent_mode->parent_pb_type->spice_model; - - assert(SPICE_MODEL_LUT == lut_spice_model->type); - - sram_ports = find_spice_model_ports(lut_spice_model, SPICE_MODEL_PORT_SRAM, - &num_sram_port, TRUE); - assert(1 == num_sram_port); - - /* Get the truth table */ - truth_table = assign_lut_truth_table(lut_logical_block, &truth_table_length); - lut_size = lut_logical_block->used_input_pins; - assert(!(0 > lut_size)); - /* Special for LUT_size = 0 */ - if (0 == lut_size) { - /* Generate sram bits*/ - sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, - 1, sram_ports[0]->default_val); - /* This is constant generator, SRAM bits should be the same */ - output_init_val = sram_bits[0]; - for (i = 0; i < (int)pow(2.,(double)lut_size); i++) { - assert(sram_bits[i] == output_init_val); - } - } else { - /* Generate sram bits*/ - sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, - lut_size, sram_ports[0]->default_val); - - assert(1 == lut_logical_block->pb->pb_graph_node->num_input_ports); - assert(1 == lut_logical_block->pb->pb_graph_node->num_output_ports); - /* Get the initial path id */ - input_init_val = (int*)my_malloc(sizeof(int)*lut_size); - for (i = 0; i < lut_size; i++) { - input_net_index = lut_logical_block->input_nets[0][i]; - input_init_val[i] = vpack_net[input_net_index].spice_net_info->init_val; - } - - init_path_id = determine_lut_path_id(lut_size, input_init_val); - /* Check */ - assert((!(0 > init_path_id))&&(init_path_id < (int)pow(2.,(double)lut_size))); - output_init_val = sram_bits[init_path_id]; - } - - /*Free*/ - for (i = 0; i < truth_table_length; i++) { - free(truth_table[i]); - } - free(truth_table); - my_free(sram_bits); - - return output_init_val; -} - -/* Deteremine the initial value of an output of a logical block - * The logical block could be a LUT, a memory block or a multiplier - */ -int get_logical_block_output_init_val(t_logical_block* cur_logical_block) { - int output_init_val = 0; - t_spice_model* cur_spice_model = NULL; - - /* Get the spice_model of current logical_block */ - assert((NULL != cur_logical_block->pb) - && ( NULL != cur_logical_block->pb->pb_graph_node) - && ( NULL != cur_logical_block->pb->pb_graph_node->pb_type)); - cur_spice_model = cur_logical_block->pb->pb_graph_node->pb_type->parent_mode->parent_pb_type->spice_model; - - /* Switch to specific cases*/ - switch (cur_spice_model->type) { - case SPICE_MODEL_LUT: - /* Determine the initial value from LUT inputs */ - output_init_val = get_lut_output_init_val(cur_logical_block); - break; - case SPICE_MODEL_HARDLOGIC: - /* We have no information, give a default 0 now... - * TODO: find a smarter way! - */ - output_init_val = get_ff_output_init_val(cur_logical_block); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SPICE MODEL (name=%s) in determining the initial output value of logical block(name=%s)!\n", - __FILE__, __LINE__, cur_spice_model->name, cur_logical_block->name); - exit(1); - } - - return output_init_val; -} - -/* Functions to manipulate struct sram_orgz_info */ -t_sram_orgz_info* alloc_one_sram_orgz_info() { - return (t_sram_orgz_info*)my_malloc(sizeof(t_sram_orgz_info)); -} - -t_mem_bank_info* alloc_one_mem_bank_info() { - return (t_mem_bank_info*)my_malloc(sizeof(t_mem_bank_info)); -} - -void free_one_mem_bank_info(t_mem_bank_info* mem_bank_info) { - return; -} - -t_scff_info* alloc_one_scff_info() { - return (t_scff_info*)my_malloc(sizeof(t_scff_info)); -} - -void free_one_scff_info(t_scff_info* scff_info) { - return; -} - -t_standalone_sram_info* alloc_one_standalone_sram_info() { - return (t_standalone_sram_info*)my_malloc(sizeof(t_standalone_sram_info)); -} - -void free_one_standalone_sram_info(t_standalone_sram_info* standalone_sram_info) { - return; -} - -void init_mem_bank_info(t_mem_bank_info* cur_mem_bank_info, - t_spice_model* cur_mem_model) { - assert(NULL != cur_mem_bank_info); - assert(NULL != cur_mem_model); - cur_mem_bank_info->mem_model = cur_mem_model; - cur_mem_bank_info->num_mem_bit = 0; - cur_mem_bank_info->num_bl = 0; - cur_mem_bank_info->num_wl = 0; - cur_mem_bank_info->reserved_bl = 0; - cur_mem_bank_info->reserved_wl = 0; - - return; -} - -void update_mem_bank_info_num_mem_bit(t_mem_bank_info* cur_mem_bank_info, - int num_mem_bit) { - assert(NULL != cur_mem_bank_info); - - cur_mem_bank_info->num_mem_bit = num_mem_bit; - - return; -} - -void init_scff_info(t_scff_info* cur_scff_info, - t_spice_model* cur_mem_model) { - assert(NULL != cur_scff_info); - assert(NULL != cur_mem_model); - - cur_scff_info->mem_model = cur_mem_model; - cur_scff_info->num_mem_bit = 0; - cur_scff_info->num_scff = 0; - - return; -} - -void update_scff_info_num_mem_bit(t_scff_info* cur_scff_info, - int num_mem_bit) { - assert(NULL != cur_scff_info); - - cur_scff_info->num_mem_bit = num_mem_bit; - - return; -} - -void init_standalone_sram_info(t_standalone_sram_info* cur_standalone_sram_info, - t_spice_model* cur_mem_model) { - assert(NULL != cur_standalone_sram_info); - assert(NULL != cur_mem_model); - - cur_standalone_sram_info->mem_model = cur_mem_model; - cur_standalone_sram_info->num_mem_bit = 0; - cur_standalone_sram_info->num_sram = 0; - - return; -} - -void update_standalone_sram_info_num_mem_bit(t_standalone_sram_info* cur_standalone_sram_info, - int num_mem_bit) { - assert(NULL != cur_standalone_sram_info); - - cur_standalone_sram_info->num_mem_bit = num_mem_bit; - - return; -} - -void init_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, - enum e_sram_orgz cur_sram_orgz_type, - t_spice_model* cur_mem_model, - int grid_nx, int grid_ny) { - int i, num_bl_per_sram, num_wl_per_sram; - int num_bl_ports; - t_spice_model_port** bl_port = NULL; - int num_wl_ports; - t_spice_model_port** wl_port = NULL; - - assert(NULL != cur_sram_orgz_info); - - cur_sram_orgz_info->type = cur_sram_orgz_type; - cur_sram_orgz_info->conf_bit_head = NULL; /* Configuration bits will be allocated later */ - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_MEMORY_BANK: - cur_sram_orgz_info->mem_bank_info = alloc_one_mem_bank_info(); - init_mem_bank_info(cur_sram_orgz_info->mem_bank_info, cur_mem_model); - find_bl_wl_ports_spice_model(cur_mem_model, - &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); - assert(1 == num_bl_ports); - assert(1 == num_wl_ports); - num_bl_per_sram = bl_port[0]->size; - num_wl_per_sram = wl_port[0]->size; - try_update_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, - num_bl_per_sram, num_wl_per_sram); - break; - case SPICE_SRAM_SCAN_CHAIN: - cur_sram_orgz_info->scff_info = alloc_one_scff_info(); - init_scff_info(cur_sram_orgz_info->scff_info, cur_mem_model); - break; - case SPICE_SRAM_STANDALONE: - cur_sram_orgz_info->standalone_sram_info = alloc_one_standalone_sram_info(); - init_standalone_sram_info(cur_sram_orgz_info->standalone_sram_info, cur_mem_model); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - /* Alloc the configuration bit information per grid */ - cur_sram_orgz_info->grid_reserved_conf_bits = (int**)my_malloc(grid_nx*sizeof(int*)); - for (i = 0; i < grid_nx; i++) { - cur_sram_orgz_info->grid_reserved_conf_bits[i] = (int*)my_calloc(grid_ny, sizeof(int)); - } - - cur_sram_orgz_info->grid_conf_bits_lsb = (int**)my_malloc(grid_nx*sizeof(int*)); - for (i = 0; i < grid_nx; i++) { - cur_sram_orgz_info->grid_conf_bits_lsb[i] = (int*)my_calloc(grid_ny, sizeof(int)); - } - - cur_sram_orgz_info->grid_conf_bits_msb = (int**)my_malloc(grid_nx*sizeof(int*)); - for (i = 0; i < grid_nx; i++) { - cur_sram_orgz_info->grid_conf_bits_msb[i] = (int*)my_calloc(grid_ny, sizeof(int)); - } - - return; -} - -void free_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, - enum e_sram_orgz cur_sram_orgz_type, - int grid_nx, int grid_ny) { - int i; - t_llist* temp = NULL; - - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_MEMORY_BANK: - free_one_mem_bank_info(cur_sram_orgz_info->mem_bank_info); - break; - case SPICE_SRAM_SCAN_CHAIN: - free_one_scff_info(cur_sram_orgz_info->scff_info); - break; - case SPICE_SRAM_STANDALONE: - free_one_standalone_sram_info(cur_sram_orgz_info->standalone_sram_info); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - /* Free configuration bits linked-list */ - temp = cur_sram_orgz_info->conf_bit_head; - while(NULL != temp) { - free_conf_bit_info((t_conf_bit_info*)(temp->dptr)); - /* Set the data pointor to NULL, then we can call linked list free function */ - temp->dptr = NULL; - /* Go the next */ - temp = temp->next; - } - free_llist(cur_sram_orgz_info->conf_bit_head); - - /* Free the configuration bit information per grid */ - for (i = 0; i < grid_nx; i++) { - my_free(cur_sram_orgz_info->grid_reserved_conf_bits[i]); - } - my_free(cur_sram_orgz_info->grid_reserved_conf_bits); - - for (i = 0; i < grid_nx; i++) { - my_free(cur_sram_orgz_info->grid_conf_bits_lsb[i]); - } - my_free(cur_sram_orgz_info->grid_conf_bits_lsb); - - for (i = 0; i < grid_nx; i++) { - my_free(cur_sram_orgz_info->grid_conf_bits_msb[i]); - } - my_free(cur_sram_orgz_info->grid_conf_bits_msb); - - return; -} - -void update_mem_bank_info_reserved_blwl(t_mem_bank_info* cur_mem_bank_info, - int updated_reserved_bl, int updated_reserved_wl) { - assert(NULL != cur_mem_bank_info); - - cur_mem_bank_info->reserved_bl = updated_reserved_bl; - cur_mem_bank_info->reserved_wl = updated_reserved_wl; - - return; -} - -void get_mem_bank_info_reserved_blwl(t_mem_bank_info* cur_mem_bank_info, - int* num_reserved_bl, int* num_reserved_wl) { - assert(NULL != cur_mem_bank_info); - - (*num_reserved_bl) = cur_mem_bank_info->reserved_bl; - (*num_reserved_wl) = cur_mem_bank_info->reserved_wl; - - return; -} - -void update_mem_bank_info_num_blwl(t_mem_bank_info* cur_mem_bank_info, - int updated_bl, int updated_wl) { - assert(NULL != cur_mem_bank_info); - - cur_mem_bank_info->num_bl = updated_bl; - cur_mem_bank_info->num_wl = updated_wl; - - return; -} - -/* Initialize the number of normal/reserved BLs and WLs, mem_bits in sram_orgz_info - * If the updated_reserved_bl|wl is larger than the existed value, - * we update the reserved_bl|wl - */ -void try_update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, - int updated_reserved_bl, int updated_reserved_wl) { - t_spice_model* mem_model = NULL; - int cur_bl, cur_wl; - - /* Check */ - assert(updated_reserved_bl == updated_reserved_wl); - - /* get memory model */ - get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - break; - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - /* CMOS technology does not need to update */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - break; - case SPICE_MODEL_DESIGN_RRAM: - /* get the current number of reserved bls and wls */ - get_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); - if ((updated_reserved_bl > cur_bl) || (updated_reserved_wl > cur_wl)) { - update_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, - updated_reserved_bl, updated_reserved_wl); - update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, - updated_reserved_bl); - update_sram_orgz_info_num_blwl(cur_sram_orgz_info, - updated_reserved_bl, updated_reserved_wl); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of design technology!", - __FILE__, __LINE__ ); - exit(1); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - -} - -/* Force to update the number of reserved BLs and WLs in sram_orgz_info - * we always update the reserved_bl|wl - */ -void update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, - int updated_reserved_bl, int updated_reserved_wl) { - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - break; - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - update_mem_bank_info_reserved_blwl(cur_sram_orgz_info->mem_bank_info, - updated_reserved_bl, updated_reserved_wl); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - return; -} - -void get_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, - int* num_reserved_bl, int* num_reserved_wl) { - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - break; - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - get_mem_bank_info_reserved_blwl(cur_sram_orgz_info->mem_bank_info, - num_reserved_bl, num_reserved_wl); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - return; -} - -void get_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info, - int* cur_bl, int* cur_wl) { - assert(NULL != cur_bl); - assert(NULL != cur_wl); - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - (*cur_bl) = 0; - (*cur_wl) = 0; - break; - case SPICE_SRAM_MEMORY_BANK: - (*cur_bl) = cur_sram_orgz_info->mem_bank_info->num_bl; - (*cur_wl) = cur_sram_orgz_info->mem_bank_info->num_wl; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - return; -} - -int get_sram_orgz_info_num_mem_bit(t_sram_orgz_info* cur_sram_orgz_info) { - - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - return cur_sram_orgz_info->standalone_sram_info->num_mem_bit; - case SPICE_SRAM_SCAN_CHAIN: - return cur_sram_orgz_info->scff_info->num_mem_bit; - case SPICE_SRAM_MEMORY_BANK: - return cur_sram_orgz_info->mem_bank_info->num_mem_bit; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - return 0; -} - -void update_sram_orgz_info_num_mem_bit(t_sram_orgz_info* cur_sram_orgz_info, - int new_num_mem_bit) { - - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - update_standalone_sram_info_num_mem_bit(cur_sram_orgz_info->standalone_sram_info, new_num_mem_bit); - break; - case SPICE_SRAM_SCAN_CHAIN: - update_scff_info_num_mem_bit(cur_sram_orgz_info->scff_info, new_num_mem_bit); - break; - case SPICE_SRAM_MEMORY_BANK: - update_mem_bank_info_num_mem_bit(cur_sram_orgz_info->mem_bank_info, new_num_mem_bit); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - return; -} - -void update_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info, - int new_bl, int new_wl) { - - assert(NULL != cur_sram_orgz_info); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - break; - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - update_mem_bank_info_num_blwl(cur_sram_orgz_info->mem_bank_info, new_bl, new_wl); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - return; -} - -void get_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info, - t_spice_model** mem_model_ptr) { - - assert(NULL != cur_sram_orgz_info); - assert(NULL != mem_model_ptr); - - /* According to the type, we allocate structs */ - switch (cur_sram_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - (*mem_model_ptr) = cur_sram_orgz_info->standalone_sram_info->mem_model; - break; - case SPICE_SRAM_SCAN_CHAIN: - (*mem_model_ptr) = cur_sram_orgz_info->scff_info->mem_model; - break; - case SPICE_SRAM_MEMORY_BANK: - (*mem_model_ptr) = cur_sram_orgz_info->mem_bank_info->mem_model; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", - __FILE__, __LINE__ ); - exit(1); - } - - assert(NULL != (*mem_model_ptr)); - - return; -} - -/* Manipulating functions for struct t_reserved_syntax_char */ -void init_reserved_syntax_char(t_reserved_syntax_char* cur_reserved_syntax_char, - char cur_syntax_char, boolean cur_verilog_reserved, boolean cur_spice_reserved) { - assert(NULL != cur_reserved_syntax_char); - - cur_reserved_syntax_char->syntax_char = cur_syntax_char; - cur_reserved_syntax_char->verilog_reserved = cur_verilog_reserved; - cur_reserved_syntax_char->spice_reserved = cur_spice_reserved; - - return; -} - -void check_mem_model_blwl_inverted(t_spice_model* cur_mem_model, - enum e_spice_model_port_type blwl_port_type, - boolean* blwl_inverted) { - int num_blwl_ports = 0; - t_spice_model_port** blwl_port = NULL; - - /* Check */ - assert((SPICE_MODEL_PORT_BL == blwl_port_type)||(SPICE_MODEL_PORT_WL == blwl_port_type)); - - /* Find BL and WL ports */ - blwl_port = find_spice_model_ports(cur_mem_model, blwl_port_type, &num_blwl_ports, TRUE); - - /* If we cannot find any return with warnings */ - if (0 == num_blwl_ports) { - (*blwl_inverted) = FALSE; - vpr_printf(TIO_MESSAGE_WARNING, "(FILE:%s,[LINE%d])Unable to find any BL/WL port for memory model(%s)!\n", - __FILE__, __LINE__, cur_mem_model->name); - return; - } - - /* Only 1 port should be found */ - assert(1 == num_blwl_ports); - /* And port size should be at least 1 */ - assert(0 < blwl_port[0]->size); - - /* if default value of a BL/WL port is 0, we do not need an inversion. */ - if (0 == blwl_port[0]->default_val) { - (*blwl_inverted) = FALSE; - } else { - /* if default value of a BL/WL port is 1, we need an inversion! */ - assert(1 == blwl_port[0]->default_val); - (*blwl_inverted) = TRUE; - } - - return; -} - -/* Useful functions for MUX architecture */ -void init_spice_mux_arch(t_spice_model* spice_model, - t_spice_mux_arch* spice_mux_arch, - int mux_size) { - int cur; - int i; - /* Make sure we have a valid pointer*/ - if (NULL == spice_mux_arch) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,LINE[%d])Invalid spice_mux_arch!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Basic info*/ - spice_mux_arch->structure = spice_model->design_tech_info.structure; - spice_mux_arch->num_input = mux_size; - /* For different structure */ - switch (spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - spice_mux_arch->num_level = determine_tree_mux_level(spice_mux_arch->num_input); - spice_mux_arch->num_input_basis = 2; - /* Determine the level and index of per MUX inputs*/ - spice_mux_arch->num_input_last_level = tree_mux_last_level_input_num(spice_mux_arch->num_level, mux_size); - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - spice_mux_arch->num_level = 1; - spice_mux_arch->num_input_basis = mux_size; - /* Determine the level and index of per MUX inputs*/ - spice_mux_arch->num_input_last_level = mux_size; - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - /* Handle speical case: input size is 2 */ - if (2 == mux_size) { - spice_mux_arch->num_level = 1; - } else { - spice_mux_arch->num_level = spice_model->design_tech_info.mux_num_level; - } - spice_mux_arch->num_input_basis = determine_num_input_basis_multilevel_mux(mux_size, spice_mux_arch->num_level); - /* Determine the level and index of per MUX inputs*/ - spice_mux_arch->num_input_last_level = multilevel_mux_last_level_input_num(spice_mux_arch->num_level, spice_mux_arch->num_input_basis, mux_size); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", - __FILE__, __LINE__, spice_model->name); - exit(1); - } - - /* Alloc*/ - spice_mux_arch->num_input_per_level = (int*) my_malloc(sizeof(int)*spice_mux_arch->num_level); - spice_mux_arch->input_level = (int*)my_malloc(sizeof(int)*spice_mux_arch->num_input); - spice_mux_arch->input_offset = (int*)my_malloc(sizeof(int)*spice_mux_arch->num_input); - - /* Assign inputs info for the last level first */ - for (i = 0; i < spice_mux_arch->num_input_last_level; i++) { - spice_mux_arch->input_level[i] = spice_mux_arch->num_level; - spice_mux_arch->input_offset[i] = i; - } - /* For the last second level*/ - if (spice_mux_arch->num_input > spice_mux_arch->num_input_last_level) { - cur = spice_mux_arch->num_input_last_level/spice_mux_arch->num_input_basis; - /* Start from the input ports that are not occupied by the last level - * last level has (cur) outputs - */ - for (i = spice_mux_arch->num_input_last_level; i < spice_mux_arch->num_input; i++) { - spice_mux_arch->input_level[i] = spice_mux_arch->num_level - 1; - spice_mux_arch->input_offset[i] = cur; - cur++; - } - assert((cur < (int)pow((double)spice_mux_arch->num_input_basis, (double)(spice_mux_arch->num_level-1))) - ||(cur == (int)pow((double)spice_mux_arch->num_input_basis, (double)(spice_mux_arch->num_level-1)))); - } - /* Fill the num_input_per_level*/ - for (i = 0; i < spice_mux_arch->num_level; i++) { - cur = i+1; - spice_mux_arch->num_input_per_level[i] = (int)pow((double)spice_mux_arch->num_input_basis, (double)cur); - if ((cur == spice_mux_arch->num_level) - &&(spice_mux_arch->num_input_last_level < spice_mux_arch->num_input_per_level[i])) { - spice_mux_arch->num_input_per_level[i] = spice_mux_arch->num_input_last_level; - } - } - - return; -} - -/* Determine if we need a speical basis. - * If we need one, we give the MUX size of this special basis - */ -int find_spice_mux_arch_special_basis_size(t_spice_mux_arch spice_mux_arch) { - int im; - int mux_size = spice_mux_arch.num_input; - int num_input_basis = spice_mux_arch.num_input_basis; - int num_input_special_basis = 0; - int special_basis_start = 0; - - /* For different structure */ - switch (spice_mux_arch.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - special_basis_start = mux_size - mux_size % num_input_basis; - for (im = special_basis_start; im < mux_size; im++) { - if (spice_mux_arch.num_level == spice_mux_arch.input_level[im]) { - num_input_special_basis++; - } - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice_mux_arch!\n", - __FILE__, __LINE__); - exit(1); - } - - return num_input_special_basis; -} - -/* Search the linked list, if we have the same mux size and spice_model - * return 1, if not we return 0 - */ -t_llist* search_mux_linked_list(t_llist* mux_head, - int mux_size, - t_spice_model* spice_model) { - t_llist* temp = mux_head; - t_spice_mux_model* cur_mux = NULL; - /* traversal the linked list*/ - while(temp) { - cur_mux = (t_spice_mux_model*)(temp->dptr); - if ((cur_mux->size == mux_size) - &&(spice_model == cur_mux->spice_model)) { - return temp; - } - /* next */ - temp = temp->next; - } - - return NULL; -} - -/* Check the linked list if we have a mux stored with same spice model - * if not, we create a new one. - */ -void check_and_add_mux_to_linked_list(t_llist** muxes_head, - int mux_size, - t_spice_model* spice_model) { - t_spice_mux_model* cur_mux = NULL; - t_llist* temp = NULL; - - /* Check code: to avoid mistake, we should check the mux size - * the mux_size should be at least 2 so that we need a mux - */ - if (mux_size < 2) { - printf("Warning:(File:%s,LINE[%d]) ilegal mux size (%d), expect to be at least 2!\n", - __FILE__, __LINE__, mux_size); - return; - } - - /* Search the linked list */ - if (NULL != search_mux_linked_list((*muxes_head),mux_size,spice_model)) { - /* We find one, there is no need to create a new one*/ - return; - } - /*Create a linked list, if head is NULL*/ - if (NULL == (*muxes_head)) { - (*muxes_head) = create_llist(1); - (*muxes_head)->dptr = my_malloc(sizeof(t_spice_mux_model)); - cur_mux = (t_spice_mux_model*)((*muxes_head)->dptr); - } else { - /* We have to create a new elment in linked list*/ - temp = insert_llist_node((*muxes_head)); - temp->dptr = my_malloc(sizeof(t_spice_mux_model)); - cur_mux = (t_spice_mux_model*)(temp->dptr); - } - /* Fill the new SPICE MUX Model*/ - cur_mux->size = mux_size; - cur_mux->spice_model = spice_model; - cur_mux->cnt = 1; /* Initialize the counter*/ - - return; -} - -/* Free muxes linked list - */ -void free_muxes_llist(t_llist* muxes_head) { - t_llist* temp = muxes_head; - while(temp) { - /* Free the mux_spice_model, remember to set the pointer to NULL */ - free(temp->dptr); - temp->dptr = NULL; - /* Move on to the next pointer*/ - temp = temp->next; - } - free_llist(muxes_head); - return; -} - - - - -/* Stats the multiplexer sizes and structure in the global routing architecture*/ -void stats_spice_muxes_routing_arch(t_llist** muxes_head, - int num_switch, - t_switch_inf* switches, - t_spice* spice, - t_det_routing_arch* routing_arch) { - int inode; - t_rr_node* node; - t_spice_model* sb_switch_spice_model = NULL; - t_spice_model* cb_switch_spice_model = NULL; - - /* Current Version: Support Uni-directional routing architecture only*/ - if (UNI_DIRECTIONAL != routing_arch->directionality) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d])Spice Modeling Only support uni-directional routing architecture.\n",__FILE__, __LINE__); - exit(1); - } - - /* The routing path is. - * OPIN ----> CHAN ----> ... ----> CHAN ----> IPIN - * Each edge is a switch, for IPIN, the switch is a connection block, - * for the rest is a switch box - */ - /* Count the sizes of muliplexers in routing architecture */ - /* Visit the global variable : num_rr_nodes, rr_node */ - for (inode = 0; inode < num_rr_nodes; inode++) { - node = &rr_node[inode]; - switch (node->type) { - case IPIN: - /* Have to consider the fan_in only, it is a connection box(multiplexer)*/ - assert((node->fan_in > 0)||(0 == node->fan_in)); - if ((0 == node->fan_in)||(1 == node->fan_in)) { - break; - } - /* Find the spice_model for multiplexers in connection blocks */ - cb_switch_spice_model = switches[node->driver_switch].spice_model; - /* we should select a spice model for the connection box*/ - assert(NULL != cb_switch_spice_model); - check_and_add_mux_to_linked_list(muxes_head, node->fan_in,cb_switch_spice_model); - break; - case CHANX: - case CHANY: - /* Channels are the same, have to consider the fan_in as well, - * it could be a switch box if previous rr_node is a channel - * or it could be a connection box if previous rr_node is a IPIN or OPIN - */ - assert((node->fan_in > 0)||(0 == node->fan_in)); - if ((0 == node->fan_in)||(1 == node->fan_in)) { - break; - } - /* Find the spice_model for multiplexers in switch blocks*/ - sb_switch_spice_model = switches[node->driver_switch].spice_model; - /* we should select a spice model for the Switch box*/ - assert(NULL != sb_switch_spice_model); - check_and_add_mux_to_linked_list(muxes_head, node->fan_in,sb_switch_spice_model); - break; - case OPIN: - /* Actually, in single driver routing architecture, the OPIN, source of a routing path, - * is directly connected to Switch Box multiplexers - */ - break; - default: - break; - } - } - - return; -} - -/* Recursively do statistics for the - * multiplexer spice models inside pb_types - */ -void stats_mux_spice_model_pb_type_rec(t_llist** muxes_head, - t_pb_type* cur_pb_type) { - - int imode, ichild, jinterc; - t_spice_model* interc_spice_model = NULL; - - if (NULL == cur_pb_type) { - vpr_printf(TIO_MESSAGE_WARNING,"(File:%s,LINE[%d])cur_pb_type is null pointor!\n",__FILE__,__LINE__); - return; - } - - /* If there is spice_model_name, this is a leaf node!*/ - if (NULL != cur_pb_type->spice_model_name) { - /* What annoys me is VPR create a sub pb_type for each lut which suppose to be a leaf node - * This may bring software convience but ruins SPICE modeling - */ - assert(NULL != cur_pb_type->spice_model); - return; - } - /* Traversal the hierarchy*/ - for (imode = 0; imode < cur_pb_type->num_modes; imode++) { - /* Then we have to statisitic the interconnections*/ - for (jinterc = 0; jinterc < cur_pb_type->modes[imode].num_interconnect; jinterc++) { - /* Check the num_mux and fan_in*/ - assert((0 == cur_pb_type->modes[imode].interconnect[jinterc].num_mux) - ||(0 < cur_pb_type->modes[imode].interconnect[jinterc].num_mux)); - if (0 == cur_pb_type->modes[imode].interconnect[jinterc].num_mux) { - continue; - } - interc_spice_model = cur_pb_type->modes[imode].interconnect[jinterc].spice_model; - if (NULL == interc_spice_model) { - assert(NULL != interc_spice_model); - } - check_and_add_mux_to_linked_list(muxes_head, - cur_pb_type->modes[imode].interconnect[jinterc].fan_in, - interc_spice_model); - } - for (ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ichild++) { - stats_mux_spice_model_pb_type_rec(muxes_head, - &cur_pb_type->modes[imode].pb_type_children[ichild]); - } - } - return; -} - -/* Statistics the MUX SPICE MODEL with the help of pb_graph - * Not the most efficient function to finish the job - * Abandon it. But remains a good framework that could be re-used in connecting - * spice components together - */ -void stats_mux_spice_model_pb_node_rec(t_llist** muxes_head, - t_pb_graph_node* cur_pb_node) { - int imode, ipb, ichild, iport, ipin; - t_pb_type* cur_pb_type = cur_pb_node->pb_type; - t_spice_model* interc_spice_model = NULL; - enum e_interconnect pin_interc_type; - - if (NULL == cur_pb_node) { - vpr_printf(TIO_MESSAGE_WARNING,"(File:%s,LINE[%d])cur_pb_node is null pointor!\n",__FILE__,__LINE__); - return; - } - - if (NULL == cur_pb_type) { - vpr_printf(TIO_MESSAGE_WARNING,"(File:%s,LINE[%d])cur_pb_type is null pointor!\n",__FILE__,__LINE__); - return; - } - - /* If there is 0 mode, this is a leaf node!*/ - if (NULL != cur_pb_type->blif_model) { - assert(0 == cur_pb_type->num_modes); - assert(NULL == cur_pb_type->modes); - /* Ensure there is blif_model, and spice_model*/ - assert(NULL != cur_pb_type->model); - assert(NULL != cur_pb_type->spice_model_name); - assert(NULL != cur_pb_type->spice_model); - return; - } - /* Traversal the hierarchy*/ - for (imode = 0; imode < cur_pb_type->num_modes; imode++) { - /* Then we have to statisitic the interconnections*/ - /* See the input ports*/ - for (iport = 0; iport < cur_pb_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_node->num_input_pins[iport]; ipin++) { - /* Ensure this is an input port */ - assert(IN_PORT == cur_pb_node->input_pins[iport][ipin].port->type); - /* See the edges, if the interconnetion type infer a MUX, we go next step*/ - pin_interc_type = find_pb_graph_pin_in_edges_interc_type(cur_pb_node->input_pins[iport][ipin]); - if ((COMPLETE_INTERC != pin_interc_type)&&(MUX_INTERC != pin_interc_type)) { - continue; - } - /* We shoule check the size of inputs, in some case of complete, the input_edge is one...*/ - if ((COMPLETE_INTERC == pin_interc_type)&&(1 == cur_pb_node->input_pins[iport][ipin].num_input_edges)) { - continue; - } - /* Note: i do care the input_edges only! They may infer multiplexers*/ - interc_spice_model = find_pb_graph_pin_in_edges_interc_spice_model(cur_pb_node->input_pins[iport][ipin]); - check_and_add_mux_to_linked_list(muxes_head, - cur_pb_node->input_pins[iport][ipin].num_input_edges, - interc_spice_model); - } - } - /* See the output ports*/ - for (iport = 0; iport < cur_pb_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_node->num_output_pins[iport]; ipin++) { - /* Ensure this is an input port */ - assert(OUT_PORT == cur_pb_node->output_pins[iport][ipin].port->type); - /* See the edges, if the interconnetion type infer a MUX, we go next step*/ - pin_interc_type = find_pb_graph_pin_in_edges_interc_type(cur_pb_node->output_pins[iport][ipin]); - if ((COMPLETE_INTERC != pin_interc_type)&&(MUX_INTERC != pin_interc_type)) { - continue; - } - /* We shoule check the size of inputs, in some case of complete, the input_edge is one...*/ - if ((COMPLETE_INTERC == pin_interc_type)&&(1 == cur_pb_node->output_pins[iport][ipin].num_input_edges)) { - continue; - } - /* Note: i do care the input_edges only! They may infer multiplexers*/ - interc_spice_model = find_pb_graph_pin_in_edges_interc_spice_model(cur_pb_node->output_pins[iport][ipin]); - check_and_add_mux_to_linked_list(muxes_head, - cur_pb_node->output_pins[iport][ipin].num_input_edges, - interc_spice_model); - } - } - /* See the clock ports*/ - for (iport = 0; iport < cur_pb_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < cur_pb_node->num_clock_pins[iport]; ipin++) { - /* Ensure this is an input port */ - assert(IN_PORT == cur_pb_node->clock_pins[iport][ipin].port->type); - /* See the edges, if the interconnetion type infer a MUX, we go next step*/ - pin_interc_type = find_pb_graph_pin_in_edges_interc_type(cur_pb_node->clock_pins[iport][ipin]); - if ((COMPLETE_INTERC != pin_interc_type)&&(MUX_INTERC != pin_interc_type)) { - continue; - } - /* We shoule check the size of inputs, in some case of complete, the input_edge is one...*/ - if ((COMPLETE_INTERC == pin_interc_type)&&(1 == cur_pb_node->clock_pins[iport][ipin].num_input_edges)) { - continue; - } - /* Note: i do care the input_edges only! They may infer multiplexers*/ - interc_spice_model = find_pb_graph_pin_in_edges_interc_spice_model(cur_pb_node->clock_pins[iport][ipin]); - check_and_add_mux_to_linked_list(muxes_head, - cur_pb_node->clock_pins[iport][ipin].num_input_edges, - interc_spice_model); - } - } - for (ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ichild++) { - /* num_pb is the number of such pb_type in a mode*/ - for (ipb = 0; ipb < cur_pb_type->modes[imode].pb_type_children[ichild].num_pb; ipb++) { - /* child_pb_grpah_nodes: [0..num_modes-1][0..num_pb_type_in_mode-1][0..num_pb_type-1]*/ - stats_mux_spice_model_pb_node_rec(muxes_head, - &cur_pb_node->child_pb_graph_nodes[imode][ichild][ipb]); - } - } - } - return; -} - - -/* Statistic for all the multiplexers in FPGA - * We determine the sizes and its structure (according to spice_model) for each type of multiplexers - * We search multiplexers in Switch Blocks, Connection blocks and Configurable Logic Blocks - * In additional to multiplexers, this function also consider crossbars. - * All the statistics are stored in a linked list, as a return value - */ -t_llist* stats_spice_muxes(int num_switches, - t_switch_inf* switches, - t_spice* spice, - t_det_routing_arch* routing_arch) { - int itype; - int imodel; - /* Linked-list to store the information of Multiplexers*/ - t_llist* muxes_head = NULL; - - /* Step 1: We should check the multiplexer spice models defined in routing architecture.*/ - stats_spice_muxes_routing_arch(&muxes_head, num_switches, switches, spice, routing_arch); - - /* Statistics after search routing resources */ - /* - temp = muxes_head; - while(temp) { - t_spice_mux_model* spice_mux_model = (t_spice_mux_model*)temp->dptr; - vpr_printf(TIO_MESSAGE_INFO,"Routing multiplexers: size=%d\n",spice_mux_model->size); - temp = temp->next; - } - */ - - /* Step 2: Count the sizes of multiplexers in complex logic blocks */ - for (itype = 0; itype < num_types; itype++) { - if (NULL != type_descriptors[itype].pb_type) { - stats_mux_spice_model_pb_type_rec(&muxes_head,type_descriptors[itype].pb_type); - } - } - - /* Step 3: count the size of multiplexer that will be used in LUTs*/ - for (imodel = 0; imodel < spice->num_spice_model; imodel++) { - /* For those LUTs that netlists are not provided. We create a netlist and thus need a MUX*/ - if ((SPICE_MODEL_LUT == spice->spice_models[imodel].type) - &&(NULL == spice->spice_models[imodel].model_netlist)) { - stats_lut_spice_mux(&muxes_head, &(spice->spice_models[imodel])); - } - } - - /* Statistics after search routing resources */ - /* - temp = muxes_head; - while(temp) { - t_spice_mux_model* spice_mux_model = (t_spice_mux_model*)temp->dptr; - vpr_printf(TIO_MESSAGE_INFO,"Pb_types multiplexers: size=%d\n",spice_mux_model->size); - temp = temp->next; - } - */ - - return muxes_head; -} - -/* Find the interconnection type of pb_graph_pin edges*/ -enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin) { - enum e_interconnect interc_type; - int def_interc_type = 0; - int iedge; - - for (iedge = 0; iedge < pb_graph_pin.num_input_edges; iedge++) { - /* Make sure all edges are legal: 1 input_pin, 1 output_pin*/ - check_pb_graph_edge(*(pb_graph_pin.input_edges[iedge])); - /* Make sure all the edges interconnect type is the same*/ - if (0 == def_interc_type) { - interc_type = pb_graph_pin.input_edges[iedge]->interconnect->type; - } else if (interc_type != pb_graph_pin.input_edges[iedge]->interconnect->type) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d])Interconnection type are not same for port(%s),pin(%d).\n", - __FILE__, __LINE__, pb_graph_pin.port->name,pb_graph_pin.pin_number); - exit(1); - } - } - - return interc_type; -} - -/* Find the interconnection type of pb_graph_pin edges*/ -t_spice_model* find_pb_graph_pin_in_edges_interc_spice_model(t_pb_graph_pin pb_graph_pin) { - t_spice_model* interc_spice_model; - int def_interc_model = 0; - int iedge; - - for (iedge = 0; iedge < pb_graph_pin.num_input_edges; iedge++) { - /* Make sure all edges are legal: 1 input_pin, 1 output_pin*/ - check_pb_graph_edge(*(pb_graph_pin.input_edges[iedge])); - /* Make sure all the edges interconnect type is the same*/ - if (0 == def_interc_model) { - interc_spice_model= pb_graph_pin.input_edges[iedge]->interconnect->spice_model; - } else if (interc_spice_model != pb_graph_pin.input_edges[iedge]->interconnect->spice_model) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d])Interconnection spice_model are not same for port(%s),pin(%d).\n", - __FILE__, __LINE__, pb_graph_pin.port->name,pb_graph_pin.pin_number); - exit(1); - } - } - - return interc_spice_model; -} - -int find_path_id_between_pb_rr_nodes(t_rr_node* local_rr_graph, - int src_node, - int des_node) { - int path_id = -1; - int prev_edge = -1; - int path_count = 0; - int iedge; - t_interconnect* cur_interc = NULL; - - /* Check */ - assert(NULL != local_rr_graph); - assert((0 == src_node)||(0 < src_node)); - assert((0 == des_node)||(0 < des_node)); - - prev_edge = local_rr_graph[des_node].prev_edge; - check_pb_graph_edge(*(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge])); - assert(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge]->output_pins[0] == local_rr_graph[des_node].pb_graph_pin); - - cur_interc = local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge]->interconnect; - /* Search des_node input edges */ - for (iedge = 0; iedge < local_rr_graph[des_node].pb_graph_pin->num_input_edges; iedge++) { - if (local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]->input_pins[0] - == local_rr_graph[src_node].pb_graph_pin) { - /* Strict check */ - assert(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge] - == local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]); - path_id = path_count; - break; - } - if (cur_interc == local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]->interconnect) { - path_count++; - } - } - - return path_id; -} - -/* Return a child_pb if it is mapped.*/ -t_pb* get_child_pb_for_phy_pb_graph_node(t_pb* cur_pb, int ipb, int jpb) { - t_pb* child_pb = NULL; - - /* TODO: more check ? */ - - if (NULL == cur_pb) { - return NULL; - } - - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - child_pb = &(cur_pb->child_pbs[ipb][jpb]); - } - - return child_pb; -} - -/* Check if all the SRAM ports have the correct SPICE MODEL */ -void config_spice_models_sram_port_spice_model(int num_spice_model, - t_spice_model* spice_models, - t_spice_model* default_sram_spice_model) { - int i, iport; - - for (i = 0; i < num_spice_model; i++) { - for (iport = 0; iport < spice_models[i].num_port; iport++) { - /* Bypass non SRAM ports */ - if (SPICE_MODEL_PORT_SRAM != spice_models[i].ports[iport].type) { - continue; - } - /* Write for the default SRAM SPICE model! */ - spice_models[i].ports[iport].spice_model = default_sram_spice_model; - /* Only show warning when we try to override the given spice_model_name ! */ - if (NULL == spice_models[i].ports[iport].spice_model_name) { - continue; - } - /* Give a warning !!! */ - if (0 != strcmp(default_sram_spice_model->name, spice_models[i].ports[iport].spice_model_name)) { - vpr_printf(TIO_MESSAGE_WARNING, - "(FILE:%s, LINE[%d]) Overwrite SRAM SPICE MODEL of SPICE model port (name:%s, port:%s) to be the correct one (name:%s)!\n", - __FILE__ ,__LINE__, - spice_models[i].name, - spice_models[i].ports[iport].prefix, - default_sram_spice_model->name); - } - } - } - - return; -} - -/* Return the child_pb of a LUT pb - * Because the mapping information is stored in the child_pb!!! - */ -t_pb* get_lut_child_pb(t_pb* cur_lut_pb, - int mode_index) { - - assert(SPICE_MODEL_LUT == cur_lut_pb->pb_graph_node->pb_type->spice_model->type); - - assert(1 == cur_lut_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children); - assert(1 == cur_lut_pb->pb_graph_node->pb_type->num_pb); - - return (&(cur_lut_pb->child_pbs[0][0])); -} - -/* Return the child_pb of a hardlogic pb - * Because the mapping information is stored in the child_pb!!! - */ -t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb, - int mode_index) { - - assert(SPICE_MODEL_HARDLOGIC == cur_hardlogic_pb->pb_graph_node->pb_type->spice_model->type); - - assert(1 == cur_hardlogic_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children); - assert(1 == cur_hardlogic_pb->pb_graph_node->pb_type->num_pb); - - return (&(cur_hardlogic_pb->child_pbs[0][0])); -} - - -int get_grid_pin_height(int grid_x, int grid_y, int pin_index) { - int pin_height; - t_type_ptr grid_type = NULL; - - /* Get type */ - grid_type = grid[grid_x][grid_y].type; - - /* Return if this is an empty type */ - if ((NULL == grid_type) - ||(EMPTY_TYPE == grid_type)) { - pin_height = 0; - return pin_height; - } - - /* Check if the pin index is in the range */ - assert ( ((0 == pin_index) || (0 < pin_index)) - &&(pin_index < grid_type->num_pins) ); - - /* Find the pin_height */ - pin_height = grid_type->pin_height[pin_index]; - - return pin_height; -} - -int get_grid_pin_side(int grid_x, int grid_y, int pin_index) { - int pin_height, side, pin_side; - t_type_ptr grid_type = NULL; - - /* Get type */ - grid_type = grid[grid_x][grid_y].type; - - /* Return if this is an empty type */ - if ((NULL == grid_type) - ||(EMPTY_TYPE == grid_type)) { - return -1; - } - - /* Check if the pin index is in the range */ - assert ( ((0 == pin_index) || (0 < pin_index)) - &&(pin_index < grid_type->num_pins) ); - - /* Find the pin_height */ - pin_height = get_grid_pin_height(grid_x, grid_y, pin_index); - - pin_side = -1; - for (side = 0; side < 4; side++) { - /* Bypass corner cases */ - /* Pin can only locate on BOTTOM side, when grid is on TOP border */ - if ((ny == grid_y)&&(2 != side)) { - continue; - } - /* Pin can only locate on LEFT side, when grid is on RIGHT border */ - if ((nx == grid_x)&&(3 != side)) { - continue; - } - /* Pin can only locate on the TOP side, when grid is on BOTTOM border */ - if ((0 == grid_y)&&(0 != side)) { - continue; - } - /* Pin can only locate on the RIGHT side, when grid is on LEFT border */ - if ((0 == grid_x)&&(1 != side)) { - continue; - } - if (1 == grid_type->pinloc[pin_height][side][pin_index]) { - if (-1 != pin_side) { - vpr_printf(TIO_MESSAGE_ERROR, "(%s, [LINE%d]) Duplicated pin(index:%d) on two sides: %s and %s of type (name=%s)!\n", - __FILE__, __LINE__, - pin_index, - convert_side_index_to_string(pin_side), - convert_side_index_to_string(side), - grid_type->name); - exit(1); - } - pin_side = side; - } - } - - return pin_side; -} - -void determine_sb_port_coordinator(t_sb cur_sb_info, int side, - int* port_x, int* port_y) { - /* Check */ - assert ((-1 < side) && (side < 4)); - /* Initialize */ - (*port_x) = -1; - (*port_y) = -1; - - switch (side) { - case TOP: - /* (0 == side) */ - /* 1. Channel Y [x][y+1] inputs */ - (*port_x) = cur_sb_info.x; - (*port_y) = cur_sb_info.y + 1; - break; - case RIGHT: - /* 1 == side */ - /* 2. Channel X [x+1][y] inputs */ - (*port_x) = cur_sb_info.x + 1; - (*port_y) = cur_sb_info.y; - break; - case BOTTOM: - /* 2 == side */ - /* 3. Channel Y [x][y] inputs */ - (*port_x) = cur_sb_info.x; - (*port_y) = cur_sb_info.y; - break; - case LEFT: - /* 3 == side */ - /* 4. Channel X [x][y] inputs */ - (*port_x) = cur_sb_info.x; - (*port_y) = cur_sb_info.y; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid side of sb[%d][%d]!\n", - __FILE__, __LINE__, cur_sb_info.x, cur_sb_info.y, side); - exit(1); - } - - return; -} - -void init_spice_models_tb_cnt(int num_spice_models, - t_spice_model* spice_model) { - int imodel; - - for (imodel = 0; imodel < num_spice_models; imodel++) { - spice_model[imodel].tb_cnt = 0; - } - - return; -} - -void init_spice_models_grid_tb_cnt(int num_spice_models, - t_spice_model* spice_model, - int grid_x, int grid_y) { - int imodel; - - for (imodel = 0; imodel < num_spice_models; imodel++) { - spice_model[imodel].tb_cnt = spice_model[imodel].grid_index_low[grid_x][grid_y]; - } - - return; -} - -void check_spice_models_grid_tb_cnt(int num_spice_models, - t_spice_model* spice_model, - int grid_x, int grid_y, - enum e_spice_model_type spice_model_type_to_check) { - int imodel; - - for (imodel = 0; imodel < num_spice_models; imodel++) { - if (spice_model_type_to_check != spice_model[imodel].type) { - continue; - } - assert(spice_model[imodel].tb_cnt == spice_model[imodel].grid_index_high[grid_x][grid_y]); - } - - return; -} - -boolean check_negative_variation(float avg_val, - t_spice_mc_variation_params variation_params) { - boolean exist_neg_val = FALSE; - - /* Assume only support gaussian variation now */ - if (avg_val < 0.) { - exist_neg_val = TRUE; - } - - return exist_neg_val; -} - -/* Check if this cby_info exists, it may be covered by a heterogenous block */ -boolean is_cb_exist(t_rr_type cb_type, - int cb_x, int cb_y) { - boolean cb_exist = TRUE; - - /* Check */ - assert((!(0 > cb_x))&&(!(cb_x > (nx + 1)))); - assert((!(0 > cb_y))&&(!(cb_y > (ny + 1)))); - - switch (cb_type) { - case CHANX: - /* Border case */ - /* Check the grid under this CB */ - if ((NULL == grid[cb_x][cb_y].type) - ||(EMPTY_TYPE == grid[cb_x][cb_y].type) - ||(1 < grid[cb_x][cb_y].type->height)) { - cb_exist = FALSE; - } - break; - case CHANY: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid CB type! Should be CHANX or CHANY.\n", - __FILE__, __LINE__); - exit(1); - } - - return cb_exist; -} - -/* Count the number of IPIN rr_nodes in a CB_info struct */ -int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info) { - int side; - int cnt = 0; - - for (side = 0; side < cur_cb_info.num_sides; side++) { - cnt += cur_cb_info.num_ipin_rr_nodes[side]; - } - - return cnt; -} - -/* Add a subckt file name to a linked list */ -t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head, - char* subckt_file_path) { - t_llist* new_head = NULL; - - if (NULL == cur_head) { - new_head = create_llist(1); - new_head->dptr = (void*) my_strdup(subckt_file_path); - } else { - new_head = insert_llist_node_before_head(cur_head); - new_head->dptr = (void*) my_strdup(subckt_file_path); - } - - return new_head; -} - -/* Check if SPICE subckt is already created - * (if they exist in a given linked-list - */ -boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head, - char* subckt_file_name) { - t_llist* temp = NULL; - - temp = subckt_llist_head; - while (temp) { - if (0 == strcmp(subckt_file_name, (char*)(temp->dptr))) { - return TRUE; - } - temp = temp->next; - } - - return FALSE; -} - -/* Get the vpack_net_num of all the input pins of a LUT physical pb */ -void get_mapped_lut_pb_input_pin_vpack_net_num(t_pb_graph_node* lut_pb_graph_node, - t_rr_node* pb_rr_graph, - int* num_lut_pin, int** lut_pin_net) { - - int ipin, inode; - - /* Check */ - assert (1 == lut_pb_graph_node->num_input_ports); - (*num_lut_pin) = lut_pb_graph_node->num_input_pins[0]; - - /* Allocate */ - (*lut_pin_net) = (int*) my_malloc ((*num_lut_pin) * sizeof(int)); - /* Fill the array */ - for (ipin = 0; ipin < (*num_lut_pin); ipin++) { - inode = lut_pb_graph_node->input_pins[0][ipin].pin_count_in_cluster; - (*lut_pin_net)[ipin] = pb_rr_graph[inode].vpack_net_num; - } - - return; -} - -/* Recursively find all the global ports in the spice_model / sub spice_model - */ -void rec_stats_spice_model_global_ports(t_spice_model* cur_spice_model, - boolean recursive, - t_llist** spice_model_head) { - int iport; - t_llist* temp = NULL; - - /* Check */ - assert(NULL != cur_spice_model); - if (0 < cur_spice_model->num_port) { - assert(NULL != cur_spice_model->ports); - } - - for (iport = 0; iport < cur_spice_model->num_port; iport++) { - /* if this spice model requires customized netlist to be included, we do not go recursively */ - if (TRUE == recursive) { - /* GO recursively first, and meanwhile count the number of global ports */ - /* For the port that requires another spice_model, i.e., SRAM - * We need include any global port in that spice model - */ - if (NULL != cur_spice_model->ports[iport].spice_model) { - rec_stats_spice_model_global_ports(cur_spice_model->ports[iport].spice_model, - recursive, spice_model_head); - } - } - /* By pass non-global ports*/ - if (FALSE == cur_spice_model->ports[iport].is_global) { - continue; - } - /* Now we have a global port, add it to linked list */ - assert (TRUE == cur_spice_model->ports[iport].is_global); - if (NULL == (*spice_model_head)) { - (*spice_model_head) = create_llist(1); - /* Configure the data pointer of linked list */ - (*spice_model_head)->dptr = (void*) (&cur_spice_model->ports[iport]); - /* Check if this ports exists in the linked list */ - } else if (FALSE == check_dptr_exist_in_llist((*spice_model_head), - (void*)(&cur_spice_model->ports[iport]))) { - /* Non-exist in the current linked-list, a new node is required - * Go to the tail of the linked-list and add a new node - */ - temp = search_llist_tail(*spice_model_head); - temp = insert_llist_node(temp); - /* Configure the data pointer of linked list */ - temp->dptr = (void*) (&cur_spice_model->ports[iport]); - } - } - - return; -} - -/* Identify if this child_pb is actually used for wiring!!! */ -boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node, - t_pb_type* cur_pb_type, - t_rr_node* pb_rr_graph) { - boolean is_used = FALSE; - int node_index; - int port_index = 0; - int iport, ipin; - - for (iport = 0; iport < cur_pb_type->num_ports && !is_used; iport++) { - if (OUT_PORT == cur_pb_type->ports[iport].type) { - for (ipin = 0; ipin < cur_pb_type->ports[iport].num_pins; ipin++) { - node_index = cur_pb_graph_node->output_pins[port_index][ipin].pin_count_in_cluster; - if ((OPEN != pb_rr_graph[node_index].net_num) - || (OPEN != pb_rr_graph[node_index].vpack_net_num)) { - return TRUE; - } - } - port_index++; - } - } - - return is_used; -} - - -/* Identify if this is an unallocated pb that is used as a wired LUT */ -boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node, - t_pb_type* cur_pb_type, - t_rr_node* pb_rr_graph) { - boolean is_used = FALSE; - - is_used = is_pb_used_for_wiring(cur_pb_graph_node, - cur_pb_type, - pb_rr_graph); - /* Return TRUE if this block is not used and it is a LUT ! */ - if ((TRUE == is_used) - && (LUT_CLASS == cur_pb_type->class_type)) { - return TRUE; - } - - return FALSE; -} - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.h b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.h deleted file mode 100644 index 066a0b296..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.h +++ /dev/null @@ -1,3 +0,0 @@ -void vpr_print_spice_netlists(t_vpr_setup vpr_setup, - t_arch Arch, - char* circuit_name); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.c b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.c deleted file mode 100644 index bfddd31f4..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.c +++ /dev/null @@ -1,860 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph_util.h" -#include "rr_graph.h" -#include "rr_graph2.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "spice_utils.h" -#include "spice_mux.h" -#include "spice_pbtypes.h" -#include "spice_subckt.h" - -/* local global variables */ -static int tb_num_hardlogic = 0; -static int testbench_load_cnt = 0; -static int upbound_sim_num_clock_cycles = 2; -static int max_sim_num_clock_cycles = 2; -static int auto_select_max_sim_num_clock_cycles = TRUE; - -/* Subroutines in this source file*/ -/* Initialize the global parameters in this source file */ -static -void init_spice_hardlogic_testbench_globals(t_spice spice) { - tb_num_hardlogic = 0; - auto_select_max_sim_num_clock_cycles = spice.spice_params.meas_params.auto_select_sim_num_clk_cycle; - upbound_sim_num_clock_cycles = spice.spice_params.meas_params.sim_num_clock_cycle + 1; - if (FALSE == auto_select_max_sim_num_clock_cycles) { - max_sim_num_clock_cycles = spice.spice_params.meas_params.sim_num_clock_cycle + 1; - } else { - max_sim_num_clock_cycles = 2; - } -} - -/* Print Common global ports in the testbench */ -static -void fprint_spice_hardlogic_testbench_global_ports(FILE* fp, int grid_x, int grid_y, - int num_clock, - t_spice spice) { - /* int i; */ - /* A valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__); - exit(1); - } - - - /* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */ - /* Print generic global ports*/ - fprint_spice_generic_testbench_global_ports(fp, - sram_spice_orgz_info, - global_ports_head); - /* VDD Load port name */ - fprintf(fp, ".global %s\n", - spice_tb_global_vdd_load_port_name); - - /*Global Vdds for FFs: TODO: TO BE REMOVED */ - fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, spice); - - /*Global Vdds for hardlogic */ - fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, spice); - - /*Global Vdds for IOPADs (TODO: TO BE MOVED TO IO_TB SOURCE FILE */ - fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_IOPAD, spice); - - /* Global VDDs for SRAMs of IOPADs */ - fprintf(fp, ".global %s\n", - spice_tb_global_vdd_io_sram_port_name); - - return; -} - -/* Dump the subckt of a hardlogic and also the input stimuli */ -void fprint_spice_hardlogic_testbench_one_hardlogic(FILE* fp, - char* subckt_name, - t_spice_model* hardlogic_spice_model) { - int iport, ipin; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - - int num_inout_port = 0; - t_spice_model_port** inout_ports = NULL; - - int num_clk_port = 0; - t_spice_model_port** clk_ports = NULL; - - /* A valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__); - exit(1); - } - - /* Check */ - assert(NULL != hardlogic_spice_model); - - /* identify the type of spice model */ - /* Call defined subckt */ - fprintf(fp, "Xhardlogic_%s[%d] \n", - hardlogic_spice_model->prefix, - hardlogic_spice_model->tb_cnt); - - /* Sequence in dumping ports: - * 1. Global ports - * 2. Input ports - * 3. Output ports - * 4. Inout ports - * 5. Configuration ports - * 6. VDD and GND ports - */ - - /* 1. Global ports */ - if (0 < rec_fprint_spice_model_global_ports(fp, hardlogic_spice_model, FALSE)) { - fprintf(fp, "+ "); - } - - /* 2. Input ports (TODO: check the number of inputs matches the spice model definition) */ - /* Find pb_type input ports */ - input_ports = find_spice_model_ports(hardlogic_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - for (iport = 0; iport < num_input_port; iport++) { - for (ipin = 0; ipin < input_ports[iport]->size; ipin++) { - fprintf(fp, "hardlogic_%s[%d]->%s[%d] ", - hardlogic_spice_model->prefix, - hardlogic_spice_model->tb_cnt, - input_ports[iport]->prefix, ipin); - } - } - if (NULL != input_ports) { - fprintf(fp, "\n"); - fprintf(fp, "+ "); - } - - /* 3. Output ports */ - /* Find pb_type output ports */ - output_ports = find_spice_model_ports(hardlogic_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - for (iport = 0; iport < num_output_port; iport++) { - for (ipin = 0; ipin < output_ports[iport]->size; ipin++) { - fprintf(fp, "hardlogic_%s[%d]->%s[%d] ", - hardlogic_spice_model->prefix, - hardlogic_spice_model->tb_cnt, - output_ports[iport]->prefix, ipin); - } - } - if (NULL != output_ports) { - fprintf(fp, "\n"); - fprintf(fp, "+ "); - } - - /* 4. Inout ports */ - /* INOUT ports */ - /* Find pb_type inout ports */ - inout_ports = find_spice_model_ports(hardlogic_spice_model, SPICE_MODEL_PORT_INOUT, &num_inout_port, TRUE); - for (iport = 0; iport < num_inout_port; iport++) { - for (ipin = 0; ipin < inout_ports[iport]->size; ipin++) { - fprintf(fp, "hardlogic_%s[%d]->%s[%d] ", - hardlogic_spice_model->prefix, - hardlogic_spice_model->tb_cnt, - inout_ports[iport]->prefix, ipin); - } - } - if (NULL != inout_ports) { - fprintf(fp, "\n"); - fprintf(fp, "+ "); - } - - /* Clocks */ - /* Identify if the clock port is a global signal */ - /* Find pb_type clock ports */ - clk_ports = find_spice_model_ports(hardlogic_spice_model, SPICE_MODEL_PORT_CLOCK, &num_clk_port, TRUE); - for (iport = 0; iport < num_clk_port; iport++) { - for (ipin = 0; ipin < clk_ports[iport]->size; ipin++) { - fprintf(fp, "hardlogic_%s[%d]->%s[%d] ", - hardlogic_spice_model->prefix, - hardlogic_spice_model->tb_cnt, - clk_ports[iport]->prefix, ipin); - } - } - if (NULL != clk_ports) { - fprintf(fp, "\n"); - fprintf(fp, "+ "); - } - - /* 5. Configuration ports */ - /* Generate SRAMs? */ - - /* 6. VDD and GND ports */ - fprintf(fp, "%s_%s[%d] %s ", - spice_tb_global_vdd_port_name, hardlogic_spice_model->prefix, hardlogic_spice_model->tb_cnt, - spice_tb_global_gnd_port_name); - fprintf(fp, "\n"); - fprintf(fp, "+ "); - - /* Call the name of subckt */ - fprintf(fp, "%s\n", hardlogic_spice_model->name); - - /* Free */ - my_free(input_ports); - my_free(output_ports); - my_free(inout_ports); - my_free(clk_ports); - - return; -} - -void fprint_spice_hardlogic_testbench_one_pb_graph_node_hardlogic(FILE* fp, - t_pb_graph_node* cur_pb_graph_node, - char* prefix, - int x, int y, - t_ivec*** LL_rr_node_indices) { - int logical_block_index = OPEN; - t_spice_model* pb_spice_model = NULL; - t_pb_type* cur_pb_type = NULL; - int iport, ipin; - - /* For pb_spice_model */ - int num_input_port; - t_spice_model_port** input_ports; - int num_output_port; - t_spice_model_port** output_ports; - - /* Two-dimension arrays, corresponding to the port map [port_id][pin_id] */ - float** input_density = NULL; - float** input_probability = NULL; - int** input_init_value = NULL; - int** input_net_num = NULL; - - char* outport_name = NULL; - t_rr_node* local_rr_graph = NULL; - float average_density = 0.; - int avg_density_cnt = 0; - int num_sim_clock_cycles = 0; - - assert(NULL != cur_pb_graph_node); - assert(NULL != prefix); - - cur_pb_type = cur_pb_graph_node->pb_type; - assert(NULL != cur_pb_type); - pb_spice_model = cur_pb_type->spice_model; - - /* Just a double check*/ - if ((SPICE_MODEL_HARDLOGIC != pb_spice_model->type) - &&(SPICE_MODEL_FF != pb_spice_model->type)) { - vpr_printf(TIO_MESSAGE_ERROR, - "(File:%s, [LINE%d]) Type of SPICE models should be either Flip-Flop or Hard Logic!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Try to find the mapped logic block index */ - logical_block_index = find_grid_mapped_logical_block(x, y, - pb_spice_model, prefix); - - /* UNCOMMENT THIS, IF YOU DO NOT WANT SIMULATE THE IDLE ELEMENTS - if (OPEN == logical_block_index) { - return; - } - */ - - /* Call the subckt and give stimulates, measurements */ - if (OPEN != logical_block_index) { - fprintf(fp,"***** Hardlogic[%d]: logical_block_index[%d], gvdd_index[%d]*****\n", - pb_spice_model->cnt, logical_block_index, logical_block[logical_block_index].mapped_spice_model_index); - } else { - fprintf(fp,"***** Hardlogic[%d]: logical_block_index[%d], gvdd_index[%d]*****\n", - pb_spice_model->cnt, -1, -1); - } - - /* Now, we print the SPICE subckt of a hard logic */ - fprint_spice_hardlogic_testbench_one_hardlogic(fp, prefix, pb_spice_model); - - /* Malloc */ - /* First dimension */ - input_density = (float**)my_malloc(sizeof(float*) * cur_pb_graph_node->num_input_ports); - input_probability = (float**)my_malloc(sizeof(float*) * cur_pb_graph_node->num_input_ports); - input_init_value = (int**)my_malloc(sizeof(int*) * cur_pb_graph_node->num_input_ports); - input_net_num = (int**)my_malloc(sizeof(int*) * cur_pb_graph_node->num_input_ports); - /* Second dimension */ - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - input_density[iport] = (float*)my_malloc(sizeof(float) * cur_pb_graph_node->num_input_pins[iport]); - input_probability[iport] = (float*)my_malloc(sizeof(float) * cur_pb_graph_node->num_input_pins[iport]); - input_init_value[iport] = (int*)my_malloc(sizeof(int) * cur_pb_graph_node->num_input_pins[iport]); - input_net_num[iport] = (int*)my_malloc(sizeof(int) * cur_pb_graph_node->num_input_pins[iport]); - } - - /* Get activity information */ - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { - /* if we find a mapped logic block */ - if (OPEN != logical_block_index) { - local_rr_graph = logical_block[logical_block_index].pb->parent_pb->rr_graph; - } else { - local_rr_graph = NULL; - } - input_net_num[iport][ipin] = pb_pin_net_num(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - input_density[iport][ipin] = pb_pin_density(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - input_probability[iport][ipin] = pb_pin_probability(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - input_init_value[iport][ipin] = pb_pin_init_value(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - } - } - - /* Add Input stimulates */ - /* Get the input port list of spice model */ - input_ports = find_spice_model_ports(pb_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - /* Check if the port map of current pb_graph_node matches that of the spice model !!!*/ - assert(num_input_port == cur_pb_graph_node->num_input_ports); - for (iport = 0; iport < num_input_port; iport++) { - assert(input_ports[iport]->size == cur_pb_graph_node->num_input_pins[iport]); - for (ipin = 0; ipin < input_ports[iport]->size; ipin++) { - /* Check the port size should match!*/ - fprintf(fp, "Vhardlogic_%s[%d]->%s[%d] hardlogic_%s[%d]->%s[%d] 0 \n", - pb_spice_model->prefix, - pb_spice_model->tb_cnt, - cur_pb_graph_node->input_pins[iport]->port->name, - ipin, - pb_spice_model->prefix, - pb_spice_model->tb_cnt, - input_ports[iport]->prefix, - ipin); - fprint_voltage_pulse_params(fp, input_init_value[iport][ipin], input_density[iport][ipin], input_probability[iport][ipin]); - } - } - - /* Add loads: Recursively */ - /* Get the output port list of spice model */ - output_ports = find_spice_model_ports(pb_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - for (iport = 0; iport < num_output_port; iport++) { - for (ipin = 0; ipin < output_ports[iport]->size; ipin++) { - outport_name = (char*)my_malloc(sizeof(char)*( 10 + - + strlen(pb_spice_model->prefix) + 1 - + strlen(my_itoa(pb_spice_model->tb_cnt)) - + 3 + strlen(output_ports[iport]->prefix) + 1 - + strlen(my_itoa(ipin)) + 2 )); - sprintf(outport_name, "hardlogic_%s[%d]->%s[%d]", - pb_spice_model->prefix, - pb_spice_model->tb_cnt, - output_ports[iport]->prefix, - ipin); - if (TRUE == run_testbench_load_extraction) { /* Additional switch, default on! */ - if (OPEN != logical_block_index) { - fprint_spice_testbench_pb_graph_pin_inv_loads_rec(fp, &testbench_load_cnt, - x, y, - &(cur_pb_graph_node->output_pins[0][0]), - logical_block[logical_block_index].pb, - outport_name, - FALSE, - LL_rr_node_indices); - } else { - fprint_spice_testbench_pb_graph_pin_inv_loads_rec(fp, &testbench_load_cnt, - x, y, - &(cur_pb_graph_node->output_pins[0][0]), - NULL, - outport_name, - FALSE, - LL_rr_node_indices); - } - } - /* Free outport_name in each iteration */ - my_free(outport_name); - } - } - - /* Calculate average density of this hardlogic */ - average_density = 0.; - avg_density_cnt = 0; - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { - assert(!(0 > input_density[iport][ipin])); - if (0. < input_density[iport][ipin]) { - average_density += input_density[iport][ipin]; - avg_density_cnt++; - } - } - } - /* Calculate the num_sim_clock_cycle for this MUX, update global max_sim_clock_cycle in this testbench */ - if (0 < avg_density_cnt) { - average_density = average_density/avg_density_cnt; - } else { - assert(0 == avg_density_cnt); - average_density = 0.; - } - if (0. == average_density) { - num_sim_clock_cycles = 2; - } else { - assert(0. < average_density); - num_sim_clock_cycles = (int)(1/average_density) + 1; - } - if (TRUE == auto_select_max_sim_num_clock_cycles) { - /* for idle blocks, 2 clock cycle is well enough... */ - if (2 < num_sim_clock_cycles) { - num_sim_clock_cycles = upbound_sim_num_clock_cycles; - } else { - num_sim_clock_cycles = 2; - } - if (max_sim_num_clock_cycles < num_sim_clock_cycles) { - max_sim_num_clock_cycles = num_sim_clock_cycles; - } - } else { - num_sim_clock_cycles = max_sim_num_clock_cycles; - } - - /* Mark temporary used */ - if (OPEN != logical_block_index) { - logical_block[logical_block_index].temp_used = 1; - } - - /* Increment the counter of the hardlogic spice model */ - pb_spice_model->tb_cnt++; - tb_num_hardlogic++; - - /* Free */ - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - my_free(input_net_num[iport]); - my_free(input_init_value[iport]); - my_free(input_density[iport]); - my_free(input_probability[iport]); - } - my_free(input_net_num); - my_free(input_init_value); - my_free(input_density); - my_free(input_probability); - my_free(input_ports); - my_free(output_ports); - - return; -} - -void fprint_spice_hardlogic_testbench_rec_pb_graph_node_hardlogics(FILE* fp, - t_pb_graph_node* cur_pb_graph_node, - char* prefix, - int x, int y, - t_ivec*** LL_rr_node_indices) { - char* formatted_prefix = format_spice_node_prefix(prefix); - int ipb, jpb, mode_index; - t_pb_type* cur_pb_type = NULL; - char* rec_prefix = NULL; - - assert(NULL != cur_pb_graph_node); - cur_pb_type = cur_pb_graph_node->pb_type; - assert(NULL != cur_pb_type); - /* Until we reach a FF */ - if (NULL != cur_pb_type->spice_model) { - if ((SPICE_MODEL_FF != cur_pb_type->spice_model->type) - &&(SPICE_MODEL_HARDLOGIC != cur_pb_type->spice_model->type)) { - return; - } - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(cur_pb_graph_node->placement_index)) - + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]", - formatted_prefix, cur_pb_type->name, cur_pb_graph_node->placement_index); - /* Print a hardlogic tb: call spice_model, stimulates */ - fprint_spice_hardlogic_testbench_one_pb_graph_node_hardlogic(fp, cur_pb_graph_node, rec_prefix, x, y, LL_rr_node_indices); - my_free(rec_prefix); - return; - } - - /* Go recursively ... */ - mode_index = find_pb_type_idle_mode_index(*(cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(cur_pb_graph_node->placement_index)) + 7 - + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]_mode[%s]", - formatted_prefix, cur_pb_type->name, cur_pb_graph_node->placement_index, - cur_pb_type->modes[mode_index].name); - /* Go recursively */ - fprint_spice_hardlogic_testbench_rec_pb_graph_node_hardlogics(fp, &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - rec_prefix, x, y, LL_rr_node_indices); - my_free(rec_prefix); - } - } - - return; -} - -void fprint_spice_hardlogic_testbench_rec_pb_hardlogics(FILE* fp, - t_pb* cur_pb, char* prefix, - int x, int y, - t_ivec*** LL_rr_node_indices) { - char* formatted_prefix = format_spice_node_prefix(prefix); - int ipb, jpb; - int mode_index; - char* rec_prefix = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - /* Check */ - assert(NULL != cur_pb); - - /* If we touch the leaf, there is no need print interc*/ - if (NULL != cur_pb->pb_graph_node->pb_type->spice_model) { - if ((SPICE_MODEL_HARDLOGIC != cur_pb->pb_graph_node->pb_type->spice_model->type) - &&(SPICE_MODEL_FF != cur_pb->pb_graph_node->pb_type->spice_model->type)) { - return; - } - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 - + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) - + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]", - formatted_prefix, cur_pb->pb_graph_node->pb_type->name, cur_pb->pb_graph_node->placement_index); - /* Print a lut tb: call spice_model, stimulates */ - fprint_spice_hardlogic_testbench_one_pb_graph_node_hardlogic(fp, cur_pb->pb_graph_node, rec_prefix, x, y, LL_rr_node_indices); - my_free(rec_prefix); - return; - } - - /* Go recursively ... */ - mode_index = cur_pb->mode; - if (!(0 < cur_pb->pb_graph_node->pb_type->num_modes)) { - return; - } - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 - + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) + 7 - + strlen(cur_pb->pb_graph_node->pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]_mode[%s]", - formatted_prefix, cur_pb->pb_graph_node->pb_type->name, - cur_pb->pb_graph_node->placement_index, - cur_pb->pb_graph_node->pb_type->modes[mode_index].name); - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - fprint_spice_hardlogic_testbench_rec_pb_hardlogics(fp, &(cur_pb->child_pbs[ipb][jpb]), rec_prefix, x, y, LL_rr_node_indices); - } else { - /* Then we go on */ - fprint_spice_hardlogic_testbench_rec_pb_graph_node_hardlogics(fp, cur_pb->child_pbs[ipb][jpb].pb_graph_node, - rec_prefix, x, y, LL_rr_node_indices); - } - } - } - - return; -} - -void fprint_spice_hardlogic_testbench_call_one_grid_defined_hardlogics(FILE* fp, - int ix, int iy, - t_ivec*** LL_rr_node_indices) { - int iblk; - char* prefix = NULL; - - if ((NULL == grid[ix][iy].type) - ||(EMPTY_TYPE == grid[ix][iy].type) - ||(0 != grid[ix][iy].offset)) { - return; - } - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - for (iblk = 0; iblk < grid[ix][iy].usage; iblk++) { - prefix = (char*)my_malloc(sizeof(char)* (5 - + strlen(my_itoa(block[grid[ix][iy].blocks[iblk]].x)) - + 2 + strlen(my_itoa(block[grid[ix][iy].blocks[iblk]].y)) - + 3 )); - sprintf(prefix, "grid[%d][%d]_", - block[grid[ix][iy].blocks[iblk]].x, - block[grid[ix][iy].blocks[iblk]].y); - /* Only for mapped block */ - assert(NULL != block[grid[ix][iy].blocks[iblk]].pb); - /* Mark the temporary net_num for the type pins*/ - mark_one_pb_parasitic_nets(block[grid[ix][iy].blocks[iblk]].pb); - /* Go into the hierachy and dump hardlogics */ - fprint_spice_hardlogic_testbench_rec_pb_hardlogics(fp, block[grid[ix][iy].blocks[iblk]].pb, prefix, ix, iy, LL_rr_node_indices); - /* Free */ - my_free(prefix); - } - /* Bypass unused blocks */ - for (iblk = grid[ix][iy].usage; iblk < grid[ix][iy].type->capacity; iblk++) { - prefix = (char*)my_malloc(sizeof(char)* (5 + strlen(my_itoa(ix)) - + 2 + strlen(my_itoa(iy)) + 3 )); - sprintf(prefix, "grid[%d][%d]_", ix, iy); - assert(NULL != grid[ix][iy].type->pb_graph_head); - /* Mark the temporary net_num for the type pins*/ - mark_grid_type_pb_graph_node_pins_temp_net_num(ix, iy); - /* Go into the hierachy and dump hardlogics */ - fprint_spice_hardlogic_testbench_rec_pb_graph_node_hardlogics(fp, grid[ix][iy].type->pb_graph_head, prefix, ix, iy, LL_rr_node_indices); - /* Free */ - my_free(prefix); - } - - return; -} - -void fprint_spice_hardlogic_testbench_call_defined_hardlogics(FILE* fp, - t_ivec*** LL_rr_node_indices) { - int ix, iy; - - for (ix = 1; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - fprint_spice_hardlogic_testbench_call_one_grid_defined_hardlogics(fp, ix, iy, LL_rr_node_indices); - } - } - - return; -} - -static -void fprint_spice_hardlogic_testbench_stimulations(FILE* fp, int grid_x, int grid_y, - int num_clocks, - t_spice spice, - t_ivec*** LL_rr_node_indices) { - /* Print generic stimuli */ - fprint_spice_testbench_generic_global_ports_stimuli(fp, num_clocks); - - /* Generate global ports stimuli */ - fprint_spice_testbench_global_ports_stimuli(fp, global_ports_head); - - /* SRAM ports */ - fprintf(fp, "***** Global Inputs for SRAMs *****\n"); - fprint_spice_testbench_global_sram_inport_stimuli(fp, sram_spice_orgz_info); - - fprintf(fp, "***** Global VDD for SRAMs *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_sram_port_name, - "vsp"); - - fprintf(fp, "***** Global VDD for load inverters *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_load_port_name, - "vsp"); - /* - fprintf(fp, "***** Global VDD for IOPADs *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_io_port_name, - "vsp"); - - fprintf(fp, "***** Global VDD for IOPAD SRAMs *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_io_sram_port_name, - "vsp"); - */ - - /* Every LUT use an independent Voltage source */ - fprintf(fp, "***** Global VDD for FFs *****\n"); - fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, spice); - fprintf(fp, "***** Global VDD for Hardlogics *****\n"); - fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, spice); - - return; -} - -void fprint_spice_hardlogic_testbench_measurements(FILE* fp, int grid_x, int grid_y, - t_spice spice, - boolean leakage_only) { - - /* int i; */ - /* First cycle reserved for measuring leakage */ - int num_clock_cycle = max_sim_num_clock_cycles; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - fprint_spice_netlist_transient_setting(fp, spice, num_clock_cycle, leakage_only); - fprint_spice_netlist_generic_measurements(fp, spice.spice_params.mc_params, spice.num_spice_model, spice.spice_models); - - /* TODO: Measure the delay of each mapped net and logical block */ - - /* Measure the power */ - /* Leakage ( the first cycle is reserved for leakage measurement) */ - /* Leakage power of FFs*/ - fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); - /* Leakage power of Hardlogic */ - fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); - - if (TRUE == leakage_only) { - return; - } - - /* Dynamic power */ - /* Dynamic power of FFs */ - fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); - - /* Dynamic power of Hardlogics */ - fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); - - return; -} - -/* Top-level function in this source file */ -int fprint_spice_one_hardlogic_testbench(char* formatted_spice_dir, - char* circuit_name, - char* hardlogic_testbench_name, - char* include_dir_path, - char* subckt_dir_path, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_arch arch, - int grid_x, int grid_y, - boolean leakage_only) { - FILE* fp = NULL; - char* title = my_strcat("FPGA Hard Logic Testbench for Design: ", circuit_name); - char* hardlogic_testbench_file_path = my_strcat(formatted_spice_dir, hardlogic_testbench_name); - int used; - - /* Check if the path exists*/ - fp = fopen(hardlogic_testbench_file_path,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create DFF Testbench SPICE netlist %s!",__FILE__, __LINE__, - hardlogic_testbench_file_path); - exit(1); - } - - /* Reset tb_cnt for all the spice models */ - init_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y); - - /* vpr_printf(TIO_MESSAGE_INFO, "Writing DFF Testbench for %s...\n", circuit_name); */ - testbench_load_cnt = 0; - - /* Print the title */ - fprint_spice_head(fp, title); - my_free(title); - - /* print technology library and design parameters*/ - /* fprint_tech_lib(fp, arch.spice->tech_lib);*/ - - /* Include parameter header files */ - fprint_spice_include_param_headers(fp, include_dir_path); - - /* Include Key subckts */ - fprint_spice_include_key_subckts(fp, subckt_dir_path); - - /* Include user-defined sub-circuit netlist */ - init_include_user_defined_netlists(*(arch.spice)); - fprint_include_user_defined_netlists(fp, *(arch.spice)); - - /* Print simulation temperature and other options for SPICE */ - fprint_spice_options(fp, arch.spice->spice_params); - - /* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */ - fprint_spice_hardlogic_testbench_global_ports(fp, grid_x, grid_y, num_clock, (*arch.spice)); - - /* Quote defined Logic blocks subckts (Grids) */ - init_spice_hardlogic_testbench_globals(*(arch.spice)); - init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, arch.spice->spice_models, SPICE_MODEL_FF); - init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, arch.spice->spice_models, SPICE_MODEL_HARDLOGIC); - - /* Now start our job formally: dump hard logic circuit one by one */ - fprint_spice_hardlogic_testbench_call_one_grid_defined_hardlogics(fp, grid_x, grid_y, LL_rr_node_indices); - - /* Back-anotate activity information to each routing resource node - * (We should have activity of each Grid port) - */ - - /* Check if the all hardlogic located in this grid have been printed */ - check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_FF); - check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_HARDLOGIC); - - /* Add stimulations */ - fprint_spice_hardlogic_testbench_stimulations(fp, grid_x, grid_y, num_clock, (*arch.spice), LL_rr_node_indices); - - /* Add measurements */ - fprint_spice_hardlogic_testbench_measurements(fp, grid_x, grid_y, (*arch.spice), leakage_only); - - /* SPICE ends*/ - fprintf(fp, ".end\n"); - - /* Close the file*/ - fclose(fp); - - if (0 < tb_num_hardlogic) { - /* - vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE Hard Logic Testbench for %s...\n", - grid_x, grid_y, circuit_name); - */ - /* Push the testbench to the linked list */ - tb_head = add_one_spice_tb_info_to_llist(tb_head, hardlogic_testbench_file_path, - max_sim_num_clock_cycles); - used = 1; - } else { - /* Remove the file generated */ - my_remove_file(hardlogic_testbench_file_path); - used = 0; - } - - return used; -} - -/* Top-level function in this source file */ -void spice_print_hardlogic_testbench(char* formatted_spice_dir, - char* circuit_name, - char* include_dir_path, - char* subckt_dir_path, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_arch arch, - boolean leakage_only) { - char* hardlogic_testbench_name = NULL; - int ix, iy; - int cnt = 0; - int used = 0; - - for (ix = 1; ix < (nx+1); ix++) { - for (iy = 1; iy < (ny+1); iy++) { - /* Name the testbench */ - hardlogic_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name) - + 6 + strlen(my_itoa(ix)) + 1 - + strlen(my_itoa(iy)) + 1 - + strlen(spice_hardlogic_testbench_postfix) + 1 )); - sprintf(hardlogic_testbench_name, "%s_grid%d_%d%s", - circuit_name, ix, iy, spice_hardlogic_testbench_postfix); - /* Start building one testbench */ - used = fprint_spice_one_hardlogic_testbench(formatted_spice_dir, circuit_name, hardlogic_testbench_name, - include_dir_path, subckt_dir_path, LL_rr_node_indices, - num_clock, arch, ix, iy, - leakage_only); - if (1 == used) { - cnt += used; - } - /* free */ - my_free(hardlogic_testbench_name); - } - } - /* Update the global counter */ - num_used_hardlogic_tb = cnt; - vpr_printf(TIO_MESSAGE_INFO,"No. of generated hard logic testbench = %d\n", num_used_hardlogic_tb); - - return; -} - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.h b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.h deleted file mode 100644 index 318ffa62f..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_hardlogic_testbench.h +++ /dev/null @@ -1,9 +0,0 @@ - -void spice_print_hardlogic_testbench(char* formatted_spice_dir, - char* circuit_name, - char* include_dir_path, - char* subckt_dir_path, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_arch arch, - boolean leakage_only); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.c b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.c deleted file mode 100644 index 461553c3b..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.c +++ /dev/null @@ -1,387 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "rr_graph_swseg.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "spice_utils.h" -#include "spice_mux.h" -#include "spice_pbtypes.h" -#include "spice_lut.h" - - -/***** Subroutines *****/ - -void fprint_spice_lut_subckt(FILE* fp, - t_spice_model spice_model) { - int i; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - float total_width; - int width_cnt; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - } - - /* Find input ports, output ports and sram ports*/ - input_ports = find_spice_model_ports(&spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(&spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - sram_ports = find_spice_model_ports(&spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - - /* Check */ - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - - fprintf(fp, "***** Auto-generated LUT info: spice_model_name = %s, size = %d *****\n", - spice_model.name, input_ports[0]->size); - /* Define the subckt*/ - fprintf(fp, ".subckt %s ", spice_model.name); /* Subckt name*/ - /* Input ports*/ - for (i = 0; i < input_ports[0]->size; i++) { - fprintf(fp, "%s%d ", input_ports[0]->prefix, i); - } - /* output ports*/ - assert(1 == output_ports[0]->size); - fprintf(fp, "%s ", output_ports[0]->prefix); - /* sram ports */ - for (i = 0; i < sram_ports[0]->size; i++) { - fprintf(fp, "%s%d ", sram_ports[0]->prefix, i); - } - /* local vdd and gnd*/ - fprintf(fp, "svdd sgnd\n"); - - /* Input buffers */ - for (i = 0; i < input_ports[0]->size; i++) { - /* For negative input of LUT MUX*/ - /* Output inverter with maximum size allowed - * until the rest of width is smaller than threshold */ - total_width = spice_model.lut_input_buffer->size * spice_model.lut_input_buffer->f_per_stage; - width_cnt = 0; - while (total_width > max_width_per_trans) { - fprintf(fp, "Xinv0_in%d_no%d %s%d lut_mux_in%d_inv svdd sgnd inv size=\'%g\'", - i, width_cnt, - input_ports[0]->prefix, i, - i, max_width_per_trans); - fprintf(fp, "\n"); - /* Update */ - total_width = total_width - max_width_per_trans; - width_cnt++; - } - /* Print if we still have to */ - if (total_width > 0) { - fprintf(fp, "Xinv0_in%d_no%d %s%d lut_mux_in%d_inv svdd sgnd inv size=\'%g\'", - i, width_cnt, - input_ports[0]->prefix, i, - i, total_width); - fprintf(fp, "\n"); - } - /* For postive input of LUT MUX, we use the tapered_buffer subckt directly */ - assert(1 == spice_model.lut_input_buffer->tapered_buf); - fprintf(fp, "X%s_in%d %s%d lut_mux_in%d svdd sgnd tapbuf_level%d_f%d\n", - spice_model.lut_input_buffer->spice_model->prefix, i, - input_ports[0]->prefix, i, i, - spice_model.lut_input_buffer->tap_buf_level, - spice_model.lut_input_buffer->f_per_stage); - fprintf(fp, "\n"); - } - - /* Output buffers already included in LUT MUX */ - /* LUT MUX*/ - assert(sram_ports[0]->size == (int)pow(2.,(double)(input_ports[0]->size))); - fprintf(fp, "Xlut_mux "); - /* SRAM ports of LUT, they are inputs of lut_muxes*/ - for (i = 0; i < sram_ports[0]->size; i++) { - fprintf(fp, "%s%d ", sram_ports[0]->prefix, i); - } - /* Output port, LUT output is LUT MUX output*/ - fprintf(fp, "%s ", output_ports[0]->prefix); - /* input port, LUT input is LUT MUX sram*/ - for (i = 0; i < input_ports[0]->size; i++) { - fprintf(fp, "lut_mux_in%d lut_mux_in%d_inv ", i, i); - } - /* Local vdd and gnd*/ - fprintf(fp, "svdd sgnd %s_mux_size%d\n", spice_model.name, sram_ports[0]->size); - - /* End of LUT subckt*/ - fprintf(fp, ".eom\n"); - - /* Free */ - free(input_ports); - free(output_ports); - free(sram_ports); - - return; -} - -/* Print LUT subckts into a SPICE file*/ -void generate_spice_luts(char* subckt_dir, - int num_spice_model, - t_spice_model* spice_models) { - FILE* fp = NULL; - char* sp_name = my_strcat(subckt_dir, luts_spice_file_name); - int imodel = 0; - - /* Create FILE*/ - fp = fopen(sp_name, "w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create SPICE netlist %s",__FILE__, __LINE__, wires_spice_file_name); - exit(1); - } - fprint_spice_head(fp,"LUTs"); - - for (imodel = 0; imodel < num_spice_model; imodel++) { - if ((SPICE_MODEL_LUT == spice_models[imodel].type) - &&(NULL == spice_models[imodel].model_netlist)) { - fprint_spice_lut_subckt(fp, spice_models[imodel]); - } - } - - /* Close*/ - fclose(fp); - - return; -} - -void fprint_pb_primitive_lut(FILE* fp, - char* subckt_prefix, - t_pb* prim_pb, - t_logical_block* mapped_logical_block, - t_pb_graph_node* cur_pb_graph_node, - int index, - t_spice_model* spice_model, - int lut_status, - t_rr_node* pb_rr_graph) { - int i; - int num_sram = 0; - int* sram_bits = NULL; /* decoded SRAM bits */ - int truth_table_length = 0; - char** truth_table = NULL; - int lut_size = 0; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - char* formatted_subckt_prefix = format_spice_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* cur_pb_type = NULL; - char* port_prefix = NULL; - int cur_num_sram = 0; - char* sram_vdd_port_name = NULL; - - int num_lut_pin_nets; - int* lut_pin_net = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == cur_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - /* Asserts */ - assert(SPICE_MODEL_LUT == spice_model->type); - - /* Check if this is an idle logical block mapped*/ - switch (lut_status) { - case PRIMITIVE_WIRED_LUT: - assert(NULL != pb_rr_graph); - if (NULL == mapped_logical_block) { - /* Get the mapped vpack_net_num of this physical LUT pb */ - get_mapped_lut_pb_input_pin_vpack_net_num(cur_pb_graph_node, pb_rr_graph, &num_lut_pin_nets, &lut_pin_net); - /* consider LUT pin remapping when assign lut truth tables */ - mapped_logical_block = &logical_block[get_pb_graph_node_wired_lut_logical_block_index(cur_pb_graph_node, pb_rr_graph)]; - /* Match truth table and post-routing results */ - truth_table = assign_post_routing_wired_lut_truth_table(mapped_logical_block, - num_lut_pin_nets, lut_pin_net, &truth_table_length); - } else { - /* Give a special truth table */ - assert (VPACK_COMB == mapped_logical_block->type); - /* Get the mapped vpack_net_num of this physical LUT pb */ - get_mapped_lut_pb_input_pin_vpack_net_num(cur_pb_graph_node, pb_rr_graph, &num_lut_pin_nets, &lut_pin_net); - /* consider LUT pin remapping when assign lut truth tables */ - /* Match truth table and post-routing results */ - truth_table = assign_post_routing_wired_lut_truth_table(mapped_logical_block, - num_lut_pin_nets, lut_pin_net, &truth_table_length); - } - break; - case PRIMITIVE_IDLE: - break; - case PRIMITIVE_NORMAL: - assert (NULL != mapped_logical_block); - /* Back-annotate to logical block */ - /* Back-annotate to logical block */ - mapped_logical_block->mapped_spice_model = spice_model; - mapped_logical_block->mapped_spice_model_index = spice_model->cnt; - - assert (VPACK_COMB == mapped_logical_block->type); - /* Get the mapped vpack_net_num of this physical LUT pb */ - get_mapped_lut_pb_input_pin_vpack_net_num(cur_pb_graph_node, pb_rr_graph, &num_lut_pin_nets, &lut_pin_net); - /* consider LUT pin remapping when assign lut truth tables */ - /* Match truth table and post-routing results */ - truth_table = assign_post_routing_lut_truth_table(mapped_logical_block, - num_lut_pin_nets, lut_pin_net, &truth_table_length); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "(FILE:%s, [LINE%d]) Invalid status(=%d) for LUT!\n", - __FILE__, __LINE__, lut_status); - exit(1); - } - /* Determine size of LUT*/ - input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - sram_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - lut_size = input_ports[0]->size; - num_sram = (int)pow(2.,(double)(lut_size)); - assert(num_sram == sram_ports[0]->size); - assert(1 == output_ports[0]->size); - - /* Get current counter of mem_bits, bl and wl */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); - - /* Generate sram bits, use the default value of SRAM port */ - sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, - lut_size, sram_ports[0]->default_val); - - /* Print the subckts*/ - cur_pb_type = cur_pb_graph_node->pb_type; - - if (NULL != mapped_logical_block) { - fprintf(fp, "***** Logical block mapped to this LUT: %s *****\n", - mapped_logical_block->name); - } - - /* Subckt definition*/ - fprintf(fp, ".subckt %s%s[%d] ", formatted_subckt_prefix, cur_pb_type->name, index); - /* Print inputs, outputs, inouts, clocks, NO SRAMs*/ - /* - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 + - strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, cur_pb_type->name, index); - */ - /* Simplify the prefix, make the SPICE netlist readable*/ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(cur_pb_type->name) + 1 + - strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s[%d]", cur_pb_type->name, index); - - /* Only dump the global ports belonging to a spice_model - * Do not go recursive, we can freely define global ports anywhere in SPICE netlist - */ - rec_fprint_spice_model_global_ports(fp, spice_model, FALSE); - - fprint_pb_type_ports(fp, port_prefix, 0, cur_pb_type); - /* SRAM bits are fixed in this subckt, no need to define them here*/ - /* Local Vdd and gnd*/ - fprintf(fp, "svdd sgnd\n"); - /* Definition ends*/ - - /* Print the encoding in SPICE netlist for debugging */ - fprintf(fp, "***** Truth Table for LUT[%d], size=%d. *****\n", - spice_model->cnt, lut_size); - for (i = 0; i < truth_table_length; i++) { - fprintf(fp,"* %s *\n", truth_table[i]); - } - - fprintf(fp, "***** SRAM bits for LUT[%d], size=%d, num_sram=%d. *****\n", - spice_model->cnt, lut_size, num_sram); - fprintf(fp, "*****"); - for (i = 0; i < num_sram; i++) { - fprintf(fp, "%d", sram_bits[i]); - } - fprintf(fp, "*****\n"); - - /* Call SRAM subckts*/ - /* Give the VDD port name for SRAMs */ - sram_vdd_port_name = (char*)my_malloc(sizeof(char)* - (strlen(spice_tb_global_vdd_lut_sram_port_name) - + 1 )); - sprintf(sram_vdd_port_name, "%s", - spice_tb_global_vdd_lut_sram_port_name); - /* Now Print SRAMs one by one */ - for (i = 0; i < num_sram; i++) { - fprint_spice_one_sram_subckt(fp, sram_spice_orgz_info, spice_model, sram_vdd_port_name); - } - - /* Call LUT subckt*/ - fprintf(fp, "X%s[%d] ", spice_model->prefix, spice_model->cnt); - /* Connect inputs*/ - /* Connect outputs*/ - fprint_pb_type_ports(fp, port_prefix, 0, cur_pb_type); - /* Connect srams*/ - for (i = 0; i < num_sram; i++) { - assert( (0 == sram_bits[i]) || (1 == sram_bits[i]) ); - fprint_spice_sram_one_outport(fp, sram_spice_orgz_info, cur_num_sram + i, sram_bits[i]); - } - - /* vdd should be connected to special global wire gvdd_lut and gnd, - * Every LUT has a special VDD for statistics - */ - fprintf(fp, "gvdd_%s[%d] sgnd %s\n", spice_model->prefix, spice_model->cnt, spice_model->name); - /* TODO: Add a nodeset for convergence */ - - /* End of subckt*/ - fprintf(fp, ".eom\n"); - - /* Store the configuraion bit to linked-list */ - add_sram_conf_bits_to_llist(sram_spice_orgz_info, cur_num_sram, - num_sram, sram_bits); - - spice_model->cnt++; - - /*Free*/ - for (i = 0; i < truth_table_length; i++) { - free(truth_table[i]); - } - free(truth_table); - my_free(formatted_subckt_prefix); - my_free(input_ports); - my_free(output_ports); - my_free(sram_ports); - my_free(sram_bits); - my_free(port_prefix); - my_free(sram_vdd_port_name); - - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.h b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.h deleted file mode 100644 index e81200141..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut.h +++ /dev/null @@ -1,20 +0,0 @@ - - - -void fprint_spice_lut_subckt(FILE* fp, - t_spice_model spice_model); - -void generate_spice_luts(char* subckt_dir, - int num_spice_model, - t_spice_model* spice_models); - - -void fprint_pb_primitive_lut(FILE* fp, - char* subckt_prefix, - t_pb* prim_pb, - t_logical_block* mapped_logical_block, - t_pb_graph_node* cur_pb_graph_node, - int index, - t_spice_model* spice_model, - int lut_status, - t_rr_node* pb_rr_graph); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.c b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.c deleted file mode 100644 index 7644654c8..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.c +++ /dev/null @@ -1,773 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph_util.h" -#include "rr_graph.h" -#include "rr_graph2.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "spice_utils.h" -#include "spice_subckt.h" -#include "spice_mux_testbench.h" - -/* local global variables */ -static int tb_num_luts = 0; -static int testbench_load_cnt = 0; -static int upbound_sim_num_clock_cycles = 2; -static int max_sim_num_clock_cycles = 2; -static int auto_select_max_sim_num_clock_cycles = TRUE; - -/* Subroutines in this source file*/ -static -void init_spice_lut_testbench_globals(t_spice spice) { - tb_num_luts = 0; - auto_select_max_sim_num_clock_cycles = spice.spice_params.meas_params.auto_select_sim_num_clk_cycle; - upbound_sim_num_clock_cycles = spice.spice_params.meas_params.sim_num_clock_cycle + 1; - if (FALSE == auto_select_max_sim_num_clock_cycles) { - max_sim_num_clock_cycles = spice.spice_params.meas_params.sim_num_clock_cycle + 1; - } else { - max_sim_num_clock_cycles = 2; - } -} - -static -void fprint_spice_lut_testbench_global_ports(FILE* fp, int grid_x, int grid_y, - int num_clock, - t_spice spice) { - /* int i; */ - /* A valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__); - exit(1); - } - /* Print generic global ports*/ - fprint_spice_generic_testbench_global_ports(fp, - sram_spice_orgz_info, - global_ports_head); - - fprintf(fp, ".global gvdd_sram_luts\n"); - fprintf(fp, ".global gvdd_load\n"); - - /*Global Vdds for LUTs*/ - fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, spice); - /* - for (i = 0; i < spice.num_spice_model; i++) { - if (SPICE_MODEL_LUT == spice.spice_models[i].type) { - fprint_global_vdds_logical_block_spice_model(fp, &(spice.spice_models[i])); - } - } - */ - - - return; -} - -void fprint_spice_lut_testbench_one_lut(FILE* fp, - char* subckt_name, - int num_inputs, int num_outputs, - int* input_init_value, - float* input_density, - float* input_probability) { - int ipin; - /* A valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__); - exit(1); - } - /* Call defined subckt */ - fprintf(fp, "Xlut[%d] ", tb_num_luts); - for (ipin = 0; ipin < num_inputs; ipin++) { - fprintf(fp, "lut[%d]->in[%d] ", tb_num_luts, ipin); - } - fprintf(fp, "lut[%d]->out gvdd 0 %s\n", tb_num_luts, subckt_name); - /* Stimulates */ - for (ipin = 0; ipin < num_inputs; ipin++) { - fprintf(fp, "Vlut[%d]->in[%d] lut[%d]->in[%d] 0 \n", - tb_num_luts, ipin, tb_num_luts, ipin); - fprint_voltage_pulse_params(fp, input_init_value[ipin], input_density[ipin], input_probability[ipin]); - } - return; -} - -void fprint_spice_lut_testbench_one_pb_graph_node_lut(FILE* fp, - t_pb_graph_node* cur_pb_graph_node, - char* prefix, - int x, int y, - t_ivec*** LL_rr_node_indices) { - int logical_block_index = OPEN; - t_spice_model* pb_spice_model = NULL; - t_pb_type* cur_pb_type = NULL; - float* input_density = NULL; - float* input_probability = NULL; - int* input_init_value = NULL; - int* input_net_num = NULL; - int iport, ipin, cur_pin; - int num_inputs, num_outputs, num_clock_pins; - char* outport_name = NULL; - t_rr_node* local_rr_graph = NULL; - float average_density = 0.; - int avg_density_cnt = 0; - int num_sim_clock_cycles = 0; - - assert(NULL != cur_pb_graph_node); - assert(NULL != prefix); - - cur_pb_type = cur_pb_graph_node->pb_type; - assert(NULL != cur_pb_type); - pb_spice_model = cur_pb_type->spice_model; - - /* Try to find the mapped logic block index */ - logical_block_index = find_grid_mapped_logical_block(x, y, - pb_spice_model, prefix); - - /* Bypass unmapped luts */ - /* - if (OPEN == logical_block_index) { - return; - } - */ - - /* Allocate input_density and probability */ - stats_pb_graph_node_port_pin_numbers(cur_pb_graph_node,&num_inputs,&num_outputs, &num_clock_pins); - assert(0 == num_clock_pins); - assert(1 == num_outputs); - assert(0 < num_inputs); - - input_density = (float*)my_malloc(sizeof(float)*num_inputs); - input_probability = (float*)my_malloc(sizeof(float)*num_inputs); - input_init_value = (int*)my_malloc(sizeof(int)*num_inputs); - input_net_num = (int*)my_malloc(sizeof(int)*num_inputs); - - /* Get activity information */ - assert(1 == cur_pb_graph_node->num_input_ports); - cur_pin = 0; - for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { - /* if we find a mapped logic block */ - if (OPEN != logical_block_index) { - local_rr_graph = logical_block[logical_block_index].pb->parent_pb->rr_graph; - } else { - local_rr_graph = NULL; - } - input_net_num[cur_pin] = pb_pin_net_num(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - input_density[cur_pin] = pb_pin_density(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - input_probability[cur_pin] = pb_pin_probability(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - input_init_value[cur_pin] = pb_pin_init_value(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); - cur_pin++; - } - assert(cur_pin == num_inputs); - } - /* Check lut pin net num consistency */ - if (OPEN != logical_block_index) { - if (0 == check_consistency_logical_block_net_num(&(logical_block[logical_block_index]), num_inputs, input_net_num)) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])LUT(name:%s) consistency check fail!\n", - __FILE__, __LINE__, logical_block[logical_block_index].name); - exit(1); - } - } - - /* Call the subckt and give stimulates, measurements */ - if (OPEN != logical_block_index) { - fprintf(fp,"***** LUT[%d]: logical_block_index[%d], gvdd_index[%d]*****\n", - tb_num_luts, logical_block_index, logical_block[logical_block_index].mapped_spice_model_index); - } else { - fprintf(fp,"***** LUT[%d]: logical_block_index[%d], gvdd_index[%d]*****\n", - tb_num_luts, -1, -1); - } - fprint_spice_lut_testbench_one_lut(fp, prefix, num_inputs, num_outputs, - input_init_value, input_density, input_probability); - /* Add loads: two inverters */ - /* Recursive add all the loads */ - outport_name = (char*)my_malloc(sizeof(char)*( 4 + strlen(my_itoa(tb_num_luts)) - + 6 + 1 )); - sprintf(outport_name, "lut[%d]->out", - tb_num_luts); - if (TRUE == run_testbench_load_extraction) { /* Additional switch, default on! */ - if (OPEN != logical_block_index) { - fprint_spice_testbench_pb_graph_pin_inv_loads_rec(fp, &testbench_load_cnt, - x, y, - &(cur_pb_graph_node->output_pins[0][0]), - logical_block[logical_block_index].pb, - outport_name, - FALSE, - LL_rr_node_indices); - } else { - fprint_spice_testbench_pb_graph_pin_inv_loads_rec(fp, &testbench_load_cnt, - x, y, - &(cur_pb_graph_node->output_pins[0][0]), - NULL, - outport_name, - FALSE, - LL_rr_node_indices); - } - } - - /* Calculate average density of this MUX */ - average_density = 0.; - avg_density_cnt = 0; - for (ipin = 0; ipin < num_inputs; ipin++) { - assert(!(0 > input_density[ipin])); - if (0. < input_density[ipin]) { - average_density += input_density[ipin]; - avg_density_cnt++; - } - } - /* Calculate the num_sim_clock_cycle for this MUX, update global max_sim_clock_cycle in this testbench */ - if (0 < avg_density_cnt) { - average_density = average_density/avg_density_cnt; - } else { - assert(0 == avg_density_cnt); - average_density = 0.; - } - if (0. == average_density) { - num_sim_clock_cycles = 2; - } else { - assert(0. < average_density); - num_sim_clock_cycles = (int)(1/average_density) + 1; - } - if (TRUE == auto_select_max_sim_num_clock_cycles) { - /* for idle blocks, 2 clock cycle is well enough... */ - if (2 < num_sim_clock_cycles) { - num_sim_clock_cycles = upbound_sim_num_clock_cycles; - } else { - num_sim_clock_cycles = 2; - } - if (max_sim_num_clock_cycles < num_sim_clock_cycles) { - max_sim_num_clock_cycles = num_sim_clock_cycles; - } - } else { - num_sim_clock_cycles = max_sim_num_clock_cycles; - } - - /* Mark temporary used */ - if (OPEN != logical_block_index) { - logical_block[logical_block_index].temp_used = 1; - } - - /* Increment the counter of the LUT spice model */ - tb_num_luts++; - pb_spice_model->tb_cnt++; - - /* Free */ - my_free(input_net_num); - my_free(input_init_value); - my_free(input_density); - my_free(input_probability); - - return; -} - -void fprint_spice_lut_testbench_rec_pb_graph_node_luts(FILE* fp, - t_pb_graph_node* cur_pb_graph_node, - char* prefix, - int x, int y, - t_ivec*** LL_rr_node_indices) { - char* formatted_prefix = format_spice_node_prefix(prefix); - int ipb, jpb, mode_index; - t_pb_type* cur_pb_type = NULL; - char* rec_prefix = NULL; - - assert(NULL != cur_pb_graph_node); - cur_pb_type = cur_pb_graph_node->pb_type; - assert(NULL != cur_pb_type); - /* Until we reach a LUT */ - if (NULL != cur_pb_type->spice_model) { - if (SPICE_MODEL_LUT != cur_pb_type->spice_model->type) { - return; - } - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(cur_pb_graph_node->placement_index)) - + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]", - formatted_prefix, cur_pb_type->name, cur_pb_graph_node->placement_index); - /* Print a lut tb: call spice_model, stimulates */ - fprint_spice_lut_testbench_one_pb_graph_node_lut(fp, cur_pb_graph_node, rec_prefix, x, y, LL_rr_node_indices); - my_free(rec_prefix); - return; - } - - /* Go recursively ... */ - mode_index = find_pb_type_idle_mode_index(*(cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(cur_pb_graph_node->placement_index)) + 7 - + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]_mode[%s]", - formatted_prefix, cur_pb_type->name, cur_pb_graph_node->placement_index, - cur_pb_type->modes[mode_index].name); - /* Go recursively */ - fprint_spice_lut_testbench_rec_pb_graph_node_luts(fp, &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - rec_prefix, x, y, LL_rr_node_indices); - my_free(rec_prefix); - } - } - - return; -} - -void fprint_spice_lut_testbench_rec_pb_luts(FILE* fp, - t_pb* cur_pb, char* prefix, - int x, int y, - t_ivec*** LL_rr_node_indices) { - char* formatted_prefix = format_spice_node_prefix(prefix); - int ipb, jpb; - int mode_index; - char* rec_prefix = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - /* Check */ - assert(NULL != cur_pb); - - /* If we touch the leaf, there is no need print interc*/ - if (NULL != cur_pb->pb_graph_node->pb_type->spice_model) { - if (SPICE_MODEL_LUT != cur_pb->pb_graph_node->pb_type->spice_model->type) { - return; - } - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 - + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) - + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]", - formatted_prefix, cur_pb->pb_graph_node->pb_type->name, cur_pb->pb_graph_node->placement_index); - /* Print a lut tb: call spice_model, stimulates */ - fprint_spice_lut_testbench_one_pb_graph_node_lut(fp, cur_pb->pb_graph_node, rec_prefix, x, y, LL_rr_node_indices); - my_free(rec_prefix); - return; - } - - /* Go recursively ... */ - mode_index = cur_pb->mode; - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Generate rec_prefix */ - rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) - + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 - + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) + 7 - + strlen(cur_pb->pb_graph_node->pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(rec_prefix, "%s%s[%d]_mode[%s]", - formatted_prefix, cur_pb->pb_graph_node->pb_type->name, - cur_pb->pb_graph_node->placement_index, - cur_pb->pb_graph_node->pb_type->modes[mode_index].name); - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - fprint_spice_lut_testbench_rec_pb_luts(fp, &(cur_pb->child_pbs[ipb][jpb]), rec_prefix, x, y, LL_rr_node_indices); - } else { - /* Print idle graph_node muxes */ - /* Then we go on */ - fprint_spice_lut_testbench_rec_pb_graph_node_luts(fp, cur_pb->child_pbs[ipb][jpb].pb_graph_node, - rec_prefix, x, y, LL_rr_node_indices); - } - my_free(rec_prefix); - } - } - - return; -} - -void fprint_spice_lut_testbench_call_one_grid_defined_luts(FILE* fp, int ix, int iy, - t_ivec*** LL_rr_node_indices) { - int iblk; - char* prefix = NULL; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - if ((NULL == grid[ix][iy].type) - ||(EMPTY_TYPE == grid[ix][iy].type) - ||(0 != grid[ix][iy].offset)) { - return; - } - - for (iblk = 0; iblk < grid[ix][iy].usage; iblk++) { - prefix = (char*)my_malloc(sizeof(char)* (5 - + strlen(my_itoa(block[grid[ix][iy].blocks[iblk]].x)) - + 2 + strlen(my_itoa(block[grid[ix][iy].blocks[iblk]].y)) - + 3 )); - sprintf(prefix, "grid[%d][%d]_", - block[grid[ix][iy].blocks[iblk]].x, - block[grid[ix][iy].blocks[iblk]].y); - /* Only for mapped block */ - assert(NULL != block[grid[ix][iy].blocks[iblk]].pb); - /* Mark the temporary net_num for the type pins*/ - mark_one_pb_parasitic_nets(block[grid[ix][iy].blocks[iblk]].pb); - fprint_spice_lut_testbench_rec_pb_luts(fp, block[grid[ix][iy].blocks[iblk]].pb, prefix, ix, iy, LL_rr_node_indices); - my_free(prefix); - } - /* By pass unused blocks */ - for (iblk = grid[ix][iy].usage; iblk < grid[ix][iy].type->capacity; iblk++) { - prefix = (char*)my_malloc(sizeof(char)* (5 + strlen(my_itoa(ix)) - + 2 + strlen(my_itoa(iy)) + 3 )); - sprintf(prefix, "grid[%d][%d]_", ix, iy); - assert(NULL != grid[ix][iy].type->pb_graph_head); - /* Mark the temporary net_num for the type pins*/ - mark_grid_type_pb_graph_node_pins_temp_net_num(ix, iy); - fprint_spice_lut_testbench_rec_pb_graph_node_luts(fp, grid[ix][iy].type->pb_graph_head, prefix, ix, iy, LL_rr_node_indices); - my_free(prefix); - } - - return; -} - -void fprint_spice_lut_testbench_call_defined_luts(FILE* fp, t_ivec*** LL_rr_node_indices) { - int ix, iy; - - for (ix = 1; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - fprint_spice_lut_testbench_call_one_grid_defined_luts(fp, ix, iy, LL_rr_node_indices); - } - } - - return; -} - -void fprint_spice_lut_testbench_conkt_lut_scan_chains(FILE* fp, int grid_x, int grid_y, - t_spice spice) { - int imodel, isc; - t_spice_model* lut_spice_model = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - for (imodel = 0; imodel < spice.num_spice_model; imodel++) { - if (SPICE_MODEL_LUT == spice.spice_models[imodel].type) { - lut_spice_model = &(spice.spice_models[imodel]); - /* Bypass LUT SPICE models that are contained by this grid */ - assert(-1 < (lut_spice_model->grid_index_high[grid_x][grid_y] - lut_spice_model->grid_index_low[grid_x][grid_y])); - if (0 == (lut_spice_model->grid_index_high[grid_x][grid_y] - lut_spice_model->grid_index_low[grid_x][grid_y])) { - continue; - } - fprintf(fp, "***** Connecting Scan-chains of %s in this grid[%d][%d] *****\n", - lut_spice_model->name, grid_x, grid_y); - for (isc = lut_spice_model->grid_index_low[grid_x][grid_y]; - isc < lut_spice_model->grid_index_high[grid_x][grid_y]; - isc++) { - fprintf(fp, "R%s[%d]_sc_short %s[%d]_sc_tail %s[%d]_sc_head\n", - lut_spice_model->prefix, isc, - lut_spice_model->prefix, isc, - lut_spice_model->prefix, isc + 1); - } - fprintf(fp, "***** END *****\n"); - fprintf(fp, "***** Scan-Chain Head of %s in grid[%d][%d]\n", - lut_spice_model->name, grid_x, grid_y); - fprintf(fp, "V%s[%d]_sc_head %s[%d]_sc_head 0 0\n", - lut_spice_model->prefix, lut_spice_model->grid_index_low[grid_x][grid_y], - lut_spice_model->prefix, lut_spice_model->grid_index_low[grid_x][grid_y]); - fprintf(fp, ".nodeset V(%s[%d]_sc_head) 0\n", - lut_spice_model->prefix, lut_spice_model->grid_index_low[grid_x][grid_y]); - } - } - - return; -} - -void fprint_spice_lut_testbench_stimulations(FILE* fp, int grid_x, int grid_y, - int num_clock, - t_spice spice, - t_ivec*** LL_rr_node_indices) { - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Print generic stimuli */ - fprint_spice_testbench_generic_global_ports_stimuli(fp, num_clock); - - /* Generate global ports stimuli */ - fprint_spice_testbench_global_ports_stimuli(fp, global_ports_head); - - /* SRAM ports */ - /* Every SRAM inputs should have a voltage source */ - fprintf(fp, "***** Global Inputs for SRAMs *****\n"); - fprint_spice_testbench_global_sram_inport_stimuli(fp, sram_spice_orgz_info); - - fprintf(fp, "***** Global VDD for LUTs SRAMs *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_lut_sram_port_name, - "vsp"); - - fprintf(fp, "***** Global VDD for SRAMs *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_sram_port_name, - "vsp"); - - fprintf(fp, "***** Global VDD for load inverters *****\n"); - fprint_spice_testbench_global_vdd_port_stimuli(fp, - spice_tb_global_vdd_load_port_name, - "vsp"); - - /* Global Vdd ports */ - /* Every LUT use an independent Voltage source */ - fprintf(fp, "***** Global VDD for Look-Up Tables (LUTs) *****\n"); - fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, spice); - - return; -} - -void fprint_spice_lut_testbench_measurements(FILE* fp, int grid_x, int grid_y, - t_spice spice, - boolean leakage_only) { - /* int i; */ - /* First cycle reserved for measuring leakage */ - int num_clock_cycle = max_sim_num_clock_cycles; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - fprint_spice_netlist_transient_setting(fp, spice, num_clock_cycle, leakage_only); - fprint_spice_netlist_generic_measurements(fp, spice.spice_params.mc_params, spice.num_spice_model, spice.spice_models); - - /* TODO: Measure the delay of each mapped net and logical block */ - - /* Measure the power */ - /* Leakage ( the first cycle is reserved for leakage measurement) */ - if (TRUE == leakage_only) { - /* Leakage power of SRAMs */ - fprintf(fp, ".measure tran leakage_power_sram_luts find p(Vgvdd_sram_luts) at=0\n"); - } else { - /* Leakage power of SRAMs */ - fprintf(fp, ".measure tran leakage_power_sram_luts avg p(Vgvdd_sram_luts) from=0 to='clock_period'\n"); - } - /* Leakage power of LUTs*/ - fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); - /* - for (i = 0; i < spice.num_spice_model; i++) { - if (SPICE_MODEL_LUT == spice.spice_models[i].type) { - fprint_measure_vdds_logical_block_spice_model(fp, &(spice.spice_models[i]), SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, leakage_only); - } - } - */ - - if (TRUE == leakage_only) { - return; - } - - /* Dynamic power */ - /* Dynamic power of SRAMs */ - fprintf(fp, ".measure tran dynamic_power_sram_luts avg p(Vgvdd_sram_luts) from='clock_period' to='%d*clock_period'\n", num_clock_cycle); - fprintf(fp, ".measure tran energy_per_cycle_sram_luts param='dynamic_power_sram_luts*clock_period'\n"); - /* Dynamic power of LUTs */ - fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); - /* - for (i = 0; i < spice.num_spice_model; i++) { - if (SPICE_MODEL_LUT == spice.spice_models[i].type) { - fprint_measure_vdds_logical_block_spice_model(fp, &(spice.spice_models[i]), SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, leakage_only); - } - } - */ - - return; -} - -/* Top-level function in this source file */ -int fprint_spice_one_lut_testbench(char* formatted_spice_dir, - char* circuit_name, - char* lut_testbench_name, - char* include_dir_path, - char* subckt_dir_path, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_arch arch, - int grid_x, int grid_y, - boolean leakage_only) { - FILE* fp = NULL; - char* formatted_subckt_dir_path = format_dir_path(subckt_dir_path); - char* temp_include_file_path = NULL; - char* title = my_strcat("FPGA LUT Testbench for Design: ", circuit_name); - char* lut_testbench_file_path = my_strcat(formatted_spice_dir, lut_testbench_name); - int used; - - /* Check if the path exists*/ - fp = fopen(lut_testbench_file_path,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create LUT Testbench SPICE netlist %s!",__FILE__, __LINE__, lut_testbench_file_path); - exit(1); - } - - /* Reset tb_cnt for all the spice models */ - init_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y); - - /*vpr_printf(TIO_MESSAGE_INFO, "Writing LUT Testbench for %s...\n", circuit_name);*/ - testbench_load_cnt = 0; - - /* Print the title */ - fprint_spice_head(fp, title); - my_free(title); - - /* print technology library and design parameters*/ - - /* Include parameter header files */ - fprint_spice_include_param_headers(fp, include_dir_path); - - /* Include Key subckts */ - fprint_spice_include_key_subckts(fp, subckt_dir_path); - - /* Include user-defined sub-circuit netlist */ - init_include_user_defined_netlists(*(arch.spice)); - fprint_include_user_defined_netlists(fp, *(arch.spice)); - - /* Special subckts for Top-level SPICE netlist */ - fprintf(fp, "****** Include subckt netlists: Look-Up Tables (LUTs) *****\n"); - spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, luts_spice_file_name); - - /* Generate filename */ - fprintf(fp, "****** Include subckt netlists: Grid[%d][%d] *****\n", - grid_x, grid_y); - temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix); - /* Check if we include an existing file! */ - if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head, - my_strcat(formatted_subckt_dir_path, temp_include_file_path))) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Intend to include a non-existed SPICE netlist %s!\n", - __FILE__, __LINE__, temp_include_file_path); - exit(1); - } - spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, temp_include_file_path); - - /* Print simulation temperature and other options for SPICE */ - fprint_spice_options(fp, arch.spice->spice_params); - - /* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */ - fprint_spice_lut_testbench_global_ports(fp, grid_x, grid_y, num_clock, (*arch.spice)); - - /* Quote defined Logic blocks subckts (Grids) */ - init_spice_lut_testbench_globals(*(arch.spice)); - init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, arch.spice->spice_models, SPICE_MODEL_LUT); - fprint_spice_lut_testbench_call_one_grid_defined_luts(fp, grid_x, grid_y, LL_rr_node_indices); - - /* Back-anotate activity information to each routing resource node - * (We should have activity of each Grid port) - */ - - /* Check if the all hardlogic located in this grid have been printed */ - check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_LUT); - - /* Add stimulations */ - fprint_spice_lut_testbench_stimulations(fp, grid_x, grid_y, num_clock, (*arch.spice), LL_rr_node_indices); - - /* Add measurements */ - fprint_spice_lut_testbench_measurements(fp, grid_x, grid_y, (*arch.spice), leakage_only); - - /* SPICE ends*/ - fprintf(fp, ".end\n"); - - /* Close the file*/ - fclose(fp); - - if (0 < tb_num_luts) { - /* - vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE LUT Testbench for %s...\n", - grid_x, grid_y, circuit_name); - */ - /* Push the testbench to the linked list */ - tb_head = add_one_spice_tb_info_to_llist(tb_head, lut_testbench_file_path, - max_sim_num_clock_cycles); - used = 1; - } else { - /* Remove the file generated */ - my_remove_file(lut_testbench_file_path); - used = 0; - } - - /* Free */ - my_free(temp_include_file_path); - - return used; -} - - -/* Top-level function in this source file */ -void spice_print_lut_testbench(char* formatted_spice_dir, - char* circuit_name, - char* include_dir_path, - char* subckt_dir_path, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_arch arch, - boolean leakage_only) { - char* lut_testbench_name = NULL; - char* temp_include_file_path = NULL; - int ix, iy; - int cnt = 0; - int used; - - vpr_printf(TIO_MESSAGE_INFO,"Generating LUT testbench...\n"); - - for (ix = 1; ix < (nx+1); ix++) { - for (iy = 1; iy < (ny+1); iy++) { - /* Check if we include an existing subckt file! */ - temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, ix, iy, spice_netlist_file_postfix); - if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head, - my_strcat(subckt_dir_path, temp_include_file_path))) { - /* free */ - my_free(temp_include_file_path); - continue; - } - - /* Create a testbench for the existing subckt */ - lut_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name) - + 6 + strlen(my_itoa(ix)) + 1 - + strlen(my_itoa(iy)) + 1 - + strlen(spice_lut_testbench_postfix) + 1 )); - sprintf(lut_testbench_name, "%s_grid%d_%d%s", - circuit_name, ix, iy, spice_lut_testbench_postfix); - used = fprint_spice_one_lut_testbench(formatted_spice_dir, circuit_name, lut_testbench_name, - include_dir_path, subckt_dir_path, LL_rr_node_indices, - num_clock, arch, ix, iy, - leakage_only); - if (1 == used) { - cnt += used; - } - /* free */ - my_free(lut_testbench_name); - my_free(temp_include_file_path); - } - } - /* Update the global counter */ - num_used_lut_tb = cnt; - vpr_printf(TIO_MESSAGE_INFO,"No. of generated LUT testbench = %d\n", num_used_lut_tb); - - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.h b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.h deleted file mode 100644 index 8ec0fef2a..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_lut_testbench.h +++ /dev/null @@ -1,10 +0,0 @@ - - -void spice_print_lut_testbench(char* formatted_spice_dir, - char* circuit_name, - char* include_dir_path, - char* subckt_dir_path, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_arch arch, - boolean leakage_only); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.h b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.h deleted file mode 100644 index 8e104ae1f..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.h +++ /dev/null @@ -1,19 +0,0 @@ - - - -void generate_spice_muxes(char* subckt_dir, - int num_switch, - t_switch_inf* switches, - t_spice* spice, - t_det_routing_arch* routing_arch); - -t_llist* search_mux_linked_list(t_llist* mux_head, - int mux_size, - t_spice_model* spice_model); - -void check_and_add_mux_to_linked_list(t_llist** muxes_head, - int mux_size, - t_spice_model* spice_model); - -void free_muxes_llist(t_llist* muxes_head); - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.c b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.c deleted file mode 100644 index 90338ac6c..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.c +++ /dev/null @@ -1,468 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "rr_graph_swseg.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "spice_utils.h" -#include "spice_pbtypes.h" -#include "spice_primitives.h" - -enum e_ff_trigger_type { - FF_RE, FF_FE -}; - -/* Subroutines */ -void fprint_pb_primitive_ff(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model) { - int i; - /* Default FF settings, applied when this FF is idle*/ - enum e_ff_trigger_type trigger_type = FF_RE; - int init_val = 0; - - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_clock_port = 0; - t_spice_model_port** clock_ports = NULL; - - int iport, ipin; - int num_pb_type_output_port = 0; - t_port** pb_type_output_ports = NULL; - - char* formatted_subckt_prefix = format_spice_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* prim_pb_type = NULL; - char* port_prefix = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find ports*/ - input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, FALSE); - output_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - clock_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, FALSE); - - /* Asserts */ - assert(3 == num_input_port); /* D, Set and Reset*/ - for (i = 0; i < num_input_port; i++) { - assert(1 == input_ports[i]->size); - } - assert(1 == num_output_port); - assert(1 == output_ports[0]->size); - assert(1 == num_clock_port); - assert(1 == clock_ports[0]->size); - - assert(SPICE_MODEL_FF == spice_model->type); - - /* Initialize */ - prim_pb_type = prim_pb_graph_node->pb_type; - - if (NULL != mapped_logical_block) { - fprintf(fp, "***** Logical block mapped to this FF: %s *****\n", - mapped_logical_block->name); - } - - /* Generate Subckt for pb_type*/ - /* - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, prim_pb_type->name, index); - */ - /* Simplify the port prefix, make SPICE netlist readable */ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s[%d]", prim_pb_type->name, index); - /* Definition line */ - fprintf(fp, ".subckt %s%s ", formatted_subckt_prefix, port_prefix); - /* print ports*/ - fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); - /* Local vdd and gnd*/ - fprintf(fp, "svdd sgnd\n"); - /* Definition ends*/ - - /* Call the dff subckt*/ - fprintf(fp, "X%s[%d] ", spice_model->prefix, spice_model->cnt); - /* Global ports */ - if (0 < rec_fprint_spice_model_global_ports(fp, spice_model, FALSE)) { - fprintf(fp, "+ "); - } - /* print ports*/ - fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); /* Use global clock for each DFF...*/ - /* Local vdd and gnd, spice_model name - * global vdd for ff - */ - fprintf(fp, "%s_%s[%d] sgnd %s\n", - spice_tb_global_vdd_port_name, - spice_model->prefix, - spice_model->cnt, - spice_model->name); - - /* Apply rising edge, and init value to the ff*/ - if (NULL != mapped_logical_block) { - /* Consider the rising edge|falling edge */ - if (0 == strcmp("re", mapped_logical_block->trigger_type)) { - trigger_type = FF_RE; - } else if (0 == strcmp("fe", mapped_logical_block->trigger_type)) { - trigger_type = FF_FE; - } else { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid ff trigger type! Should be [re|fe].\n", - __FILE__, __LINE__); - exit(1); - } - /* Assign initial value */ - if (1 == mapped_logical_block->init_val) { - init_val = 1; - } else { - init_val = 0; - } - - /* Back-annotate to logical block */ - mapped_logical_block->mapped_spice_model = spice_model; - mapped_logical_block->mapped_spice_model_index = spice_model->cnt; - } else { - trigger_type = FF_RE; - init_val = 0; - } - /* TODO: apply falling edge, initial value to FF!!!*/ - /*fprintf(fp, "\n");*/ - - /* Add nodeset */ - pb_type_output_ports = find_pb_type_ports_match_spice_model_port_type(prim_pb_type, SPICE_MODEL_PORT_OUTPUT, &num_pb_type_output_port); - for (iport = 0; iport < num_pb_type_output_port; iport++) { - for (ipin = 0; ipin < pb_type_output_ports[iport]->num_pins; ipin++) { - fprintf(fp, ".nodeset V(%s->%s[%d]) ", port_prefix, pb_type_output_ports[iport]->name, ipin); - if (0 == init_val) { - fprintf(fp, "0\n"); - } else { - assert(1 == init_val); - fprintf(fp, "vsp\n"); - } - } - } - - /* End */ - fprintf(fp, ".eom\n"); - - spice_model->cnt++; - - /*Free*/ - my_free(formatted_subckt_prefix); - my_free(port_prefix); - - return; -} - -/* Print hardlogic SPICE subckt*/ -void fprint_pb_primitive_hardlogic(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model) { - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_clock_port = 0; - t_spice_model_port** clock_ports = NULL; - - char* formatted_subckt_prefix = format_spice_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* prim_pb_type = NULL; - char* port_prefix = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find ports*/ - input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - clock_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, TRUE); - - /* Asserts */ - assert(SPICE_MODEL_HARDLOGIC == spice_model->type); - - /* Initialize */ - prim_pb_type = prim_pb_graph_node->pb_type; - - if (NULL != mapped_logical_block) { - fprintf(fp, "***** Logical block mapped to this hardlogic: %s *****\n", - mapped_logical_block->name); - } - - - /* Generate Subckt for pb_type*/ - /* - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, prim_pb_type->name, index); - */ - /* Simplify the port prefix, make SPICE netlist readable */ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s[%d]", prim_pb_type->name, index); - /* Definition line */ - fprintf(fp, ".subckt %s%s ", formatted_subckt_prefix, port_prefix); - /* print ports*/ - fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); - /* Local vdd and gnd*/ - fprintf(fp, "svdd sgnd\n"); - /* Definition ends*/ - - /* Back-annotate to logical block */ - if (NULL != mapped_logical_block) { - mapped_logical_block->mapped_spice_model = spice_model; - mapped_logical_block->mapped_spice_model_index = spice_model->cnt; - } - - /* Call the dff subckt*/ - fprintf(fp, "X%s[%d] ", spice_model->prefix, spice_model->cnt); - /* print ports*/ - fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); - /* Local vdd and gnd, spice_model name, - * Global vdd for hardlogic to split - */ - fprintf(fp, "gvdd_%s[%d] sgnd %s\n", spice_model->prefix, spice_model->cnt, spice_model->name); - - /* End */ - fprintf(fp, ".eom\n"); - - spice_model->cnt++; - - /*Free*/ - free(formatted_subckt_prefix); - free(port_prefix); - - return; -} - -void fprint_pb_primitive_io(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model) { - int num_pad_port = 0; /* INOUT port */ - t_spice_model_port** pad_ports = NULL; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_clock_port = 0; - t_spice_model_port** clock_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - int i; - int num_sram = 0; - int expected_num_sram = 0; - int* sram_bits = NULL; - int cur_num_sram = 0; - - char* formatted_subckt_prefix = format_spice_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* prim_pb_type = NULL; - char* port_prefix = NULL; - char* sram_vdd_port_name = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find ports*/ - pad_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INOUT, &num_pad_port, TRUE); - input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - clock_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, TRUE); - sram_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - - /* Asserts */ - assert(SPICE_MODEL_IOPAD == spice_model->type); - - /* Initialize */ - - prim_pb_type = prim_pb_graph_node->pb_type; - - if (NULL != mapped_logical_block) { - fprintf(fp, "***** Logical block mapped to this IO: %s *****\n", - mapped_logical_block->name); - } - - /* Generate Subckt for pb_type*/ - /* - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, prim_pb_type->name, index); - */ - /* Simplify the port prefix, make SPICE netlist readable */ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s[%d]", prim_pb_type->name, index); - - /* Decode SRAM bits */ - assert((1 == num_sram_port)&&(NULL != sram_ports)&&(1 == sram_ports[0]->size)); - num_sram = count_num_sram_bits_one_spice_model(spice_model, -1); - /* what is the SRAM bit of a mode? */ - /* If logical block is not NULL, we need to decode the sram bit */ - if (NULL != mapped_logical_block) { - assert(NULL != mapped_logical_block->pb->pb_graph_node->pb_type->mode_bits); - sram_bits = decode_mode_bits(mapped_logical_block->pb->pb_graph_node->pb_type->mode_bits, &expected_num_sram); - assert(expected_num_sram == num_sram); - } else { - /* Initialize */ - sram_bits = (int*)my_calloc(num_sram, sizeof(int)); - for (i = 0; i < num_sram; i++) { - sram_bits[i] = sram_ports[0]->default_val; - } - } - - /* Get current counter of mem_bits, bl and wl */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); - - /* Definition line */ - fprintf(fp, ".subckt %s%s ", formatted_subckt_prefix, port_prefix); - /* print ports*/ - fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); - /* Local vdd and gnd*/ - fprintf(fp, "svdd sgnd\n"); - /* Definition ends*/ - - /* Call the iopad subckt*/ - fprintf(fp, "X%s[%d] ", spice_model->prefix, spice_model->cnt); - /* Only dump the global ports belonging to a spice_model - * Do not go recursive, we can freely define global ports anywhere in SPICE netlist - */ - if (0 < rec_fprint_spice_model_global_ports(fp, spice_model, FALSE)) { - fprintf(fp, "+ "); - } - /* print regular ports*/ - fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); - /* Print inout port */ - fprintf(fp, " %s%s[%d] ", - gio_inout_prefix, - spice_model->prefix, - spice_model->cnt); - /* Print SRAM ports */ - for (i = 0; i < num_sram; i++) { - fprint_spice_sram_one_outport(fp, sram_spice_orgz_info, cur_num_sram + i, sram_bits[i]); - /* We need the invertered signal for better convergency */ - fprint_spice_sram_one_outport(fp, sram_spice_orgz_info, cur_num_sram + i, 1 - sram_bits[i]); - } - - /* Local vdd and gnd, spice_model name, - * TODO: Global vdd for i/o pad to split? - */ - fprintf(fp, "%s_%s[%d] sgnd %s\n", - spice_tb_global_vdd_port_name, - spice_model->prefix, - spice_model->cnt, - spice_model->name); - - /* Print the encoding in SPICE netlist for debugging */ - fprintf(fp, "***** SRAM bits for IOPAD[%d] *****\n", - spice_model->cnt); - fprintf(fp, "*****"); - for (i = 0; i < num_sram; i++) { - fprintf(fp, "%d", sram_bits[i]); - } - fprintf(fp, "*****\n"); - - /* Call SRAM subckts*/ - /* Give the VDD port name for SRAMs */ - sram_vdd_port_name = (char*)my_malloc(sizeof(char)* - (strlen(spice_tb_global_vdd_io_sram_port_name) - + 1 )); - sprintf(sram_vdd_port_name, "%s", - spice_tb_global_vdd_io_sram_port_name); - /* Now Print SRAMs one by one */ - for (i = 0; i < num_sram; i++) { - fprint_spice_one_sram_subckt(fp, sram_spice_orgz_info, spice_model, sram_vdd_port_name); - } - - /* Store the configuraion bit to linked-list */ - add_sram_conf_bits_to_llist(sram_spice_orgz_info, cur_num_sram, - num_sram, sram_bits); - - /* End */ - fprintf(fp, ".eom\n"); - - /* Back-annotate to logical block */ - if (NULL != mapped_logical_block) { - mapped_logical_block->mapped_spice_model = spice_model; - mapped_logical_block->mapped_spice_model_index = spice_model->cnt; - } - - /* Update the spice_model counter */ - spice_model->cnt++; - - /*Free*/ - my_free(formatted_subckt_prefix); - my_free(port_prefix); - my_free(sram_vdd_port_name); - - return; -} - - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.h b/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.h deleted file mode 100644 index e923fe18b..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_primitives.h +++ /dev/null @@ -1,22 +0,0 @@ - -void fprint_pb_primitive_ff(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model); - - -void fprint_pb_primitive_hardlogic(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model); - -void fprint_pb_primitive_io(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.c deleted file mode 100644 index 951736b66..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.c +++ /dev/null @@ -1,326 +0,0 @@ -/***********************************/ -/* Synthesizable Verilog Dumping */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "vpr_utils.h" -#include "path_delay.h" -#include "stats.h" - -/* Include FPGA-SPICE utils */ -#include "read_xml_spice_util.h" -#include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "fpga_spice_globals.h" -#include "fpga_spice_bitstream.h" -#include "verilog_modelsim_autodeck.h" - -/* Include SynVerilog headers */ -#include "verilog_global.h" -#include "verilog_utils.h" -#include "verilog_submodules.h" -#include "verilog_decoder.h" -#include "verilog_pbtypes.h" -#include "verilog_routing.h" -#include "verilog_top_netlist.h" -#include "verilog_autocheck_tb.h" - - -/***** Subroutines *****/ -/* Alloc array that records Configuration bits for : - * (1) Switch blocks - * (2) Connection boxes - * TODO: Can be improved in alloc strategy to be more memory efficient! - */ -static -void alloc_global_routing_conf_bits() { - int i; - - /* Alloc array for Switch blocks */ - num_conf_bits_sb = (int**)my_malloc((nx+1)*sizeof(int*)); - for (i = 0; i < (nx + 1); i++) { - num_conf_bits_sb[i] = (int*)my_calloc((ny+1), sizeof(int)); - } - - /* Alloc array for Connection blocks */ - num_conf_bits_cbx = (int**)my_malloc((nx+1)*sizeof(int*)); - for (i = 0; i < (nx + 1); i++) { - num_conf_bits_cbx[i] = (int*)my_calloc((ny+1), sizeof(int)); - } - - num_conf_bits_cby = (int**)my_malloc((nx+1)*sizeof(int*)); - for (i = 0; i < (nx + 1); i++) { - num_conf_bits_cby[i] = (int*)my_calloc((ny+1), sizeof(int)); - } - - return; -} - -static -void free_global_routing_conf_bits() { - int i; - - /* Free array for Switch blocks */ - for (i = 0; i < (nx + 1); i++) { - my_free(num_conf_bits_sb[i]); - } - my_free(num_conf_bits_sb); - - /* Free array for Connection box */ - for (i = 0; i < (nx + 1); i++) { - my_free(num_conf_bits_cbx[i]); - } - my_free(num_conf_bits_cbx); - - for (i = 0; i < (nx + 1); i++) { - my_free(num_conf_bits_cby[i]); - } - my_free(num_conf_bits_cby); - - return; -} - -/* Top-level function*/ -void vpr_dump_syn_verilog(t_vpr_setup vpr_setup, - t_arch Arch, - char* circuit_name) { - /* Timer */ - clock_t t_start; - clock_t t_end; - float run_time_sec; - - int num_clocks = Arch.spice->spice_params.stimulate_params.num_clocks; - /* int vpr_crit_path_delay = Arch.spice->spice_params.stimulate_params.vpr_crit_path_delay; */ - - /* Directory paths */ - char* verilog_dir_formatted = NULL; - char* submodule_dir_path= NULL; - char* lb_dir_path = NULL; - char* rr_dir_path = NULL; - char* top_netlist_file = NULL; - char* top_netlist_path = NULL; - char* bitstream_file_name = NULL; - char* bitstream_file_path = NULL; - char* hex_file_name = NULL; - char* hex_file_path = NULL; - char* top_testbench_file_name = NULL; - char* top_auto_testbench_file_name = NULL; - char* top_auto_preconf_testbench_file_name = NULL; - char* top_testbench_file_path = NULL; - char* top_auto_testbench_file_path = NULL; - char* top_auto_preconf_testbench_file_path = NULL; - char* blif_testbench_file_name = NULL; - char* blif_testbench_file_path = NULL; - - char* chomped_parent_dir = NULL; - char* chomped_circuit_name = NULL; - - boolean tb_preconf = TRUE; - - /* Check if the routing architecture we support*/ - if (UNI_DIRECTIONAL != vpr_setup.RoutingArch.directionality) { - vpr_printf(TIO_MESSAGE_ERROR, "FPGA synthesizable Verilog dumping only support uni-directional routing architecture!\n"); - exit(1); - } - - /* We don't support mrFPGA */ -#ifdef MRFPGA_H - if (is_mrFPGA) { - vpr_printf(TIO_MESSAGE_ERROR, "FPGA synthesizable verilog dumping do not support mrFPGA!\n"); - exit(1); - } -#endif - - assert ( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog); - - /* VerilogGenerator formally starts*/ - vpr_printf(TIO_MESSAGE_INFO, "\nFPGA synthesizable verilog generator starts...\n"); - - /* Start time count */ - t_start = clock(); - - /* Format the directory paths */ - split_path_prog_name(circuit_name, '/', &chomped_parent_dir, &chomped_circuit_name); - - if (NULL != vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.syn_verilog_dump_dir) { - verilog_dir_formatted = format_dir_path(vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.syn_verilog_dump_dir); - } else { - verilog_dir_formatted = format_dir_path(my_strcat(format_dir_path(chomped_parent_dir),default_verilog_dir_name)); - } - /* lb directory */ - (lb_dir_path) = my_strcat(verilog_dir_formatted, default_lb_dir_name); - /* routing resources directory */ - (rr_dir_path) = my_strcat(verilog_dir_formatted, default_rr_dir_name); - /* submodule_dir_path */ - (submodule_dir_path) = my_strcat(verilog_dir_formatted, default_submodule_dir_name); - /* Top netlists dir_path */ - top_netlist_file = my_strcat(chomped_circuit_name, verilog_top_postfix); - top_netlist_path = my_strcat(verilog_dir_formatted, top_netlist_file); - bitstream_file_name = my_strcat(chomped_circuit_name, bitstream_verilog_file_postfix); - bitstream_file_path = my_strcat(verilog_dir_formatted, bitstream_file_name); - hex_file_name = my_strcat(chomped_circuit_name, hex_verilog_file_postfix); - hex_file_path = my_strcat(verilog_dir_formatted, hex_file_name); - top_testbench_file_name = my_strcat(chomped_circuit_name, top_testbench_verilog_file_postfix); - top_testbench_file_path = my_strcat(verilog_dir_formatted, top_testbench_file_name); - top_auto_testbench_file_name = my_strcat(chomped_circuit_name, top_auto_testbench_verilog_file_postfix); - top_auto_testbench_file_path = my_strcat(verilog_dir_formatted, top_auto_testbench_file_name); - top_auto_preconf_testbench_file_name = my_strcat(chomped_circuit_name, top_auto_preconf_testbench_verilog_file_postfix); - top_auto_preconf_testbench_file_path = my_strcat(verilog_dir_formatted, top_auto_preconf_testbench_file_name); - blif_testbench_file_name = my_strcat(chomped_circuit_name, blif_testbench_verilog_file_postfix); - blif_testbench_file_path = my_strcat(verilog_dir_formatted, blif_testbench_file_name); - - /* Create directories */ - create_dir_path(verilog_dir_formatted); - create_dir_path(lb_dir_path); - create_dir_path(rr_dir_path); - create_dir_path(submodule_dir_path); - - /* assign the global variable of SRAM model */ - assert(NULL != Arch.sram_inf.verilog_sram_inf_orgz); /* Check !*/ - sram_verilog_model = Arch.sram_inf.verilog_sram_inf_orgz->spice_model; - sram_verilog_orgz_type = Arch.sram_inf.verilog_sram_inf_orgz->type; - /* initialize the SRAM organization information struct */ - sram_verilog_orgz_info = alloc_one_sram_orgz_info(); - init_sram_orgz_info(sram_verilog_orgz_info, sram_verilog_orgz_type, sram_verilog_model, nx + 2, ny + 2); - /* Check all the SRAM port is using the correct SRAM SPICE MODEL */ - config_spice_models_sram_port_spice_model(Arch.spice->num_spice_model, - Arch.spice->spice_models, - Arch.sram_inf.verilog_sram_inf_orgz->spice_model); - - /* Assign global variables of input and output pads */ - iopad_verilog_model = find_iopad_spice_model(Arch.spice->num_spice_model, Arch.spice->spice_models); - assert(NULL != iopad_verilog_model); - - /* zero the counter of each spice_model */ - zero_spice_models_cnt(Arch.spice->num_spice_model, Arch.spice->spice_models); - - /* Initialize the user-defined verilog netlists to be included */ - init_list_include_verilog_netlists(Arch.spice); - - /* Initial global variables about configuration bits */ - alloc_global_routing_conf_bits(); - - /* Initialize the number of configuration bits of all the grids */ - vpr_printf(TIO_MESSAGE_INFO, "Count the number of configuration bits, IO pads in each logic block...\n"); - /* init_grids_num_conf_bits(sram_verilog_orgz_type); */ - init_grids_num_conf_bits(sram_verilog_orgz_info); - init_grids_num_iopads(); - /* init_grids_num_mode_bits(); */ - - /* Dump routing resources: switch blocks, connection blocks and channel tracks */ - dump_verilog_routing_resources(rr_dir_path, Arch, &vpr_setup.RoutingArch, - num_rr_nodes, rr_node, rr_node_indices); - - /* Dump logic blocks */ - dump_verilog_logic_blocks(lb_dir_path, &Arch); - - /* Dump decoder modules only when memory bank is required */ - switch(sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - /* Dump verilog decoder */ - dump_verilog_decoder(submodule_dir_path); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Dump internal structures of submodules */ - dump_verilog_submodules(submodule_dir_path, Arch, &vpr_setup.RoutingArch, vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.include_timing, vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.init_sim); - - /* Dump top-level verilog */ - dump_verilog_top_netlist(chomped_circuit_name, top_netlist_path, lb_dir_path, rr_dir_path, - num_rr_nodes, rr_node, rr_node_indices, num_clocks, *(Arch.spice)); - - /* Dump SDC constraints */ - // dump_verilog_sdc_file(); - - /* dump verilog testbench only for top-level */ - if (( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_tb) || ( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_auto_tb)){ - if ( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_tb){ - dump_verilog_top_testbench(chomped_circuit_name, top_testbench_file_path, num_clocks, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); - } - // AA: to generate autocheck testbench but only one bitstream - if ( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_auto_tb) { - dump_verilog_top_auto_testbench(chomped_circuit_name, top_auto_testbench_file_path, num_clocks, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice), - modelsim_auto_testbench_module_postfix); - } - // AA: to generate autocheck preconfigured testbench - if (( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_auto_tb) && (tb_preconf)) { - dump_verilog_top_auto_preconf_testbench(chomped_circuit_name, - top_auto_preconf_testbench_file_path, - num_clocks, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, - *(Arch.spice), - modelsim_auto_preconf_testbench_module_postfix, - hex_file_path); - dump_fpga_spice_hex(hex_file_path, chomped_circuit_name, sram_verilog_orgz_info); - } - /* Dump bitstream file */ - dump_fpga_spice_bitstream(bitstream_file_path, chomped_circuit_name, sram_verilog_orgz_info); - } - - - /* Output Modelsim Autodeck scripts */ - if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_modelsim_autodeck) { - dump_verilog_modelsim_autodeck(sram_verilog_orgz_info, *(Arch.spice), - Arch.spice->spice_params.meas_params.sim_num_clock_cycle, - verilog_dir_formatted, chomped_circuit_name, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.modelsim_ini_path, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.include_timing, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.init_sim, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_tb, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_auto_tb, - tb_preconf); - } - - /* dump verilog testbench only for input blif */ - if ( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_input_blif_tb) { - dump_verilog_input_blif_testbench(chomped_circuit_name, blif_testbench_file_path, num_clocks, - vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); - } - - /* End time count */ - t_end = clock(); - - run_time_sec = (float)(t_end - t_start) / CLOCKS_PER_SEC; - vpr_printf(TIO_MESSAGE_INFO, "Synthesizable verilog dumping took %g seconds\n", run_time_sec); - - /* Free global array */ - free_global_routing_conf_bits(); - - /* Free sram_orgz_info */ - free_sram_orgz_info(sram_verilog_orgz_info, - sram_verilog_orgz_info->type, - nx + 2, ny + 2); - /* Free */ - my_free(verilog_dir_formatted); - my_free(lb_dir_path); - my_free(rr_dir_path); - my_free(top_netlist_file); - my_free(top_netlist_path); - my_free(submodule_dir_path); - - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.h deleted file mode 100644 index 8723d1038..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_api.h +++ /dev/null @@ -1,4 +0,0 @@ - -void vpr_dump_syn_verilog(t_vpr_setup vpr_setup, - t_arch Arch, - char* circuit_name); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.c deleted file mode 100644 index ee5c526fb..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.c +++ /dev/null @@ -1,967 +0,0 @@ -/***********************************/ -/* Dump Synthesizable Veriolog */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "read_xml_spice_util.h" -#include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "fpga_spice_globals.h" -#include "fpga_spice_bitstream.h" - -/* Include verilog support headers*/ -#include "verilog_global.h" -#include "verilog_utils.h" -#include "verilog_routing.h" -#include "verilog_pbtypes.h" -#include "verilog_decoder.h" -#include "verilog_top_netlist.h" -#include "verilog_autocheck_tb.h" - - -/* Global varaiable only accessible in this source file*/ -static char* top_netlist_bl_enable_port_name = "en_bl"; -static char* top_netlist_wl_enable_port_name = "en_wl"; -static char* top_netlist_bl_data_in_port_name = "data_in"; -static char* top_netlist_addr_bl_port_name = "addr_bl"; -static char* top_netlist_addr_wl_port_name = "addr_wl"; -static char* top_netlist_array_bl_port_name = "bl_bus"; -static char* top_netlist_array_wl_port_name = "wl_bus"; -static char* top_netlist_array_blb_port_name = "blb_bus"; -static char* top_netlist_array_wlb_port_name = "wlb_bus"; -static char* top_netlist_reserved_bl_port_postfix = "_reserved_bl"; -static char* top_netlist_reserved_wl_port_postfix = "_reserved_wl"; -static char* top_netlist_normal_bl_port_postfix = "_bl"; -static char* top_netlist_normal_wl_port_postfix = "_wl"; -static char* top_netlist_normal_blb_port_postfix = "_blb"; -static char* top_netlist_normal_wlb_port_postfix = "_wlb"; -static char* top_netlist_scan_chain_head_prefix = "sc_in"; - - -static char* top_tb_reset_port_name = "greset"; -static char* top_tb_set_port_name = "gset"; -static char* top_tb_prog_reset_port_name = "prog_reset"; -static char* top_tb_prog_set_port_name = "prog_set"; -static char* top_tb_config_done_port_name = "config_done"; -static char* top_tb_op_clock_port_name = "op_clock"; -static char* top_tb_prog_clock_port_name = "prog_clock"; -static char* top_tb_inout_reg_postfix = "_reg"; -static char* top_tb_clock_reg_postfix = "_reg"; - -/* Local Subroutines declaration */ - -/******** Subroutines ***********/ -/** Top level function 2: Testbench for the top-level netlist - * This testbench includes a top-level module of a mapped FPGA and voltage pulses - */ -static -void dump_verilog_top_netlist_memory_bank_ports(FILE* fp, - enum e_dump_verilog_port_type dump_port_type) { - t_spice_model* mem_model = NULL; - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - char split_sign; - - split_sign = determine_verilog_generic_port_split_sign(dump_port_type); - - /* Only accept two types of dump_port_type here! */ - assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); - - /* Check */ - assert (sram_verilog_orgz_info->type == SPICE_SRAM_MEMORY_BANK); - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Depending on the memory technology*/ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - assert(NULL != mem_model); - - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - /* Depend on the memory technology */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_bl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- BL enable port \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_wl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- WL enable port \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_bl_data_in_port_name, 0, 0); - fprintf(fp, "%c //--- BL data input port \n", split_sign); - break; - case SPICE_MODEL_DESIGN_RRAM: - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_bl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- BL enable port \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_wl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- WL enable port \n", split_sign); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); - fprintf(fp, "%c //--- Address of bit lines \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); - fprintf(fp, " //--- Address of word lines \n"); - - return; -} - -static -void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head, - enum e_dump_verilog_port_type dump_port_type) { - t_llist* temp = head; - t_spice_model_port* cur_global_port = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - } - - fprintf(fp, "//----- BEGIN Global ports -----\n"); - while(NULL != temp) { - cur_global_port = (t_spice_model_port*)(temp->dptr); - dump_verilog_generic_port(fp, dump_port_type, - cur_global_port->prefix, 0, cur_global_port->size - 1); - fprintf(fp, ";\n"); - /* Go to the next */ - temp = temp->next; - } - fprintf(fp, "//----- END Global ports -----\n"); - - return; -} - -/* Connect a global port to a voltage stimuli */ -static -void dump_verilog_top_testbench_wire_one_global_port_stimuli(FILE* fp, t_spice_model_port* cur_global_port, - char* voltage_stimuli_port_name) { - int ipin; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - assert(NULL != cur_global_port); - - for (ipin = 0; ipin < cur_global_port->size; ipin++) { - fprintf(fp, "assign %s[%d] = ", - cur_global_port->prefix, ipin); - assert((0 == cur_global_port->default_val)||(1 == cur_global_port->default_val)); - if (1 == cur_global_port->default_val) { - fprintf(fp, "~"); - } - fprintf(fp, "%s;\n", - voltage_stimuli_port_name); - } - - return; -} - -static -void dump_verilog_top_testbench_global_ports_stimuli(FILE* fp, t_llist* head) { - t_llist* temp = head; - t_spice_model_port* cur_global_port = NULL; - int ipin; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - fprintf(fp, "//----- Connecting Global ports -----\n"); - while(NULL != temp) { - cur_global_port = (t_spice_model_port*)(temp->dptr); - /* Make sure this is a global port */ - assert(TRUE == cur_global_port->is_global); - /* If this is a clock signal, connect to op_clock signal */ - if (SPICE_MODEL_PORT_CLOCK == cur_global_port->type) { - /* Special for programming clock */ - if (TRUE == cur_global_port->is_prog) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_clock_port_name); - } else { - assert(FALSE == cur_global_port->is_prog); - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_op_clock_port_name); - } - /* If this is a config_enable signal, connect to config_done signal */ - } else if (TRUE == cur_global_port->is_config_enable) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_clock_port_name); - /* If this is a set/reset signal, connect to global reset and set signals */ - } else if (TRUE == cur_global_port->is_reset) { - /* Special for programming reset */ - if (TRUE == cur_global_port->is_prog) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_reset_port_name); - } else { - assert(FALSE == cur_global_port->is_prog); - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_reset_port_name); - } - /* If this is a set/reset signal, connect to global reset and set signals */ - } else if (TRUE == cur_global_port->is_set) { - /* Special for programming reset */ - if (TRUE == cur_global_port->is_prog) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_set_port_name); - } else { - assert(FALSE == cur_global_port->is_prog); - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_set_port_name); - } - } else { - /* Other global signals stuck at the default values */ - for (ipin = 0; ipin < cur_global_port->size; ipin++) { - fprintf(fp, "assign %s[%d] = 1'b%d;\n", - cur_global_port->prefix, ipin, cur_global_port->default_val); - } - } - /* Go to the next */ - temp = temp->next; - } - fprintf(fp, "//----- End Connecting Global ports -----\n"); - - return; -} - -static -void dump_verilog_top_netlist_scan_chain_ports(FILE* fp, - enum e_dump_verilog_port_type dump_port_type) { - /* Only accept two types of dump_port_type here! */ - assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); - - /* Check */ - assert (sram_verilog_orgz_info->type == SPICE_SRAM_SCAN_CHAIN); - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Only the head of scan-chain will be the primary input in the top-level netlist - * TODO: we may have multiple scan-chains, their heads will be the primary outputs - */ - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_scan_chain_head_prefix, 0, 0); - fprintf(fp, " //---- Scan-chain head \n"); - - return; -} - -static -void dump_verilog_top_module_ports(FILE* fp, - enum e_dump_verilog_port_type dump_port_type) { - char* port_name = NULL; - char split_sign; - enum e_dump_verilog_port_type actual_dump_port_type; - boolean dump_global_port_type = FALSE; - - split_sign = determine_verilog_generic_port_split_sign(dump_port_type); - - /* Only accept two types of dump_port_type here! */ - assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); - - if (VERILOG_PORT_INPUT == dump_port_type) { - dump_global_port_type = TRUE; - } - - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, dump_global_port_type)) { - fprintf(fp, "%c\n", split_sign); - } - /* Inputs and outputs of I/O pads */ - /* Inout Pads */ - assert(NULL != iopad_verilog_model); - if ((NULL == iopad_verilog_model) - ||(iopad_verilog_model->cnt > 0)) { - actual_dump_port_type = VERILOG_PORT_CONKT; - if (VERILOG_PORT_INPUT == dump_port_type) { - actual_dump_port_type = VERILOG_PORT_INOUT; - } - /* Malloc and assign port_name */ - port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); - sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); - /* Dump a register port */ - dump_verilog_generic_port(fp, actual_dump_port_type, - port_name, iopad_verilog_model->cnt - 1, 0); - fprintf(fp, "%c //---FPGA inouts \n", split_sign); - /* Free port_name */ - my_free(port_name); - } - - /* Configuration ports depend on the organization of SRAMs */ - switch(sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - dump_verilog_generic_port(fp, dump_port_type, - sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); - fprintf(fp, " //--- SRAM outputs \n"); - /* Definition ends */ - break; - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_top_netlist_scan_chain_ports(fp, dump_port_type); - /* Definition ends */ - break; - case SPICE_SRAM_MEMORY_BANK: - dump_verilog_top_netlist_memory_bank_ports(fp, dump_port_type); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -static -void dump_verilog_top_testbench_call_top_module(FILE* fp, - char* circuit_name) { - - /* Include defined top-level module */ - fprintf(fp, "//----- Device Under Test (DUT) ----\n"); - fprintf(fp, "//------Call defined Top-level Verilog Module -----\n"); - fprintf(fp, "%s_top U0 (\n", circuit_name); - - dump_verilog_top_module_ports(fp, VERILOG_PORT_CONKT); - - fprintf(fp, ");\n"); - return; -} - -/* Find the number of configuration clock cycles for a top-level testbench - * A valid configuration clock cycle is allocated for an element with - * (1) SRAM_val=1; - * (2) BL = 1 && WL = 1; - * (3) BL = 1 && WL = 0 with a paired conf_bit; - */ -static -int dump_verilog_top_testbench_find_num_config_clock_cycles(t_llist* head) { - int cnt = 0; - t_llist* temp = head; - t_conf_bit_info* temp_conf_bit_info = NULL; - - while (NULL != temp) { - /* Fetch the conf_bit_info */ - temp_conf_bit_info = (t_conf_bit_info*)(temp->dptr); - /* Check if conf_bit_info needs a clock cycle*/ - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - cnt++; - temp_conf_bit_info->index_in_top_tb = cnt; - break; - case SPICE_SRAM_MEMORY_BANK: - cnt++; - temp_conf_bit_info->index_in_top_tb = cnt; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - /* Go to the next */ - temp = temp->next; - } - - return cnt; -} - -static -void dump_verilog_top_auto_testbench_ports(FILE* fp, - char* circuit_name, - t_syn_verilog_opts syn_verilog_opts, - char* postfix){ - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - int iblock, iopad_idx; - t_spice_model* mem_model = NULL; - char* port_name = NULL; - - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - fprintf(fp, "`include \"%s\"\n", syn_verilog_opts.verilog_benchmark_file); - fprintf(fp, "module %s;\n", my_strcat(circuit_name, postfix)); - /* Local wires */ - /* 1. reset, set, clock signals */ - /* 2. iopad signals */ - - /* Connect to defined signals */ - /* set and reset signals */ - fprintf(fp, "\n"); - dump_verilog_top_testbench_global_ports(fp, global_ports_head, VERILOG_PORT_WIRE); - fprintf(fp, "\n"); - - /* TODO: dump each global signal as reg here */ - - /* Inputs and outputs of I/O pads */ - /* Inout Pads */ - assert(NULL != iopad_verilog_model); - if ((NULL == iopad_verilog_model) - ||(iopad_verilog_model->cnt > 0)) { - /* Malloc and assign port_name */ - port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); - sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); - /* Dump a wired port */ - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - port_name, iopad_verilog_model->cnt - 1, 0); - fprintf(fp, "; //--- FPGA inouts \n"); - /* Free port_name */ - my_free(port_name); - /* Malloc and assign port_name */ - port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + strlen(top_tb_inout_reg_postfix) + 1)); - sprintf(port_name, "%s%s%s", gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix); - /* Dump a wired port */ - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - port_name, iopad_verilog_model->cnt - 1, 0); - fprintf(fp, "; //--- reg for FPGA inouts \n"); - /* Free port_name */ - my_free(port_name); - } - - /* Add a signal to identify the configuration phase is finished */ - fprintf(fp, "reg [0:0] %s;\n", top_tb_config_done_port_name); - /* Programming clock */ - fprintf(fp, "wire [0:0] %s;\n", top_tb_prog_clock_port_name); - fprintf(fp, "reg [0:0] %s%s;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); - /* Operation clock */ - fprintf(fp, "wire [0:0] %s;\n", top_tb_op_clock_port_name); - fprintf(fp, "reg [0:0] %s%s;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); - /* Programming set and reset */ - fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_reset_port_name); - fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_set_port_name); - /* Global set and reset */ - fprintf(fp, "reg [0:0] %s;\n", top_tb_reset_port_name); - fprintf(fp, "reg [0:0] %s;\n", top_tb_set_port_name); - /* Generate stimuli for global ports or connect them to existed signals */ - dump_verilog_top_testbench_global_ports_stimuli(fp, global_ports_head); - - /* Configuration ports depend on the organization of SRAMs */ - switch(sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); - fprintf(fp, "; //---- SRAM outputs \n"); - break; - case SPICE_SRAM_SCAN_CHAIN: - /* We put the head of scan-chains here - */ - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - top_netlist_scan_chain_head_prefix, 0, 0); - fprintf(fp, "; //---- Scan-chain head \n"); - break; - case SPICE_SRAM_MEMORY_BANK: - /* Get the number of array BLs/WLs, decoder sizes */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - fprintf(fp, " wire [0:0] %s;\n", - top_netlist_bl_enable_port_name - ); - fprintf(fp, " wire [0:0] %s;\n", - top_netlist_wl_enable_port_name - ); - /* Wire en_bl, en_wl to prog_clock */ - fprintf(fp, "assign %s[0:0] = %s[0:0];\n", - top_netlist_bl_enable_port_name, - top_tb_prog_clock_port_name); - fprintf(fp, "assign %s [0:0]= %s[0:0];\n", - top_netlist_wl_enable_port_name, - top_tb_prog_clock_port_name); - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); - fprintf(fp, "; //--- Address of bit lines \n"); - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); - fprintf(fp, "; //--- Address of word lines \n"); - /* data_in is only require by BL decoder of SRAM array - * As for RRAM array, the data_in signal will not be used - */ - if (SPICE_MODEL_DESIGN_CMOS == mem_model->design_tech) { - fprintf(fp, " reg [0:0] %s; // --- Data_in signal for BL decoder, only required by SRAM array \n", - top_netlist_bl_data_in_port_name); - } - /* I add all the Bit lines and Word lines here just for testbench usage - fprintf(fp, " input wire [%d:0] %s_out; //--- Bit lines \n", - sram_verilog_model->cnt - 1, sram_verilog_model->prefix); - fprintf(fp, " input wire [%d:0] %s_outb; //--- Word lines \n", - sram_verilog_model->cnt - 1, sram_verilog_model->prefix); - */ - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Add signals from blif benchmark and short-wire them to FPGA I/O PADs - * This brings convenience to checking functionality - */ - fprintf(fp, "//-----Link Blif Benchmark inputs to FPGA IOPADs -----\n"); - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* General INOUT*/ - if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { - iopad_idx = logical_block[iblock].mapped_spice_model_index; - /* Make sure We find the correct logical block !*/ - assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); - fprintf(fp, "//----- Blif Benchmark inout %s is mapped to FPGA IOPAD %s[%d] -----\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx); - if(VPACK_INPAD == logical_block[iblock].type){ - fprintf(fp, "wire in_%s_%s_%d_;\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx); - fprintf(fp, "assign in_%s_%s_%d_ = %s%s[%d];\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); - } else{ - fprintf(fp, "wire %s_%s_%d_;\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx); - fprintf(fp, "assign %s_%s_%d_ = %s%s[%d];\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); - fprintf(fp, "wire %s_benchmark;\n", logical_block[iblock].name); - fprintf(fp, "reg %s_verification;\n", logical_block[iblock].name); - } - - } - } - - return; -} - -static -void dump_verilog_top_auto_testbench_call_benchmark(FILE* fp, char* blif_circuit_name){ - int iblock, iopad_idx; - fprintf(fp, "// Benchmark instanciation\n"); - fprintf(fp, " %s Benchmark(\n", blif_circuit_name); - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* General INOUT*/ - if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { - iopad_idx = logical_block[iblock].mapped_spice_model_index; - /* Make sure We find the correct logical block !*/ - assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); - if(iblock>0){ - fprintf(fp, ",\n"); - } - if(TRUE == logical_block[iblock].is_clock){ - fprintf(fp, " %s", top_tb_op_clock_port_name); - } else if(VPACK_INPAD == logical_block[iblock].type){ - fprintf(fp, " in_%s_%s_%d_", logical_block[iblock].name, gio_inout_prefix, iopad_idx); - } else if(VPACK_OUTPAD == logical_block[iblock].type){ - fprintf(fp, " %s_benchmark", logical_block[iblock].name); - } - } - } - fprintf(fp, " );\n"); - fprintf(fp, "// End Benchmark instanciation\n\n"); - return; -} - -static -void dump_verilog_top_auto_testbench_check(FILE* fp){ - int iblock, iopad_idx; - fprintf(fp, " // Begin checking\n"); - fprintf(fp, " always@(negedge %s) begin\n", top_tb_op_clock_port_name); - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { - iopad_idx = logical_block[iblock].mapped_spice_model_index; - /* Make sure We find the correct logical block !*/ - assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); - if(VPACK_OUTPAD == logical_block[iblock].type){ - fprintf(fp, " %s_verification <= %s_benchmark ^ %s_%s_%d_ ;\n", logical_block[iblock].name, logical_block[iblock].name, logical_block[iblock].name, gio_inout_prefix, iopad_idx); - } - } - } - fprintf(fp, " end\n\n"); - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { - iopad_idx = logical_block[iblock].mapped_spice_model_index; - /* Make sure We find the correct logical block !*/ - assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); - if(VPACK_OUTPAD == logical_block[iblock].type){ - fprintf(fp, " always@(posedge %s_verification) begin\n", logical_block[iblock].name); - fprintf(fp, " if(%s_verification) begin\n", logical_block[iblock].name); - fprintf(fp, " $display(\"Mismatch on %s_verification\");\n", logical_block[iblock].name); - fprintf(fp, " $finish;\n"); - fprintf(fp, " end\n"); - fprintf(fp, " end\n\n"); - } - } - } - return; -} - -void dump_verilog_top_auto_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog, - char* postfix) { - FILE* fp = NULL; - char* title = my_strcat("FPGA Verilog Testbench for Top-level netlist of Design: ", circuit_name); - - /* Check if the path exists*/ - fp = fopen(top_netlist_name,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); - exit(1); - } - - vpr_printf(TIO_MESSAGE_INFO, "Writing Autochecked Testbench for FPGA Top-level Verilog netlist for %s...\n", circuit_name); - - /* Print the title */ - dump_verilog_file_header(fp, title); - my_free(title); - /* Start of testbench */ - dump_verilog_top_auto_testbench_ports(fp, circuit_name, syn_verilog_opts, postfix); - - /* Call defined top-level module */ - dump_verilog_top_testbench_call_top_module(fp, circuit_name); - - /* Call defined benchmark */ - dump_verilog_top_auto_testbench_call_benchmark(fp, blif_circuit_name); - - /* Add stimuli for reset, set, clock and iopad signals */ - dump_verilog_top_testbench_stimuli(fp, num_clock, syn_verilog_opts, verilog); - - /* Add output autocheck */ - dump_verilog_top_auto_testbench_check(fp); - - /* Testbench ends*/ - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - return; -} - -static -void dump_verilog_top_preconf_testbench_stimuli(FILE* fp, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog, - char* hex_file_path, - t_spice spice) { - int inet, iblock, iopad_idx; - int found_mapped_inpad = 0; - t_spice_model* scff_mem_model = NULL; - /* Find Input Pad Spice model */ - t_spice_net_info* cur_spice_net_info = NULL; - int iscff, num_scffs; - float prog_clock_period = (1./spice.spice_params.stimulate_params.prog_clock_freq); - float op_clock_period = (1./spice.spice_params.stimulate_params.op_clock_freq); - - num_scffs = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &scff_mem_model); - - fprintf(fp, " // Loading configuration as initial state\n"); - fprintf(fp, "integer count;\n"); - fprintf(fp, "integer file;\n"); - fprintf(fp, "reg[0:%d] tmp;\n\n", (num_scffs - 1)); - fprintf(fp, "initial begin\n"); - fprintf(fp, " file = $fopen(\"%s\", \"r\");\n", hex_file_path); - fprintf(fp, " for(count = %d; count > -1 ; count = count - 1) begin\n", (num_scffs - 1)); - fprintf(fp, " tmp[count] = $fgetc(file);\n"); - fprintf(fp, " end\n"); - fprintf(fp, " $signal_force(\"U0/%s_scff_out\", tmp, 0, 1, , 1);\n", scff_mem_model->prefix ); - fprintf(fp, " $fclose(file);\n"); - fprintf(fp, "end\n"); - fprintf(fp, " // End loading configuration as initial state\n\n"); - - /* config_done signal: indicate when configuration is finished */ - fprintf(fp, "//----- %s ----\n", top_tb_config_done_port_name); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- CONFIG_DONE GENERATOR\n"); - fprintf(fp, " %s = 1'b0;\n", top_tb_config_done_port_name); - fprintf(fp, " //----- %s signal is enabled after 50ns delay ----\n", - top_tb_config_done_port_name); - fprintf(fp, " #50 %s = 1'b1;\n", top_tb_config_done_port_name); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of %s ----\n", - top_tb_config_done_port_name); - fprintf(fp, "\n"); - - /* Generate stimilus of programming clock */ - fprintf(fp, "//----- Raw Programming clock ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- PROG_CLOCK INITIALIZATION\n"); - fprintf(fp, " %s%s = 1'b0;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of Programming clock ----\n"); - fprintf(fp, "\n"); - /* Programming is already done - */ - fprintf(fp, "//---- Actual programming clock is triggered only when %s and %s are disabled\n", - top_tb_config_done_port_name, - top_tb_prog_reset_port_name); - fprintf(fp, " assign %s = %s%s & (~%s) & (~%s);\n", - top_tb_prog_clock_port_name, - top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, - top_tb_config_done_port_name, - top_tb_prog_reset_port_name); - /* - fprintf(fp, " assign %s = %s%s & (~%s);\n", - top_tb_prog_clock_port_name, - top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, - top_tb_config_done_port_name); - */ - fprintf(fp, "//----- END of Actual Programming clock ----\n"); - fprintf(fp, "\n"); - - /* Generate stimilus of programming clock */ - fprintf(fp, "//----- Raw Operation clock ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- OP_CLOCK INITIALIZATION\n"); - fprintf(fp, " %s%s = 1'b0;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "always wait(~%s)\n", top_tb_reset_port_name); - fprintf(fp, " begin //--- OP_CLOCK GENERATOR\n"); - fprintf(fp, " #%.2f %s%s = ~%s%s;\n", - 0.5*op_clock_period / verilog_sim_timescale, - top_tb_op_clock_port_name, top_tb_clock_reg_postfix, - top_tb_op_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of Operation clock ----\n"); - /* Operation clock should be enabled after programming phase finishes. - * Before configuration is done (config_done is enabled), operation clock should be always zero. - */ - fprintf(fp, "//---- Actual operation clock is triggered only when %s is enabled \n", - top_tb_config_done_port_name); - fprintf(fp, " assign %s = %s%s & (%s);\n", - top_tb_op_clock_port_name, - top_tb_op_clock_port_name, top_tb_clock_reg_postfix, - top_tb_config_done_port_name); - fprintf(fp, "//----- END of Actual Operation clock ----\n"); - fprintf(fp, "\n"); - - /* Reset signal for configuration circuit : only enable during the first clock cycle in programming phase */ - fprintf(fp, "//----- Programming Reset Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- PROGRAMMING RESET GENERATOR\n"); - fprintf(fp, " %s = 1'b0;\n", top_tb_prog_reset_port_name); - /* Reset is disenabled to avoid configuration reset */ - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* Set signal for configuration circuit : only enable during the first clock cycle in programming phase */ - fprintf(fp, "//----- Programming set Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- PROGRAMMING SET GENERATOR\n"); - fprintf(fp, "%s = 1'b0;\n", top_tb_prog_set_port_name); - fprintf(fp, "//----- Programming set signal is always disabled -----\n"); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* reset signals: only enabled during the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- RESET GENERATOR\n"); - fprintf(fp, " %s = 1'b1;\n", top_tb_reset_port_name); - /* Reset is enabled until the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in operation phase ----\n"); - fprintf(fp, "wait(%s);\n", - top_tb_config_done_port_name); - fprintf(fp, "#%.2f %s = 1'b1;\n", - (1 * op_clock_period)/ verilog_sim_timescale, - top_tb_reset_port_name); - fprintf(fp, "#%.2f %s = 1'b0;\n", - (2 * op_clock_period) / verilog_sim_timescale, - top_tb_reset_port_name); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* set signals */ - fprintf(fp, "//----- Set Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- SET GENERATOR\n"); - fprintf(fp, "%s = 1'b0;\n", top_tb_set_port_name); - fprintf(fp, "//----- Set signal is always disabled -----\n"); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* Inputs stimuli: BL/WL address lines */ - //dump_verilog_top_testbench_conf_bits_serial(fp, sram_verilog_orgz_info->conf_bit_head); - - /* For each input_signal - * TODO: this part is low-efficent for run-time concern... Need improve - */ - assert(NULL != iopad_verilog_model); - for (iopad_idx = 0; iopad_idx < iopad_verilog_model->cnt; iopad_idx++) { - /* Find if this inpad is mapped to a logical block */ - found_mapped_inpad = 0; - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* Bypass OUTPAD: donot put any voltage stimuli */ - /* Make sure We find the correct logical block !*/ - if ((iopad_verilog_model == logical_block[iblock].mapped_spice_model) - &&(iopad_idx == logical_block[iblock].mapped_spice_model_index)) { - /* Output PAD only need a short connection */ - if (VPACK_OUTPAD == logical_block[iblock].type) { - fprintf(fp, "//----- Output %s does not need a Stimuli ----\n", logical_block[iblock].name); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s[%d] GENERATOR\n", gio_inout_prefix, iopad_idx); - fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - verilog_default_signal_init_value); - fprintf(fp, "end\n"); - found_mapped_inpad = 1; - break; - } - /* Input PAD only need a short connection */ - assert(VPACK_INPAD == logical_block[iblock].type); - cur_spice_net_info = NULL; - for (inet = 0; inet < num_nets; inet++) { - if (0 == strcmp(clb_net[inet].name, logical_block[iblock].name)) { - cur_spice_net_info = clb_net[inet].spice_net_info; - break; - } - } - assert(NULL != cur_spice_net_info); - assert(!(0 > cur_spice_net_info->density)); - assert(!(1 < cur_spice_net_info->density)); - assert(!(0 > cur_spice_net_info->probability)); - assert(!(1 < cur_spice_net_info->probability)); - /* Connect the reg to inouts */ - fprintf(fp, "//----- Input %s Stimuli ----\n", logical_block[iblock].name); - fprintf(fp, "assign %s%s[%d] = %s%s%s[%d];\n", - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx); - /* Get the net information */ - /* TODO: Give the net name in the blif file !*/ - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s GENERATOR\n", logical_block[iblock].name); - fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - cur_spice_net_info->init_val); - fprintf(fp, "end\n"); - fprintf(fp, "always wait (~%s)\n", top_tb_reset_port_name); - fprintf(fp, " begin \n"); - fprintf(fp, " %s%s%s[%d] = ~%s%s%s[%d];\n #%.2f\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - (op_clock_period * 2 * ((int)(cur_spice_net_info->probability / cur_spice_net_info->density)+ iblock) / verilog_sim_timescale)); - fprintf(fp, " %s%s%s[%d] = ~%s%s%s[%d];\n #%.2f;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - (op_clock_period * 2 * ((int)((cur_spice_net_info->density / cur_spice_net_info->probability) * 2.5 + iblock)) / verilog_sim_timescale)); - fprintf(fp, " end \n"); - fprintf(fp, "\n"); - found_mapped_inpad++; - } - } - assert((0 == found_mapped_inpad)||(1 == found_mapped_inpad)); - /* If we find one iopad already, we finished in this round here */ - if (1 == found_mapped_inpad) { - continue; - } - /* if we cannot find any mapped inpad from tech.-mapped netlist, give a default */ - /* Connect the reg to inouts */ - fprintf(fp, "//----- Input %s[%d] Stimuli ----\n", gio_inout_prefix, iopad_idx); - fprintf(fp, "assign %s%s[%d] = %s%s%s[%d];\n", - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx); - /* TODO: Give the net name in the blif file !*/ - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s[%d] GENERATOR\n", gio_inout_prefix, iopad_idx); - fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - verilog_default_signal_init_value); - fprintf(fp, "end\n"); - } - - return; -} - -void dump_verilog_top_auto_preconf_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog, - char* postfix, - char* hex_file_path) { - FILE* fp = NULL; - char* title = my_strcat("FPGA Verilog Testbench for Top-level netlist of Design: ", circuit_name); - - /* Check if the path exists*/ - fp = fopen(top_netlist_name,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); - exit(1); - } - - vpr_printf(TIO_MESSAGE_INFO, "Writing Autocheked and Preconfigured Testbench for FPGA Top-level Verilog netlist for %s...\n", circuit_name); - - /* Print the title */ - dump_verilog_file_header(fp, title); - my_free(title); - - /* Start of testbench */ - dump_verilog_top_auto_testbench_ports(fp, circuit_name, syn_verilog_opts, postfix); - - /* Call defined top-level module */ - dump_verilog_top_testbench_call_top_module(fp, circuit_name); - - /* Call defined benchmark */ - dump_verilog_top_auto_testbench_call_benchmark(fp, blif_circuit_name); - - /* Add stimuli for reset, set, clock and iopad signals */ - dump_verilog_top_preconf_testbench_stimuli(fp, num_clock, syn_verilog_opts, verilog, hex_file_path, verilog); - - /* Add output autocheck */ - dump_verilog_top_auto_testbench_check(fp); - - /* Testbench ends*/ - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - return; -} - -void dump_fpga_spice_hex(char* hex_file_path, - char* chomped_circuit_name, - t_sram_orgz_info* sram_verilog_orgz_info) { - FILE* fp = NULL; - t_llist* temp = sram_verilog_orgz_info->conf_bit_head; - t_conf_bit_info* cur_conf_bit_info = NULL; - - fp = fopen(hex_file_path, "w"); - while (NULL != temp) { - cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); - fprintf(fp, "%d", cur_conf_bit_info->sram_bit->val); - temp = temp->next; - } - fclose(fp); - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.h deleted file mode 100644 index bd085e7a2..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_autocheck_tb.h +++ /dev/null @@ -1,19 +0,0 @@ -void dump_verilog_top_auto_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog, - char* postfix); - - -void dump_verilog_top_auto_preconf_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog, - char* postfix, - char* hex_file_path); - -void dump_fpga_spice_hex(char* hex_file_path, - char* chomped_circuit_name, - t_sram_orgz_info* sram_verilog_orgz_info); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.c deleted file mode 100644 index 80ff69342..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.c +++ /dev/null @@ -1,230 +0,0 @@ -/***********************************/ -/* Synthesizable Verilog Dumping */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "vpr_utils.h" -#include "path_delay.h" -#include "stats.h" - -/* Include FPGA-SPICE utils */ -#include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "spice_mux.h" -#include "fpga_spice_globals.h" - -/* Include verilog utils */ -#include "verilog_global.h" -#include "verilog_utils.h" - -/***** Subroutines *****/ -void determine_verilog_blwl_decoder_size(INP t_sram_orgz_info* cur_sram_verilog_orgz_info, - OUTP int* num_array_bl, OUTP int* num_array_wl, - OUTP int* bl_decoder_size, OUTP int* wl_decoder_size) { - t_spice_model* mem_model = NULL; - int num_mem_bit; - int num_reserved_bl, num_reserved_wl; - - /* Check */ - assert(SPICE_SRAM_MEMORY_BANK == sram_verilog_orgz_info->type); - - num_mem_bit = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, num_array_bl, num_array_wl); - get_sram_orgz_info_reserved_blwl(sram_verilog_orgz_info, &num_reserved_bl, &num_reserved_wl); - - /* Sizes of decodes depend on the Memory technology */ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - switch (mem_model->design_tech) { - /* CMOS SRAM*/ - case SPICE_MODEL_DESIGN_CMOS: - /* SRAMs can efficiently share BLs and WLs, - * Actual number of BLs and WLs will be sqrt(num_bls) and sqrt(num_wls) - */ - assert(0 == num_reserved_bl); - assert(0 == num_reserved_wl); - (*num_array_bl) = ceil(sqrt(*num_array_bl)); - (*num_array_wl) = ceil(sqrt(*num_array_wl)); - (*bl_decoder_size) = determine_decoder_size(*num_array_bl); - (*wl_decoder_size) = determine_decoder_size(*num_array_wl); - break; - /* RRAM */ - case SPICE_MODEL_DESIGN_RRAM: - /* Currently we do not have more efficient way to share the BLs and WLs as CMOS SRAMs */ - (*bl_decoder_size) = determine_decoder_size(*num_array_bl); - (*wl_decoder_size) = determine_decoder_size(*num_array_wl); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology [CMOS|RRAM] for memory technology!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -void dump_verilog_decoder(char* submodule_dir) { - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - FILE* fp = NULL; - t_spice_model* mem_model = NULL; - boolean bl_inverted = FALSE; - boolean wl_inverted = FALSE; - - char* verilog_name = my_strcat(submodule_dir, decoders_verilog_file_name); - - /* Print the muxes netlist*/ - fp = fopen(verilog_name, "w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create decoder SPICE netlist %s",__FILE__, __LINE__, verilog_name); - exit(1); - } - - /* Check */ - assert(SPICE_SRAM_MEMORY_BANK == sram_verilog_orgz_info->type); - - /* Get number of BLs,WLs and decoder sizes */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, - &bl_decoder_size, &wl_decoder_size); - - /* Generate file header*/ - vpr_printf(TIO_MESSAGE_INFO, "Writing Decoder verilog netlist...\n"); - - /* Generate the descriptions*/ - dump_verilog_file_header(fp, " Verilog Decoders"); - - /* Different design technology requires different BL decoder logic */ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - /* Find if we need an inversion of the BL */ - check_mem_model_blwl_inverted(mem_model, SPICE_MODEL_PORT_BL, &bl_inverted); - check_mem_model_blwl_inverted(mem_model, SPICE_MODEL_PORT_WL, &wl_inverted); - - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: /* CMOS SRAM*/ - /* SRAM technology requires its BL decoder has an additional input called data_in - * only the selected BL will be set to the value of data_in, other BLs will be in high-resistance state - */ - /* Start the BL decoder module definition */ - fprintf(fp, "//----- BL Decoder convert %d bits to binary %d bits -----\n", - bl_decoder_size, num_array_bl); - fprintf(fp, "module bl_decoder%dto%d (\n", - bl_decoder_size, num_array_bl); - fprintf(fp, "input wire enable,\n"); - fprintf(fp, "input wire [%d:0] addr_in,\n", - bl_decoder_size - 1); - fprintf(fp, "input wire data_in,\n"); - fprintf(fp, "output reg [0:%d] addr_out\n", - num_array_bl - 1); - fprintf(fp, ");\n"); - - /* Wee need to know the default value of bl port and wl port */ - - /* Internal logics */ - - fprintf(fp, "always@(addr_out,addr_in,enable, data_in)\n"); - fprintf(fp, "begin\n"); - fprintf(fp, "\taddr_out = %d'bz;\n", num_array_bl); - fprintf(fp, "\tif (1'b1 == enable) begin\n"); - fprintf(fp, "\t\taddr_out[addr_in] = data_in;\n"); - fprintf(fp, "\tend\n"); - fprintf(fp, "end\n"); - - fprintf(fp, "endmodule\n"); - break; - case SPICE_MODEL_DESIGN_RRAM: /* RRAM */ - /* For RRAM technology, BL decoder should be same as the WL decoder */ - /* Start the BL decoder module definition */ - fprintf(fp, "//----- BL Decoder convert %d bits to binary %d bits -----\n", - bl_decoder_size, num_array_bl); - fprintf(fp, "module bl_decoder%dto%d (\n", - bl_decoder_size, num_array_bl); - fprintf(fp, "input wire enable,\n"); - fprintf(fp, "input wire [%d:0] addr_in,\n", - bl_decoder_size-1); - fprintf(fp, "output reg [0:%d] addr_out\n", - num_array_bl-1); - fprintf(fp, ");\n"); - - /* Internal logics */ - fprintf(fp, "always@(addr_out,addr_in,enable)\n"); - fprintf(fp, "begin\n"); - if (TRUE == bl_inverted) { - fprintf(fp, "\taddr_out = %d'b1;\n", num_array_bl); - } else { - assert (FALSE == bl_inverted); - fprintf(fp, "\taddr_out = %d'b0;\n", num_array_bl); - } - fprintf(fp, "\tif (1'b1 == enable) begin\n"); - if (TRUE == bl_inverted) { - fprintf(fp, "\t\taddr_out[addr_in] = 1'b0;\n"); - } else { - assert (FALSE == bl_inverted); - fprintf(fp, "\t\taddr_out[addr_in] = 1'b1;\n"); - } - fprintf(fp, "\tend\n"); - fprintf(fp, "end\n"); - - fprintf(fp, "endmodule\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology [CMOS|RRAM] for memory technology!\n", - __FILE__, __LINE__); - exit(1); - } - - /* WL decoder logic is the same whatever SRAM or RRAM technology is considered */ - /* Start the WL module definition */ - fprintf(fp, "//----- WL Decoder convert %d bits to binary %d bits -----\n", - wl_decoder_size, num_array_wl); - fprintf(fp, "module wl_decoder%dto%d (\n", - wl_decoder_size, num_array_wl); - fprintf(fp, "input wire enable,\n"); - fprintf(fp, "input wire [%d:0] addr_in,\n", - wl_decoder_size-1); - fprintf(fp, "output reg [0:%d] addr_out\n", - num_array_bl-1); - fprintf(fp, ");\n"); - - /* Internal logics */ - fprintf(fp, "always@(addr_out,addr_in,enable)\n"); - fprintf(fp, "begin\n"); - if (TRUE == wl_inverted) { - fprintf(fp, "\taddr_out = %d'b1;\n", num_array_wl); - } else { - assert (FALSE == wl_inverted); - fprintf(fp, "\taddr_out = %d'b0;\n", num_array_wl); - } - fprintf(fp, "\tif (1'b1 == enable) begin\n"); - if (TRUE == wl_inverted) { - fprintf(fp, "\t\taddr_out[addr_in] = 1'b0;\n"); - } else { - assert (FALSE == wl_inverted); - fprintf(fp, "\t\taddr_out[addr_in] = 1'b1;\n"); - } - fprintf(fp, "\tend\n"); - fprintf(fp, "end\n"); - - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - /* Add fname to the linked list */ - submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); - - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.h deleted file mode 100644 index 12c91fc91..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_decoder.h +++ /dev/null @@ -1,7 +0,0 @@ - - -void determine_verilog_blwl_decoder_size(INP t_sram_orgz_info* cur_sram_verilog_orgz_info, - OUTP int* num_array_bl, OUTP int* num_array_wl, - OUTP int* bl_decoder_size, OUTP int* wl_decoder_size); - -void dump_verilog_decoder(char* submodule_dir); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.c deleted file mode 100644 index 4e143f9b6..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.c +++ /dev/null @@ -1,75 +0,0 @@ -/***********************************/ -/* Synthesizable Verilog Dumping */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include "spice_types.h" -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "verilog_global.h" - -char* verilog_netlist_file_postfix = ".v"; -float verilog_sim_timescale = 1e-9; // Verilog Simulation time scale (minimum time unit) : 1ns -char* verilog_timing_preproc_flag = "ENABLE_TIMING"; // the flag to enable timing definition during compilation -char* verilog_init_sim_preproc_flag = "INITIALIZATION"; // the flag to enable initialization during simulation - -char* default_verilog_dir_name = "syn_verilogs/"; -char* default_lb_dir_name = "lb/"; -char* default_rr_dir_name = "routing/"; -char* default_submodule_dir_name = "sub_module/"; -char* default_modelsim_dir_name = "msim_projects/"; - -char* modelsim_project_name_postfix = "_fpga_msim"; -char* modelsim_proc_script_name_postfix = "_proc.tcl"; -char* modelsim_top_script_name_postfix = "_runsim.tcl"; -char* modelsim_testbench_module_postfix = "_top_tb"; -char* modelsim_auto_testbench_module_postfix = "_top_auto_tb"; -char* modelsim_auto_preconf_testbench_module_postfix = "_top_auto_preconf_tb"; -char* modelsim_simulation_time_unit = "ns"; - -char* verilog_top_postfix = "_top.v"; -char* bitstream_verilog_file_postfix = ".bitstream"; -char* hex_verilog_file_postfix = ".hex"; -char* top_testbench_verilog_file_postfix = "_top_tb.v"; -char* top_auto_testbench_verilog_file_postfix = "_top_auto_tb.v"; -char* top_auto_preconf_testbench_verilog_file_postfix = "_top_auto_preconf_tb.v"; -char* blif_testbench_verilog_file_postfix = "_blif_tb.v"; -char* submodule_verilog_file_name = "sub_module.v"; -char* logic_block_verilog_file_name = "logic_blocks.v"; -char* luts_verilog_file_name = "luts.v"; -char* routing_verilog_file_name = "routing.v"; -char* sub_module_verilog_file_name = "sub_module.v"; -char* muxes_verilog_file_name = "muxes.v"; -char* wires_verilog_file_name = "wires.v"; -char* essentials_verilog_file_name = "inv_buf_passgate.v"; -char* decoders_verilog_file_name = "decoders.v"; - -char* verilog_mux_basis_posfix = "_basis"; -char* verilog_mux_special_basis_posfix = "_special_basis"; - -/* Prefix for subckt Verilog netlists */ -char* grid_verilog_file_name_prefix = "grid_"; -char* chanx_verilog_file_name_prefix = "chanx_"; -char* chany_verilog_file_name_prefix = "chany_"; -char* sb_verilog_file_name_prefix = "sb_"; -char* cbx_verilog_file_name_prefix = "cbx_"; -char* cby_verilog_file_name_prefix = "cby_"; - -/* SRAM SPICE MODEL should be set as global*/ -t_spice_model* sram_verilog_model = NULL; -enum e_sram_orgz sram_verilog_orgz_type = SPICE_SRAM_STANDALONE; -t_sram_orgz_info* sram_verilog_orgz_info = NULL; - -/* Input and Output Pad spice model. should be set as global */ -t_spice_model* iopad_verilog_model = NULL; - -/* Linked-list that stores all the configuration bits */ -t_llist* conf_bits_head = NULL; - -/* Linked-list that stores submodule Verilog file mames */ -t_llist* grid_verilog_subckt_file_path_head = NULL; -t_llist* routing_verilog_subckt_file_path_head = NULL; -t_llist* submodule_verilog_subckt_file_path_head = NULL; - - -int verilog_default_signal_init_value = 0; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.h deleted file mode 100644 index e2ced7899..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_global.h +++ /dev/null @@ -1,77 +0,0 @@ -/* global parameters for dumping synthesizable verilog */ - -extern char* verilog_netlist_file_postfix; -extern float verilog_sim_timescale; -extern char* verilog_timing_preproc_flag; // the flag to enable timing definition during compilation -extern char* verilog_init_sim_preproc_flag; // the flag to enable initialization during simulation - -extern char* default_verilog_dir_name; -extern char* default_lb_dir_name; -extern char* default_rr_dir_name; -extern char* default_submodule_dir_name; -extern char* default_modelsim_dir_name; - -extern char* modelsim_project_name_postfix; -extern char* modelsim_proc_script_name_postfix; -extern char* modelsim_top_script_name_postfix; -extern char* modelsim_testbench_module_postfix; -extern char* modelsim_auto_testbench_module_postfix; -extern char* modelsim_auto_preconf_testbench_module_postfix; -extern char* modelsim_simulation_time_unit; - -extern char* verilog_top_postfix; -extern char* bitstream_verilog_file_postfix; -extern char* hex_verilog_file_postfix; -extern char* top_testbench_verilog_file_postfix; -extern char* top_auto_testbench_verilog_file_postfix; -extern char* top_auto_preconf_testbench_verilog_file_postfix; -extern char* blif_testbench_verilog_file_postfix; -extern char* submodule_verilog_file_name; -extern char* logic_block_verilog_file_name; -extern char* luts_verilog_file_name; -extern char* routing_verilog_file_name; -extern char* sub_module_verilog_file_name; -extern char* muxes_verilog_file_name; -extern char* muxes_verilog_file_name; -extern char* wires_verilog_file_name; -extern char* essentials_verilog_file_name; -extern char* decoders_verilog_file_name; -extern char* verilog_mux_basis_posfix; -extern char* verilog_mux_special_basis_posfix; - -/* Prefix for subckt Verilog netlists */ -extern char* grid_verilog_file_name_prefix; -extern char* chanx_verilog_file_name_prefix; -extern char* chany_verilog_file_name_prefix; -extern char* sb_verilog_file_name_prefix; -extern char* cbx_verilog_file_name_prefix; -extern char* cby_verilog_file_name_prefix; - -extern t_spice_model* sram_verilog_model; -extern enum e_sram_orgz sram_verilog_orgz_type; -extern t_sram_orgz_info* sram_verilog_orgz_info; - -/* Input and Output Pad spice model. should be set as global */ -extern t_spice_model* inpad_verilog_model; -extern t_spice_model* outpad_verilog_model; -extern t_spice_model* iopad_verilog_model; - -/* Linked-list that stores all the configuration bits */ -extern t_llist* conf_bits_head; - -/* Linked-list that stores submodule Verilog file mames */ -extern t_llist* grid_verilog_subckt_file_path_head; -extern t_llist* routing_verilog_subckt_file_path_head; -extern t_llist* submodule_verilog_subckt_file_path_head; - - -extern int verilog_default_signal_init_value; - -enum e_dump_verilog_port_type { -VERILOG_PORT_INPUT, -VERILOG_PORT_OUTPUT, -VERILOG_PORT_INOUT, -VERILOG_PORT_WIRE, -VERILOG_PORT_REG, -VERILOG_PORT_CONKT -}; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.c deleted file mode 100644 index 94134c061..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.c +++ /dev/null @@ -1,403 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "rr_graph_swseg.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_globals.h" - -/* Include verilog support headers*/ -#include "verilog_global.h" -#include "verilog_utils.h" -#include "verilog_pbtypes.h" -#include "verilog_lut.h" - - -/***** Subroutines *****/ -void dump_verilog_pb_primitive_lut(FILE* fp, - char* subckt_prefix, - t_pb* prim_pb, - t_logical_block* mapped_logical_block, - t_pb_graph_node* cur_pb_graph_node, - int index, - t_spice_model* verilog_model, - int lut_status, - t_rr_node* pb_rr_graph) { - int i; - int* sram_bits = NULL; /* decoded SRAM bits */ - int truth_table_length = 0; - char** truth_table = NULL; - int lut_size = 0; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - int num_pb_type_input_port = 0; - t_port** pb_type_input_ports = NULL; - - int num_pb_type_output_port = 0; - t_port** pb_type_output_ports = NULL; - - char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* cur_pb_type = NULL; - char* port_prefix = NULL; - int cur_num_sram = 0; - int num_sram = 0; - /* For each SRAM, we could have multiple BLs/WLs */ - int num_bl_ports = 0; - t_spice_model_port** bl_port = NULL; - int num_wl_ports = 0; - t_spice_model_port** wl_port = NULL; - int num_bl_per_sram = 0; - int num_wl_per_sram = 0; - int num_conf_bits = 0; - int num_reserved_conf_bits = 0; - int cur_bl, cur_wl; - t_spice_model* mem_model = NULL; - - int num_lut_pin_nets; - int* lut_pin_net = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == cur_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - /* Asserts */ - assert(SPICE_MODEL_LUT == verilog_model->type); - - /* Check if this is an idle logical block mapped*/ - switch (lut_status) { - case PRIMITIVE_WIRED_LUT: - assert(NULL != pb_rr_graph); - if (NULL == mapped_logical_block) { - /* Get the mapped vpack_net_num of this physical LUT pb */ - get_mapped_lut_pb_input_pin_vpack_net_num(cur_pb_graph_node, pb_rr_graph, &num_lut_pin_nets, &lut_pin_net); - /* consider LUT pin remapping when assign lut truth tables */ - mapped_logical_block = &logical_block[get_pb_graph_node_wired_lut_logical_block_index(cur_pb_graph_node, pb_rr_graph)]; - /* Match truth table and post-routing results */ - truth_table = assign_post_routing_wired_lut_truth_table(mapped_logical_block, - num_lut_pin_nets, lut_pin_net, &truth_table_length); - } else { - /* Give a special truth table */ - assert (VPACK_COMB == mapped_logical_block->type); - /* Get the mapped vpack_net_num of this physical LUT pb */ - get_mapped_lut_pb_input_pin_vpack_net_num(cur_pb_graph_node, pb_rr_graph, &num_lut_pin_nets, &lut_pin_net); - /* consider LUT pin remapping when assign lut truth tables */ - /* Match truth table and post-routing results */ - truth_table = assign_post_routing_wired_lut_truth_table(mapped_logical_block, - num_lut_pin_nets, lut_pin_net, &truth_table_length); - } - break; - case PRIMITIVE_IDLE: - break; - case PRIMITIVE_NORMAL: - assert (NULL != mapped_logical_block); - /* Back-annotate to logical block */ - mapped_logical_block->mapped_spice_model = verilog_model; - mapped_logical_block->mapped_spice_model_index = verilog_model->cnt; - - assert (VPACK_COMB == mapped_logical_block->type); - /* Get the mapped vpack_net_num of this physical LUT pb */ - get_mapped_lut_pb_input_pin_vpack_net_num(cur_pb_graph_node, pb_rr_graph, &num_lut_pin_nets, &lut_pin_net); - /* consider LUT pin remapping when assign lut truth tables */ - /* Match truth table and post-routing results */ - truth_table = assign_post_routing_lut_truth_table(mapped_logical_block, - num_lut_pin_nets, lut_pin_net, &truth_table_length); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "(FILE:%s, [LINE%d]) Invalid status(=%d) for LUT!\n", - __FILE__, __LINE__, lut_status); - exit(1); - } - - /* Determine size of LUT*/ - input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - assert(1 == num_input_port); - assert(1 == num_output_port); - lut_size = input_ports[0]->size; - assert(1 == output_ports[0]->size); - /* Find SRAM ports */ - sram_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - assert(1 == num_sram_port); - /* Count the number of configuration bits */ - num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); - /* Get memory model */ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - - /* Find the number of BLs/WLs of each SRAM */ - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - /* Detect the SRAM SPICE model linked to this SRAM port */ - assert(NULL != sram_ports[0]->spice_model); - assert(SPICE_MODEL_SRAM == sram_ports[0]->spice_model->type); - find_bl_wl_ports_spice_model(sram_ports[0]->spice_model, - &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); - assert(1 == num_bl_ports); - assert(1 == num_wl_ports); - num_bl_per_sram = bl_port[0]->size; - num_wl_per_sram = wl_port[0]->size; - /* Asserts */ - assert(num_bl_per_sram == num_wl_per_sram); - break; - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Generate sram bits*/ - sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, - lut_size, sram_ports[0]->default_val); - - /* Print the subckts*/ - cur_pb_type = cur_pb_graph_node->pb_type; - - /* Comment lines */ - fprintf(fp, "//----- LUT Verilog module: %s%s_%d_ -----\n", - formatted_subckt_prefix, cur_pb_type->name, index); - - /* Simplify the prefix, make the SPICE netlist readable*/ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(cur_pb_type->name) + 1 + - strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s_%d_", cur_pb_type->name, index); - - /* Subckt definition*/ - fprintf(fp, "module %s%s_%d_ (", - formatted_subckt_prefix, cur_pb_type->name, index); - fprintf(fp, "\n"); - /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, TRUE)) { - fprintf(fp, ",\n"); - } - /* Print inputs, outputs, inouts, clocks, NO SRAMs*/ - dump_verilog_pb_type_ports(fp, port_prefix, 0, cur_pb_type, TRUE, TRUE); - /* Print SRAM ports */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, &cur_bl, &cur_wl); - /* connect to reserved BL/WLs ? */ - num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model, sram_verilog_orgz_info->type, 0); - /* Get the number of configuration bits required by this MUX */ - num_conf_bits = count_num_conf_bits_one_spice_model(verilog_model, sram_verilog_orgz_info->type, 0); - /* Reserved sram ports */ - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, num_reserved_conf_bits - 1, - VERILOG_PORT_INPUT); - if ( 0 < num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - /* Normal sram ports */ - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_conf_bits - 1, - VERILOG_PORT_INPUT); - /* Local Vdd and gnd*/ - fprintf(fp, ");\n"); - /* Definition ends*/ - - /* Specify inputs are wires */ - pb_type_input_ports = find_pb_type_ports_match_spice_model_port_type(cur_pb_type, SPICE_MODEL_PORT_INPUT, &num_pb_type_input_port); - assert(1 == num_pb_type_input_port); - fprintf(fp, "wire [0:%d] %s__%s;\n", - input_ports[0]->size - 1, port_prefix, pb_type_input_ports[0]->name); - for (i = 0; i < input_ports[0]->size; i++) { - fprintf(fp, "assign %s__%s[%d] = %s__%s_%d_;\n", - port_prefix, pb_type_input_ports[0]->name, i, - port_prefix, pb_type_input_ports[0]->name, i); - } - /* Specify outputs are wires */ - pb_type_output_ports = find_pb_type_ports_match_spice_model_port_type(cur_pb_type, SPICE_MODEL_PORT_OUTPUT, &num_pb_type_output_port); - assert(1 == num_pb_type_output_port); - fprintf(fp, "wire [0:%d] %s__%s;\n", - output_ports[0]->size - 1, port_prefix, pb_type_output_ports[0]->name); - for (i = 0; i < output_ports[0]->size; i++) { - fprintf(fp, "assign %s__%s_%d_ = %s__%s[%d];\n", - port_prefix, pb_type_output_ports[0]->name, i, - port_prefix, pb_type_output_ports[0]->name, i); - } - - /* Specify SRAM output are wires */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - dump_verilog_sram_config_bus_internal_wires(fp, sram_verilog_orgz_info, cur_num_sram, cur_num_sram + num_sram - 1); - /* - fprintf(fp, "wire [%d:%d] %s_out;\n", - cur_num_sram, cur_num_sram + num_sram - 1, mem_model->prefix); - fprintf(fp, "wire [%d:%d] %s_outb;\n", - cur_num_sram, cur_num_sram + num_sram - 1, mem_model->prefix); - */ - - num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - - /* Call LUT subckt*/ - fprintf(fp, "%s %s_%d_ (", verilog_model->name, verilog_model->prefix, verilog_model->cnt); - fprintf(fp, "\n"); - /* if we have to add global ports when dumping submodules of LUTs - * otherwise, the port map here does not match that of submodules - * Only dump the global ports belonging to a spice_model - * DISABLE recursive here ! - */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - /* Connect inputs*/ - /* Connect outputs*/ - fprintf(fp, "//----- Input and output ports -----\n"); - dump_verilog_pb_type_bus_ports(fp, port_prefix, 0, cur_pb_type, FALSE, TRUE); - fprintf(fp, "//----- SRAM ports -----\n"); - /* Connect srams: TODO: to find the SRAM model used by this Verilog model */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - /* TODO: switch depending on the type of configuration circuit */ - switch (sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - break; - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_sram_one_port(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_sram - 1, - 1, VERILOG_PORT_CONKT); - fprintf(fp, ", "); - dump_verilog_sram_one_outport(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_sram - 1, - 1, VERILOG_PORT_CONKT); - break; - case SPICE_SRAM_MEMORY_BANK: - dump_verilog_sram_one_outport(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_sram - 1, - 0, VERILOG_PORT_CONKT); - fprintf(fp, ", "); - dump_verilog_sram_one_outport(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_sram - 1, - 1, VERILOG_PORT_CONKT); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", - __FILE__, __LINE__); - exit(1); - } - /* vdd should be connected to special global wire gvdd_lut and gnd, - * Every LUT has a special VDD for statistics - */ - fprintf(fp, ");\n"); - - /* Print the encoding in SPICE netlist for debugging */ - if (NULL != mapped_logical_block) { - fprintf(fp, "//----- Truth Table for LUT node (%s). -----\n", - mapped_logical_block->name); - } - fprintf(fp, "//----- Truth Table for LUT[%d], size=%d. -----\n", - verilog_model->cnt, lut_size); - for (i = 0; i < truth_table_length; i++) { - fprintf(fp,"// %s \n", truth_table[i]); - } - - fprintf(fp, "//----- SRAM bits for LUT[%d], size=%d, num_sram=%d. -----\n", - verilog_model->cnt, lut_size, num_sram); - fprintf(fp, "//-----"); - fprint_commented_sram_bits(fp, num_sram, sram_bits); - fprintf(fp, "-----\n"); - - /* Decode the SRAM bits to BL/WL bits. */ - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - for (i = 0; i < num_sram; i++) { - /* TODO: should be more structural in coding !!! */ - /* Decode the SRAM bits to BL/WL bits. - * first half part is BL, the other half part is WL - */ - decode_and_add_verilog_sram_membank_conf_bit_to_llist(sram_verilog_orgz_info, cur_num_sram + i, - num_bl_per_sram, num_wl_per_sram, - sram_bits[i]); - } - /* NUM_SRAM is set to be consistent with number of BL/WLs - * TODO: NUM_SRAM should be the as they are. - * Should use another variable i.e., num_bl - */ - break; - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - /* Store the configuraion bit to linked-list */ - add_mux_conf_bits_to_llist(0, sram_verilog_orgz_info, - num_sram, sram_bits, - verilog_model); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Call SRAM subckts only - * when Configuration organization style is memory bank */ - /* No. of SRAMs is different from the number of configuration lines. - * Especially when SRAMs/RRAMs are configured with BL/WLs - */ - num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); - for (i = 0; i < num_sram; i++) { - /* Dump the configuration port bus */ - /*TODO: to be more smart!!! num_reserved_conf_bits and num_conf_bits/num_sram should be determined by each mem_bit */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - dump_verilog_mem_config_bus(fp, mem_model, sram_verilog_orgz_info, - cur_num_sram, num_reserved_conf_bits, num_conf_bits/num_sram); - /* This function should be called in the very end, - * because we update the counter of mem_model after each sram submodule is dumped !!! - */ - dump_verilog_sram_submodule(fp, sram_verilog_orgz_info, - mem_model); /* use the mem_model in sram_verilog_orgz_info */ - } - - /* End of subckt*/ - fprintf(fp, "endmodule\n"); - - /* Comment lines */ - fprintf(fp, "//----- END LUT Verilog module: %s%s_%d_ -----\n\n", - formatted_subckt_prefix, cur_pb_type->name, index); - - /* Update counter */ - verilog_model->cnt++; - - /*Free*/ - my_free(formatted_subckt_prefix); - my_free(input_ports); - my_free(output_ports); - my_free(sram_ports); - my_free(sram_bits); - my_free(port_prefix); - - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.h deleted file mode 100644 index 5167284e3..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_lut.h +++ /dev/null @@ -1,10 +0,0 @@ - -void dump_verilog_pb_primitive_lut(FILE* fp, - char* subckt_prefix, - t_pb* prim_pb, - t_logical_block* mapped_logical_block, - t_pb_graph_node* cur_pb_graph_node, - int index, - t_spice_model* spice_model, - int lut_status, - t_rr_node* pb_rr_graph); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.h deleted file mode 100644 index dcadc018f..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.h +++ /dev/null @@ -1,13 +0,0 @@ - -void dump_verilog_modelsim_autodeck(t_sram_orgz_info* cur_sram_orgz_info, - t_spice spice, - int num_operating_clock_cycles, - char* verilog_dir_formatted, - char* chomped_circuit_name, - char* simulator_ini_path, - boolean include_timing, - boolean init_sim, - boolean print_top_tb, - boolean print_top_auto_tb, - boolean tb_preconf); - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.c deleted file mode 100644 index c653791e8..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.c +++ /dev/null @@ -1,514 +0,0 @@ -/***********************************/ -/* SPICE Modeling for VPR */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "rr_graph_swseg.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_globals.h" - -/* Include verilog support headers*/ -#include "verilog_global.h" -#include "verilog_utils.h" -#include "verilog_pbtypes.h" -#include "verilog_primitives.h" - -/* Subroutines */ -void dump_verilog_pb_primitive_ff(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* verilog_model) { - int i; - - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_clock_port = 0; - t_spice_model_port** clock_ports = NULL; - - char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* prim_pb_type = NULL; - char* port_prefix = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find ports*/ - input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, FALSE); - output_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - clock_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, FALSE); - - /* Asserts */ - assert(3 == num_input_port); /* D, Set and Reset*/ - for (i = 0; i < num_input_port; i++) { - assert(1 == input_ports[i]->size); - } - assert(1 == num_output_port); - assert(1 == output_ports[0]->size); - assert(1 == num_clock_port); - assert(1 == clock_ports[0]->size); - - assert(SPICE_MODEL_FF == verilog_model->type); - - /* Initialize */ - prim_pb_type = prim_pb_graph_node->pb_type; - - /* Generate Subckt for pb_type*/ - /* - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, prim_pb_type->name, index); - */ - /* Simplify the port prefix, make SPICE netlist readable */ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s_%d_", prim_pb_type->name, index); - - - if (NULL != mapped_logical_block) { - fprintf(fp, "//----- Flip-flop Verilog module: %s -----\n", - mapped_logical_block->name); - } - /* Comment lines */ - fprintf(fp, "//----- Flip-flop Verilog module: %s%s -----\n", - formatted_subckt_prefix, port_prefix); - /* Definition line */ - fprintf(fp, "module %s%s (", formatted_subckt_prefix, port_prefix); - /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, TRUE)) { - fprintf(fp, ",\n"); - } - /* print ports*/ - dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, TRUE, FALSE); - /* Local vdd and gnd*/ - fprintf(fp, ");\n"); - /* Definition ends*/ - - /* Call the dff subckt*/ - fprintf(fp, "%s %s_%d_ (", verilog_model->name, verilog_model->prefix, verilog_model->cnt); - /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, TRUE)) { - fprintf(fp, ",\n"); - } - /* print ports*/ - dump_verilog_pb_type_ports(fp, port_prefix, 1, prim_pb_type, FALSE, FALSE); /* Use global clock for each DFF...*/ - - /* Local vdd and gnd, verilog_model name - * TODO: global vdd for ff - */ - fprintf(fp, ");\n"); - - /* Apply rising edge, and init value to the ff*/ - if (NULL != mapped_logical_block) { - /* Back-annotate to logical block */ - mapped_logical_block->mapped_spice_model = verilog_model; - mapped_logical_block->mapped_spice_model_index = verilog_model->cnt; - } - /* TODO: apply falling edge, initial value to FF!!!*/ - /*fprintf(fp, "\n");*/ - - /* End */ - fprintf(fp, "endmodule\n"); - - /* Comment lines */ - fprintf(fp, "//----- END Flip-flop Verilog module: %s%s -----\n\n", - formatted_subckt_prefix, port_prefix); - - verilog_model->cnt++; - - /*Free*/ - my_free(formatted_subckt_prefix); - my_free(port_prefix); - - return; -} - -/* Print hardlogic SPICE subckt*/ -void dump_verilog_pb_primitive_hardlogic(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* verilog_model) { - char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* prim_pb_type = NULL; - char* port_prefix = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Asserts */ - assert(SPICE_MODEL_HARDLOGIC == verilog_model->type); - - /* Initialize */ - prim_pb_type = prim_pb_graph_node->pb_type; - - /* Generate Subckt for pb_type*/ - /* - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, prim_pb_type->name, index); - */ - /* Simplify the port prefix, make SPICE netlist readable */ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s_%d_", prim_pb_type->name, index); - /* Comment lines */ - fprintf(fp, "//----- Hardlogic Verilog module: %s%s -----\n", - formatted_subckt_prefix, port_prefix); - /* Definition line */ - fprintf(fp, "module %s%s (", formatted_subckt_prefix, port_prefix); - fprintf(fp, "\n"); - /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, TRUE)) { - fprintf(fp, ",\n"); - } - /* print ports*/ - dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, TRUE, FALSE); - /* Local vdd and gnd*/ - fprintf(fp, ");\n"); - /* Definition ends*/ - - /* Back-annotate to logical block */ - if (NULL != mapped_logical_block) { - mapped_logical_block->mapped_spice_model = verilog_model; - mapped_logical_block->mapped_spice_model_index = verilog_model->cnt; - } - - /* Call the hardlogic subckt*/ - fprintf(fp, "%s %s_%d_ (", verilog_model->name, verilog_model->prefix, verilog_model->cnt); - fprintf(fp, "\n"); - /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, TRUE)) { - fprintf(fp, ",\n"); - } - /* print ports*/ - dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, FALSE, FALSE); - /* Local vdd and gnd, verilog_model name, - * Global vdd for hardlogic to split - */ - fprintf(fp, ");\n"); - - /* End */ - fprintf(fp, "endmodule\n"); - /* Comment lines */ - fprintf(fp, "//----- EDN Hardlogic Verilog module: %s%s -----\n", - formatted_subckt_prefix, port_prefix); - - verilog_model->cnt++; - - /*Free*/ - free(formatted_subckt_prefix); - free(port_prefix); - - return; -} - -/* Dump a I/O pad primitive node */ -void dump_verilog_pb_primitive_io(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* verilog_model) { - int num_pad_port = 0; /* INOUT port */ - t_spice_model_port** pad_ports = NULL; - int num_input_port = 0; - t_spice_model_port** input_ports = NULL; - int num_output_port = 0; - t_spice_model_port** output_ports = NULL; - int num_clock_port = 0; - t_spice_model_port** clock_ports = NULL; - int num_sram_port = 0; - t_spice_model_port** sram_ports = NULL; - - int i; - int num_sram = 0; - int* sram_bits = NULL; - - char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - t_pb_type* prim_pb_type = NULL; - char* port_prefix = NULL; - - /* For each SRAM, we could have multiple BLs/WLs */ - int num_bl_ports = 0; - t_spice_model_port** bl_port = NULL; - int num_wl_ports = 0; - t_spice_model_port** wl_port = NULL; - int num_bl_per_sram = 0; - int num_wl_per_sram = 0; - int expected_num_sram; - - int cur_num_sram = 0; - int num_conf_bits = 0; - int num_reserved_conf_bits = 0; - t_spice_model* mem_model = NULL; - int cur_bl, cur_wl; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure a valid pb_graph_node */ - if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find ports*/ - pad_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INOUT, &num_pad_port, TRUE); - input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - clock_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, TRUE); - sram_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); - - /* Asserts */ - assert(SPICE_MODEL_IOPAD == verilog_model->type); /* Support IO PAD which matches the physical design */ - - /* Initialize */ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - - prim_pb_type = prim_pb_graph_node->pb_type; - - /* Generate Subckt for pb_type*/ - /* Simplify the port prefix, make SPICE netlist readable */ - port_prefix = (char*)my_malloc(sizeof(char)* - (strlen(prim_pb_type->name) + 1 - + strlen(my_itoa(index)) + 1 + 1)); - sprintf(port_prefix, "%s_%d_", prim_pb_type->name, index); - /* Comment lines */ - fprintf(fp, "//----- IO Verilog module: %s%s -----\n", - formatted_subckt_prefix, port_prefix); - /* Definition line */ - fprintf(fp, "module %s%s (", formatted_subckt_prefix, port_prefix); - fprintf(fp, "\n"); - /* Only dump the global ports belonging to a spice_model - */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, TRUE)) { - fprintf(fp, ",\n"); - } - - /* TODO: assert this is physical mode */ - assert((1 == num_sram_port)&&(NULL != sram_ports)&&(1 == sram_ports[0]->size)); - num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); - /* Get current counter of mem_bits, bl and wl */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, &cur_bl, &cur_wl); - /* print ports --> input ports */ - dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, TRUE, TRUE); - /* Print output port */ - fprintf(fp, "inout [%d:%d] %s%s\n", - verilog_model->cnt, verilog_model->cnt, - gio_inout_prefix, verilog_model->prefix); - /* Print SRAM ports */ - /* connect to reserved BL/WLs ? */ - num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model, sram_verilog_orgz_info->type, 0); - /* Get the number of configuration bits required by this MUX */ - num_conf_bits = count_num_conf_bits_one_spice_model(verilog_model, sram_verilog_orgz_info->type, 0); - /* Reserved sram ports */ - if (0 < num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, num_reserved_conf_bits - 1, - VERILOG_PORT_INPUT); - /* Normal sram ports */ - if (0 < num_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_sram - 1, - VERILOG_PORT_INPUT); - /* Local vdd and gnd*/ - fprintf(fp, ");\n"); - - dump_verilog_sram_config_bus_internal_wires(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram + num_sram - 1); - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - /* Local wires */ - /* Find the number of BLs/WLs of each SRAM */ - /* Detect the SRAM SPICE model linked to this SRAM port */ - assert(NULL != sram_ports[0]->spice_model); - assert(SPICE_MODEL_SRAM == sram_ports[0]->spice_model->type); - find_bl_wl_ports_spice_model(sram_ports[0]->spice_model, - &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); - assert(1 == num_bl_ports); - assert(1 == num_wl_ports); - num_bl_per_sram = bl_port[0]->size; - num_wl_per_sram = wl_port[0]->size; - break; - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", - __FILE__, __LINE__); - exit(1); - } - /* Definition ends*/ - - /* Dump the configuration port bus */ - dump_verilog_mem_config_bus(fp, mem_model, sram_verilog_orgz_info, - cur_num_sram, num_reserved_conf_bits, num_conf_bits); - - /* Call the I/O subckt*/ - fprintf(fp, "%s %s_%d_ (", verilog_model->name, verilog_model->prefix, verilog_model->cnt); - fprintf(fp, "\n"); - /* Only dump the global ports belonging to a spice_model - * Disable recursive here ! - */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - - /* assert */ - assert((1 == num_sram_port)&&(NULL != sram_ports)&&(1 == sram_ports[0]->size)); - num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); - /* print ports --> input ports */ - dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, FALSE, TRUE); - /* Print inout port */ - fprintf(fp, "%s%s[%d], ", gio_inout_prefix, - verilog_model->prefix, verilog_model->cnt); - /* Print SRAM ports */ - /* Connect srams: TODO: to find the SRAM model used by this Verilog model */ - dump_verilog_sram_one_outport(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram, - 0, VERILOG_PORT_CONKT); - fprintf(fp, ", "); - dump_verilog_sram_one_outport(fp, sram_verilog_orgz_info, - cur_num_sram, cur_num_sram, - 1, VERILOG_PORT_CONKT); - - /* Local vdd and gnd, verilog_model name, - * TODO: Global vdd for i/o pad to split? - */ - fprintf(fp, ");\n"); - - /* Call SRAM subckt */ - assert((1 == num_sram_port)&&(NULL != sram_ports)&&(1 == sram_ports[0]->size)); - /* what is the SRAM bit of a mode? */ - /* If logical block is not NULL, we need to decode the sram bit */ - if (NULL != mapped_logical_block) { - assert(NULL != mapped_logical_block->pb->pb_graph_node->pb_type->mode_bits); - sram_bits = decode_mode_bits(mapped_logical_block->pb->pb_graph_node->pb_type->mode_bits, &expected_num_sram); - assert(expected_num_sram == num_sram); - } else { - /* Initialize */ - sram_bits = (int*)my_calloc(num_sram, sizeof(int)); - for (i = 0; i < num_sram; i++) { - sram_bits[i] = sram_ports[0]->default_val; - } - } - /* SRAM_bit will be later reconfigured according to operating mode */ - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_MEMORY_BANK: - for (i = 0; i < num_sram; i++) { - /* Decode the SRAM bits to BL/WL bits. - * first half part is BL, the other half part is WL - */ - decode_and_add_verilog_sram_membank_conf_bit_to_llist(sram_verilog_orgz_info, cur_num_sram + i, - num_bl_per_sram, num_wl_per_sram, - sram_bits[i]); - } - break; - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - /* Store the configuraion bit to linked-list */ - add_mux_conf_bits_to_llist(0, sram_verilog_orgz_info, - num_sram, sram_bits, - verilog_model); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", - __FILE__, __LINE__); - exit(1); - } - /* Call SRAM subckts only - * when Configuration organization style is memory bank */ - num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); - for (i = 0; i < num_sram; i++) { - dump_verilog_sram_submodule(fp, sram_verilog_orgz_info, - mem_model); /* use the mem_model in sram_verilog_orgz_info */ - } - - /* End */ - fprintf(fp, "endmodule\n"); - /* Comment lines */ - fprintf(fp, "//----- END IO Verilog module: %s%s -----\n\n", - formatted_subckt_prefix, port_prefix); - - /* Back-annotate to logical block */ - if (NULL != mapped_logical_block) { - mapped_logical_block->mapped_spice_model = verilog_model; - mapped_logical_block->mapped_spice_model_index = verilog_model->cnt; - } - - /* Update the verilog_model counter */ - verilog_model->cnt++; - - /*Free*/ - free(formatted_subckt_prefix); - free(port_prefix); - my_free(input_ports); - my_free(output_ports); - my_free(pad_ports); - my_free(clock_ports); - my_free(sram_ports); - my_free(sram_bits); - - return; -} - - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.h deleted file mode 100644 index 26afa752a..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_primitives.h +++ /dev/null @@ -1,22 +0,0 @@ - -void dump_verilog_pb_primitive_ff(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model); - - -void dump_verilog_pb_primitive_hardlogic(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model); - -void dump_verilog_pb_primitive_io(FILE* fp, - char* subckt_prefix, - t_logical_block* mapped_logical_block, - t_pb_graph_node* prim_pb_graph_node, - int index, - t_spice_model* spice_model); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.h deleted file mode 100644 index bb03b98ec..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.h +++ /dev/null @@ -1,87 +0,0 @@ - -void dump_verilog_routing_chan_subckt(FILE* fp, - int x, int y, t_rr_type chan_type, - int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices, - int num_segment, t_segment_inf* segments); - -void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, - int pin_index, int side, - int x, int y, - boolean dump_port_type); - -void dump_verilog_grid_side_pins(FILE* fp, - t_rr_type pin_type, int x, int y, int side, - boolean dump_port_type); - -void dump_verilog_switch_box_chan_port(FILE* fp, - t_sb* cur_sb_info, - int chan_side, - t_rr_node* cur_rr_node, - enum PORTS cur_rr_node_direction); - -void dump_verilog_switch_box_short_interc(FILE* fp, - t_sb* cur_sb_info, - int chan_side, - t_rr_node* cur_rr_node, - int actual_fan_in, - t_rr_node* drive_rr_node); - -void dump_verilog_switch_box_mux(FILE* fp, - t_sb* cur_sb_info, - int chan_side, - t_rr_node* cur_rr_node, - int mux_size, - t_rr_node** drive_rr_nodes, - int switch_index); - -int count_verilog_switch_box_interc_conf_bits(t_sb cur_sb_info, int chan_side, - t_rr_node* cur_rr_node); - -int count_verilog_switch_box_interc_reserved_conf_bits(t_sb cur_sb_info, int chan_side, - t_rr_node* cur_rr_node); - -void dump_verilog_switch_box_interc(FILE* fp, - t_sb* cur_sb_info, - int chan_side, - t_rr_node* cur_rr_node); - -int count_verilog_switch_box_reserved_conf_bits(t_sb cur_sb_info); -int count_verilog_switch_box_conf_bits(t_sb cur_sb_info); - -void dump_verilog_routing_switch_box_subckt(FILE* fp, t_sb* cur_sb_info, - int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices); - -void dump_verilog_connection_box_short_interc(FILE* fp, - t_cb* cur_cb_info, - t_rr_node* src_rr_node); - -void dump_verilog_connection_box_mux(FILE* fp, - t_cb* cur_cb_info, - t_rr_node* src_rr_node); - -void dump_verilog_connection_box_interc(FILE* fp, - t_cb* cur_cb_info, - t_rr_node* src_rr_node); - - -int count_verilog_connection_box_interc_conf_bits(t_rr_node* cur_rr_node); -int count_verilog_connection_box_interc_reserved_conf_bits(t_rr_node* cur_rr_node); -int count_verilog_connection_box_one_side_conf_bits(int num_ipin_rr_nodes, - t_rr_node** ipin_rr_node); -int count_verilog_connection_box_one_side_reserved_conf_bits(int num_ipin_rr_nodes, - t_rr_node** ipin_rr_node); -int count_verilog_connection_box_conf_bits(t_cb* cur_cb_info); -int count_verilog_connection_box_reserved_conf_bits(t_cb* cur_cb_info); - -void dump_verilog_routing_connection_box_subckt(FILE* fp, t_cb* cur_cb_info, - int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices); - -void dump_verilog_routing_resources(char* subckt_dir, - t_arch arch, - t_det_routing_arch* routing_arch, - int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices); - diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.h deleted file mode 100644 index 5fa6bff1e..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.h +++ /dev/null @@ -1,6 +0,0 @@ - -void dump_verilog_submodules(char* submodule_dir, - t_arch Arch, - t_det_routing_arch* routing_arch, - boolean include_timing, - boolean init_sim); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.c b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.c deleted file mode 100644 index b93540fc3..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.c +++ /dev/null @@ -1,2962 +0,0 @@ -/***********************************/ -/* Dump Synthesizable Veriolog */ -/* Xifan TANG, EPFL/LSI */ -/***********************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include vpr structs*/ -#include "util.h" -#include "physical_types.h" -#include "vpr_types.h" -#include "globals.h" -#include "rr_graph.h" -#include "vpr_utils.h" - -/* Include spice support headers*/ -#include "read_xml_spice_util.h" -#include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "fpga_spice_globals.h" -#include "fpga_spice_bitstream.h" - -/* Include verilog support headers*/ -#include "verilog_global.h" -#include "verilog_utils.h" -#include "verilog_routing.h" -#include "verilog_pbtypes.h" -#include "verilog_decoder.h" -#include "verilog_top_netlist.h" - - -/* Global varaiable only accessible in this source file*/ -static char* top_netlist_bl_enable_port_name = "en_bl"; -static char* top_netlist_wl_enable_port_name = "en_wl"; -static char* top_netlist_bl_data_in_port_name = "data_in"; -static char* top_netlist_addr_bl_port_name = "addr_bl"; -static char* top_netlist_addr_wl_port_name = "addr_wl"; -static char* top_netlist_array_bl_port_name = "bl_bus"; -static char* top_netlist_array_wl_port_name = "wl_bus"; -static char* top_netlist_array_blb_port_name = "blb_bus"; -static char* top_netlist_array_wlb_port_name = "wlb_bus"; -static char* top_netlist_reserved_bl_port_postfix = "_reserved_bl"; -static char* top_netlist_reserved_wl_port_postfix = "_reserved_wl"; -static char* top_netlist_normal_bl_port_postfix = "_bl"; -static char* top_netlist_normal_wl_port_postfix = "_wl"; -static char* top_netlist_normal_blb_port_postfix = "_blb"; -static char* top_netlist_normal_wlb_port_postfix = "_wlb"; -static char* top_netlist_scan_chain_head_prefix = "sc_in"; - - -static char* top_tb_reset_port_name = "greset"; -static char* top_tb_set_port_name = "gset"; -static char* top_tb_prog_reset_port_name = "prog_reset"; -static char* top_tb_prog_set_port_name = "prog_set"; -static char* top_tb_config_done_port_name = "config_done"; -static char* top_tb_op_clock_port_name = "op_clock"; -static char* top_tb_prog_clock_port_name = "prog_clock"; -static char* top_tb_inout_reg_postfix = "_reg"; -static char* top_tb_clock_reg_postfix = "_reg"; - -/* Local Subroutines declaration */ - -/******** Subroutines ***********/ - -static -void dump_verilog_top_netlist_memory_bank_ports(FILE* fp, - enum e_dump_verilog_port_type dump_port_type) { - t_spice_model* mem_model = NULL; - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - char split_sign; - - split_sign = determine_verilog_generic_port_split_sign(dump_port_type); - - /* Only accept two types of dump_port_type here! */ - assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); - - /* Check */ - assert (sram_verilog_orgz_info->type == SPICE_SRAM_MEMORY_BANK); - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Depending on the memory technology*/ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - assert(NULL != mem_model); - - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - /* Depend on the memory technology */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_bl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- BL enable port \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_wl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- WL enable port \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_bl_data_in_port_name, 0, 0); - fprintf(fp, "%c //--- BL data input port \n", split_sign); - break; - case SPICE_MODEL_DESIGN_RRAM: - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_bl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- BL enable port \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_wl_enable_port_name, 0, 0); - fprintf(fp, "%c //--- WL enable port \n", split_sign); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); - fprintf(fp, "%c //--- Address of bit lines \n", split_sign); - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); - fprintf(fp, " //--- Address of word lines \n"); - - return; -} - -/* Connect BLs and WLs to configuration bus in the top-level Verilog netlist*/ -static -void dump_verilog_top_netlist_memory_bank_internal_wires(FILE* fp) { - t_spice_model* mem_model = NULL; - int iinv, icol, irow; - int num_bl, num_wl; - int num_array_bl, num_array_wl; - int num_reserved_bl, num_reserved_wl; - int cur_bl_lsb, cur_wl_lsb; - int cur_bl_msb, cur_wl_msb; - int bl_decoder_size, wl_decoder_size; - int num_blb_ports, num_wlb_ports; - t_spice_model_port** blb_port = NULL; - t_spice_model_port** wlb_port = NULL; - t_spice_model* blb_inv_spice_model = NULL; - t_spice_model* wlb_inv_spice_model = NULL; - - /* Check */ - assert (sram_verilog_orgz_info->type == SPICE_SRAM_MEMORY_BANK); - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Depending on the memory technology*/ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - assert(NULL != mem_model); - - /* Get the total number of BLs and WLs */ - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, &num_bl, &num_wl); - /* Get the reserved BLs and WLs */ - get_sram_orgz_info_reserved_blwl(sram_verilog_orgz_info, &num_reserved_bl, &num_reserved_wl); - - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - /* Get BLB and WLB ports */ - find_blb_wlb_ports_spice_model(mem_model, &num_blb_ports, &blb_port, - &num_wlb_ports, &wlb_port); - /* Get inverter spice_model */ - - /* Important!!!: - * BL/WL should always start from LSB to MSB! - * In order to follow this convention in primitive nodes. - */ - /* No. of BLs and WLs in the array */ - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - top_netlist_array_bl_port_name, 0, num_array_bl - 1); - fprintf(fp, "; //--- Array Bit lines bus \n"); - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - top_netlist_array_wl_port_name, 0, num_array_wl - 1); - fprintf(fp, "; //--- Array Bit lines bus \n"); - if (1 == num_blb_ports) { - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - top_netlist_array_blb_port_name, 0, num_array_bl - 1); - fprintf(fp, "; //--- Inverted Array Bit lines bus \n"); - } - if (1 == num_wlb_ports) { - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - top_netlist_array_wlb_port_name, 0, num_array_wl - 1); - fprintf(fp, "; //--- Inverted Array Word lines bus \n"); - } - fprintf(fp, "\n"); - - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - assert( 0 == num_reserved_bl ); - assert( 0 == num_reserved_wl ); - /* SRAMs are place in an array - * BLs of SRAMs in the same column are connected to a common BL - * BLs of SRAMs in the same row are connected to a common WL - */ - /* Declare wires */ - fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Bit lines \n", - 0, num_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); - fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Word lines \n", - 0, num_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); - /* Declare inverted wires if needed */ - if (1 == num_blb_ports) { - fprintf(fp, " wire [%d:%d] %s%s; //---- Inverted Normal Bit lines \n", - 0, num_bl - 1, mem_model->prefix, top_netlist_normal_blb_port_postfix); - /* get inv_spice_model */ - blb_inv_spice_model = blb_port[0]->inv_spice_model; - /* Make an inversion of the BL */ - for (iinv = 0; iinv < num_array_bl - 1; iinv++) { - fprintf(fp, " %s %s_blb_%d (%s[%d], %s[%d]);\n", - blb_inv_spice_model->name, blb_inv_spice_model->prefix, - iinv, - top_netlist_array_bl_port_name, iinv, - top_netlist_array_blb_port_name, iinv); - } - } - if (1 == num_wlb_ports) { - fprintf(fp, " wire [%d:%d] %s%s; //---- Inverted Normal Word lines \n", - 0, num_wl - 1, mem_model->prefix, top_netlist_normal_wlb_port_postfix); - /* get inv_spice_model */ - wlb_inv_spice_model = wlb_port[0]->inv_spice_model; - /* Make an inversion of the WL */ - for (iinv = 0; iinv < num_array_wl - 1; iinv++) { - fprintf(fp, " %s %s_wlb_%d (%s[%d], %s[%d]);\n", - wlb_inv_spice_model->name, wlb_inv_spice_model->prefix, - iinv, - top_netlist_array_wl_port_name, iinv, - top_netlist_array_wlb_port_name, iinv); - } - } - /* Connections for columns */ - for (icol = 0; icol < num_array_bl; icol++) { - cur_bl_lsb = icol * num_array_bl; - cur_bl_msb = (icol + 1) * num_array_bl - 1; - /* Check if the msb exceeds the upbound of num_bl */ - if (cur_bl_msb > num_bl - 1) { - cur_bl_msb = num_bl - 1; - } - /* connect to the BLs of all the SRAMs in the column */ - fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", - mem_model->prefix, top_netlist_normal_bl_port_postfix, cur_bl_lsb, cur_bl_msb, - top_netlist_array_bl_port_name, 0, cur_bl_msb - cur_bl_lsb); - if (1 == num_blb_ports) { - fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", - mem_model->prefix, top_netlist_normal_blb_port_postfix, cur_bl_lsb, cur_bl_msb, - top_netlist_array_blb_port_name, 0, cur_bl_msb - cur_bl_lsb); - } - /* Finish if MSB meets the upbound */ - if (cur_bl_msb == num_bl - 1) { - break; - } - } - /* Connections for rows */ - for (irow = 0; irow < num_array_wl; irow++) { - cur_wl_lsb = irow * num_array_wl; - cur_wl_msb = (irow + 1) * num_array_wl - 1; - /* Check if the msb exceeds the upbound of num_bl */ - if (cur_wl_msb > num_wl - 1) { - cur_wl_msb = num_wl - 1; - } - /* connect to the BLs of all the SRAMs in the column */ - for (icol = cur_wl_lsb; icol < cur_wl_msb + 1; icol++) { - fprintf(fp, " assign %s%s[%d] = %s[%d];\n", - mem_model->prefix, top_netlist_normal_wl_port_postfix, icol, - top_netlist_array_wl_port_name, irow); - if (1 == num_wlb_ports) { - fprintf(fp, " assign %s%s[%d] = %s[%d];\n", - mem_model->prefix, top_netlist_normal_wlb_port_postfix, icol, - top_netlist_array_wlb_port_name, irow); - } - } - /* Finish if MSB meets the upbound */ - if (cur_wl_msb == num_wl - 1) { - break; - } - } - break; - case SPICE_MODEL_DESIGN_RRAM: - /* Check: there should be reserved BLs and WLs */ - assert( 0 < num_reserved_bl ); - assert( 0 < num_reserved_wl ); - /* Declare reserved and normal conf_bits ports */ - fprintf(fp, " wire [0:%d] %s%s; //---- Reserved Bit lines \n", - num_reserved_bl - 1, mem_model->prefix, top_netlist_reserved_bl_port_postfix); - fprintf(fp, " wire [0:%d] %s%s; //---- Reserved Word lines \n", - num_reserved_wl - 1, mem_model->prefix, top_netlist_reserved_wl_port_postfix); - fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Bit lines \n", - num_reserved_bl, num_array_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); - fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Word lines \n", - num_reserved_wl, num_array_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); - /* Connect reserved conf_bits and normal conf_bits to the bus */ - fprintf(fp, " assign %s%s[0:%d] = %s[0:%d];\n", - mem_model->prefix, top_netlist_reserved_bl_port_postfix, num_reserved_bl - 1, - top_netlist_array_bl_port_name, num_reserved_bl - 1); - fprintf(fp, " assign %s%s[0:%d] = %s[0:%d];\n", - mem_model->prefix, top_netlist_reserved_wl_port_postfix, num_reserved_wl - 1, - top_netlist_array_wl_port_name, num_reserved_wl - 1); - fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", - mem_model->prefix, top_netlist_normal_bl_port_postfix, num_reserved_bl, num_array_bl - 1, - top_netlist_array_bl_port_name, num_reserved_bl, num_array_bl - 1); - fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", - mem_model->prefix, top_netlist_normal_wl_port_postfix, num_reserved_wl, num_array_wl - 1, - top_netlist_array_wl_port_name, num_reserved_wl, num_array_wl - 1); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* Delcare primary inputs/outputs for scan-chains in the top-level netlists - */ -static -void dump_verilog_top_netlist_scan_chain_ports(FILE* fp, - enum e_dump_verilog_port_type dump_port_type) { - /* Only accept two types of dump_port_type here! */ - assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); - - /* Check */ - assert (sram_verilog_orgz_info->type == SPICE_SRAM_SCAN_CHAIN); - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Only the head of scan-chain will be the primary input in the top-level netlist - * TODO: we may have multiple scan-chains, their heads will be the primary outputs - */ - dump_verilog_generic_port(fp, dump_port_type, - top_netlist_scan_chain_head_prefix, 0, 0); - fprintf(fp, " //---- Scan-chain head \n"); - - return; -} - -/* Connect scan-chain flip-flops in the top-level netlist */ -static -void dump_verilog_top_netlist_scan_chain_internal_wires(FILE* fp) { - t_spice_model* scff_mem_model = NULL; - int iscff, num_scffs; - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - num_scffs = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &scff_mem_model); - /* Check */ - assert( SPICE_MODEL_SCFF == scff_mem_model->type ); - - /* Delcare local wires */ - fprintf(fp, " wire [0:%d] %s_scff_in;\n", - num_scffs - 1, scff_mem_model->prefix); - - fprintf(fp, " wire [0:%d] %s_scff_out;\n", - num_scffs - 1, scff_mem_model->prefix); - - /* Exception for head: connect to primary inputs */ - fprintf(fp, " assign %s_scff_in[%d] = %s;\n", - scff_mem_model->prefix, 0, - top_netlist_scan_chain_head_prefix); - - /* Connected the scan-chain flip-flops */ - /* Ensure we are in the correct range */ - /* - fprintf(fp, " genvar i;\n"); - fprintf(fp, " generate\n"); - fprintf(fp, " for (i = %d; i < %d; i = i + 1) begin\n", - 1, num_scffs - 1); - fprintf(fp, "assign %s_scff_in[i] = %s_scff_out[i - 1];\n", - scff_mem_model->prefix, - scff_mem_model->prefix); - fprintf(fp, " end\n"); - fprintf(fp, " endgenerate;\n"); - */ - - return; -} - -/* Dump ports for the top-level module in Verilog netlist */ -static -void dump_verilog_top_module_ports(FILE* fp, - enum e_dump_verilog_port_type dump_port_type) { - char* port_name = NULL; - char split_sign; - enum e_dump_verilog_port_type actual_dump_port_type; - boolean dump_global_port_type = FALSE; - - split_sign = determine_verilog_generic_port_split_sign(dump_port_type); - - /* Only accept two types of dump_port_type here! */ - assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); - - if (VERILOG_PORT_INPUT == dump_port_type) { - dump_global_port_type = TRUE; - } - - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, dump_global_port_type)) { - fprintf(fp, "%c\n", split_sign); - } - /* Inputs and outputs of I/O pads */ - /* Inout Pads */ - assert(NULL != iopad_verilog_model); - if ((NULL == iopad_verilog_model) - ||(iopad_verilog_model->cnt > 0)) { - actual_dump_port_type = VERILOG_PORT_CONKT; - if (VERILOG_PORT_INPUT == dump_port_type) { - actual_dump_port_type = VERILOG_PORT_INOUT; - } - /* Malloc and assign port_name */ - port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); - sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); - /* Dump a register port */ - dump_verilog_generic_port(fp, actual_dump_port_type, - port_name, iopad_verilog_model->cnt - 1, 0); - fprintf(fp, "%c //---FPGA inouts \n", split_sign); - /* Free port_name */ - my_free(port_name); - } - - /* Configuration ports depend on the organization of SRAMs */ - switch(sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - dump_verilog_generic_port(fp, dump_port_type, - sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); - fprintf(fp, " //--- SRAM outputs \n"); - /* Definition ends */ - break; - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_top_netlist_scan_chain_ports(fp, dump_port_type); - /* Definition ends */ - break; - case SPICE_SRAM_MEMORY_BANK: - dump_verilog_top_netlist_memory_bank_ports(fp, dump_port_type); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - - -/* Dump ports for the top-level Verilog netlist */ -static -void dump_verilog_top_netlist_ports(FILE* fp, - int num_clocks, - char* circuit_name, - t_spice verilog) { - - /* A valid file handler */ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - fprintf(fp, "//----- Top-level Verilog Module -----\n"); - fprintf(fp, "module %s_top (\n", circuit_name); - fprintf(fp, "\n"); - - dump_verilog_top_module_ports(fp, VERILOG_PORT_INPUT); - - fprintf(fp, ");\n"); - - return; -} - - -static -void dump_verilog_top_netlist_internal_wires(FILE* fp) { - /* Configuration ports depend on the organization of SRAMs */ - switch(sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - /* Definition ends */ - break; - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_top_netlist_scan_chain_internal_wires(fp); - /* Definition ends */ - break; - case SPICE_SRAM_MEMORY_BANK: - dump_verilog_top_netlist_memory_bank_internal_wires(fp); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -static -void dump_verilog_defined_one_grid(FILE* fp, - int ix, int iy) { - /* Comment lines */ - fprintf(fp, "//----- BEGIN Call Grid[%d][%d] module -----\n", ix, iy); - /* Print the Grid module */ - fprintf(fp, "grid_%d__%d_ ", ix, iy); /* Call the name of subckt */ - fprintf(fp, "grid_%d__%d__0_ ", ix, iy); - fprintf(fp, "("); - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - - if (IO_TYPE == grid[ix][iy].type) { - dump_verilog_io_grid_pins(fp, ix, iy, 1, FALSE, FALSE); - } else { - dump_verilog_grid_pins(fp, ix, iy, 1, FALSE, FALSE); - } - - /* IO PAD */ - dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, - iopad_verilog_model->grid_index_low[ix][iy], - iopad_verilog_model->grid_index_high[ix][iy] - 1, - VERILOG_PORT_CONKT); - - /* Print configuration ports */ - /* Reserved configuration ports */ - if (0 < sram_verilog_orgz_info->grid_reserved_conf_bits[ix][iy]) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, - sram_verilog_orgz_info->grid_reserved_conf_bits[ix][iy] - 1, - VERILOG_PORT_CONKT); - /* Normal configuration ports */ - if (0 < (sram_verilog_orgz_info->grid_conf_bits_msb[ix][iy] - - sram_verilog_orgz_info->grid_conf_bits_lsb[ix][iy])) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - sram_verilog_orgz_info->grid_conf_bits_lsb[ix][iy], - sram_verilog_orgz_info->grid_conf_bits_msb[ix][iy] - 1, - VERILOG_PORT_CONKT); - fprintf(fp, ");\n"); - /* Comment lines */ - fprintf(fp, "//----- END call Grid[%d][%d] module -----\n\n", ix, iy); - - return; -} - - -/***** Print (call) the defined grids *****/ -static -void dump_verilog_defined_grids(FILE* fp) { - int ix, iy; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Normal Grids */ - for (ix = 1; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - /* Bypass EMPTY grid */ - if (EMPTY_TYPE == grid[ix][iy].type) { - continue; - } - assert(IO_TYPE != grid[ix][iy].type); - dump_verilog_defined_one_grid(fp, ix, iy); - } - } - - /* IO Grids */ - /* LEFT side */ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { - /* Bypass EMPTY grid */ - if (EMPTY_TYPE == grid[ix][iy].type) { - continue; - } - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_defined_one_grid(fp, ix, iy); - } - - /* RIGHT side */ - ix = nx + 1; - for (iy = 1; iy < (ny + 1); iy++) { - /* Bypass EMPTY grid */ - if (EMPTY_TYPE == grid[ix][iy].type) { - continue; - } - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_defined_one_grid(fp, ix, iy); - } - - /* BOTTOM side */ - iy = 0; - for (ix = 1; ix < (nx + 1); ix++) { - /* Bypass EMPTY grid */ - if (EMPTY_TYPE == grid[ix][iy].type) { - continue; - } - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_defined_one_grid(fp, ix, iy); - } - - /* TOP side */ - iy = ny + 1; - for (ix = 1; ix < (nx + 1); ix++) { - /* Bypass EMPTY grid */ - if (EMPTY_TYPE == grid[ix][iy].type) { - continue; - } - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_defined_one_grid(fp, ix, iy); - } - - return; -} - -/* Call defined channels. - * Ensure the port name here is co-herent to other sub-circuits(SB,CB,grid)!!! - */ -static -void dump_verilog_defined_one_channel(FILE* fp, - t_rr_type chan_type, int x, int y, - int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices) { - int itrack; - int chan_width = 0; - t_rr_node** chan_rr_nodes = NULL; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Check */ - assert((CHANX == chan_type)||(CHANY == chan_type)); - /* check x*/ - assert((!(0 > x))&&(x < (nx + 1))); - /* check y*/ - assert((!(0 > y))&&(y < (ny + 1))); - - /* Collect rr_nodes for Tracks for chanx[ix][iy] */ - chan_rr_nodes = get_chan_rr_nodes(&chan_width, chan_type, x, y, - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); - - /* Comment lines */ - switch (chan_type) { - case CHANX: - fprintf(fp, "//----- BEGIN Call Channel-X [%d][%d] module -----\n", x, y); - break; - case CHANY: - fprintf(fp, "//----- BEGIN call Channel-Y [%d][%d] module -----\n\n", x, y); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid Channel Type!\n", __FILE__, __LINE__); - exit(1); - } - - /* Call the define sub-circuit */ - fprintf(fp, "%s_%d__%d_ ", - convert_chan_type_to_string(chan_type), - x, y); - fprintf(fp, "%s_%d__%d__0_ ", - convert_chan_type_to_string(chan_type), - x, y); - fprintf(fp, "("); - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - - /* LEFT/BOTTOM side port of CHANX/CHANY */ - /* We apply an opposite port naming rule than function: fprint_routing_chan_subckt - * In top-level netlists, we follow the same port name as switch blocks and connection blocks - * When a track is in INC_DIRECTION, the LEFT/BOTTOM port would be an output of a switch block - * When a track is in DEC_DIRECTION, the LEFT/BOTTOM port would be an input of a switch block - */ - for (itrack = 0; itrack < chan_width; itrack++) { - switch (chan_rr_nodes[itrack]->direction) { - case INC_DIRECTION: - fprintf(fp, "%s_%d__%d__out_%d_, ", - convert_chan_type_to_string(chan_type), - x, y, itrack); - fprintf(fp, "\n"); - break; - case DEC_DIRECTION: - fprintf(fp, "%s_%d__%d__in_%d_, ", - convert_chan_type_to_string(chan_type), - x, y, itrack); - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of %s[%d][%d]_track[%d]!\n", - __FILE__, __LINE__, - convert_chan_type_to_string(chan_type), - x, y, itrack); - exit(1); - } - } - /* RIGHT/TOP side port of CHANX/CHANY */ - /* We apply an opposite port naming rule than function: fprint_routing_chan_subckt - * In top-level netlists, we follow the same port name as switch blocks and connection blocks - * When a track is in INC_DIRECTION, the RIGHT/TOP port would be an input of a switch block - * When a track is in DEC_DIRECTION, the RIGHT/TOP port would be an output of a switch block - */ - for (itrack = 0; itrack < chan_width; itrack++) { - switch (chan_rr_nodes[itrack]->direction) { - case INC_DIRECTION: - fprintf(fp, "%s_%d__%d__in_%d_, ", - convert_chan_type_to_string(chan_type), - x, y, itrack); - fprintf(fp, "\n"); - break; - case DEC_DIRECTION: - fprintf(fp, "%s_%d__%d__out_%d_, ", - convert_chan_type_to_string(chan_type), - x, y, itrack); - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of %s[%d][%d]_track[%d]!\n", - __FILE__, __LINE__, - convert_chan_type_to_string(chan_type), - x, y, itrack); - exit(1); - } - } - - /* output at middle point */ - for (itrack = 0; itrack < chan_width; itrack++) { - fprintf(fp, "%s_%d__%d__midout_%d_ ", - convert_chan_type_to_string(chan_type), - x, y, itrack); - if (itrack < chan_width - 1) { - fprintf(fp, ","); - } - fprintf(fp, "\n"); - } - fprintf(fp, ");\n"); - - /* Comment lines */ - switch (chan_type) { - case CHANX: - fprintf(fp, "//----- END Call Channel-X [%d][%d] module -----\n", x, y); - break; - case CHANY: - fprintf(fp, "//----- END call Channel-Y [%d][%d] module -----\n\n", x, y); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid Channel Type!\n", __FILE__, __LINE__); - exit(1); - } - - /* Free */ - my_free(chan_rr_nodes); - - return; -} - -/* Call the sub-circuits for channels : Channel X and Channel Y*/ -static -void dump_verilog_defined_channels(FILE* fp, - int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices) { - int ix, iy; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); - exit(1); - } - - /* Channel X */ - for (iy = 0; iy < (ny + 1); iy++) { - for (ix = 1; ix < (nx + 1); ix++) { - dump_verilog_defined_one_channel(fp, CHANX, ix, iy, - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); - } - } - - /* Channel Y */ - for (ix = 0; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - dump_verilog_defined_one_channel(fp, CHANY, ix, iy, - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); - } - } - - return; -} - -/* Call the defined sub-circuit of connection box - * TODO: actually most of this function is copied from - * spice_routing.c : dump_verilog_conneciton_box_interc - * Should be more clever to use the original function - */ -static -void dump_verilog_defined_one_connection_box(FILE* fp, - t_cb cur_cb_info) { - int itrack, inode, side, x, y; - int side_cnt = 0; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - /* Check */ - assert((!(0 > cur_cb_info.x))&&(!(cur_cb_info.x > (nx + 1)))); - assert((!(0 > cur_cb_info.y))&&(!(cur_cb_info.y > (ny + 1)))); - - x = cur_cb_info.x; - y = cur_cb_info.y; - - /* Print the definition of subckt*/ - /* Identify the type of connection box */ - switch(cur_cb_info.type) { - case CHANX: - /* Comment lines */ - fprintf(fp, "//----- BEGIN Call Connection Box-X direction [%d][%d] module -----\n", x, y); - /* Print module */ - fprintf(fp, "cbx_%d__%d_ ", x, y); - fprintf(fp, "cbx_%d__%d__0_ ", x, y); - break; - case CHANY: - /* Comment lines */ - fprintf(fp, "//----- BEGIN Call Connection Box-Y direction [%d][%d] module -----\n", x, y); - /* Print module */ - fprintf(fp, "cby_%d__%d_ ", x, y); - fprintf(fp, "cby_%d__%d__0_ ", x, y); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); - exit(1); - } - - fprintf(fp, "("); - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - - /* Print the ports of channels*/ - /* connect to the mid point of a track*/ - side_cnt = 0; - for (side = 0; side < cur_cb_info.num_sides; side++) { - /* Bypass side with zero channel width */ - if (0 == cur_cb_info.chan_width[side]) { - continue; - } - assert (0 < cur_cb_info.chan_width[side]); - side_cnt++; - fprintf(fp, "//----- %s side inputs: channel track middle outputs -----\n", convert_side_index_to_string(side)); - for (itrack = 0; itrack < cur_cb_info.chan_width[side]; itrack++) { - fprintf(fp, "%s_%d__%d__midout_%d_, ", - convert_chan_type_to_string(cur_cb_info.type), - cur_cb_info.x, cur_cb_info.y, itrack); - fprintf(fp, "\n"); - } - } - /*check side_cnt */ - assert(1 == side_cnt); - - side_cnt = 0; - /* Print the ports of grids*/ - for (side = 0; side < cur_cb_info.num_sides; side++) { - /* Bypass side with zero IPINs*/ - if (0 == cur_cb_info.num_ipin_rr_nodes[side]) { - continue; - } - side_cnt++; - assert(0 < cur_cb_info.num_ipin_rr_nodes[side]); - assert(NULL != cur_cb_info.ipin_rr_node[side]); - fprintf(fp, "//----- %s side outputs: CLB input pins -----\n", convert_side_index_to_string(side)); - for (inode = 0; inode < cur_cb_info.num_ipin_rr_nodes[side]; inode++) { - /* Print each INPUT Pins of a grid */ - dump_verilog_grid_side_pin_with_given_index(fp, OPIN, - cur_cb_info.ipin_rr_node[side][inode]->ptc_num, - cur_cb_info.ipin_rr_node_grid_side[side][inode], - cur_cb_info.ipin_rr_node[side][inode]->xlow, - cur_cb_info.ipin_rr_node[side][inode]->ylow, - FALSE); /* Do not specify direction of port */ - fprintf(fp, ", \n"); - } - } - /* Make sure only 2 sides of IPINs are printed */ - assert((1 == side_cnt)||(2 == side_cnt)); - - /* Configuration ports */ - /* Reserved sram ports */ - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, cur_cb_info.num_reserved_conf_bits - 1, - VERILOG_PORT_CONKT); - /* Normal sram ports */ - if (0 < (cur_cb_info.num_reserved_conf_bits)) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - cur_cb_info.conf_bits_lsb, cur_cb_info.conf_bits_msb - 1, - VERILOG_PORT_CONKT); - - fprintf(fp, ");\n"); - - /* Comment lines */ - switch(cur_cb_info.type) { - case CHANX: - fprintf(fp, "//----- END call Connection Box-X direction [%d][%d] module -----\n\n", x, y); - break; - case CHANY: - fprintf(fp, "//----- END call Connection Box-Y direction [%d][%d] module -----\n\n", x, y); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); - exit(1); - } - - /* Check */ - assert((1 == side_cnt)||(2 == side_cnt)); - - return; -} - -/* Call the sub-circuits for connection boxes */ -static -void dump_verilog_defined_connection_boxes(FILE* fp) { - int ix, iy; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* X - channels [1...nx][0..ny]*/ - for (iy = 0; iy < (ny + 1); iy++) { - for (ix = 1; ix < (nx + 1); ix++) { - if ((TRUE == is_cb_exist(CHANX, ix, iy)) - &&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) { - dump_verilog_defined_one_connection_box(fp, cbx_info[ix][iy]); - } - } - } - /* Y - channels [1...ny][0..nx]*/ - for (ix = 0; ix < (nx + 1); ix++) { - for (iy = 1; iy < (ny + 1); iy++) { - if ((TRUE == is_cb_exist(CHANY, ix, iy)) - &&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) { - dump_verilog_defined_one_connection_box(fp, cby_info[ix][iy]); - } - } - } - - return; -} - -/* Call the defined switch box sub-circuit - * TODO: This function is also copied from - * spice_routing.c : dump_verilog_routing_switch_box_subckt - */ -static -void dump_verilog_defined_one_switch_box(FILE* fp, - t_sb cur_sb_info) { - int ix, iy, side, itrack, x, y, inode; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Check */ - assert((!(0 > cur_sb_info.x))&&(!(cur_sb_info.x > (nx + 1)))); - assert((!(0 > cur_sb_info.y))&&(!(cur_sb_info.y > (ny + 1)))); - - x = cur_sb_info.x; - y = cur_sb_info.y; - - /* Comment lines */ - fprintf(fp, "//----- BEGIN call module Switch blocks [%d][%d] -----\n", - cur_sb_info.x, cur_sb_info.y); - /* Print module*/ - fprintf(fp, "sb_%d__%d_ ", cur_sb_info.x, cur_sb_info.y); - fprintf(fp, "sb_%d__%d__0_ ", cur_sb_info.x, cur_sb_info.y); - fprintf(fp, "("); - - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - - for (side = 0; side < cur_sb_info.num_sides; side++) { - determine_sb_port_coordinator(cur_sb_info, side, &ix, &iy); - - fprintf(fp, "//----- %s side channel ports-----\n", convert_side_index_to_string(side)); - for (itrack = 0; itrack < cur_sb_info.chan_width[side]; itrack++) { - switch (cur_sb_info.chan_rr_node_direction[side][itrack]) { - case OUT_PORT: - fprintf(fp, "%s_%d__%d__out_%d_, ", - convert_chan_type_to_string(cur_sb_info.chan_rr_node[side][itrack]->type), - ix, iy, itrack); - break; - case IN_PORT: - fprintf(fp, "%s_%d__%d__in_%d_, ", - convert_chan_type_to_string(cur_sb_info.chan_rr_node[side][itrack]->type), - ix, iy, itrack); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of sb[%d][%d] side[%d] track[%d]!\n", - __FILE__, __LINE__, x, y, side, itrack); - exit(1); - } - } - fprintf(fp, "\n"); - fprintf(fp, "//----- %s side inputs: CLB output pins -----\n", convert_side_index_to_string(side)); - /* Dump OPINs of adjacent CLBs */ - for (inode = 0; inode < cur_sb_info.num_opin_rr_nodes[side]; inode++) { - dump_verilog_grid_side_pin_with_given_index(fp, IPIN, - cur_sb_info.opin_rr_node[side][inode]->ptc_num, - cur_sb_info.opin_rr_node_grid_side[side][inode], - cur_sb_info.opin_rr_node[side][inode]->xlow, - cur_sb_info.opin_rr_node[side][inode]->ylow, - FALSE); /* Do not specify the direction of port */ - fprintf(fp, ","); - } - fprintf(fp, "\n"); - } - - /* Configuration ports */ - /* output of each configuration bit */ - /* Reserved sram ports */ - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, cur_sb_info.num_reserved_conf_bits - 1, - VERILOG_PORT_CONKT); - /* Normal sram ports */ - if (0 < (cur_sb_info.num_reserved_conf_bits)) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - cur_sb_info.conf_bits_lsb, - cur_sb_info.conf_bits_msb - 1, - VERILOG_PORT_CONKT); - - fprintf(fp, ");\n"); - - /* Comment lines */ - fprintf(fp, "//----- END call module Switch blocks [%d][%d] -----\n\n", x, y); - - /* Free */ - - return; -} - -static -void dump_verilog_defined_switch_boxes(FILE* fp) { - int ix, iy; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - for (ix = 0; ix < (nx + 1); ix++) { - for (iy = 0; iy < (ny + 1); iy++) { - dump_verilog_defined_one_switch_box(fp, sb_info[ix][iy]); - } - } - - return; -} - -/* Apply a CLB to CLB direct connection to a SPICE netlist - */ -static -void dump_verilog_one_clb2clb_direct(FILE* fp, - int from_grid_x, int from_grid_y, - int to_grid_x, int to_grid_y, - t_clb_to_clb_directs* cur_direct) { - int ipin, cur_from_clb_pin_index, cur_to_clb_pin_index; - int cur_from_clb_pin_side, cur_to_clb_pin_side; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Check bandwidth match between from_clb and to_clb pins */ - if (0 != (cur_direct->from_clb_pin_end_index - cur_direct->from_clb_pin_start_index - - cur_direct->to_clb_pin_end_index - cur_direct->to_clb_pin_start_index)) { - vpr_printf(TIO_MESSAGE_ERROR, "(%s, [LINE%d]) Unmatch pin bandwidth in direct connection (name=%s)!\n", - __FILE__, __LINE__, cur_direct->name); - exit(1); - } - - for (ipin = 0; ipin < cur_direct->from_clb_pin_end_index - cur_direct->from_clb_pin_start_index; ipin++) { - /* Update pin index and get the side of the pins on grids */ - cur_from_clb_pin_index = cur_direct->from_clb_pin_start_index + ipin; - cur_to_clb_pin_index = cur_direct->to_clb_pin_start_index + ipin; - cur_from_clb_pin_side = get_grid_pin_side(from_grid_x, from_grid_y, cur_from_clb_pin_index); - cur_to_clb_pin_side = get_grid_pin_side(to_grid_x, to_grid_y, cur_to_clb_pin_index); - /* Call the subckt that has already been defined before */ - fprintf(fp, "%s ", cur_direct->spice_model->name); - fprintf(fp, "%s_%d_ (", cur_direct->spice_model->prefix, cur_direct->spice_model->cnt); - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_direct->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - /* Input: Print the source grid pin */ - dump_verilog_toplevel_one_grid_side_pin_with_given_index(fp, OPIN, - cur_from_clb_pin_index, - cur_from_clb_pin_side, - from_grid_x, from_grid_y, - FALSE); - fprintf(fp, ", "); - /* Output: Print the destination grid pin */ - dump_verilog_toplevel_one_grid_side_pin_with_given_index(fp, IPIN, - cur_to_clb_pin_index, - cur_to_clb_pin_side, - to_grid_x, from_grid_y, - FALSE); - fprintf(fp, ");\n"); - - /* Stats the number of spice_model used*/ - cur_direct->spice_model->cnt++; - } - - return; -} - -/* Apply CLB to CLB direct connections to a Verilog netlist - */ -static -void dump_verilog_clb2clb_directs(FILE* fp, - int num_directs, t_clb_to_clb_directs* direct) { - int ix, iy, idirect; - int to_clb_x, to_clb_y; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - fprintf(fp, "//----- BEGIN CLB to CLB Direct Connections -----\n"); - - /* Scan the grid, visit each grid and apply direct connections */ - for (ix = 0; ix < (nx + 1); ix++) { - for (iy = 0; iy < (ny + 1); iy++) { - /* Bypass EMPTY_TYPE*/ - if ((NULL == grid[ix][iy].type) - || (EMPTY_TYPE == grid[ix][iy].type)) { - continue; - } - /* Check each clb2clb directs, - * see if a match to the type - */ - for (idirect = 0; idirect < num_directs; idirect++) { - /* Bypass unmatch types */ - if (grid[ix][iy].type != direct[idirect].from_clb_type) { - continue; - } - /* Apply x/y_offset */ - to_clb_x = ix + direct[idirect].x_offset; - to_clb_y = iy + direct[idirect].y_offset; - /* see if the destination CLB is in the bound */ - if ((FALSE == is_grid_coordinate_in_range(0, nx, to_clb_x)) - ||(FALSE == is_grid_coordinate_in_range(0, ny, to_clb_y))) { - continue; - } - /* Check if capacity (z_offset) is in the range - if (FALSE == is_grid_coordinate_in_range(0, grid[ix][iy].type->capacity, grid[ix][iy].type->z + direct[idirect].z_offset)) { - continue; - } - */ - /* Check if the to_clb_type matches */ - if (grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) { - continue; - } - /* Bypass x/y_offset = 1 - * since it may be addressed in Connection blocks - if (1 == (x_offset + y_offset)) { - continue; - } - */ - /* Now we can print a direct connection with the spice models */ - dump_verilog_one_clb2clb_direct(fp, - ix, iy, - to_clb_x, to_clb_y, - &direct[idirect]); - } - } - } - - fprintf(fp, "//----- END CLB to CLB Direct Connections -----\n"); - - return; - -} - -/** Dump Standalone SRAMs - */ -static -void dump_verilog_configuration_circuits_standalone_srams(FILE* fp) { - int i; - /* Check */ - assert(SPICE_SRAM_STANDALONE == sram_verilog_orgz_type); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler!",__FILE__, __LINE__); - exit(1); - } - - /* Dump each SRAM */ - fprintf(fp, "//------ Standalone SRAMs -----\n"); - for (i = 0; i < sram_verilog_model->cnt; i++) { - fprintf(fp, "%s %s_%d (\n", - sram_verilog_model->name, sram_verilog_model->prefix, i); - /* Input and 2 outputs */ - fprintf(fp, "%s_in[%d] %s_out[%d] %s_outb[%d] ", - sram_verilog_model->prefix, i, - sram_verilog_model->prefix, i, - sram_verilog_model->prefix, i); - fprintf(fp, ");\n"); - } - fprintf(fp, "//------ END Standalone SRAMs -----\n"); - - return; -} - -/** Dump scan-chains - */ -static -void dump_verilog_configuration_circuits_scan_chains(FILE* fp) { - int i; - /* Check */ - assert(SPICE_SRAM_SCAN_CHAIN == sram_verilog_orgz_type); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); - exit(1); - } - - /* Dump each Scan-chain FF */ - fprintf(fp, "//------ Scan-chain FFs -----\n"); - for (i = 0; i < sram_verilog_model->cnt; i++) { - /* Connect the head of current scff to the tail of previous scff*/ - if (0 < i) { - fprintf(fp, " "); - fprintf(fp, "assign "); - dump_verilog_sram_one_port(fp, sram_verilog_orgz_info, i, i, 0, VERILOG_PORT_CONKT); - fprintf(fp, " = "); - dump_verilog_sram_one_port(fp, sram_verilog_orgz_info, i - 1, i - 1, 1, VERILOG_PORT_CONKT); - fprintf(fp, ";\n"); - } - } - fprintf(fp, "//------ END Scan-chain FFs -----\n"); - - return; -} - -/* Dump a memory bank to configure all the Bit lines and Word lines */ -static -void dump_verilog_configuration_circuits_memory_bank(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info) { - int bl_decoder_size, wl_decoder_size; - int num_array_bl, num_array_wl; - t_spice_model* mem_model = NULL; - - /* Check */ - assert(SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type); - assert(NULL != cur_sram_orgz_info->mem_bank_info); - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); - exit(1); - } - - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - /* Get memory model */ - get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); - assert(NULL != mem_model); - - /* Comment lines */ - fprintf(fp, "//----- BEGIN call decoders for memory bank controller -----\n"); - - /* Dump Decoders for Bit lines and Word lines */ - /* Two huge decoders - * TODO: divide to a number of small decoders ? - */ - /* Bit lines decoder */ - fprintf(fp, "bl_decoder%dto%d mem_bank_bl_decoder (", - bl_decoder_size, num_array_bl); - /* Prefix of BL & WL is fixed, in order to simplify grouping nets */ - fprintf(fp, "%s, %s[%d:0], ", - top_netlist_bl_enable_port_name, - top_netlist_addr_bl_port_name, bl_decoder_size - 1); - /* Port map depends on the memory technology */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - /* Data input port of BL decoder, only required by SRAM array */ - fprintf(fp, "%s, ", - top_netlist_bl_data_in_port_name); - break; - case SPICE_MODEL_DESIGN_RRAM: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - fprintf(fp, "%s[0:%d]", - top_netlist_array_bl_port_name, num_array_bl - 1); - fprintf(fp, ");\n"); - - /* Word lines decoder is the same for both technology */ - fprintf(fp, "wl_decoder%dto%d mem_bank_wl_decoder (", - wl_decoder_size, num_array_wl); - fprintf(fp, "%s, %s[%d:0], ", - top_netlist_wl_enable_port_name, - top_netlist_addr_wl_port_name, wl_decoder_size - 1); - fprintf(fp, "%s[0:%d]", - top_netlist_array_wl_port_name, num_array_wl - 1); - fprintf(fp, ");\n"); - - /* Comment lines */ - fprintf(fp, "//----- END call decoders for memory bank controller -----\n\n"); - - return; -} - -/* Dump the configuration circuits in verilog according to user-specification - * Supported styles of configuration circuits: - * 1. Scan-chains - * 2. Memory banks - * 3. Standalone SRAMs - */ -static -void dump_verilog_configuration_circuits(FILE* fp) { - switch(sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - dump_verilog_configuration_circuits_standalone_srams(fp); - break; - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_configuration_circuits_scan_chains(fp); - break; - case SPICE_SRAM_MEMORY_BANK: - dump_verilog_configuration_circuits_memory_bank(fp, sram_verilog_orgz_info); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - return; -} - -/* Dump all the global ports that are stored in the linked list */ -static -void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head, - enum e_dump_verilog_port_type dump_port_type) { - t_llist* temp = head; - t_spice_model_port* cur_global_port = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - } - - fprintf(fp, "//----- BEGIN Global ports -----\n"); - while(NULL != temp) { - cur_global_port = (t_spice_model_port*)(temp->dptr); - dump_verilog_generic_port(fp, dump_port_type, - cur_global_port->prefix, 0, cur_global_port->size - 1); - fprintf(fp, ";\n"); - /* Go to the next */ - temp = temp->next; - } - fprintf(fp, "//----- END Global ports -----\n"); - - return; -} - -/* Connect a global port to a voltage stimuli */ -static -void dump_verilog_top_testbench_wire_one_global_port_stimuli(FILE* fp, t_spice_model_port* cur_global_port, - char* voltage_stimuli_port_name) { - int ipin; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - assert(NULL != cur_global_port); - - for (ipin = 0; ipin < cur_global_port->size; ipin++) { - fprintf(fp, "assign %s[%d] = ", - cur_global_port->prefix, ipin); - assert((0 == cur_global_port->default_val)||(1 == cur_global_port->default_val)); - if (1 == cur_global_port->default_val) { - fprintf(fp, "~"); - } - fprintf(fp, "%s;\n", - voltage_stimuli_port_name); - } - - return; -} - -/* Print stimuli for global ports in top-level testbench */ -static -void dump_verilog_top_testbench_global_ports_stimuli(FILE* fp, t_llist* head) { - t_llist* temp = head; - t_spice_model_port* cur_global_port = NULL; - int ipin; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - fprintf(fp, "//----- Connecting Global ports -----\n"); - while(NULL != temp) { - cur_global_port = (t_spice_model_port*)(temp->dptr); - /* Make sure this is a global port */ - assert(TRUE == cur_global_port->is_global); - /* If this is a clock signal, connect to op_clock signal */ - if (SPICE_MODEL_PORT_CLOCK == cur_global_port->type) { - /* Special for programming clock */ - if (TRUE == cur_global_port->is_prog) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_clock_port_name); - } else { - assert(FALSE == cur_global_port->is_prog); - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_op_clock_port_name); - } - /* If this is a config_enable signal, connect to config_done signal */ - } else if (TRUE == cur_global_port->is_config_enable) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_clock_port_name); - /* If this is a set/reset signal, connect to global reset and set signals */ - } else if (TRUE == cur_global_port->is_reset) { - /* Special for programming reset */ - if (TRUE == cur_global_port->is_prog) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_reset_port_name); - } else { - assert(FALSE == cur_global_port->is_prog); - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_reset_port_name); - } - /* If this is a set/reset signal, connect to global reset and set signals */ - } else if (TRUE == cur_global_port->is_set) { - /* Special for programming reset */ - if (TRUE == cur_global_port->is_prog) { - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_set_port_name); - } else { - assert(FALSE == cur_global_port->is_prog); - dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_set_port_name); - } - } else { - /* Other global signals stuck at the default values */ - for (ipin = 0; ipin < cur_global_port->size; ipin++) { - fprintf(fp, "assign %s[%d] = 1'b%d;\n", - cur_global_port->prefix, ipin, cur_global_port->default_val); - } - } - /* Go to the next */ - temp = temp->next; - } - fprintf(fp, "//----- End Connecting Global ports -----\n"); - - return; -} - -static -void dump_verilog_top_testbench_ports(FILE* fp, - char* circuit_name) { - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - int iblock, iopad_idx; - t_spice_model* mem_model = NULL; - char* port_name = NULL; - - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - - fprintf(fp, "module %s_top_tb;\n", circuit_name); - /* Local wires */ - /* 1. reset, set, clock signals */ - /* 2. iopad signals */ - - /* Connect to defined signals */ - /* set and reset signals */ - fprintf(fp, "\n"); - dump_verilog_top_testbench_global_ports(fp, global_ports_head, VERILOG_PORT_WIRE); - fprintf(fp, "\n"); - - /* TODO: dump each global signal as reg here */ - - /* Inputs and outputs of I/O pads */ - /* Inout Pads */ - assert(NULL != iopad_verilog_model); - if ((NULL == iopad_verilog_model) - ||(iopad_verilog_model->cnt > 0)) { - /* Malloc and assign port_name */ - port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); - sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); - /* Dump a wired port */ - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - port_name, iopad_verilog_model->cnt - 1, 0); - fprintf(fp, "; //--- FPGA inouts \n"); - /* Free port_name */ - my_free(port_name); - /* Malloc and assign port_name */ - port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + strlen(top_tb_inout_reg_postfix) + 1)); - sprintf(port_name, "%s%s%s", gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix); - /* Dump a wired port */ - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - port_name, iopad_verilog_model->cnt - 1, 0); - fprintf(fp, "; //--- reg for FPGA inouts \n"); - /* Free port_name */ - my_free(port_name); - } - - /* Add a signal to identify the configuration phase is finished */ - fprintf(fp, "reg [0:0] %s;\n", top_tb_config_done_port_name); - /* Programming clock */ - fprintf(fp, "wire [0:0] %s;\n", top_tb_prog_clock_port_name); - fprintf(fp, "reg [0:0] %s%s;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); - /* Operation clock */ - fprintf(fp, "wire [0:0] %s;\n", top_tb_op_clock_port_name); - fprintf(fp, "reg [0:0] %s%s;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); - /* Programming set and reset */ - fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_reset_port_name); - fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_set_port_name); - /* Global set and reset */ - fprintf(fp, "reg [0:0] %s;\n", top_tb_reset_port_name); - fprintf(fp, "reg [0:0] %s;\n", top_tb_set_port_name); - /* Generate stimuli for global ports or connect them to existed signals */ - dump_verilog_top_testbench_global_ports_stimuli(fp, global_ports_head); - - /* Configuration ports depend on the organization of SRAMs */ - switch(sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, - sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); - fprintf(fp, "; //---- SRAM outputs \n"); - break; - case SPICE_SRAM_SCAN_CHAIN: - /* We put the head of scan-chains here - */ - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - top_netlist_scan_chain_head_prefix, 0, 0); - fprintf(fp, "; //---- Scan-chain head \n"); - break; - case SPICE_SRAM_MEMORY_BANK: - /* Get the number of array BLs/WLs, decoder sizes */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - fprintf(fp, " wire [0:0] %s;\n", - top_netlist_bl_enable_port_name - ); - fprintf(fp, " wire [0:0] %s;\n", - top_netlist_wl_enable_port_name - ); - /* Wire en_bl, en_wl to prog_clock */ - fprintf(fp, "assign %s[0:0] = %s[0:0];\n", - top_netlist_bl_enable_port_name, - top_tb_prog_clock_port_name); - fprintf(fp, "assign %s [0:0]= %s[0:0];\n", - top_netlist_wl_enable_port_name, - top_tb_prog_clock_port_name); - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); - fprintf(fp, "; //--- Address of bit lines \n"); - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); - fprintf(fp, "; //--- Address of word lines \n"); - /* data_in is only require by BL decoder of SRAM array - * As for RRAM array, the data_in signal will not be used - */ - if (SPICE_MODEL_DESIGN_CMOS == mem_model->design_tech) { - fprintf(fp, " reg [0:0] %s; // --- Data_in signal for BL decoder, only required by SRAM array \n", - top_netlist_bl_data_in_port_name); - } - /* I add all the Bit lines and Word lines here just for testbench usage - fprintf(fp, " input wire [%d:0] %s_out; //--- Bit lines \n", - sram_verilog_model->cnt - 1, sram_verilog_model->prefix); - fprintf(fp, " input wire [%d:0] %s_outb; //--- Word lines \n", - sram_verilog_model->cnt - 1, sram_verilog_model->prefix); - */ - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Add signals from blif benchmark and short-wire them to FPGA I/O PADs - * This brings convenience to checking functionality - */ - fprintf(fp, "//-----Link Blif Benchmark inputs to FPGA IOPADs -----\n"); - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* General INOUT*/ - if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { - iopad_idx = logical_block[iblock].mapped_spice_model_index; - /* Make sure We find the correct logical block !*/ - assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); - fprintf(fp, "//----- Blif Benchmark inout %s is mapped to FPGA IOPAD %s[%d] -----\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx); - if(VPACK_INPAD == logical_block[iblock].type){ - fprintf(fp, "wire in_%s_%s_%d_;\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx); - fprintf(fp, "assign in_%s_%s_%d_ = %s%s[%d];\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); - } else{ - fprintf(fp, "wire %s_%s_%d_;\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx); - fprintf(fp, "assign %s_%s_%d_ = %s%s[%d];\n", - logical_block[iblock].name, gio_inout_prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); - } - } - } - - return; -} - -static -void dump_verilog_top_testbench_call_top_module(FILE* fp, - char* circuit_name) { - - /* Include defined top-level module */ - fprintf(fp, "//----- Device Under Test (DUT) ----\n"); - fprintf(fp, "//------Call defined Top-level Verilog Module -----\n"); - fprintf(fp, "%s_top U0 (\n", circuit_name); - - dump_verilog_top_module_ports(fp, VERILOG_PORT_CONKT); - - fprintf(fp, ");\n"); - return; -} - -/* Find the number of configuration clock cycles for a top-level testbench - * A valid configuration clock cycle is allocated for an element with - * (1) SRAM_val=1; - * (2) BL = 1 && WL = 1; - * (3) BL = 1 && WL = 0 with a paired conf_bit; - */ -static -int dump_verilog_top_testbench_find_num_config_clock_cycles(t_llist* head) { - int cnt = 0; - t_llist* temp = head; - t_conf_bit_info* temp_conf_bit_info = NULL; - - while (NULL != temp) { - /* Fetch the conf_bit_info */ - temp_conf_bit_info = (t_conf_bit_info*)(temp->dptr); - /* Check if conf_bit_info needs a clock cycle*/ - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - cnt++; - temp_conf_bit_info->index_in_top_tb = cnt; - break; - case SPICE_SRAM_MEMORY_BANK: - cnt++; - temp_conf_bit_info->index_in_top_tb = cnt; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - /* Go to the next */ - temp = temp->next; - } - - return cnt; -} - - -/* Dump configuration bits of a SRAM memory bank - * The efficient sharing BLs/WLs force configuration to be done WL by WL - * (We always assume that Word Lines are the write/read enable signal for SRAMs) - * All the SRAMs controlled by the same WL will be configuration during one programming cycle - * by assign different BL values for each of them. - */ -static -void dump_verilog_top_testbench_sram_memory_bank_conf_bits_serial(FILE* fp, - t_llist* cur_conf_bit) { - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - int** array_bit = NULL; - t_conf_bit_info*** array_conf_bit_info = NULL; - - int ibl, iwl, cur_wl, cur_bl; - char* wl_addr = NULL; - char* bl_addr = NULL; - - t_llist* temp = cur_conf_bit; - t_conf_bit_info* cur_conf_bit_info = NULL; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); - exit(1); - } - - /* Dump one configuring operation on BL and WL addresses */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - /* We will allocate the configuration bits to be written for each programming cycle */ - array_bit = (int**)my_malloc(sizeof(int*)*num_array_wl); - array_conf_bit_info = (t_conf_bit_info***)my_malloc(sizeof(t_conf_bit_info**)*num_array_wl); - /* Initialization */ - for (iwl = 0; iwl < num_array_wl; iwl++) { - array_bit[iwl] = (int*)my_malloc(sizeof(int)*num_array_bl); - array_conf_bit_info[iwl] = (t_conf_bit_info**)my_malloc(sizeof(t_conf_bit_info*)*num_array_bl); - for (ibl = 0; ibl < num_array_bl; ibl++) { - array_bit[iwl][ibl] = 0; - array_conf_bit_info[iwl][ibl] = NULL; - } - } - - /* Classify each configuration bit info to its assciated bl/wl codes - * The bl_addr and wl_addr recorded in the list is the absoluate address, - */ - while (NULL != temp) { - cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); - /* Memory bank requires the address to be given to the decoder*/ - assert( cur_conf_bit_info->bl->addr == cur_conf_bit_info->wl->addr ); - cur_wl = cur_conf_bit_info->bl->addr / num_array_bl; - cur_bl = cur_conf_bit_info->bl->addr % num_array_bl; - /* Update the SRAM bit array */ - array_bit[cur_wl][cur_bl] = cur_conf_bit_info->bl->val; - array_conf_bit_info[cur_wl][cur_bl] = cur_conf_bit_info; - /* Check if SRAM bit is valid */ - assert( (0 == array_bit[cur_wl][cur_bl]) || (1 == array_bit[cur_wl][cur_bl]) ); - /* Go to next */ - temp = temp->next; - } - - /* Dump decoder input for each programming cycle */ - for (iwl = 0; iwl < num_array_wl; iwl++) { - for (ibl = 0; ibl < num_array_bl; ibl++) { - /* Bypass configuration bit not available */ - if ( NULL == array_conf_bit_info[iwl][ibl]) { - continue; - } - /* Check */ - assert(( 1 == array_bit[iwl][ibl] )||( 0 == array_bit[iwl][ibl] )); - assert( NULL != array_conf_bit_info[iwl][ibl]); - /* If this WL is selected , we decode its index to address */ - bl_addr = (char*)my_calloc(bl_decoder_size + 1, sizeof(char)); - /* If this WL is selected , we decode its index to address */ - encode_decoder_addr(ibl, bl_decoder_size, bl_addr); - /* Word line address */ - wl_addr = (char*)my_calloc(wl_decoder_size + 1, sizeof(char)); - encode_decoder_addr(iwl, wl_decoder_size, wl_addr); - /* Get corresponding conf_bit */ - cur_conf_bit_info = array_conf_bit_info[iwl][ibl]; - /* One operation per clock cycle */ - /* Information about this configuration bit */ - fprintf(fp, " //--- Configuration bit No.: %d \n", cur_conf_bit_info->index); - fprintf(fp, " //--- Bit Line Address: %d, \n", cur_conf_bit_info->bl->addr); - fprintf(fp, " //--- Word Line Address: %d \n ", cur_conf_bit_info->wl->addr); - fprintf(fp, " //--- Bit Line index: %d, \n", ibl); - fprintf(fp, " //--- Word Line index: %d \n ", iwl); - fprintf(fp, " //--- Bit Line Value: %d, \n", cur_conf_bit_info->bl->val); - fprintf(fp, " //--- Word Line Value: %d \n ", cur_conf_bit_info->wl->val); - fprintf(fp, " //--- SPICE model name: %s \n", cur_conf_bit_info->parent_spice_model->name); - fprintf(fp, " //--- SPICE model index: %d \n", cur_conf_bit_info->parent_spice_model_index); - fprintf(fp, " prog_cycle_blwl(%d'b%s, %d'b%s, 1'b%d); //--- (BL_addr_code, WL_addr_code, bl_data_in) \n", - bl_decoder_size, bl_addr, wl_decoder_size, wl_addr, array_bit[iwl][ibl]); - fprintf(fp, "\n"); - } - } - - /* Free */ - for (iwl = 0; iwl < num_array_wl; iwl++) { - my_free(array_bit[iwl]); - my_free(array_conf_bit_info[iwl]); - } - my_free(array_bit); - my_free(array_conf_bit_info); - - return; -} - -static -void dump_verilog_top_testbench_rram_memory_bank_conf_bits_serial(FILE* fp, - t_llist* cur_conf_bit) { - int num_bl, num_wl; - int bl_decoder_size, wl_decoder_size; - char* wl_addr = NULL; - char* bl_addr = NULL; - - t_llist* temp = cur_conf_bit; - t_conf_bit_info* cur_conf_bit_info = NULL; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); - exit(1); - } - - - /* Dump one configuring operation on BL and WL addresses */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_bl, &num_wl, &bl_decoder_size, &wl_decoder_size); - - while (NULL != temp) { - cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); - /* For memory bank, we do not care the sequence. - * To be easy to understand, we go from the first to the last - * IMPORTANT: sequence seems to be critical. - * Reversing the sequence leading to functional incorrect. - */ - /* Memory bank requires the address to be given to the decoder*/ - /* Decode address to BLs and WLs*/ - /* Encode addresses */ - /* Bit line address */ - /* If this WL is selected , we decode its index to address */ - bl_addr = (char*)my_calloc(bl_decoder_size + 1, sizeof(char)); - /* If this WL is selected , we decode its index to address */ - assert(NULL != cur_conf_bit_info->bl); - encode_decoder_addr(cur_conf_bit_info->bl->addr, bl_decoder_size, bl_addr); - /* Word line address */ - wl_addr = (char*)my_calloc(wl_decoder_size + 1, sizeof(char)); - encode_decoder_addr(cur_conf_bit_info->wl->addr, wl_decoder_size, wl_addr); - assert(NULL != cur_conf_bit_info->wl); - /* One operation per clock cycle */ - /* Information about this configuration bit */ - fprintf(fp, " //--- Configuration bit No.: %d \n", cur_conf_bit_info->index); - fprintf(fp, " //--- Bit Line: %d, \n", cur_conf_bit_info->bl->val); - fprintf(fp, " //--- Word Line: %d \n ", cur_conf_bit_info->wl->val); - fprintf(fp, " //--- SPICE model name: %s \n", cur_conf_bit_info->parent_spice_model->name); - fprintf(fp, " //--- SPICE model index: %d \n", cur_conf_bit_info->parent_spice_model_index); - fprintf(fp, " prog_cycle_blwl(%d'b%s, %d'b%s); //--- (BL_addr_code, WL_addr_code) \n", - bl_decoder_size, bl_addr, wl_decoder_size, wl_addr); - fprintf(fp, "\n"); - /* Free */ - my_free(wl_addr); - my_free(bl_addr); - /* Go to next */ - temp = temp->next; - } - - return; -} - -static -void dump_verilog_top_testbench_memory_bank_conf_bits_serial(FILE* fp, - t_llist* cur_conf_bit) { - t_spice_model* mem_model = NULL; - - /* Depending on the memory technology*/ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - assert(NULL != mem_model); - - /* Check */ - assert(SPICE_SRAM_MEMORY_BANK == sram_verilog_orgz_info->type); - - /* fork on the memory technology */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - dump_verilog_top_testbench_sram_memory_bank_conf_bits_serial(fp, cur_conf_bit); - break; - case SPICE_MODEL_DESIGN_RRAM: - dump_verilog_top_testbench_rram_memory_bank_conf_bits_serial(fp, cur_conf_bit); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for memory in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* For scan chain, the last bit should go first!*/ -/* The sequence of linked list is already reversed, we just need to output each bit */ -static -void dump_verilog_top_testbench_scan_chain_conf_bits_serial(FILE* fp, - t_llist* cur_conf_bit) { - t_llist* temp = cur_conf_bit; - t_conf_bit_info* cur_conf_bit_info = NULL; - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); - exit(1); - } - - /* Configuration phase: configure each SRAM or BL/WL */ - fprintf(fp, "//----- Configuration phase -----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Scan_chain default input\n"); - /* Initial value should be the first configuration bits - * In the rest of programming cycles, - * configuration bits are fed at the falling edge of programming clock. - */ - /* We do not care the value of scan_chain head during the first programming cycle - * It is reset anyway - */ - fprintf(fp, " "); - dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, - top_netlist_scan_chain_head_prefix, 0, 0); - fprintf(fp, " = 1'b%d;\n", - 0 ); - fprintf(fp, "\n"); - /* Check we have a valid first bit */ - while (NULL != temp) { - cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); - /* Scan-chain only loads the SRAM values */ - fprintf(fp, "//---- Configuration bit No.: %d \n ", cur_conf_bit_info->index); - fprintf(fp, "//---- SRAM value: %d \n", cur_conf_bit_info->sram_bit->val); - fprintf(fp, "//---- SPICE model name: %s \n ", cur_conf_bit_info->parent_spice_model->name); - fprintf(fp, "//---- SPICE model index: %d \n", cur_conf_bit_info->parent_spice_model_index); - fprintf(fp, "\n"); - /* First bit is special */ - fprintf(fp, " prog_cycle_scan_chain(1'b%d); //--- (Scan_chain bits) \n", - cur_conf_bit_info->sram_bit->val); - fprintf(fp, "\n"); - /* Go to next */ - temp = temp->next; - } - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of Configuration phase -----\n"); - - return; -} - -/* dump configuration bits which are stored in the linked list - * USE while LOOP !!! Recursive method causes memory corruptions! - * We start dump configuration bit from the tail of the linked list - * until the head of the linked list - */ -static -void dump_verilog_top_testbench_one_conf_bit_serial(FILE* fp, - t_llist* cur_conf_bit) { - - /* We already touch the tail, start dump */ - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_top_testbench_scan_chain_conf_bits_serial(fp, cur_conf_bit); - break; - case SPICE_SRAM_MEMORY_BANK: - /* Should work differently depending on memory technology */ - dump_verilog_top_testbench_memory_bank_conf_bits_serial(fp, cur_conf_bit); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -static -void dump_verilog_top_testbench_conf_bits_serial(FILE* fp, - t_llist* head) { - int num_bl, num_wl; - int bl_decoder_size, wl_decoder_size; - t_llist* new_head = head; - - switch (sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - /* For scan chain, the last bit should go first!*/ - /* We do not need to reverse the linked list HERE !!! - * Because, it is already arranged in the seqence of MSB to LSB - * Note that the first element in the linked list is the last bit now! - */ - /* For each element in linked list, generate a voltage stimuli */ - dump_verilog_top_testbench_one_conf_bit_serial(fp, head); - break; - case SPICE_SRAM_MEMORY_BANK: - /* Configuration bits are loaded differently depending on memory technology */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_bl, &num_wl, &bl_decoder_size, &wl_decoder_size); - /* Configuration phase: configure each SRAM or BL/WL */ - fprintf(fp, "//----- Configuration phase -----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- BL_WL_ADDR\n"); - fprintf(fp, " addr_bl = {%d {1'b0}};\n", bl_decoder_size); - fprintf(fp, " addr_wl = {%d {1'b0}};\n", wl_decoder_size); - /* For each element in linked list, generate a voltage stimuli */ - /* Reverse the linked list first !!! */ - new_head = reverse_llist(new_head); - dump_verilog_top_testbench_one_conf_bit_serial(fp, new_head); - /* Recover the sequence of linked list (reverse again) !!! */ - new_head = reverse_llist(new_head); - /* Check */ - assert(head == new_head); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of Configuration phase -----\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* Print tasks, which is very useful in generating stimuli for each clock cycle - * For memory-bank manipulations only - */ -static -void dump_verilog_top_testbench_stimuli_serial_version_tasks_memory_bank(FILE* fp) { - int num_array_bl, num_array_wl; - int bl_decoder_size, wl_decoder_size; - t_spice_model* mem_model = NULL; - - /* Check */ - assert (sram_verilog_orgz_info->type == SPICE_SRAM_MEMORY_BANK); - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find the number of array BLs/WLs and decoder sizes */ - determine_verilog_blwl_decoder_size(sram_verilog_orgz_info, - &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); - - /* Depending on the memory technology*/ - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); - assert(NULL != mem_model); - - /* Depend on the memory technology */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - /* Declare two tasks: - * 1. assign BL/WL IO pads values during a programming clock cycle - * 2. assign BL/WL IO pads values during a operating clock cycle - */ - fprintf(fp, "\n"); - fprintf(fp, "//----- Task 1: input values during a programming clock cycle -----\n"); - fprintf(fp, "task prog_cycle_blwl;\n"); - fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); - fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); - fprintf(fp, " input [0:0] bl_data_in_val;\n"); - fprintf(fp, " begin\n"); - fprintf(fp, " @(posedge %s);\n", top_tb_prog_clock_port_name); - /* - fprintf(fp, " $display($time, \"Programming cycle: load BL address with \%h, load WL address with \%h\",\n"); - fprintf(fp, " bl_addr_val, wl_addr_val);\n"); - */ - fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); - fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); - fprintf(fp, " %s = bl_data_in_val;\n", top_netlist_bl_data_in_port_name); - fprintf(fp, " end\n"); - fprintf(fp, "endtask //---prog_cycle_stimuli\n"); - fprintf(fp, "\n"); - fprintf(fp, "//----- Task 2: input values during a operating clock cycle -----\n"); - fprintf(fp, "task op_cycle_blwl;\n"); - fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); - fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); - fprintf(fp, " input [0:0] bl_data_in_val;\n"); - fprintf(fp, " begin\n"); - fprintf(fp, " @(posedge %s);\n", top_tb_op_clock_port_name); - /* - fprintf(fp, " $display($time, \"Operating cycle: load BL address with \%h, load WL address with \%h\",\n"); - fprintf(fp, " bl_addr_val, wl_addr_val);\n"); - */ - fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); - fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); - fprintf(fp, " %s = bl_data_in_val;\n", top_netlist_bl_data_in_port_name); - fprintf(fp, " end\n"); - fprintf(fp, "endtask //---op_cycle_stimuli\n"); - fprintf(fp, "\n"); - break; - case SPICE_MODEL_DESIGN_RRAM: - /* Declare two tasks: - * 1. assign BL/WL IO pads values during a programming clock cycle - * 2. assign BL/WL IO pads values during a operating clock cycle - */ - fprintf(fp, "\n"); - fprintf(fp, "//----- Task 1: input values during a programming clock cycle -----\n"); - fprintf(fp, "task prog_cycle_blwl;\n"); - fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); - fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); - fprintf(fp, " begin\n"); - fprintf(fp, " @(posedge %s);\n", top_tb_prog_clock_port_name); - /* - fprintf(fp, " $display($time, \"Programming cycle: load BL address with \%h, load WL address with \%h\",\n"); - fprintf(fp, " bl_addr_val, wl_addr_val);\n"); - */ - fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); - fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); - fprintf(fp, " end\n"); - fprintf(fp, "endtask //---prog_cycle_stimuli\n"); - fprintf(fp, "\n"); - fprintf(fp, "//----- Task 2: input values during a operating clock cycle -----\n"); - fprintf(fp, "task op_cycle_blwl;\n"); - fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); - fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); - fprintf(fp, " begin\n"); - fprintf(fp, " @(posedge %s);\n", top_tb_op_clock_port_name); - /* - fprintf(fp, " $display($time, \"Operating cycle: load BL address with \%h, load WL address with \%h\",\n"); - fprintf(fp, " bl_addr_val, wl_addr_val);\n"); - */ - fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); - fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); - fprintf(fp, " end\n"); - fprintf(fp, "endtask //---op_cycle_stimuli\n"); - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* Print tasks, which is very useful in generating stimuli for each clock cycle - * For scan-chain manipulation: - * During each programming cycle, we feed the input of scan chain with a memory bit - */ -static -void dump_verilog_top_testbench_stimuli_serial_version_tasks_scan_chain(FILE* fp) { - - /* Check */ - assert ( SPICE_SRAM_SCAN_CHAIN == sram_verilog_orgz_info->type); - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Feed the scan-chain input at each falling edge of programming clock - * It aims at avoid racing the programming clock (scan-chain data changes at the rising edge). - */ - fprintf(fp, "\n"); - fprintf(fp, "//----- Task: input values during a programming clock cycle -----\n"); - fprintf(fp, "task prog_cycle_scan_chain;\n"); - fprintf(fp, " input %s_val;\n", - top_netlist_scan_chain_head_prefix); - fprintf(fp, " begin\n"); - fprintf(fp, " @(negedge %s);\n", top_tb_prog_clock_port_name); - fprintf(fp, " "); - dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, - top_netlist_scan_chain_head_prefix, 0, 0); - fprintf(fp, " = %s_val;\n", - top_netlist_scan_chain_head_prefix); - fprintf(fp, " end\n"); - fprintf(fp, "endtask //---prog_cycle_stimuli\n"); - fprintf(fp, "\n"); - - return; -} - -/* Print tasks, which is very useful in generating stimuli for each clock cycle */ -static -void dump_verilog_top_testbench_stimuli_serial_version_tasks(FILE* fp) { - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - switch (sram_verilog_orgz_info->type) { - case SPICE_SRAM_STANDALONE: - break; - case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_top_testbench_stimuli_serial_version_tasks_scan_chain(fp); - break; - case SPICE_SRAM_MEMORY_BANK: - dump_verilog_top_testbench_stimuli_serial_version_tasks_memory_bank(fp); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - - -/* Print Stimulations for top-level netlist - * Test a complete configuration phase: - * configuration bits are programming in serial (one by one) - * Task list: - * 1. For clock signal, we should create voltage waveforms for two types of clock signals: - * a. operation clock - * b. programming clock - * 2. For Set/Reset, TODO: should we reset the chip after programming phase ends and before operation phase starts - * 3. For input/output clb nets (mapped to I/O grids), we should create voltage waveforms only after programming phase - */ -static -void dump_verilog_top_testbench_stimuli_serial_version(FILE* fp, - int num_clock, - t_spice spice) { - int inet, iblock, iopad_idx; - int found_mapped_inpad = 0; - int num_config_clock_cycles = 0; - float prog_clock_period = (1./spice.spice_params.stimulate_params.prog_clock_freq); - float op_clock_period = (1./spice.spice_params.stimulate_params.op_clock_freq); - - /* Find Input Pad Spice model */ - t_spice_net_info* cur_spice_net_info = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Dump tasks */ - dump_verilog_top_testbench_stimuli_serial_version_tasks(fp); - - /* Estimate the number of configuration clock cycles - * by traversing the linked-list and count the number of SRAM=1 or BL=1&WL=1 in it. - * We plus 1 additional config clock cycle here because we need to reset everything during the first clock cycle - */ - num_config_clock_cycles = 1 + dump_verilog_top_testbench_find_num_config_clock_cycles(sram_verilog_orgz_info->conf_bit_head); - fprintf(fp, "//----- Number of clock cycles in configuration phase: %d -----\n", - num_config_clock_cycles); - - /* config_done signal: indicate when configuration is finished */ - fprintf(fp, "//----- %s ----\n", top_tb_config_done_port_name); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- CONFIG_DONE GENERATOR\n"); - fprintf(fp, " %s = 1'b0;\n", top_tb_config_done_port_name); - fprintf(fp, " //----- %s signal is enabled after %d configurating operations are done ----\n", - top_tb_config_done_port_name, num_config_clock_cycles); - fprintf(fp, " #%.2f %s = 1'b1;\n", - num_config_clock_cycles * prog_clock_period / verilog_sim_timescale, top_tb_config_done_port_name); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of %s ----\n", - top_tb_config_done_port_name); - fprintf(fp, "\n"); - - /* Generate stimilus of programming clock */ - fprintf(fp, "//----- Raw Programming clock ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- PROG_CLOCK INITIALIZATION\n"); - fprintf(fp, " %s%s = 1'b0;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "always\n"); - fprintf(fp, " begin //--- PROG_CLOCK GENERATOR\n"); - fprintf(fp, " #%.2f %s%s = ~%s%s;\n", - 0.5*prog_clock_period / verilog_sim_timescale, - top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, - top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of Programming clock ----\n"); - fprintf(fp, "\n"); - /* Programming clock should be only enabled during programming phase. - * When configuration is done (config_done is enabled), programming clock should be always zero. - */ - fprintf(fp, "//---- Actual programming clock is triggered only when %s and %s are disabled\n", - top_tb_config_done_port_name, - top_tb_prog_reset_port_name); - fprintf(fp, " assign %s = %s%s & (~%s) & (~%s);\n", - top_tb_prog_clock_port_name, - top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, - top_tb_config_done_port_name, - top_tb_prog_reset_port_name); - /* - fprintf(fp, " assign %s = %s%s & (~%s);\n", - top_tb_prog_clock_port_name, - top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, - top_tb_config_done_port_name); - */ - fprintf(fp, "//----- END of Actual Programming clock ----\n"); - fprintf(fp, "\n"); - - /* Generate stimilus of programming clock */ - fprintf(fp, "//----- Raw Operation clock ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- OP_CLOCK INITIALIZATION\n"); - fprintf(fp, " %s%s = 1'b0;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "always wait(~%s)\n", top_tb_reset_port_name); - fprintf(fp, " begin //--- OP_CLOCK GENERATOR\n"); - fprintf(fp, " #%.2f %s%s = ~%s%s;\n", - 0.5*op_clock_period / verilog_sim_timescale, - top_tb_op_clock_port_name, top_tb_clock_reg_postfix, - top_tb_op_clock_port_name, top_tb_clock_reg_postfix); - fprintf(fp, " end\n"); - fprintf(fp, "//----- END of Operation clock ----\n"); - /* Operation clock should be enabled after programming phase finishes. - * Before configuration is done (config_done is enabled), operation clock should be always zero. - */ - fprintf(fp, "//---- Actual operation clock is triggered only when %s is enabled \n", - top_tb_config_done_port_name); - fprintf(fp, " assign %s = %s%s & (%s);\n", - top_tb_op_clock_port_name, - top_tb_op_clock_port_name, top_tb_clock_reg_postfix, - top_tb_config_done_port_name); - fprintf(fp, "//----- END of Actual Operation clock ----\n"); - fprintf(fp, "\n"); - - /* Reset signal for configuration circuit : only enable during the first clock cycle in programming phase */ - fprintf(fp, "//----- Programming Reset Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- PROGRAMMING RESET GENERATOR\n"); - fprintf(fp, " %s = 1'b1;\n", top_tb_prog_reset_port_name); - /* Reset is enabled until the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in programming phase ----\n"); - fprintf(fp, "#%.2f %s = 1'b0;\n", - (1 * prog_clock_period) / verilog_sim_timescale, - top_tb_prog_reset_port_name); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* Set signal for configuration circuit : only enable during the first clock cycle in programming phase */ - fprintf(fp, "//----- Programming set Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- PROGRAMMING SET GENERATOR\n"); - fprintf(fp, "%s = 1'b0;\n", top_tb_prog_set_port_name); - fprintf(fp, "//----- Programming set signal is always disabled -----\n"); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* reset signals: only enabled during the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- RESET GENERATOR\n"); - fprintf(fp, " %s = 1'b1;\n", top_tb_reset_port_name); - /* Reset is enabled until the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in operation phase ----\n"); - fprintf(fp, "wait(%s);\n", - top_tb_config_done_port_name); - fprintf(fp, "#%.2f %s = 1'b1;\n", - (1 * op_clock_period)/ verilog_sim_timescale, - top_tb_reset_port_name); - fprintf(fp, "#%.2f %s = 1'b0;\n", - (2 * op_clock_period) / verilog_sim_timescale, - top_tb_reset_port_name); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* set signals */ - fprintf(fp, "//----- Set Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- SET GENERATOR\n"); - fprintf(fp, "%s = 1'b0;\n", top_tb_set_port_name); - fprintf(fp, "//----- Set signal is always disabled -----\n"); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* Inputs stimuli: BL/WL address lines */ - dump_verilog_top_testbench_conf_bits_serial(fp, sram_verilog_orgz_info->conf_bit_head); - - /* For each input_signal - * TODO: this part is low-efficent for run-time concern... Need improve - */ - assert(NULL != iopad_verilog_model); - for (iopad_idx = 0; iopad_idx < iopad_verilog_model->cnt; iopad_idx++) { - /* Find if this inpad is mapped to a logical block */ - found_mapped_inpad = 0; - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* Bypass OUTPAD: donot put any voltage stimuli */ - /* Make sure We find the correct logical block !*/ - if ((iopad_verilog_model == logical_block[iblock].mapped_spice_model) - &&(iopad_idx == logical_block[iblock].mapped_spice_model_index)) { - /* Output PAD only need a short connection */ - if (VPACK_OUTPAD == logical_block[iblock].type) { - fprintf(fp, "//----- Output %s does not need a Stimuli ----\n", logical_block[iblock].name); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s[%d] GENERATOR\n", gio_inout_prefix, iopad_idx); - fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - verilog_default_signal_init_value); - fprintf(fp, "end\n"); - found_mapped_inpad = 1; - break; - } - /* Input PAD only need a short connection */ - assert(VPACK_INPAD == logical_block[iblock].type); - cur_spice_net_info = NULL; - for (inet = 0; inet < num_nets; inet++) { - if (0 == strcmp(clb_net[inet].name, logical_block[iblock].name)) { - cur_spice_net_info = clb_net[inet].spice_net_info; - break; - } - } - assert(NULL != cur_spice_net_info); - assert(!(0 > cur_spice_net_info->density)); - assert(!(1 < cur_spice_net_info->density)); - assert(!(0 > cur_spice_net_info->probability)); - assert(!(1 < cur_spice_net_info->probability)); - /* Connect the reg to inouts */ - fprintf(fp, "//----- Input %s Stimuli ----\n", logical_block[iblock].name); - fprintf(fp, "assign %s%s[%d] = %s%s%s[%d];\n", - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx); - /* Get the net information */ - /* TODO: Give the net name in the blif file !*/ - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s GENERATOR\n", logical_block[iblock].name); - fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - cur_spice_net_info->init_val); - fprintf(fp, "end\n"); - fprintf(fp, "always wait (~%s)\n", top_tb_reset_port_name); - fprintf(fp, " begin \n"); - fprintf(fp, " %s%s%s[%d] = ~%s%s%s[%d];\n #%.2f\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - (((float)(int)((100 * op_clock_period) / verilog_sim_timescale) / 100) * ((int)(cur_spice_net_info->probability / cur_spice_net_info->density)+ iblock))); - fprintf(fp, " %s%s%s[%d] = ~%s%s%s[%d];\n #%.2f;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - (((float)(int)((100 * op_clock_period) / verilog_sim_timescale) / 100) * ((int)(cur_spice_net_info->density / cur_spice_net_info->probability) * 2.5 + iblock))); - fprintf(fp, " end \n"); - fprintf(fp, "\n"); - found_mapped_inpad++; - } - } - assert((0 == found_mapped_inpad)||(1 == found_mapped_inpad)); - /* If we find one iopad already, we finished in this round here */ - if (1 == found_mapped_inpad) { - continue; - } - /* if we cannot find any mapped inpad from tech.-mapped netlist, give a default */ - /* Connect the reg to inouts */ - fprintf(fp, "//----- Input %s[%d] Stimuli ----\n", gio_inout_prefix, iopad_idx); - fprintf(fp, "assign %s%s[%d] = %s%s%s[%d];\n", - gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx); - /* TODO: Give the net name in the blif file !*/ - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s[%d] GENERATOR\n", gio_inout_prefix, iopad_idx); - fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", - gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, - verilog_default_signal_init_value); - fprintf(fp, "end\n"); - } - - /* Finish */ - - return; -} - -/* Generate the stimuli for the top-level testbench - * The simulation consists of two phases: configuration phase and operation phase - * We have two choices for the configuration phase: - * 1. Configuration bits are loaded serially. - * This is actually what we do for a physical FPGA - * 2. Configuration bits are loaded parallel. - * This is only feasible in simulation, which is convenient to check functionality. - */ -void dump_verilog_top_testbench_stimuli(FILE* fp, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog) { - - /* Only serial version is avaiable now */ - dump_verilog_top_testbench_stimuli_serial_version(fp, num_clock, verilog); - /* - if (TRUE == syn_verilog_opts.tb_serial_config_mode) { - } else { - dump_verilog_top_testbench_stimuli_parallel_version(fp, num_clock, verilog); - } - */ - - return; -} - -/* Dump the ports for input blif nestlist */ -static -void dump_verilog_input_blif_testbench_ports(FILE* fp, - char* circuit_name) { - int iblock; - - fprintf(fp, "module %s_blif_tb;\n", circuit_name); - - fprintf(fp, " reg %s;\n", top_tb_reset_port_name); - - /* Print all the inputs/outputs*/ - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* Make sure We find the correct logical block !*/ - switch (logical_block[iblock].type) { - case VPACK_INPAD: - fprintf(fp, " reg %s;\n", logical_block[iblock].name); - break; - case VPACK_OUTPAD: - fprintf(fp, " wire %s;\n", logical_block[iblock].name); - break; - case VPACK_COMB: - case VPACK_LATCH: - case VPACK_EMPTY: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", - __FILE__, __LINE__, iblock); - exit(1); - } - } - - return; -} - -/* Dump the module to be tested for input blif nestlist */ -static -void dump_verilog_input_blif_testbench_call_top_module(FILE* fp, - char* circuit_name) { - int iblock, cnt; - /* Initialize a counter */ - cnt = 0; - - fprintf(fp, "%s uut (\n", circuit_name); - /* Print all the inputs/outputs*/ - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* Make sure We find the correct logical block !*/ - switch (logical_block[iblock].type) { - case VPACK_INPAD: - case VPACK_OUTPAD: - /* Dump a comma only when needed*/ - if (0 < cnt) { - fprintf(fp, ",\n"); - } - /* Dump an input/output, avoid additional comma leading to wrong connections */ - fprintf(fp, "%s", logical_block[iblock].name); - /* Update counter */ - cnt++; - break; - case VPACK_COMB: - case VPACK_LATCH: - case VPACK_EMPTY: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", - __FILE__, __LINE__, iblock); - exit(1); - } - } - fprintf(fp, ");\n"); - fprintf(fp, "//---- End call module %s (%d inputs and outputs) -----\n", - circuit_name, cnt); - - return; -} - -/* Dump voltage stimuli for input blif nestlist */ -static -void dump_verilog_input_blif_testbench_stimuli(FILE* fp, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice spice) { - int iblock, inet; - t_spice_net_info* cur_spice_net_info = NULL; - float op_clock_period = 1./spice.spice_params.stimulate_params.op_clock_freq; - - fprintf(fp, "//----- Operation clock period: %.2g -----\n", op_clock_period); - - /* reset signals: only enabled during the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset Stimuli ----\n"); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- RESET GENERATOR\n"); - fprintf(fp, " %s = 1'b1;\n", top_tb_reset_port_name); - /* Reset is enabled until the first clock cycle in operation phase */ - fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in operation phase ----\n"); - fprintf(fp, "#%.2f %s = 1'b0;\n", - (1 * op_clock_period) / verilog_sim_timescale, - top_tb_reset_port_name); - fprintf(fp, "end\n"); - fprintf(fp, "\n"); - - /* Regular inputs */ - for (iblock = 0; iblock < num_logical_blocks; iblock++) { - /* Make sure We find the correct logical block !*/ - switch (logical_block[iblock].type) { - case VPACK_INPAD: - cur_spice_net_info = NULL; - for (inet = 0; inet < num_nets; inet++) { - if (0 == strcmp(clb_net[inet].name, logical_block[iblock].name)) { - cur_spice_net_info = clb_net[inet].spice_net_info; - break; - } - } - assert(NULL != cur_spice_net_info); - assert(!(0 > cur_spice_net_info->density)); - assert(!(1 < cur_spice_net_info->density)); - assert(!(0 > cur_spice_net_info->probability)); - assert(!(1 < cur_spice_net_info->probability)); - /* Get the net information */ - /* TODO: Give the net name in the blif file !*/ - fprintf(fp, "//----- Input %s Stimuli ----\n", logical_block[iblock].name); - fprintf(fp, "initial\n"); - fprintf(fp, " begin //--- Input %s GENERATOR\n", logical_block[iblock].name); - fprintf(fp, " %s = 1'b%d;\n", - logical_block[iblock].name, - cur_spice_net_info->init_val); - fprintf(fp, "end\n"); - fprintf(fp, "always wait (~%s)\n", top_tb_reset_port_name); - fprintf(fp, " begin \n"); - fprintf(fp, " #%.2f %s = ~%s;\n", - (op_clock_period * cur_spice_net_info->density * 2. / cur_spice_net_info->probability) / verilog_sim_timescale, - logical_block[iblock].name, - logical_block[iblock].name); - fprintf(fp, " end \n"); - fprintf(fp, "\n"); - break; - case VPACK_OUTPAD: - case VPACK_COMB: - case VPACK_LATCH: - case VPACK_EMPTY: - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", - __FILE__, __LINE__, iblock); - exit(1); - } - } - - return; -} - -/***** Print Top-level SPICE netlist *****/ -void dump_verilog_top_netlist(char* circuit_name, - char* top_netlist_name, - char* include_dir_path, - char* subckt_dir_path, - int LL_num_rr_nodes, - t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_spice verilog) { - FILE* fp = NULL; - char* formatted_subckt_dir_path = format_dir_path(subckt_dir_path); - char* temp_include_file_path = NULL; - char* title = my_strcat("FPGA Verilog Netlist for Design: ", circuit_name); - - /* Check if the path exists*/ - fp = fopen(top_netlist_name,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog netlist %s!",__FILE__, __LINE__, top_netlist_name); - exit(1); - } - - vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Top-level Verilog Netlist for %s...\n", circuit_name); - - /* Print the title */ - dump_verilog_file_header(fp, title); - my_free(title); - - /* Include user-defined sub-circuit netlist */ - fprintf(fp, "//----- Include User-defined netlists -----\n"); - init_include_user_defined_verilog_netlists(verilog); - dump_include_user_defined_verilog_netlists(fp, verilog); - - /* Special subckts for Top-level SPICE netlist */ - fprintf(fp, "//----- Include subckt netlists: Multiplexers -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, muxes_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//----- Include subckt netlists: Wires -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, wires_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//----- Include subckt netlists: Look-Up Tables (LUTs) -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//------ Include subckt netlists: Logic Blocks -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, logic_block_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//----- Include subckt netlists: Routing structures (Switch Boxes, Channels, Connection Boxes) -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, routing_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - /* Include decoders if required */ - switch(sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - /* Include verilog decoder */ - fprintf(fp, "//----- Include subckt netlists: Decoders (controller for memeory bank) -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, decoders_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Print all global wires*/ - dump_verilog_top_netlist_ports(fp, num_clock, circuit_name, verilog); - - dump_verilog_top_netlist_internal_wires(fp); - - /* Quote defined Logic blocks subckts (Grids) */ - dump_verilog_defined_grids(fp); - - /* Quote Routing structures: Channels */ - dump_verilog_defined_channels(fp, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); - - /* Quote Routing structures: Conneciton Boxes */ - dump_verilog_defined_connection_boxes(fp); - - /* Quote Routing structures: Switch Boxes */ - dump_verilog_defined_switch_boxes(fp); - - /* Apply CLB to CLB direct connections */ - dump_verilog_clb2clb_directs(fp, num_clb2clb_directs, clb2clb_direct); - - /* Dump configuration circuits */ - dump_verilog_configuration_circuits(fp); - - /* verilog ends*/ - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - return; -} - -/***** Print Top-level SPICE netlist *****/ -void dump_verilog_top_netlist_tile_orgz(char* circuit_name, - char* top_netlist_name, - char* include_dir_path, - char* subckt_dir_path, - int LL_num_rr_nodes, - t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_spice verilog) { - FILE* fp = NULL; - char* formatted_subckt_dir_path = format_dir_path(subckt_dir_path); - char* temp_include_file_path = NULL; - char* title = my_strcat("FPGA Verilog Netlist for Design: ", circuit_name); - - /* Check if the path exists*/ - fp = fopen(top_netlist_name,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog netlist %s!",__FILE__, __LINE__, top_netlist_name); - exit(1); - } - - vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Top-level Verilog Netlist for %s...\n", circuit_name); - - /* Print the title */ - dump_verilog_file_header(fp, title); - my_free(title); - - /* Include user-defined sub-circuit netlist */ - fprintf(fp, "//----- Include User-defined netlists -----\n"); - init_include_user_defined_verilog_netlists(verilog); - dump_include_user_defined_verilog_netlists(fp, verilog); - - /* Special subckts for Top-level SPICE netlist */ - fprintf(fp, "//----- Include subckt netlists: Multiplexers -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, muxes_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//----- Include subckt netlists: Wires -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, wires_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//----- Include subckt netlists: Look-Up Tables (LUTs) -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//------ Include subckt netlists: Logic Blocks -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, logic_block_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - fprintf(fp, "//----- Include subckt netlists: Routing structures (Switch Boxes, Channels, Connection Boxes) -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, routing_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - - /* Include decoders if required */ - switch(sram_verilog_orgz_type) { - case SPICE_SRAM_STANDALONE: - case SPICE_SRAM_SCAN_CHAIN: - break; - case SPICE_SRAM_MEMORY_BANK: - /* Include verilog decoder */ - fprintf(fp, "//----- Include subckt netlists: Decoders (controller for memeory bank) -----\n"); - temp_include_file_path = my_strcat(formatted_subckt_dir_path, decoders_verilog_file_name); - fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); - my_free(temp_include_file_path); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Print all global wires*/ - dump_verilog_top_netlist_ports(fp, num_clock, circuit_name, verilog); - - dump_verilog_top_netlist_internal_wires(fp); - - /* Quote defined Logic blocks subckts (Grids) */ - dump_verilog_defined_grids(fp); - - /* Quote Routing structures: Channels */ - dump_verilog_defined_channels(fp, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); - - /* Quote Routing structures: Conneciton Boxes */ - dump_verilog_defined_connection_boxes(fp); - - /* Quote Routing structures: Switch Boxes */ - dump_verilog_defined_switch_boxes(fp); - - /* Apply CLB to CLB direct connections */ - dump_verilog_clb2clb_directs(fp, num_clb2clb_directs, clb2clb_direct); - - /* Dump configuration circuits */ - dump_verilog_configuration_circuits(fp); - - /* verilog ends*/ - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - return; -} - -/** Top level function 2: Testbench for the top-level netlist - * This testbench includes a top-level module of a mapped FPGA and voltage pulses - */ -void dump_verilog_top_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog) { - FILE* fp = NULL; - char* title = my_strcat("FPGA Verilog Testbench for Top-level netlist of Design: ", circuit_name); - - /* Check if the path exists*/ - fp = fopen(top_netlist_name,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); - exit(1); - } - - vpr_printf(TIO_MESSAGE_INFO, "Writing Testbench for FPGA Top-level Verilog netlist for %s...\n", circuit_name); - - /* Print the title */ - dump_verilog_file_header(fp, title); - my_free(title); - - /* Start of testbench */ - dump_verilog_top_testbench_ports(fp, circuit_name); - - /* Call defined top-level module */ - dump_verilog_top_testbench_call_top_module(fp, circuit_name); - - /* Add stimuli for reset, set, clock and iopad signals */ - dump_verilog_top_testbench_stimuli(fp, num_clock, syn_verilog_opts, verilog); - - /* Testbench ends*/ - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - return; -} - -/** Top level function 3: Testbench for the top-level blif netlist (before FPGA mapping) - * This testbench includes a top-level module of a mapped FPGA and voltage pulses - */ -void dump_verilog_input_blif_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog) { - FILE* fp = NULL; - char* title = my_strcat("FPGA Verilog Testbench for input blif netlist of Design: ", circuit_name); - - /* Check if the path exists*/ - fp = fopen(top_netlist_name,"w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); - exit(1); - } - - vpr_printf(TIO_MESSAGE_INFO, "Writing Testbench for blif netlist: %s...\n", circuit_name); - - /* Print the title */ - dump_verilog_file_header(fp, title); - my_free(title); - - /* Start of testbench */ - dump_verilog_input_blif_testbench_ports(fp, circuit_name); - - /* Call defined top-level module */ - dump_verilog_input_blif_testbench_call_top_module(fp, circuit_name); - - /* Add stimuli for reset, set, clock and iopad signals */ - dump_verilog_input_blif_testbench_stimuli(fp, num_clock, syn_verilog_opts, verilog); - - /* Testbench ends*/ - fprintf(fp, "endmodule\n"); - - /* Close the file*/ - fclose(fp); - - return; - -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.h deleted file mode 100644 index 449e05591..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_top_netlist.h +++ /dev/null @@ -1,37 +0,0 @@ - -void dump_verilog_top_netlist(char* circuit_name, - char* top_netlist_name, - char* include_dir_path, - char* subckt_dir_path, - int LL_num_rr_nodes, - t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_spice spice); - -void dump_verilog_top_netlist_tile_orgz(char* circuit_name, - char* top_netlist_name, - char* include_dir_path, - char* subckt_dir_path, - int LL_num_rr_nodes, - t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices, - int num_clock, - t_spice verilog); - -void dump_verilog_top_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog); - -void dump_verilog_input_blif_testbench(char* circuit_name, - char* top_netlist_name, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog); - -void dump_verilog_top_testbench_stimuli(FILE* fp, - int num_clock, - t_syn_verilog_opts syn_verilog_opts, - t_spice verilog); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.h b/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.h deleted file mode 100644 index 6438dee65..000000000 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.h +++ /dev/null @@ -1,158 +0,0 @@ - - -void init_list_include_verilog_netlists(t_spice* spice); - -void init_include_user_defined_verilog_netlists(t_spice spice); - -void dump_include_user_defined_verilog_netlists(FILE* fp, - t_spice spice); - -void dump_verilog_file_header(FILE* fp, - char* usage); - -void dump_verilog_preproc(FILE* fp, - boolean include_timing); - -FILE* verilog_create_one_subckt_file(char* subckt_dir, - char* subckt_name_prefix, - char* verilog_subckt_file_name_prefix, - int grid_x, int grid_y, - char** verilog_fname); - -void dump_verilog_subckt_header_file(t_llist* subckt_llist_head, - char* subckt_dir, - char* header_file_name); - -char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_generic_port(FILE* fp, - enum e_dump_verilog_port_type dump_port_type, - char* port_name, int port_lsb, int port_msb); - -void decode_verilog_memory_bank_sram(t_spice_model* cur_sram_spice_model, int sram_bit, - int bl_len, int wl_len, int bl_offset, int wl_offset, - int* bl_conf_bits, int* wl_conf_bits); - -void -decode_and_add_verilog_sram_membank_conf_bit_to_llist(t_sram_orgz_info* cur_sram_orgz_info, - int mem_index, - int num_bl_per_sram, int num_wl_per_sram, - int cur_sram_bit); - - -void decode_verilog_one_level_4t1r_mux(int path_id, - int bit_len, int* conf_bits); - -void decode_verilog_rram_mux(t_spice_model* mux_spice_model, - int mux_size, int path_id, - int* bit_len, int** conf_bits, int* mux_level); - -int determine_decoder_size(int num_addr_out); - -char* chomp_verilog_node_prefix(char* verilog_node_prefix); - -char* format_verilog_node_prefix(char* verilog_node_prefix); - -char* verilog_convert_port_type_to_string(enum e_spice_model_port_type port_type); - -int rec_dump_verilog_spice_model_global_ports(FILE* fp, - t_spice_model* cur_spice_model, - boolean dump_port_type, - boolean recursive); - -int dump_verilog_global_ports(FILE* fp, t_llist* head, - boolean dump_port_type); - -void dump_verilog_mux_sram_one_outport(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info, - t_spice_model* cur_mux_spice_model, int mux_size, - int sram_lsb, int sram_msb, - int port_type_index, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_sram_one_outport(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info, - int sram_lsb, int sram_msb, - int port_type_index, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_sram_outports(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info, - int sram_lsb, int sram_msb, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_sram_one_port(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info, - int sram_lsb, int sram_msb, - int port_type_index, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_sram_ports(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, - int sram_lsb, int sram_msb, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_reserved_sram_one_port(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info, - int sram_lsb, int sram_msb, - int port_type_index, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_reserved_sram_ports(FILE* fp, - t_sram_orgz_info* cur_sram_orgz_info, - int sram_lsb, int sram_msb, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, - t_spice_model* cur_mux_verilog_model, int mux_size, - t_spice_model* cur_sram_verilog_model); - -void dump_verilog_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, - t_spice_model* sram_verilog_model); - -void dump_verilog_scff_config_bus(FILE* fp, - t_spice_model* mem_spice_model, - t_sram_orgz_info* cur_sram_orgz_info, - int lsb, int msb, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_mem_config_bus(FILE* fp, t_spice_model* mem_spice_model, - t_sram_orgz_info* cur_sram_orgz_info, - int cur_num_sram, - int num_mem_reserved_conf_bits, - int num_mem_conf_bits); - -void dump_verilog_cmos_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, - t_sram_orgz_info* cur_sram_orgz_info, - int mux_size, int cur_num_sram, - int num_mux_reserved_conf_bits, - int num_mux_conf_bits); - -void dump_verilog_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, - t_sram_orgz_info* cur_sram_orgz_info, - int mux_size, int cur_num_sram, - int num_mux_reserved_conf_bits, - int num_mux_conf_bits); - -void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_model, - t_sram_orgz_info* cur_sram_orgz_info, - int mux_size, int cur_num_sram, - int num_mux_reserved_conf_bits, - int num_mux_conf_bits); - -void dump_verilog_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_model, - t_sram_orgz_info* cur_sram_orgz_info, - int mux_size, int cur_num_sram, - int num_mux_reserved_conf_bits, - int num_mux_conf_bits); - -void dump_verilog_grid_common_port(FILE* fp, t_spice_model* cur_verilog_model, - char* general_port_prefix, int lsb, int msb, - enum e_dump_verilog_port_type dump_port_type); - -void dump_verilog_sram_config_bus_internal_wires(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, - int lsb, int msb); - -void dump_verilog_toplevel_one_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, - int pin_index, int side, - int x, int y, - boolean dump_port_type); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.c similarity index 50% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.c index 6b54ea2ff..a9278760c 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_api.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.c @@ -23,37 +23,53 @@ /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "fpga_spice_setup.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_setup.h" #include "spice_api.h" #include "verilog_api.h" +#include "fpga_bitstream.h" /* Top-level API of FPGA-SPICE */ -void vpr_fpga_spice_tool_suites(t_vpr_setup vpr_setup, +void vpr_fpga_x2p_tool_suites(t_vpr_setup vpr_setup, t_arch Arch) { + t_sram_orgz_info* sram_bitstream_orgz_info = NULL; + /* Common initializations and malloc operations */ /* If FPGA-SPICE is not called, we should initialize the spice_models */ if (TRUE == vpr_setup.FPGA_SPICE_Opts.do_fpga_spice) { - fpga_spice_setup(vpr_setup, &Arch); + fpga_x2p_setup(vpr_setup, &Arch); } /* Xifan TANG: SPICE Modeling, SPICE Netlist Output */ - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice) { - vpr_print_spice_netlists(vpr_setup, Arch, vpr_setup.FileNameOpts.CircuitName); + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice) { + vpr_fpga_spice(vpr_setup, Arch, vpr_setup.FileNameOpts.CircuitName); } /* Xifan TANG: Synthesizable verilog dumping */ - if (vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog) { - vpr_dump_syn_verilog(vpr_setup, Arch, vpr_setup.FileNameOpts.CircuitName); + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog) { + vpr_fpga_verilog(vpr_setup, Arch, vpr_setup.FileNameOpts.CircuitName); } + /* Xifan Tang: Bitstream Generator */ + if ((TRUE == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream) + &&(FALSE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice) + &&(FALSE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog)) { + /* Run bitstream generation here only when other functionalities are disabled; + * bitstream will be run inside SPICE and Verilog Generators + */ + vpr_fpga_bitstream_generator(vpr_setup, Arch, vpr_setup.FileNameOpts.CircuitName, &sram_bitstream_orgz_info); + /* Free sram_orgz_info */ + free_sram_orgz_info(sram_bitstream_orgz_info, + sram_bitstream_orgz_info->type); + } + /* Free */ if (TRUE == vpr_setup.FPGA_SPICE_Opts.do_fpga_spice) { /* Free all the backannotation containing post routing information */ free_backannotate_vpr_post_route_info(); /* TODO: free other linked lists ! */ - fpga_spice_free(&Arch); + fpga_x2p_free(&Arch); } diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.h new file mode 100644 index 000000000..898344745 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_api.h @@ -0,0 +1,5 @@ + + +void vpr_fpga_x2p_tool_suites(t_vpr_setup vpr_setup, + t_arch Arch); + diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_backannotate_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_backannotate_utils.c similarity index 72% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_backannotate_utils.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_backannotate_utils.c index a4bcdf598..438ba3746 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_backannotate_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_backannotate_utils.c @@ -22,16 +22,167 @@ #include "vpr_utils.h" #include "path_delay.h" #include "stats.h" +#include "route_common.h" /* Include spice support headers*/ #include "read_xml_spice_util.h" #include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "spice_lut.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_rr_graph_utils.h" +#include "fpga_x2p_lut_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_pb_rr_graph.h" +#include "fpga_x2p_router.h" + +/* Get initial value of a Latch/FF output*/ +int get_ff_output_init_val(t_logical_block* ff_logical_block) { + assert((0 == ff_logical_block->init_val)||(1 == ff_logical_block->init_val)); + + return ff_logical_block->init_val; +} + +int determine_rr_node_default_prev_node(t_rr_node* cur_rr_node) { + int default_prev_node = DEFAULT_PREV_NODE; + + /* Judge if the prev_node should be */ + if ((NULL != switch_inf[cur_rr_node->driver_switch].spice_model) + && (TRUE == switch_inf[cur_rr_node->driver_switch].spice_model->design_tech_info.mux_info->add_const_input)) { + default_prev_node = OPEN; /* The constant input will be the last input!!! */ + } + + return default_prev_node; +} + +/* Get initial value of a mapped LUT output*/ +int get_lut_output_init_val(t_logical_block* lut_logical_block) { + int i; + int* sram_bits = NULL; /* decoded SRAM bits */ + int truth_table_length = 0; + char** truth_table = NULL; + int lut_size = 0; + int input_net_index = OPEN; + int* input_init_val = NULL; + int init_path_id = 0; + int output_init_val = 0; + + t_spice_model* lut_spice_model = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + /* Ensure a valid file handler*/ + if (NULL == lut_logical_block) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid LUT logical block!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get SPICE model */ + assert((NULL != lut_logical_block->pb) + && ( NULL != lut_logical_block->pb->pb_graph_node) + && ( NULL != lut_logical_block->pb->pb_graph_node->pb_type)); + lut_spice_model = lut_logical_block->pb->pb_graph_node->pb_type->parent_mode->parent_pb_type->phy_pb_type->spice_model; + + assert(SPICE_MODEL_LUT == lut_spice_model->type); + + sram_ports = find_spice_model_ports(lut_spice_model, SPICE_MODEL_PORT_SRAM, + &num_sram_port, TRUE); + assert((1 == num_sram_port) || (2 == num_sram_port)); + + /* Get the truth table */ + truth_table = assign_lut_truth_table(lut_logical_block, &truth_table_length); + lut_size = lut_logical_block->used_input_pins; + assert(!(0 > lut_size)); + /* Special for LUT_size = 0 */ + if (0 == lut_size) { + /* Generate sram bits*/ + sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, + 1, sram_ports[0]->default_val); + /* This is constant generator, SRAM bits should be the same */ + output_init_val = sram_bits[0]; + for (i = 0; i < (int)pow(2.,(double)lut_size); i++) { + assert(sram_bits[i] == output_init_val); + } + } else { + /* Generate sram bits*/ + sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, + lut_size, sram_ports[0]->default_val); + + assert(1 == lut_logical_block->pb->pb_graph_node->num_input_ports); + assert(1 == lut_logical_block->pb->pb_graph_node->num_output_ports); + /* Get the initial path id */ + input_init_val = (int*)my_malloc(sizeof(int)*lut_size); + for (i = 0; i < lut_size; i++) { + input_net_index = lut_logical_block->input_nets[0][i]; + input_init_val[i] = vpack_net[input_net_index].spice_net_info->init_val; + if ((1 != input_init_val[i]) && (0 != input_init_val[i])) { + assert ((1 == input_init_val[i]) || (0 == input_init_val[i])); + } + } + + init_path_id = determine_lut_path_id(lut_size, input_init_val); + /* Check */ + assert((!(0 > init_path_id))&&(init_path_id < (int)pow(2.,(double)lut_size))); + output_init_val = sram_bits[init_path_id]; + } + + /* Check */ + if ((1 != output_init_val) && (0 != output_init_val)) { + assert ((1 == output_init_val) || (0 == output_init_val)); + } + + /*Free*/ + for (i = 0; i < truth_table_length; i++) { + free(truth_table[i]); + } + free(truth_table); + my_free(sram_bits); + my_free(input_init_val); + + return output_init_val; +} + +/* Deteremine the initial value of an output of a logical block + * The logical block could be a LUT, a memory block or a multiplier + */ +int get_logical_block_output_init_val(t_logical_block* cur_logical_block) { + int output_init_val = 0; + t_spice_model* cur_spice_model = NULL; + + /* Get the spice_model of current logical_block */ + assert((NULL != cur_logical_block->pb) + && ( NULL != cur_logical_block->pb->pb_graph_node) + && ( NULL != cur_logical_block->pb->pb_graph_node->pb_type)); + + /* We only care LUT here, for other blocks we cannot force now, for others, we just give zero. */ + if (0 == strcmp(cur_logical_block->model->name, BLIF_LUT_KEYWORD)) { + cur_spice_model = cur_logical_block->pb->pb_graph_node->pb_type->parent_mode->parent_pb_type->phy_pb_type->spice_model; + } else { + return get_ff_output_init_val(cur_logical_block); + } + + /* Switch to specific cases*/ + switch (cur_spice_model->type) { + case SPICE_MODEL_LUT: + /* Determine the initial value from LUT inputs */ + output_init_val = get_lut_output_init_val(cur_logical_block); + break; + case SPICE_MODEL_HARDLOGIC: + /* We have no information, give a default 0 now... + * TODO: find a smarter way! + */ + output_init_val = get_ff_output_init_val(cur_logical_block); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SPICE MODEL (name=%s) in determining the initial output value of logical block(name=%s)!\n", + __FILE__, __LINE__, cur_spice_model->name, cur_logical_block->name); + exit(1); + } + + return output_init_val; +} -#include "fpga_spice_backannotate_utils.h" /* Alloc, initialize and free functions for sb_info & cb_info */ /* Initialize a SB_info */ @@ -227,7 +378,7 @@ int get_rr_node_index_in_sb_info(t_rr_node* cur_rr_node, int inode, cnt, ret; cnt = 0; - ret = -1; + ret = OPEN; /* Depending on the type of rr_node, we search different arrays */ switch (cur_rr_node->type) { @@ -301,26 +452,6 @@ int is_rr_node_exist_opposite_side_in_sb_info(t_sb cur_sb_info, return interc; } -/* Check if the drivers for cur_rr_node imply a short connection in this Switch block - */ -boolean check_drive_rr_node_imply_short(t_sb cur_sb_info, - t_rr_node* src_rr_node, - int chan_side) { - int inode, index, side; - - assert((CHANX == src_rr_node->type) || (CHANY == src_rr_node->type)); - - for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) { - get_rr_node_side_and_index_in_sb_info(src_rr_node->drive_rr_nodes[inode], cur_sb_info, IN_PORT, &side, &index); - /* We need to be sure that drive_rr_node is part of the SB */ - if (((-1 == index)||(-1 == side)) - && ((CHANX == src_rr_node->drive_rr_nodes[inode]->type)||(CHANY == src_rr_node->drive_rr_nodes[inode]->type))) { - return TRUE; - } - } - - return FALSE; -} /* Get the side and index of a given rr_node in a SB_info * Return cur_rr_node_side & cur_rr_node_index @@ -359,6 +490,28 @@ void get_rr_node_side_and_index_in_sb_info(t_rr_node* cur_rr_node, return; } +/* Check if the drivers for cur_rr_node imply a short connection in this Switch block + */ +boolean check_drive_rr_node_imply_short(t_sb cur_sb_info, + t_rr_node* src_rr_node, + int chan_side) { + int inode, index, side; + + assert((CHANX == src_rr_node->type) || (CHANY == src_rr_node->type)); + + for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) { + get_rr_node_side_and_index_in_sb_info(src_rr_node->drive_rr_nodes[inode], cur_sb_info, IN_PORT, &side, &index); + /* We need to be sure that drive_rr_node is part of the SB */ + if (((-1 == index)||(-1 == side)) + && ((CHANX == src_rr_node->drive_rr_nodes[inode]->type)||(CHANY == src_rr_node->drive_rr_nodes[inode]->type))) { + return TRUE; + } + } + + return FALSE; +} + + /* Get the index of a given rr_node in a CB_info */ int get_rr_node_index_in_cb_info(t_rr_node* cur_rr_node, t_cb cur_cb_info, @@ -489,10 +642,15 @@ void rec_backannotate_rr_node_net_num(int LL_num_rr_nodes, */ for (iedge = 0; iedge < LL_rr_node[src_node_index].num_edges; iedge++) { to_node = LL_rr_node[src_node_index].edges[iedge]; - assert(OPEN != LL_rr_node[to_node].prev_node); + /* assert(OPEN != LL_rr_node[to_node].prev_node); */ if (src_node_index == LL_rr_node[to_node].prev_node) { assert(iedge == LL_rr_node[to_node].prev_edge); /* assert(LL_rr_node[src_node_index].net_num == LL_rr_node[to_node].net_num); */ + /* Label parasitic net */ + if ((OPEN == LL_rr_node[to_node].net_num) + && (OPEN != LL_rr_node[src_node_index].net_num)) { + LL_rr_node[to_node].is_parasitic_net = TRUE; + } /* Propagate the net_num */ LL_rr_node[to_node].net_num = LL_rr_node[src_node_index].net_num; /* Make the flag which indicates a changing has been made */ @@ -688,143 +846,6 @@ void free_clb_nets_spice_net_info() { return; } -static -void build_prev_node_list_rr_nodes(int LL_num_rr_nodes, - t_rr_node* LL_rr_node) { - int inode, iedge, to_node, cur; - /* int jnode, switch_box_x, switch_box_y, chan_side, switch_index; */ - int* cur_index = (int*)my_malloc(sizeof(int)*LL_num_rr_nodes); - - /* This function is not timing-efficient, I comment it */ - /* - for (inode = 0; inode < LL_num_rr_nodes; inode++) { - find_prev_rr_nodes_with_src(&(LL_rr_nodes[inode]), - &(LL_rr_nodes[inode].num_drive_rr_nodes), - &(LL_rr_nodes[inode].drive_rr_nodes), - &(LL_rr_nodes[inode].drive_switches)); - } - */ - for (inode = 0; inode < LL_num_rr_nodes; inode++) { - /* Malloc */ - LL_rr_node[inode].num_drive_rr_nodes = LL_rr_node[inode].fan_in; - if (0 == LL_rr_node[inode].fan_in) { - continue; - } - LL_rr_node[inode].drive_rr_nodes = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*LL_rr_node[inode].num_drive_rr_nodes); - LL_rr_node[inode].drive_switches = (int*)my_malloc(sizeof(int)*LL_rr_node[inode].num_drive_rr_nodes); - } - /* Initialize */ - for (inode = 0; inode < LL_num_rr_nodes; inode++) { - cur_index[inode] = 0; - for (iedge = 0; iedge < LL_rr_node[inode].num_drive_rr_nodes; iedge++) { - LL_rr_node[inode].drive_rr_nodes[iedge] = NULL; - LL_rr_node[inode].drive_switches[iedge] = -1; - } - } - /* Fill */ - for (inode = 0; inode < LL_num_rr_nodes; inode++) { - for (iedge = 0; iedge < LL_rr_node[inode].num_edges; iedge++) { - to_node = LL_rr_node[inode].edges[iedge]; - cur = cur_index[to_node]; - LL_rr_node[to_node].drive_rr_nodes[cur] = &(LL_rr_node[inode]); - LL_rr_node[to_node].drive_switches[cur] = LL_rr_node[inode].switches[iedge]; - /* Update cur_index[to_node]*/ - assert(NULL != LL_rr_node[to_node].drive_rr_nodes[cur]); - cur_index[to_node]++; - } - } - /* Check */ - for (inode = 0; inode < LL_num_rr_nodes; inode++) { - assert(cur_index[inode] == LL_rr_node[inode].num_drive_rr_nodes); - } - - /* TODO: fill the sb_drive_rr_nodes */ - //for (inode = 0; inode < LL_num_rr_nodes; inode++) { - // /* Initial */ - // LL_rr_node[inode].sb_num_drive_rr_nodes = 0; - // LL_rr_node[inode].sb_drive_rr_nodes = NULL; - // LL_rr_node[inode].sb_drive_switches = NULL; - // /* Find SB source rr nodes: channels*/ - // switch (LL_rr_node[inode].type) { - // case CHANX: - // assert(LL_rr_node[inode].ylow == LL_rr_node[inode].yhigh); - // switch (LL_rr_node[inode].direction) { - // case INC_DIRECTION: - // switch_box_x = LL_rr_node[inode].xlow-1; - // switch_box_y = LL_rr_node[inode].ylow; - // chan_side = RIGHT; - // break; - // case DEC_DIRECTION: - // switch_box_x = LL_rr_node[inode].xhigh; - // switch_box_y = LL_rr_node[inode].yhigh; - // chan_side = LEFT; - // break; - // case BI_DIRECTION: - // vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Bidirectional routing wires are not supported!\n", - // __FILE__, __LINE__); - // exit(1); - // default: - // vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid rr_node direction!\n", - // __FILE__, __LINE__); - // exit(1); - // } - // find_drive_rr_nodes_switch_box(switch_box_x, switch_box_y, &(LL_rr_node[inode]), chan_side, 0, - // &(LL_rr_node[inode].sb_num_drive_rr_nodes), - // &(LL_rr_node[inode].sb_drive_rr_nodes), &switch_index); - // /* fill the sb_drive_switches */ - // LL_rr_node[inode].sb_drive_switches = (int*)my_malloc(sizeof(int)*LL_rr_node[inode].sb_num_drive_rr_nodes); - // for (jnode = 0; jnode < LL_rr_node[inode].sb_num_drive_rr_nodes; jnode++) { - // LL_rr_node[inode].sb_drive_switches[jnode] = switch_index; - // } - // break; - // case CHANY: - // /* TODO: fill the sb_drive_rr_nodes */ - // assert(LL_rr_node[inode].xlow == LL_rr_node[inode].xhigh); - // switch (LL_rr_node[inode].direction) { - // case INC_DIRECTION: - // switch_box_x = LL_rr_node[inode].xlow; - // switch_box_y = LL_rr_node[inode].ylow-1; - // chan_side = TOP; - // break; - // case DEC_DIRECTION: - // switch_box_x = LL_rr_node[inode].xhigh; - // switch_box_y = LL_rr_node[inode].yhigh; - // chan_side = BOTTOM; - // break; - // case BI_DIRECTION: - // vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Bidirectional routing wires are not supported!\n", - // __FILE__, __LINE__); - // exit(1); - // default: - // vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid rr_node direction!\n", - // __FILE__, __LINE__); - // exit(1); - // } - // find_drive_rr_nodes_switch_box(switch_box_x, switch_box_y, &(LL_rr_node[inode]), chan_side, 0, - // &(LL_rr_node[inode].sb_num_drive_rr_nodes), - // &(LL_rr_node[inode].sb_drive_rr_nodes), &switch_index); - // /* fill the sb_drive_switches */ - // LL_rr_node[inode].sb_drive_switches = (int*)my_malloc(sizeof(int)*LL_rr_node[inode].sb_num_drive_rr_nodes); - // for (jnode = 0; jnode < LL_rr_node[inode].sb_num_drive_rr_nodes; jnode++) { - // LL_rr_node[inode].sb_drive_switches[jnode] = switch_index; - // } - // break; - // case SOURCE: - // case OPIN: - // case SINK: - // case IPIN: - // case NUM_RR_TYPES: - // break; - // default: - // vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid rr_node type!\n", - // __FILE__, __LINE__); - // exit(1); - // } - //} - - return; -} - static void set_one_pb_rr_node_default_prev_node_edge(t_rr_node* pb_rr_graph, t_pb_graph_pin* des_pb_graph_pin, @@ -856,6 +877,14 @@ void set_one_pb_rr_node_default_prev_node_edge(t_rr_node* pb_rr_graph, break; } + /* prev_node may not exist since some pb_graph_pin is accessible in some mode, we do not need to find a prev_edge */ + if (OPEN == prev_node) { + /* backannotate */ + pb_rr_graph[node_index].prev_node = prev_node; + pb_rr_graph[node_index].prev_edge = prev_edge; + return; + } + /* Find prev_edge */ for (iedge = 0; iedge < pb_rr_graph[prev_node].pb_graph_pin->num_output_edges; iedge++) { check_pb_graph_edge(*(pb_rr_graph[prev_node].pb_graph_pin->output_edges[iedge])); @@ -879,16 +908,24 @@ static void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, t_pb_graph_node* cur_pb_graph_node, t_rr_node* pb_rr_nodes) { - int ipb, jpb, select_mode_index; + int imode, ipb, jpb, select_mode_index; int iport, ipin, node_index; t_pb_graph_node* child_pb_graph_node; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; /* Return when we meet a null pb */ if (NULL == cur_pb) { - /* Skip non-LUT pb*/ - if (LUT_CLASS != cur_pb_graph_node->pb_type->class_type) { - return; + /* Wired LUT does not has a pb but has a net_num */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + node_index = cur_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + if (OPEN != pb_rr_nodes[node_index].net_num) { + pb_rr_nodes[node_index].vpack_net_num = pb_rr_nodes[node_index].net_num; + } + } } + + /* Wired LUT does not has a pb but has a net_num */ for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; @@ -897,11 +934,33 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, } } } + /* Return if this is a leaf node */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + return; + } + + /* Go recusrively */ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + /* For wired LUT */ + if (FALSE == is_pb_used_for_wiring(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + &(cur_pb_graph_node->pb_type->modes[imode].pb_type_children[ipb]), + pb_rr_nodes)) { + continue; + } + /* Reach here means that this LUT is in wired mode (a buffer) + * synchronize the net num + */ + back_annotate_one_pb_rr_node_map_info_rec(NULL, + &(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + pb_rr_nodes); + } + } + } return; } - - select_mode_index = cur_pb->mode; /* For all the input/output/clock pins of this pb, * check the net_num and assign default prev_node, prev_edge @@ -914,10 +973,10 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, * | * input_pins, edges, output_pins */ + select_mode_index = cur_pb->mode; for (iport = 0; iport < cur_pb->pb_graph_node->num_output_ports; iport++) { for (ipin = 0; ipin < cur_pb->pb_graph_node->num_output_pins[iport]; ipin++) { /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; node_index = cur_pb->pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; /* If we find an OPEN net, try to find the parasitic net_num*/ if (OPEN == pb_rr_nodes[node_index].net_num) { @@ -935,7 +994,7 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, ||(NULL == cur_pb->child_pbs)) { return; } - + /* We check input_pins of child_pb_graph_node and its the input_edges * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node * cur_pb_graph_node.input_pins -----------------> child_pb_graph_node.input_pins @@ -943,6 +1002,7 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, * | * input_pins, edges, output_pins */ + select_mode_index = cur_pb->mode; for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { child_pb_graph_node = &(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]); @@ -950,14 +1010,13 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; /* If we find an OPEN net, try to find the parasitic net_num*/ if (OPEN == pb_rr_nodes[node_index].net_num) { set_one_pb_rr_node_default_prev_node_edge(pb_rr_nodes, &(child_pb_graph_node->input_pins[iport][ipin]), select_mode_index); - } else { + } else { pb_rr_nodes[node_index].vpack_net_num = pb_rr_nodes[node_index].net_num; } } @@ -966,7 +1025,6 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; node_index = child_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster; /* If we find an OPEN net, try to find the parasitic net_num*/ if (OPEN == pb_rr_nodes[node_index].net_num) { @@ -980,7 +1038,7 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, } } } - + /* Go recursively */ for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { @@ -988,18 +1046,16 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb, back_annotate_one_pb_rr_node_map_info_rec(&(cur_pb->child_pbs[ipb][jpb]), &(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]), cur_pb->rr_graph); - } else { + } else if (TRUE == is_pb_used_for_wiring(&(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]), + &(cur_pb->pb_graph_node->pb_type->modes[select_mode_index].pb_type_children[ipb]), + cur_pb->rr_graph)) { /* For wired LUT */ - if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]), - &(cur_pb->pb_graph_node->pb_type->modes[select_mode_index].pb_type_children[ipb]), - cur_pb->rr_graph)) { /* Reach here means that this LUT is in wired mode (a buffer) * synchronize the net num */ back_annotate_one_pb_rr_node_map_info_rec(NULL, &(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]), cur_pb->rr_graph); - } } } } @@ -1016,9 +1072,9 @@ void back_annotate_pb_rr_node_map_info() { for (iblk = 0; iblk < num_blocks; iblk++) { /* By pass IO */ if (IO_TYPE == block[iblk].type) { - continue; + continue; } - back_annotate_one_pb_rr_node_map_info_rec(block[iblk].pb, + back_annotate_one_pb_rr_node_map_info_rec(block[iblk].pb, block[iblk].pb->pb_graph_node, block[iblk].pb->rr_graph); } @@ -1036,7 +1092,7 @@ void set_one_pb_rr_node_net_num(t_rr_node* pb_rr_graph, assert(NULL != des_pb_graph_pin); assert(NULL != pb_rr_graph); - node_index = des_pb_graph_pin->pin_count_in_cluster; + node_index = des_pb_graph_pin->rr_node_index_physical_pb; assert(OPEN == pb_rr_graph[node_index].net_num); /* if this pin has 0 driver, return OPEN */ @@ -1048,12 +1104,20 @@ void set_one_pb_rr_node_net_num(t_rr_node* pb_rr_graph, prev_node = pb_rr_graph[node_index].prev_node; prev_edge = pb_rr_graph[node_index].prev_edge; + + /* Some node may be disconnected */ + if (OPEN == prev_node) { + pb_rr_graph[node_index].net_num = OPEN; + pb_rr_graph[node_index].vpack_net_num = OPEN; + return; + } + assert(OPEN != prev_node); assert(OPEN != prev_edge); /* Set default prev_node */ check_pb_graph_edge(*(pb_rr_graph[prev_node].pb_graph_pin->output_edges[prev_edge])); - assert(node_index == pb_rr_graph[prev_node].pb_graph_pin->output_edges[prev_edge]->output_pins[0]->pin_count_in_cluster); + assert(node_index == pb_rr_graph[prev_node].pb_graph_pin->output_edges[prev_edge]->output_pins[0]->rr_node_index_physical_pb); pb_rr_graph[node_index].net_num = pb_rr_graph[prev_node].net_num; pb_rr_graph[node_index].vpack_net_num = pb_rr_graph[prev_node].net_num; @@ -1062,7 +1126,7 @@ void set_one_pb_rr_node_net_num(t_rr_node* pb_rr_graph, /* Mark the net_num of all the rr_nodes in complex blocks */ static -void backannotate_one_pb_rr_nodes_net_info_rec(t_pb* cur_pb) { +void backannotate_one_pb_rr_nodes_net_info_rec(t_phy_pb* cur_pb) { int ipb, jpb, select_mode_index; int iport, ipin, node_index; t_rr_node* pb_rr_nodes = NULL; @@ -1097,13 +1161,13 @@ void backannotate_one_pb_rr_nodes_net_info_rec(t_pb* cur_pb) { for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = child_pb_graph_node->input_pins[iport][ipin].rr_node_index_physical_pb; /* If we find an OPEN net, try to find the parasitic net_num*/ if (OPEN == pb_rr_nodes[node_index].net_num) { set_one_pb_rr_node_net_num(pb_rr_nodes, &(child_pb_graph_node->input_pins[iport][ipin])); - } else { - assert(pb_rr_nodes[node_index].net_num == pb_rr_nodes[node_index].vpack_net_num); + /* Label this net as parasitic net */ + pb_rr_nodes[node_index].is_parasitic_net = TRUE; } } } @@ -1111,13 +1175,13 @@ void backannotate_one_pb_rr_nodes_net_info_rec(t_pb* cur_pb) { for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; - node_index = child_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster; + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = child_pb_graph_node->clock_pins[iport][ipin].rr_node_index_physical_pb; /* If we find an OPEN net, try to find the parasitic net_num*/ if (OPEN == pb_rr_nodes[node_index].net_num) { - set_one_pb_rr_node_net_num(pb_rr_nodes, &(child_pb_graph_node->clock_pins[iport][ipin])); - } else { - assert(pb_rr_nodes[node_index].net_num == pb_rr_nodes[node_index].vpack_net_num); + set_one_pb_rr_node_net_num(pb_rr_nodes, &(child_pb_graph_node->clock_pins[iport][ipin])); + /* Label this net as parasitic net */ + pb_rr_nodes[node_index].is_parasitic_net = TRUE; } } } @@ -1145,13 +1209,13 @@ void backannotate_one_pb_rr_nodes_net_info_rec(t_pb* cur_pb) { for (iport = 0; iport < cur_pb->pb_graph_node->num_output_ports; iport++) { for (ipin = 0; ipin < cur_pb->pb_graph_node->num_output_pins[iport]; ipin++) { /* Get the selected edge of current pin*/ - pb_rr_nodes = cur_pb->rr_graph; - node_index = cur_pb->pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb->pb_graph_node->output_pins[iport][ipin].rr_node_index_physical_pb; /* If we find an OPEN net, try to find the parasitic net_num*/ if (OPEN == pb_rr_nodes[node_index].net_num) { set_one_pb_rr_node_net_num(pb_rr_nodes, &(cur_pb->pb_graph_node->output_pins[iport][ipin])); - } else { - assert(pb_rr_nodes[node_index].net_num == pb_rr_nodes[node_index].vpack_net_num); + /* Label this net as parasitic net */ + pb_rr_nodes[node_index].is_parasitic_net = TRUE; } } } @@ -1169,7 +1233,7 @@ void backannotate_pb_rr_nodes_net_info() { if (IO_TYPE == block[iblk].type) { continue; } - backannotate_one_pb_rr_nodes_net_info_rec(block[iblk].pb); + backannotate_one_pb_rr_nodes_net_info_rec((t_phy_pb*)block[iblk].phy_pb); } return; @@ -1178,7 +1242,7 @@ void backannotate_pb_rr_nodes_net_info() { /* Mark the prev_edge and prev_node of all the rr_nodes in global routing */ static void back_annotate_rr_node_map_info() { - int inode, jnode, inet; + int inode, jnode, inet, default_prev_node; int next_node, iedge; t_trace* tptr; t_rr_type rr_type; @@ -1200,8 +1264,11 @@ void back_annotate_rr_node_map_info() { } assert(0 < rr_node[inode].num_edges); for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { - jnode = rr_node[inode].edges[iedge]; - if (&(rr_node[inode]) == rr_node[jnode].drive_rr_nodes[0]) { + jnode = rr_node[inode].edges[iedge]; + default_prev_node = determine_rr_node_default_prev_node(&rr_node[jnode]); + if (DEFAULT_PREV_NODE == default_prev_node) { + rr_node[jnode].prev_node = default_prev_node; + } else if (&(rr_node[inode]) == rr_node[jnode].drive_rr_nodes[default_prev_node]) { rr_node[jnode].prev_node = inode; rr_node[jnode].prev_edge = iedge; } @@ -1252,7 +1319,8 @@ void back_annotate_rr_node_map_info() { assert(OPEN != rr_node[next_node].prev_edge); break; default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid traceback element type.\n"); + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid traceback element type.\n", + __FILE__, __LINE__); exit(1); } tptr = tptr->next; @@ -1262,17 +1330,6 @@ void back_annotate_rr_node_map_info() { return; } -void backup_one_pb_rr_node_pack_prev_node_edge(t_rr_node* pb_rr_node) { - - pb_rr_node->prev_node_in_pack = pb_rr_node->prev_node; - pb_rr_node->prev_edge_in_pack = pb_rr_node->prev_edge; - pb_rr_node->net_num_in_pack = pb_rr_node->net_num; - pb_rr_node->prev_node = OPEN; - pb_rr_node->prev_edge = OPEN; - - return; -} - void rec_sync_pb_post_routing_vpack_net_num(t_pb* cur_pb) { int ipb, jpb, select_mode_index; int iport, ipin, node_index; @@ -1364,13 +1421,6 @@ void update_one_io_grid_pack_net_num(int x, int y) { assert(block[blk_id].y == y); assert(OPEN != blk_id); } - /* Bypass invalide block id - * block id could be invalid in IO blocks - * TODO: figure out why, now I just bypass - */ - if (OPEN == blk_id) { - continue; - } pb = block[blk_id].pb; assert(NULL != pb); rec_sync_pb_post_routing_vpack_net_num(pb); @@ -1381,7 +1431,7 @@ void update_one_io_grid_pack_net_num(int x, int y) { /* During routing stage, VPR swap logic equivalent pins - * which potentially changes the packing results (prev_node, prev_edge) in local routing + * which potentially changes the packing results (net_num and vpack_net_num) in local routing * The following functions are to update the local routing results to match them with routing results */ void update_one_grid_pack_net_num(int x, int y) { @@ -1396,17 +1446,14 @@ void update_one_grid_pack_net_num(int x, int y) { assert((!(y < 0))&&(y < (ny + 2))); type = grid[x][y].type; - /* Bypass IO_TYPE*/ - if ((EMPTY_TYPE == type)||(IO_TYPE == type)) { - //if ((EMPTY_TYPE == type)) { - return; - } + + /* check */ + assert ((NULL != type) + && (EMPTY_TYPE != type) + && (IO_TYPE != type)); + for (iblk = 0; iblk < grid[x][y].usage; iblk++) { blk_id = grid[x][y].blocks[iblk]; - if ((IO_TYPE != type)) { - assert(block[blk_id].x == x); - assert(block[blk_id].y == y); - } pb = block[blk_id].pb; assert(NULL != pb); local_rr_graph = pb->rr_graph; @@ -1417,24 +1464,23 @@ void update_one_grid_pack_net_num(int x, int y) { /* Find the pb net_num and update OPIN net_num */ pin_global_rr_node_id = get_rr_node_index(x, y, OPIN, ipin, rr_node_indices); if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; - local_rr_graph[ipin].net_num = OPEN; - local_rr_graph[ipin].vpack_net_num = OPEN; + if ( (OPEN != local_rr_graph[ipin].net_num) + && (TRUE == vpack_net[local_rr_graph[ipin].net_num].is_global)) { + local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; + local_rr_graph[ipin].vpack_net_num = local_rr_graph[ipin].net_num; + local_rr_graph[ipin].net_num = vpack_to_clb_net_mapping[local_rr_graph[ipin].net_num]; + } else { + local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; + local_rr_graph[ipin].net_num = OPEN; + local_rr_graph[ipin].vpack_net_num = OPEN; //local_rr_graph[ipin].prev_node = 0; //local_rr_graph[ipin].prev_edge = 0; + } continue; /* bypass non-mapped OPIN */ } /* back annotate pb ! */ rr_node[pin_global_rr_node_id].pb = pb; vpack_net_id = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - //printf("Update post-route pb_rr_graph output: vpack_net_name = %s\n", - // vpack_net[vpack_net_id].name); - /* Special for IO_TYPE */ - if (IO_TYPE == type) { - assert(local_rr_graph[ipin].net_num == rr_node[pin_global_rr_node_id].vpack_net_num); - local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; - continue; - } assert(ipin == local_rr_graph[ipin].pb_graph_pin->pin_count_in_cluster); /* Update net_num */ local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; @@ -1461,26 +1507,26 @@ void update_one_grid_pack_net_num(int x, int y) { } else if (RECEIVER == type->class_inf[class_id].type) { /* Find the global rr_node net_num and update pb net_num */ pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, ipin, rr_node_indices); + /* Special for global net, preserve them in the local rr_graph */ /* Get the index of Vpack net from global rr_node net_num (clb_net index)*/ if (OPEN == rr_node[pin_global_rr_node_id].net_num) { - local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; - local_rr_graph[ipin].net_num = OPEN; - local_rr_graph[ipin].vpack_net_num = OPEN; + if ( (OPEN != local_rr_graph[ipin].net_num) + && (TRUE == vpack_net[local_rr_graph[ipin].net_num].is_global)) { + local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; + local_rr_graph[ipin].vpack_net_num = local_rr_graph[ipin].net_num; + local_rr_graph[ipin].net_num = vpack_to_clb_net_mapping[local_rr_graph[ipin].net_num]; + } else { + local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; + local_rr_graph[ipin].net_num = OPEN; + local_rr_graph[ipin].vpack_net_num = OPEN; //local_rr_graph[ipin].prev_node = 0; //local_rr_graph[ipin].prev_edge = 0; + } continue; /* bypass non-mapped IPIN */ } /* back annotate pb ! */ rr_node[pin_global_rr_node_id].pb = pb; vpack_net_id = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; - //printf("Update post-route pb_rr_graph input: vpack_net_name = %s\n", - // vpack_net[vpack_net_id].name); - /* Special for IO_TYPE */ - if (IO_TYPE == type) { - assert(local_rr_graph[ipin].net_num == rr_node[pin_global_rr_node_id].vpack_net_num); - local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; - continue; - } assert(ipin == local_rr_graph[ipin].pb_graph_pin->pin_count_in_cluster); /* Update net_num */ local_rr_graph[ipin].net_num_in_pack = local_rr_graph[ipin].net_num; @@ -1502,19 +1548,6 @@ void update_one_grid_pack_net_num(int x, int y) { continue; /* OPEN PIN */ } } - /* Second run to backannoate parasitic OPIN net_num*/ - //for (ipin = 0; ipin < type->num_pins; ipin++) { - // class_id = type->pin_class[ipin]; - // if (DRIVER == type->class_inf[class_id].type) { - // /* Find the pb net_num and update OPIN net_num */ - // pin_global_rr_node_id = get_rr_node_index(x, y, OPIN, ipin, rr_node_indices); - // if (OPEN == local_rr_graph[ipin].net_num) { - // continue; /* bypass non-mapped OPIN */ - // } - // rr_node[pin_global_rr_node_id].net_num = vpack_to_clb_net_mapping[local_rr_graph[ipin].net_num]; - // rr_node[pin_global_rr_node_id].vpack_net_num = vpack_to_clb_net_mapping[local_rr_graph[ipin].net_num]; - // } - //} } return; @@ -1596,9 +1629,9 @@ void update_one_unused_grid_output_pins_parasitic_nets(int ix, int iy) { * are absorbed into CLBs during packing, therefore they are invisible in * clb_nets. But indeed, they exist in global routing as parasitic nets. */ -void update_one_used_grid_pb_pins_parasitic_nets(t_pb* cur_pb, +void update_one_used_grid_pb_pins_parasitic_nets(t_phy_pb* cur_pb, int ix, int iy) { - int ipin; + int ipin, cur_pin; int pin_global_rr_node_id,class_id; t_type_ptr type = NULL; t_rr_node* local_rr_graph = NULL; @@ -1614,22 +1647,26 @@ void update_one_used_grid_pb_pins_parasitic_nets(t_pb* cur_pb, } assert(NULL != cur_pb); - local_rr_graph = cur_pb->rr_graph; + local_rr_graph = cur_pb->rr_graph->rr_node; for (ipin = 0; ipin < type->num_pins; ipin++) { class_id = type->pin_class[ipin]; if (DRIVER == type->class_inf[class_id].type) { /* Find the pb net_num and update OPIN net_num */ pin_global_rr_node_id = get_rr_node_index(ix, iy, OPIN, ipin, rr_node_indices); - assert(local_rr_graph[ipin].vpack_net_num == local_rr_graph[ipin].net_num); if (OPEN == local_rr_graph[ipin].net_num) { assert(OPEN == local_rr_graph[ipin].vpack_net_num); rr_node[pin_global_rr_node_id].net_num = OPEN; rr_node[pin_global_rr_node_id].vpack_net_num = OPEN; continue; /* bypass non-mapped OPIN */ } - assert(ipin == local_rr_graph[ipin].pb_graph_pin->pin_count_in_cluster); + cur_pin = local_rr_graph[ipin].pb_graph_pin->rr_node_index_physical_pb; //rr_node[pin_global_rr_node_id].net_num = vpack_to_clb_net_mapping[local_rr_graph[ipin].net_num]; - rr_node[pin_global_rr_node_id].vpack_net_num = local_rr_graph[ipin].vpack_net_num; + rr_node[pin_global_rr_node_id].vpack_net_num = local_rr_graph[cur_pin].vpack_net_num; + if ( (OPEN == rr_node[pin_global_rr_node_id].vpack_net_num) + && (OPEN != local_rr_graph[cur_pin].vpack_net_num)) { + /* Label this net as parasitic net */ + rr_node[pin_global_rr_node_id].is_parasitic_net = TRUE; + } } else if (RECEIVER == type->class_inf[class_id].type) { /* Find the global rr_node net_num and update pb net_num */ pin_global_rr_node_id = get_rr_node_index(ix, iy, IPIN, ipin, rr_node_indices); @@ -1639,9 +1676,14 @@ void update_one_used_grid_pb_pins_parasitic_nets(t_pb* cur_pb, local_rr_graph[ipin].vpack_net_num = OPEN; continue; /* bypass non-mapped IPIN */ } - assert(ipin == local_rr_graph[ipin].pb_graph_pin->pin_count_in_cluster); - local_rr_graph[ipin].net_num = rr_node[pin_global_rr_node_id].vpack_net_num; - local_rr_graph[ipin].vpack_net_num = rr_node[pin_global_rr_node_id].vpack_net_num; + cur_pin = local_rr_graph[ipin].pb_graph_pin->rr_node_index_physical_pb; + local_rr_graph[cur_pin].net_num = rr_node[pin_global_rr_node_id].vpack_net_num; + local_rr_graph[cur_pin].vpack_net_num = rr_node[pin_global_rr_node_id].vpack_net_num; + if ( (OPEN == local_rr_graph[cur_pin].vpack_net_num) + && (OPEN == rr_node[pin_global_rr_node_id].vpack_net_num)) { + /* Label this net as parasitic net */ + local_rr_graph[cur_pin].is_parasitic_net = TRUE; + } } else { continue; /* OPEN PIN */ } @@ -1663,12 +1705,12 @@ void update_one_grid_pb_pins_parasitic_nets(int ix, int iy) { /* Only for mapped block */ assert(NULL != block[grid[ix][iy].blocks[iblk]].pb); /* Mark the temporary net_num for the type pins*/ - mark_one_pb_parasitic_nets(block[grid[ix][iy].blocks[iblk]].pb); + mark_one_pb_parasitic_nets((t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb); /* Update parasitic nets */ - update_one_used_grid_pb_pins_parasitic_nets(block[grid[ix][iy].blocks[iblk]].pb, + update_one_used_grid_pb_pins_parasitic_nets((t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb, ix, iy); /* update parasitic nets in each pb */ - backannotate_one_pb_rr_nodes_net_info_rec(block[grid[ix][iy].blocks[iblk]].pb); + backannotate_one_pb_rr_nodes_net_info_rec((t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb); } /* By pass Unused blocks */ for (iblk = grid[ix][iy].usage; iblk < grid[ix][iy].type->capacity; iblk++) { @@ -2515,6 +2557,9 @@ void parasitic_net_estimation() { init_rr_nodes_vpack_net_num_changed(num_rr_nodes, rr_node); + init_rr_nodes_is_parasitic_net(num_rr_nodes, + rr_node); + /* * vpr_printf(TIO_MESSAGE_INFO, "Backannotating local routing net...\n"); backannotate_pb_rr_nodes_net_info(); @@ -2547,12 +2592,506 @@ void parasitic_net_estimation() { return; } +/* Annotate the physical_mode_pin in pb_type ports, + * Go recursively until we reach a primtiive node + */ +void rec_annotate_pb_type_primitive_node_physical_mode_pin(t_pb_type* top_pb_type, + t_pb_type* cur_pb_type) { + int imode, ipb; + + /* See if this is a primitive pb_graph_node */ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* bypass physical modes only when there are more than 1 modes available ! */ + if ((1 == cur_pb_type->modes[imode].define_physical_mode) + &&(1 < cur_pb_type->num_modes)) { + continue; + } + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + rec_annotate_pb_type_primitive_node_physical_mode_pin(top_pb_type, + &(cur_pb_type->modes[imode].pb_type_children[ipb])); + } + } + return; + } + + /* Reach here, it means a primitive mode */ + assert (TRUE == is_primitive_pb_type(cur_pb_type)); + /* Check the physical pb_type */ + /* Find the physical_pb_type with the name provided */ + cur_pb_type->phy_pb_type = rec_get_pb_type_by_name(top_pb_type, cur_pb_type->physical_pb_type_name); + /* Overwrite class type */ + if (UNKNOWN_CLASS != cur_pb_type->class_type) { + cur_pb_type->phy_pb_type->class_type = cur_pb_type->class_type; + } + vpr_printf(TIO_MESSAGE_INFO, + "Link physical pb_type (name=%s) for pb_type (name=%s)!\n", + cur_pb_type->physical_pb_type_name, cur_pb_type->name); + /* Check: We should find one! */ + if (NULL == cur_pb_type->phy_pb_type) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Fail to find physical pb_type (name=%s) for pb_type (name=%s)!\n", + __FILE__, __LINE__, cur_pb_type->physical_pb_type_name, cur_pb_type->name); + exit(1); + } + /* Check: the one should be linked to a SPICE model ! */ + if (NULL == cur_pb_type->phy_pb_type->spice_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Found physical pb_type (name=%s) for pb_type (name=%s) does not have a SPICE model definition!\n", + __FILE__, __LINE__, cur_pb_type->physical_pb_type_name, cur_pb_type->name); + exit(1); + } + /* Check: the one should be in a physical mode! */ + if (FALSE == cur_pb_type->phy_pb_type->parent_mode->define_physical_mode) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Found physical pb_type (name=%s) for pb_type (name=%s) does not belong to a physical mode!\n", + __FILE__, __LINE__, cur_pb_type->physical_pb_type_name, cur_pb_type->name); + exit(1); + } + + /* Now we are sure about the phy_pb_type that is found */ + /* Find matched port one by one */ + annotate_pb_type_port_to_phy_pb_type(cur_pb_type, cur_pb_type->phy_pb_type); + + return; +} + +/* Annotate the physical_mode_pin in pb_type ports, + * Go recursively until we reach a primtiive node + */ +void rec_annotate_phy_pb_type_primitive_node_physical_mode_pin(t_pb_type* top_pb_type, + t_pb_type* cur_pb_type) { + int phy_mode_idx, ipb, iport; + boolean is_top_pb_type = (top_pb_type == cur_pb_type) ? TRUE : FALSE; + + /* For top_pb_type: itself is a physical pb_type */ + if ((TRUE == is_top_pb_type) + || (TRUE == is_primitive_pb_type(cur_pb_type))) { + /* Reach here, it means a primitive mode */ + /* Check the physical pb_type */ + /* Find the physical_pb_type with the name provided */ + cur_pb_type->phy_pb_type = cur_pb_type; + /* Overwrite class type */ + if (UNKNOWN_CLASS != cur_pb_type->class_type) { + cur_pb_type->phy_pb_type->class_type = cur_pb_type->class_type; + } + /* Now we are sure about the phy_pb_type that is found */ + /* Find matched port one by one */ + for (iport = 0; iport < cur_pb_type->num_ports; iport++) { + cur_pb_type->ports[iport].phy_pb_type_port = &(cur_pb_type->ports[iport]); + cur_pb_type->ports[iport].phy_pb_type_port_lsb = 0; + cur_pb_type->ports[iport].phy_pb_type_port_msb = cur_pb_type->ports[iport].num_pins - 1; + } + /* return when it is a primitive node */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + /* ONLY FOR PRIMITIVE NODE: Copy the pb_type_name from the name of cur_pb_type */ + cur_pb_type->physical_pb_type_name = my_strdup(cur_pb_type->name); + /* Copy the name of ports to the physical_mode_pin to the port itself */ + for (iport = 0; iport < cur_pb_type->num_ports; iport++) { + cur_pb_type->ports[iport].physical_mode_pin = my_strdup(cur_pb_type->ports[iport].name); + } + return; + } + } + + /* See if this is a primitive pb_graph_node */ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + if (FALSE == is_top_pb_type) { + cur_pb_type->phy_pb_type = NULL; /* Special for top_pb_type */ + } + /* we only care physical modes */ + phy_mode_idx = find_pb_type_physical_mode_index((*cur_pb_type)); + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[phy_mode_idx].num_pb_type_children; ipb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + rec_annotate_phy_pb_type_primitive_node_physical_mode_pin(top_pb_type, + &(cur_pb_type->modes[phy_mode_idx].pb_type_children[ipb])); + } + } + + return; +} + +/* Go recursively visiting each primitive node in the pb_graph_node + * Label the primitive node with a placement index which is unique at the top-level node + */ +void rec_mark_pb_graph_node_primitive_placement_index_in_top_node(t_pb_graph_node* cur_pb_graph_node) { + int imode, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + + cur_pb_type = cur_pb_graph_node->pb_type; + + /* See if this is a primitive pb_graph_node */ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb].placement_index); + rec_mark_pb_graph_node_primitive_placement_index_in_top_node(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb])); + } + } + } + return; + } + + /* Reach here, it means a primitive mode */ + assert (NULL != cur_pb_type->phy_pb_type ); + /* Label placement_index_in_top_node */ + cur_pb_graph_node->placement_index_in_top_node = cur_pb_type->temp_placement_index; + cur_pb_type->temp_placement_index++; + + return; +} + +/* Recursively go to the primitive pb_graph_node + * create a link from the primitive pb_graph_node to its physical pb_graph_pin */ +void rec_link_primitive_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_node* top_pb_graph_node, + t_pb_graph_node* cur_pb_graph_node) { + int imode, ipb, jpb; + int physical_pb_graph_node_placement_index = -1; + t_pb_type* cur_pb_type = NULL; + t_pb_graph_node* phy_pb_graph_node = NULL; + boolean is_top_pb_graph_node = (top_pb_graph_node == cur_pb_graph_node) ? TRUE : FALSE; + + cur_pb_type = cur_pb_graph_node->pb_type; + + /* For top_pb_type: itself is a physical pb_type */ + if (TRUE == is_top_pb_graph_node) { + /* Reach here, it means a primitive mode */ + assert (NULL != cur_pb_type->phy_pb_type); + /* Create linkes between pb_graph_pins and pb_graph_nodes */ + cur_pb_graph_node->physical_pb_graph_node = top_pb_graph_node; + link_pb_graph_node_pins_to_phy_pb_graph_pins(top_pb_graph_node, top_pb_graph_node->physical_pb_graph_node); + } + + /* For primitive node */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + /* Reach here, it means a primitive mode */ + assert (NULL != cur_pb_type->phy_pb_type); + /* Get the physical pb_graph_node with the scaled placement_index! */ + physical_pb_graph_node_placement_index = (int) (cur_pb_type->physical_pb_type_index_factor + * (float) cur_pb_graph_node->placement_index_in_top_node) + + cur_pb_type->physical_pb_type_index_offset; + phy_pb_graph_node = rec_get_pb_graph_node_by_pb_type_and_placement_index_in_top_node(top_pb_graph_node, + cur_pb_type->phy_pb_type, + physical_pb_graph_node_placement_index); + assert(NULL != phy_pb_graph_node); + /* Create linkes between pb_graph_pins and pb_graph_nodes */ + cur_pb_graph_node->physical_pb_graph_node = phy_pb_graph_node; + link_pb_graph_node_pins_to_phy_pb_graph_pins(cur_pb_graph_node, cur_pb_graph_node->physical_pb_graph_node); + return; + } + + /* See if this is a primitive pb_graph_node */ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* bypass physical modes only when there are more than 1 modes available ! */ + if ((1 == cur_pb_type->modes[imode].define_physical_mode) + &&(1 < cur_pb_type->num_modes)) { + continue; + } + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb].placement_index); + rec_link_primitive_pb_graph_node_pin_to_phy_pb_graph_pin(top_pb_graph_node, + &(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb])); + } + } + } + } + + + return; +} + +/* Back-annotate the physical mode pins defined in pb_type to pb_graph_node + * For each pb_graph_node available in type->pb_graph_head + * 1. Label each primitive nodes with the placement_index_top_node + * 2. find the pb_graph_pin of primitive nodes in the pb_graph_node + * 3. identify the physical mode pin definition (in pb_type) + * 4. create a link to the pb_graph_pin in physical mode + */ +void annotate_physical_mode_pins_in_pb_graph_node() { + int itype; + + for (itype = 0; itype < num_types; itype++) { + /* Bybass NULL/EMPTY_TYPE */ + if (EMPTY_TYPE == &type_descriptors[itype]) { + continue; + } + /* reset phy_pb_type in all the pb_types */ + rec_reset_pb_type_phy_pb_type(type_descriptors[itype].pb_type); + /* reset the rr_node_index_physical_pb of each pb_graph_pin to be OPEN ! */ + rec_reset_pb_graph_node_rr_node_index_physical_pb(type_descriptors[itype].pb_graph_head); + /* annotate the physical mode pins in the physical primitive pb_type*/ + rec_annotate_phy_pb_type_primitive_node_physical_mode_pin(type_descriptors[itype].pb_type, type_descriptors[itype].pb_type); + /* annotate the physical mode pins in the primitive pb_type*/ + rec_annotate_pb_type_primitive_node_physical_mode_pin(type_descriptors[itype].pb_type, type_descriptors[itype].pb_type); + /* reset temp_placement_index in all the pb_types */ + rec_reset_pb_type_temp_placement_index(type_descriptors[itype].pb_type); + /* Recursively find the primitive pb_grpah_nodes */ + rec_mark_pb_graph_node_primitive_placement_index_in_top_node(type_descriptors[itype].pb_graph_head); + /* Recursively link the pb_graph_pin of primitive nodes in operating pb to physical pb */ + rec_link_primitive_pb_graph_node_pin_to_phy_pb_graph_pin(type_descriptors[itype].pb_graph_head, type_descriptors[itype].pb_graph_head); + } + + return; +} + +/* Allocate pb in mapped blocks, corresponding to physical modes */ +void alloc_and_load_phy_pb_for_mapped_block(int num_mapped_blocks, t_block* mapped_block, + int L_num_vpack_nets, t_net* L_vpack_net) { + int iblk; + t_phy_pb* top_phy_pb = NULL; + boolean route_success = FALSE; + + for (iblk = 0; iblk < num_mapped_blocks; iblk++) { + vpr_printf(TIO_MESSAGE_INFO, + "Start backannotate clb (%s) to its physical pb!\n", + mapped_block[iblk].pb->name); + top_phy_pb = (t_phy_pb*) my_calloc(1, sizeof(t_phy_pb)); + /* Create a pristine pb for pb_graph_nodes in the physical modes */ + top_phy_pb->pb_graph_node = mapped_block[iblk].type->pb_graph_head; + /* alloc_and_load_pb_stats(maped_block[iblk].phy_pb, num_models, max_nets_in_pb_type); */ + top_phy_pb->parent_pb = NULL; + top_phy_pb->mode = 0; /* Top-level should have only one mode!!! */ + /* Allocate rr_graph for the phy_pb */ + /* vpr_printf(TIO_MESSAGE_INFO, "Allocating routing resource graph for %d physical pb!\r", iblk); + */ + alloc_and_load_rr_graph_for_phy_pb(mapped_block[iblk].pb, top_phy_pb, L_num_vpack_nets, L_vpack_net); + /* Perform routing for the phy_pb !!! */ + route_success = try_breadth_first_route_pb_rr_graph(top_phy_pb->rr_graph); + if (TRUE == route_success) { + /* vpr_printf(TIO_MESSAGE_INFO, "Route successfully for %d physical pbs!\r", iblk); */ + } else { + assert(FALSE == route_success); + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) Route fail for physical pb (x=%d, y=%d, type_name=%s)!\n", + __FILE__, __LINE__, mapped_block[iblk].x, mapped_block[iblk].y, mapped_block[iblk].type->name); + exit(1); + } + /* Backannotate routing results to physical pb_rr_graph */ + backannotate_rr_graph_routing_results_to_net_name(top_phy_pb->rr_graph); + vpr_printf(TIO_MESSAGE_INFO, + "Backannotate routing results successfully for physical pb (%s)!\n", + mapped_block[iblk].pb->name); + /* Allocate and load child_pb graphs */ + alloc_and_load_phy_pb_children_for_one_mapped_block(mapped_block[iblk].pb, top_phy_pb); + /* Give top_phy_pb to grid */ + mapped_block[iblk].phy_pb = (void*)top_phy_pb; + /* Create a link from pb to phy_pb */ + mapped_block[iblk].pb->phy_pb = (void*)top_phy_pb; + } + vpr_printf(TIO_MESSAGE_INFO, "\n"); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + + return; +} + +/* This function does the following tasks: + * 1. Find the wired LUTs in pb recursively(used as buffers) + * 2. Allocate the pb (if not allocated) + * 3. Update the mapping information (net_num) in the rr_graph of pb + * 4. Create the wired LUTs in logical block array + * 5. Create new vpack nets to rewire the logical blocks + */ +void rec_backannotate_one_pb_wired_luts_and_adapt_graph(t_pb* cur_pb, + int* L_num_logical_blocks, t_net** L_logical_block, + int* L_num_vpack_nets, t_net** L_vpack_net) { + int mode_index, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + t_pb* lut_child_pb = NULL; + + cur_pb_type = cur_pb->pb_graph_node->pb_type; + mode_index = cur_pb->mode; + + /* Go recursively until we reach a primitive node which is a LUT */ + + /* Return if we reach the primitive */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + /* We only care the LUTs, that is in wired mode */ + if ((LUT_CLASS != cur_pb_type->class_type) + || (WIRED_LUT_MODE_INDEX != mode_index)) { + return; + } + /* Reach here means that this LUT is in wired mode (a buffer) + * Check if we need to allocate new logical block + */ + lut_child_pb = get_lut_child_pb(cur_pb, mode_index); + assert (NULL != lut_child_pb); + if (OPEN != lut_child_pb->logical_block) { + return; + } + /* We need to + * 1. Add a new logical block + * 2. Add a new vpack_net + * 3. Update pb rr_graph + */ + } + + /* recursive for the child_pbs*/ + assert (FALSE == is_primitive_pb_type(cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + rec_backannotate_one_pb_wired_luts_and_adapt_graph(&(cur_pb->child_pbs[ipb][jpb]), + L_num_logical_blocks, L_logical_block, + L_num_vpack_nets, L_vpack_net); + } else { + if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), + cur_pb->rr_graph)) { + /* Reach here means that this LUT is in wired mode (a buffer) */ + /* 1. Allocate a child pb */ + allocate_wired_lut_pbs(&(cur_pb->child_pbs), + cur_pb_type->modes[mode_index].num_pb_type_children, + cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb, + ipb, jpb); + /* Load the LUT information to the pb */ + /* 2. Add a new logical block */ + /* 3. Add a new vpack_net */ + /* + load_wired_lut_pbs(&(cur_pb->child_pbs[ipb][jpb]), + &(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), + cur_pb->rr_graph, + L_num_logical_blocks, L_logical_block, + L_num_vpack_nets, L_vpack_net); + */ + /* 4. Update pb rr_graph */ + } + } + } + } + + return; +} + +/* Back-annotate all the wired LUTs (used as buffers) in pbs + * and adapt BLIF graph and pb graph! + */ +static +void backannotate_pb_wired_luts(int num_mapped_blocks, t_block* mapped_block, + int* L_num_logical_blocks, t_net** L_logical_block, + int* L_num_vpack_nets, t_net** L_vpack_net) { + + int iblk; + + for (iblk = 0; iblk < num_mapped_blocks; iblk++) { + /* Find wired LUTs in each pb recusively */ + rec_backannotate_one_pb_wired_luts_and_adapt_graph(mapped_block[iblk].pb, + L_num_logical_blocks, L_logical_block, + L_num_vpack_nets, L_vpack_net); + } + + vpr_printf(TIO_MESSAGE_INFO, "\n"); + + return; +} + +int find_matched_block_id_for_one_grid(int x, int y) { + int iblk, jblk, blk_id; + boolean already_exist = FALSE; + + /* We need to find a valid block ID here */ + for (iblk = 0; iblk < num_blocks; iblk++) { + /* We only care the matched x,y coordinate */ + if ( (x != block[iblk].x) + || (y != block[iblk].y)) { + continue; + } + /* Now, we double check if the block is already in the list */ + already_exist = FALSE; + for (jblk = 0; jblk < grid[x][y].usage; jblk++) { + blk_id = grid[x][y].blocks[jblk]; + if (iblk != blk_id) { + continue; + } + /* Already in the list, we do not return the value */ + already_exist = TRUE; + break; + } + /* Return if does not exist */ + if (FALSE == already_exist) { + return iblk; + } + } + + return OPEN; +} + +/* Some IO blocks has an invalid BLOCK ID but with a >0 usage + * We go through the block list and find the missing block ID + */ +void annotate_grid_block_info() { + int ix, iy; + t_type_ptr type = NULL; + int iblk, blk_id; + + for (ix = 0; ix < (nx + 2); ix++) { + for (iy = 0; iy < (ny + 2); iy++) { + type = grid[ix][iy].type; + /* bypass EMPTY type */ + if ((NULL == type) || (EMPTY_TYPE == type)) { + continue; + } + if (IO_TYPE != type) { + continue; + } + for (iblk = 0; iblk < grid[ix][iy].usage; iblk++) { + blk_id = grid[ix][iy].blocks[iblk]; + if (OPEN != blk_id) { + continue; + } + vpr_printf(TIO_MESSAGE_INFO, + "Detect an invalid block id for grid[%d][%d] (usage:%d, blk_id:%d), trying to find a matched block from list!\n", + ix, iy, grid[ix][iy].usage, iblk); + /* We detect an invalid blk_id, try to find one in the block list */ + grid[ix][iy].blocks[iblk] = find_matched_block_id_for_one_grid(ix, iy); + if (OPEN == grid[ix][iy].blocks[iblk]) { + vpr_printf(TIO_MESSAGE_WARNING, + "Fail to find a valid block id for grid[%d][%d] (usage:%d, blk_id:%d) in the block list!\n", + ix, iy, grid[ix][iy].usage, iblk); + } else { + vpr_printf(TIO_MESSAGE_INFO, + "Manage to find a valid block id (=%d) for grid[%d][%d]!\n", + grid[ix][iy].blocks[iblk], ix, iy); + } + } + } + } + + return; +} + /* Back-Annotate post routing results to the VPR routing-resource graphs */ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch, - boolean parasitic_net_estimation_off) { + boolean read_activity_file, + boolean parasitic_net_estimation_on) { vpr_printf(TIO_MESSAGE_INFO, "Start backannotating post route information for SPICE modeling...\n"); + /* Back-annotate the wired LUTs in pbs */ + /* Paused due to difficulties in identify which part of the LUT fan-out is wired.... + vpr_printf(TIO_MESSAGE_INFO, "Back-annotate wired LUTs in pbs...\n"); + backannotate_pb_wired_luts(num_blocks, block, + &num_logical_blocks, &logical_block, + &num_logical_nets, &vpack_net); + */ + /* Give spice_name_tag for each pb*/ vpr_printf(TIO_MESSAGE_INFO, "Generate SPICE name tags for pbs...\n"); gen_spice_name_tags_all_pbs(); @@ -2578,65 +3117,42 @@ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch, /* Update local_rr_graphs to match post-route results*/ vpr_printf(TIO_MESSAGE_INFO, "Update CLB local routing graph to match post-route results...\n"); + /* Complete the grid block information */ + annotate_grid_block_info(); update_grid_pbs_post_route_rr_graph(); vpr_printf(TIO_MESSAGE_INFO,"Back annotating mapping information to local routing resource nodes...\n"); back_annotate_pb_rr_node_map_info(); + /* Annotate physical mode pins defined in each primitive pb_type/pb_graph_node */ + vpr_printf(TIO_MESSAGE_INFO, "Annotate physical mode pins for pbs ...\n"); + annotate_physical_mode_pins_in_pb_graph_node(); + alloc_and_load_phy_pb_for_mapped_block(num_blocks, block, num_logical_nets, vpack_net); + + vpr_printf(TIO_MESSAGE_INFO, "Generate SPICE name tags for phy_pbs...\n"); + gen_spice_name_tags_all_phy_pbs(); + /* Backannotate activity information, initialize the waveform information */ /* Parasitic Net Activity Estimation */ - if (FALSE == parasitic_net_estimation_off) { - vpr_printf(TIO_MESSAGE_WARNING, "Parasitic Net Estimation starts...\n"); + if (TRUE == parasitic_net_estimation_on) { + vpr_printf(TIO_MESSAGE_INFO, "Parasitic Net Estimation starts...\n"); parasitic_net_estimation(); } else { vpr_printf(TIO_MESSAGE_WARNING, "Parasitic Net Estimation is turned off...Accuracy loss may be expected!\n"); } /* Net activities */ - vpr_printf(TIO_MESSAGE_INFO, "Backannoating Net activities...\n"); - backannotate_clb_nets_act_info(); - vpr_printf(TIO_MESSAGE_INFO, "Determine Net initial values...\n"); - backannotate_clb_nets_init_val(); + if (TRUE == read_activity_file) { + vpr_printf(TIO_MESSAGE_INFO, "Backannoating Net activities...\n"); + backannotate_clb_nets_act_info(); + vpr_printf(TIO_MESSAGE_INFO, "Determine Net initial values...\n"); + backannotate_clb_nets_init_val(); + } else { + vpr_printf(TIO_MESSAGE_INFO, "Net activity backannoation is bypassed...\n"); + } vpr_printf(TIO_MESSAGE_INFO, "Finish backannotating post route information for SPICE modeling.\n"); return; } -void backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch) { - - vpr_printf(TIO_MESSAGE_INFO, "Start backannotating post route information...\n"); - /* Build previous node lists for each rr_node */ - vpr_printf(TIO_MESSAGE_INFO, "Building previous node list for all Routing Resource Nodes...\n"); - build_prev_node_list_rr_nodes(num_rr_nodes, rr_node); - /* This function should go very first because it gives all the net_num */ - vpr_printf(TIO_MESSAGE_INFO,"Back annotating mapping information to global routing resource nodes...\n"); - back_annotate_rr_node_map_info(); - /* Update local_rr_graphs to match post-route results*/ - vpr_printf(TIO_MESSAGE_INFO, "Update logic block local routing graph to match post-route results...\n"); - update_grid_pbs_post_route_rr_graph(); - vpr_printf(TIO_MESSAGE_INFO,"Back annotating mapping information to local routing resource nodes...\n"); - back_annotate_pb_rr_node_map_info(); - - /* Build Array for each Switch block and Connection block */ - vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each Switch block...\n"); - alloc_and_build_switch_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices); - vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed infromation for each to Connection block...\n"); - alloc_and_build_connection_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices); - - /* Backannotate activity information, initialize the waveform information */ - vpr_printf(TIO_MESSAGE_INFO, "Update logic block pins parasitic nets (1st time: for output pins)...\n"); - update_grid_pb_pins_parasitic_nets(); - vpr_printf(TIO_MESSAGE_WARNING, "Parasitic Net Estimation starts...\n"); - parasitic_net_estimation(); - - /* Net activities */ - vpr_printf(TIO_MESSAGE_INFO, "Backannoating Net activities...\n"); - backannotate_clb_nets_act_info(); - vpr_printf(TIO_MESSAGE_INFO, "Determine Net initial values...\n"); - backannotate_clb_nets_init_val(); - - vpr_printf(TIO_MESSAGE_INFO, "Finish backannotating post route information.\n"); - - return; -} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_backannotate_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_backannotate_utils.h similarity index 75% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_backannotate_utils.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_backannotate_utils.h index 56623ffa1..2c72cbfdb 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_backannotate_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_backannotate_utils.h @@ -1,4 +1,10 @@ +int get_ff_output_init_val(t_logical_block* ff_logical_block); + +int get_lut_output_init_val(t_logical_block* lut_logical_block); + +int get_logical_block_output_init_val(t_logical_block* cur_logical_block); + void init_one_sb_info(t_sb* cur_sb); void free_one_sb_info(t_sb* cur_sb); @@ -73,10 +79,27 @@ void build_one_connection_block_info(t_cb* cur_cb, int cb_x, int cb_y, t_rr_type t_rr_node* LL_rr_node, t_ivec*** LL_rr_node_indices); +void update_one_grid_pack_prev_node_edge(int x, int y); + +void update_grid_pbs_post_route_rr_graph(); + void free_backannotate_vpr_post_route_info(); +void rec_annotate_pb_type_primitive_node_physical_mode_pin(t_pb_type* top_pb_type, + t_pb_type* cur_pb_type); + +void rec_mark_pb_graph_node_primitive_placement_index_in_top_node(t_pb_graph_node* cur_pb_graph_node, + int* start_index); + +void rec_link_primitive_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_node* top_pb_graph_node, + t_pb_graph_node* cur_pb_graph_node); + +void annotate_physical_mode_pins_in_pb_graph_node(); + +void alloc_and_load_phy_pb_for_mapped_block(int num_mapped_blocks, t_block* mapped_block, + int L_num_vpack_nets, t_net* L_vpack_net); + void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch, - boolean parasitic_net_estimation_off); - -void backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch); + boolean read_activity_file, + boolean parasitic_net_estimation); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c new file mode 100644 index 000000000..b4e83160d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c @@ -0,0 +1,1597 @@ +/***********************************/ +/* Synthesizable Verilog Dumping */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" + +/* FPGA-SPICE utils */ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_globals.h" + +/* Determine the size of input address of a decoder */ +int determine_decoder_size(int num_addr_out) { + return ceil(log(num_addr_out)/log(2.)); +} + +int count_num_sram_bits_one_lut_spice_model(t_spice_model* cur_spice_model) { + int num_sram_bits = 0; + int iport; + int lut_size; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + int lut_sram_port = 0; + int mode_sram_port = 0; + + assert(NULL != cur_spice_model); + assert(SPICE_MODEL_LUT == cur_spice_model->type); + + /* Check ports */ + input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + assert(1 == num_input_port); + + /* Determine size of LUT*/ + lut_size = input_ports[0]->size; + + num_sram_bits = 0; + lut_sram_port = 0; + mode_sram_port = 0; + /* Total SRAM bit count = LUT SRAM bit + Mode bit */ + for (iport = 0; iport < num_sram_port; iport++) { + if (FALSE == sram_ports[iport]->mode_select) { + num_sram_bits += (int)pow(2.,(double)(lut_size)); + assert(num_sram_bits == sram_ports[iport]->size); + lut_sram_port++; + } else { + assert (TRUE == sram_ports[iport]->mode_select); + num_sram_bits += sram_ports[iport]->size; + mode_sram_port++; + } + } + assert (1 == lut_sram_port); + assert ((0 == mode_sram_port) || (1 == mode_sram_port)); + + /* TODO: could be more smart! Use mapped spice_model of SRAM ports! + * Support Non-volatile RRAM-based SRAM */ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * Number of memory bits is still same as CMOS SRAM + */ + break; + case SPICE_MODEL_DESIGN_CMOS: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + + /* Free */ + my_free(input_ports); + my_free(sram_ports); + + return num_sram_bits; +} + +int count_num_sram_bits_one_mux_spice_model(t_spice_model* cur_spice_model, + int mux_size) { + int num_sram_bits = 0; + int num_input_size = mux_size; + + assert(SPICE_MODEL_MUX == cur_spice_model->type); + + assert((2 == mux_size)||(2 < mux_size)); + + num_input_size = get_mux_full_input_size (cur_spice_model, mux_size); + + /* Number of configuration bits depends on the MUX structure */ + switch (cur_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_TREE: + num_sram_bits = determine_tree_mux_level(num_input_size); + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + num_sram_bits = num_input_size; + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + num_sram_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level + * determine_num_input_basis_multilevel_mux(num_input_size, + cur_spice_model->design_tech_info.mux_info->mux_num_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_sram_bits = 1; + } + /* Also the number of configuration bits depends on the technology*/ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* 4T1R MUX requires more configuration bits */ + if (SPICE_MODEL_STRUCTURE_TREE == cur_spice_model->design_tech_info.mux_info->structure) { + /* For tree-structure: we need 3 times more config. bits */ + num_sram_bits = 3 * num_sram_bits; + } else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.mux_info->structure) { + /* For multi-level structure: we need 1 more config. bits for each level */ + num_sram_bits += cur_spice_model->design_tech_info.mux_info->mux_num_level; + } else { + num_sram_bits = (num_sram_bits + 1); + } + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_sram_bits = 3; + } + break; + case SPICE_MODEL_DESIGN_CMOS: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + + /* Free */ + + return num_sram_bits; +} + + +int count_num_sram_bits_one_generic_spice_model(t_spice_model* cur_spice_model) { + int iport; + int num_sram_bits = 0; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + /* Other block, we just count the number SRAM ports defined by user */ + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + if (0 < num_sram_port) { + assert(NULL != sram_ports); + } + for (iport = 0; iport < num_sram_port; iport++) { + assert(NULL != sram_ports[iport]->spice_model); + num_sram_bits += sram_ports[iport]->size; + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * Number of memory bits is still same as CMOS SRAM + */ + case SPICE_MODEL_DESIGN_CMOS: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + } + + /* Free */ + my_free(sram_ports); + + return num_sram_bits; +} + +/* Count the number of configuration bits of a spice model */ +int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model, + int mux_size) { + assert(NULL != cur_spice_model); + + /* Only LUT and MUX requires configuration bits*/ + switch (cur_spice_model->type) { + case SPICE_MODEL_LUT: + return count_num_sram_bits_one_lut_spice_model(cur_spice_model); + case SPICE_MODEL_MUX: + return count_num_sram_bits_one_mux_spice_model(cur_spice_model, mux_size); + case SPICE_MODEL_WIRE: + case SPICE_MODEL_FF: + case SPICE_MODEL_SRAM: + case SPICE_MODEL_HARDLOGIC: + case SPICE_MODEL_SCFF: + case SPICE_MODEL_IOPAD: + return count_num_sram_bits_one_generic_spice_model(cur_spice_model); + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); + exit(1); + } + + return -1; +} + +int count_num_mode_bits_one_generic_spice_model(t_spice_model* cur_spice_model) { + int iport; + int num_mode_bits = 0; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + /* Other block, we just count the number SRAM ports defined by user */ + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + if (0 < num_sram_port) { + assert(NULL != sram_ports); + for (iport = 0; iport < num_sram_port; iport++) { + assert(NULL != sram_ports[iport]->spice_model); + if (FALSE == sram_ports[iport]->mode_select) { + continue; + } + num_mode_bits += sram_ports[iport]->size; + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * Number of memory bits is still same as CMOS SRAM + */ + case SPICE_MODEL_DESIGN_CMOS: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + } + } + + /* Free */ + my_free(sram_ports); + + return num_mode_bits; +} + + +/* Count the number of configuration bits of a spice model */ +int count_num_mode_bits_one_spice_model(t_spice_model* cur_spice_model) { + assert(NULL != cur_spice_model); + + /* Only LUT and MUX requires configuration bits*/ + switch (cur_spice_model->type) { + case SPICE_MODEL_LUT: + case SPICE_MODEL_MUX: + case SPICE_MODEL_WIRE: + case SPICE_MODEL_FF: + case SPICE_MODEL_SRAM: + case SPICE_MODEL_HARDLOGIC: + case SPICE_MODEL_SCFF: + case SPICE_MODEL_IOPAD: + return count_num_mode_bits_one_generic_spice_model(cur_spice_model); + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); + exit(1); + } + + return -1; +} + + +/* For a non-volatile SRAM, we determine its number of reserved conf. bits */ +int count_num_reserved_conf_bits_one_rram_sram_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type) { + int num_reserved_conf_bits = 0; + int num_bl_ports, num_wl_ports; + t_spice_model_port** bl_ports = NULL; + t_spice_model_port** wl_ports = NULL; + + /* Check */ + assert(SPICE_MODEL_SRAM == cur_spice_model->type); + + switch (cur_sram_orgz_type) { + case SPICE_SRAM_MEMORY_BANK: + find_bl_wl_ports_spice_model(cur_spice_model, + &num_bl_ports, &bl_ports, + &num_wl_ports, &wl_ports); + assert((1 == num_bl_ports)&&(1 == num_wl_ports)); + assert(bl_ports[0]->size == wl_ports[0]->size); + num_reserved_conf_bits = bl_ports[0]->size - 1; /*TODO: to be more smart: num_bl-1 of SRAM model ?*/ + break; + case SPICE_SRAM_SCAN_CHAIN: + case SPICE_SRAM_STANDALONE: + num_reserved_conf_bits = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Free */ + my_free(bl_ports); + my_free(wl_ports); + + return num_reserved_conf_bits; +} + + +/* For a multiplexer, determine its reserved configuration bits */ +int count_num_reserved_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type) { + int num_reserved_conf_bits = 0; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + int iport; + + /* Check */ + assert(SPICE_MODEL_LUT == cur_spice_model->type); + + /* Determine size of LUT*/ + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + /* TODO: could be more smart! Use mapped spice_model of SRAM ports! + * Support Non-volatile RRAM-based SRAM */ + for (iport = 0; iport < num_sram_port; iport++) { + switch (sram_ports[iport]->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * In memory bank, by intensively share the Bit/Word Lines, + * we only need 1 additional BL and WL for each memory bit. + * Number of memory bits is still same as CMOS SRAM + */ + num_reserved_conf_bits = + count_num_reserved_conf_bits_one_rram_sram_spice_model(sram_ports[iport]->spice_model, + cur_sram_orgz_type); + break; + case SPICE_MODEL_DESIGN_CMOS: + num_reserved_conf_bits = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + } + + /* Free */ + my_free(sram_ports); + + return num_reserved_conf_bits; +} + +/* For a multiplexer, determine its reserved configuration bits */ +int count_num_reserved_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size) { + int num_reserved_conf_bits = 0; + int num_input_size = mux_size; + + /* Check */ + assert(SPICE_MODEL_MUX == cur_spice_model->type); + assert((2 == mux_size)||(2 < mux_size)); + + num_input_size = get_mux_full_input_size(cur_spice_model, mux_size); + + /* Number of configuration bits depends on the MUX structure */ + switch (cur_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_TREE: + num_reserved_conf_bits = 2; + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + num_reserved_conf_bits = num_input_size; + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + num_reserved_conf_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level * + determine_num_input_basis_multilevel_mux(num_input_size, + cur_spice_model->design_tech_info.mux_info->mux_num_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_reserved_conf_bits = 2; + } + /* Also the number of configuration bits depends on the technology*/ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + switch (cur_sram_orgz_type) { + case SPICE_SRAM_MEMORY_BANK: + /* In memory bank, by intensively share the Bit/Word Lines, + * we only need 1 additional BL and WL for each MUX level. + */ + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_reserved_conf_bits = 2; + } + break; + case SPICE_SRAM_SCAN_CHAIN: + case SPICE_SRAM_STANDALONE: + /* 4T1R MUX requires more configuration bits */ + if (SPICE_MODEL_STRUCTURE_TREE == cur_spice_model->design_tech_info.mux_info->structure) { + /* For tree-structure: we need 3 times more config. bits */ + num_reserved_conf_bits = 0; + } else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.mux_info->structure) { + /* For multi-level structure: we need 1 more config. bits for each level */ + num_reserved_conf_bits = 0; + } else { + num_reserved_conf_bits = 0; + } + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_reserved_conf_bits = 0; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case SPICE_MODEL_DESIGN_CMOS: + num_reserved_conf_bits = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + + return num_reserved_conf_bits; +} + + +int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size) { + int num_reserved_conf_bits = 0; + int temp_num_reserved_conf_bits = 0; + int iport; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + assert(NULL != cur_spice_model); + + /* Only LUT and MUX requires configuration bits*/ + switch (cur_spice_model->type) { + case SPICE_MODEL_LUT: + num_reserved_conf_bits = + count_num_reserved_conf_bits_one_lut_spice_model(cur_spice_model, + cur_sram_orgz_type); + break; + case SPICE_MODEL_MUX: + num_reserved_conf_bits = + count_num_reserved_conf_bits_one_mux_spice_model(cur_spice_model, + cur_sram_orgz_type, + mux_size); + break; + case SPICE_MODEL_WIRE: + case SPICE_MODEL_FF: + case SPICE_MODEL_SRAM: + case SPICE_MODEL_HARDLOGIC: + case SPICE_MODEL_SCFF: + case SPICE_MODEL_IOPAD: + /* Other block, we just count the number SRAM ports defined by user */ + num_reserved_conf_bits = 0; + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + if (0 < num_sram_port) { + assert(NULL != sram_ports); + for (iport = 0; iport < num_sram_port; iport++) { + assert(NULL != sram_ports[iport]->spice_model); + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + switch (sram_ports[iport]->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * Number of memory bits is still same as CMOS SRAM + */ + temp_num_reserved_conf_bits = + count_num_reserved_conf_bits_one_rram_sram_spice_model(sram_ports[iport]->spice_model, + cur_sram_orgz_type); + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + break; + case SPICE_MODEL_DESIGN_CMOS: + num_reserved_conf_bits = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + } + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); + exit(1); + } + + /* Free */ + my_free(sram_ports); + + return num_reserved_conf_bits; +} + + +int count_num_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type) { + int num_conf_bits = 0; + int iport; + int lut_size; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + int lut_sram_port = 0; + int mode_sram_port = 0; + + assert(NULL != cur_spice_model); + assert(SPICE_MODEL_LUT == cur_spice_model->type); + + /* Determine size of LUT*/ + input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + assert(1 == num_input_port); + lut_size = input_ports[0]->size; + + /* Check lut sram bits and mode bits */ + num_conf_bits = 0; + lut_sram_port = 0; + mode_sram_port = 0; + /* Total SRAM bit count = LUT SRAM bit + Mode bit */ + for (iport = 0; iport < num_sram_port; iport++) { + if (FALSE == sram_ports[iport]->mode_select) { + num_conf_bits += (int)pow(2.,(double)(lut_size)); + assert(num_conf_bits == sram_ports[iport]->size); + lut_sram_port++; + } else { + assert (TRUE == sram_ports[iport]->mode_select); + num_conf_bits += sram_ports[iport]->size; + mode_sram_port++; + } + } + assert (1 == lut_sram_port); + assert ((0 == mode_sram_port) || (1 == mode_sram_port)); + + /* TODO: could be more smart! Use mapped spice_model of SRAM ports! + * Support Non-volatile RRAM-based SRAM */ + switch (sram_ports[0]->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * In memory bank, by intensively share the Bit/Word Lines, + * we only need 1 additional BL and WL for each memory bit. + * Number of memory bits is still same as CMOS SRAM + */ + switch (cur_sram_orgz_type) { + case SPICE_SRAM_MEMORY_BANK: + break; + case SPICE_SRAM_SCAN_CHAIN: + case SPICE_SRAM_STANDALONE: + num_conf_bits = 2 * num_conf_bits; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case SPICE_MODEL_DESIGN_CMOS: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + + /* Free */ + my_free(input_ports); + my_free(sram_ports); + + return num_conf_bits; +} + + +int count_num_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size) { + int num_conf_bits = 0; + int num_input_size = mux_size; + + assert(NULL != cur_spice_model); + assert(SPICE_MODEL_MUX == cur_spice_model->type); + + assert((2 == mux_size)||(2 < mux_size)); + + num_input_size = get_mux_full_input_size(cur_spice_model, mux_size); + + /* Number of configuration bits depends on the MUX structure */ + switch (cur_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_TREE: + num_conf_bits = determine_tree_mux_level(num_input_size); + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + num_conf_bits = num_input_size; + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + num_conf_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level + * determine_num_input_basis_multilevel_mux(num_input_size, + cur_spice_model->design_tech_info.mux_info->mux_num_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_conf_bits = 1; + } + /* Also the number of configuration bits depends on the technology*/ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + switch (cur_sram_orgz_type) { + case SPICE_SRAM_MEMORY_BANK: + /* In memory bank, by intensively share the Bit/Word Lines, + * we only need 1 additional BL and WL for each MUX level. + */ + num_conf_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level; + /* For 2:1 MUX, whatever structure, there is only one level */ + if (2 == num_input_size) { + num_conf_bits = 1; + } + break; + case SPICE_SRAM_SCAN_CHAIN: + case SPICE_SRAM_STANDALONE: + /* Currently we keep the same as CMOS MUX */ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case SPICE_MODEL_DESIGN_CMOS: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + + /* Free */ + + return num_conf_bits; +} + +int count_num_conf_bits_one_generic_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type) { + int num_conf_bits = 0; + int iport; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + assert(NULL != cur_spice_model); + + /* Other block, we just count the number SRAM ports defined by user */ + num_conf_bits = 0; + sram_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + if (0 < num_sram_port) { + assert(NULL != sram_ports); + for (iport = 0; iport < num_sram_port; iport++) { + assert(NULL != sram_ports[iport]->spice_model); + /* TODO: could be more smart! + * Support Non-volatile RRAM-based SRAM */ + switch (sram_ports[iport]->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * Number of memory bits is still same as CMOS SRAM + */ + switch (cur_sram_orgz_type) { + case SPICE_SRAM_MEMORY_BANK: + num_conf_bits += sram_ports[iport]->size; + break; + case SPICE_SRAM_SCAN_CHAIN: + case SPICE_SRAM_STANDALONE: + num_conf_bits += sram_ports[iport]->size; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case SPICE_MODEL_DESIGN_CMOS: + /* Non-volatile SRAM requires 2 BLs and 2 WLs for each 1 memory bit, + * Number of memory bits is still same as CMOS SRAM + */ + switch (cur_sram_orgz_type) { + case SPICE_SRAM_MEMORY_BANK: + num_conf_bits += sram_ports[iport]->size; + break; + case SPICE_SRAM_SCAN_CHAIN: + case SPICE_SRAM_STANDALONE: + num_conf_bits += sram_ports[iport]->size; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid type of SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of LUT(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + } + } + + /* Free */ + my_free(sram_ports); + + return num_conf_bits; +} + + + +/* Count the number of configuration bits of a spice model */ +int count_num_conf_bits_one_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size) { + assert(NULL != cur_spice_model); + + /* Only LUT and MUX requires configuration bits*/ + switch (cur_spice_model->type) { + case SPICE_MODEL_LUT: + return count_num_conf_bits_one_lut_spice_model(cur_spice_model, cur_sram_orgz_type); + case SPICE_MODEL_MUX: + return count_num_conf_bits_one_mux_spice_model(cur_spice_model, cur_sram_orgz_type, mux_size); + case SPICE_MODEL_WIRE: + case SPICE_MODEL_FF: + case SPICE_MODEL_SRAM: + case SPICE_MODEL_HARDLOGIC: + case SPICE_MODEL_SCFF: + case SPICE_MODEL_IOPAD: + return count_num_conf_bits_one_generic_spice_model(cur_spice_model, cur_sram_orgz_type); + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); + exit(1); + } + return -1; +} + +int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc, + enum e_sram_orgz cur_sram_orgz_type) { + int fan_in = 0; + enum e_interconnect spice_interc_type = DIRECT_INTERC; + + int num_reserved_conf_bits = 0; + int temp_num_reserved_conf_bits = 0; + + /* 1. identify pin interconnection type, + * 2. Identify the number of fan-in (Consider interconnection edges of only selected mode) + * 3. Select and print the SPICE netlist + */ + if (NULL == cur_interc) { + return num_reserved_conf_bits; + } else { + fan_in = cur_interc->fan_in; + if (0 == fan_in) { + return num_reserved_conf_bits; + } + } + /* Initialize the interconnection type that will be implemented in SPICE netlist*/ + switch (cur_interc->type) { + case DIRECT_INTERC: + assert(cur_interc->fan_out == fan_in); + spice_interc_type = DIRECT_INTERC; + break; + case COMPLETE_INTERC: + if (1 == fan_in) { + spice_interc_type = DIRECT_INTERC; + } else { + assert((2 == fan_in)||(2 < fan_in)); + spice_interc_type = MUX_INTERC; + } + break; + case MUX_INTERC: + assert((2 == fan_in)||(2 < fan_in)); + spice_interc_type = MUX_INTERC; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + /* This time, (2nd round), count the number of configuration bits, according to interc type*/ + switch (spice_interc_type) { + case DIRECT_INTERC: + /* Check : + * 1. Direct interc has only one fan-in! + */ + assert((cur_interc->fan_out == fan_in) + ||((COMPLETE_INTERC == cur_interc->type)&&(1 == fan_in))); + break; + case COMPLETE_INTERC: + case MUX_INTERC: + /* Check : + * MUX should have at least 2 fan_in + */ + assert((2 == fan_in)||(2 < fan_in)); + assert((1 == cur_interc->fan_out)||(1 < cur_interc->fan_out)); + /* 2. spice_model is a wire */ + assert(NULL != cur_interc->spice_model); + assert(SPICE_MODEL_MUX == cur_interc->spice_model->type); + temp_num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(cur_interc->spice_model, + cur_sram_orgz_type, fan_in); + /* FOR COMPLETE_INTERC: we should consider fan_out number ! */ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + return num_reserved_conf_bits; +} + +/* add configuration bits of a MUX to linked-list + * when SRAM organization type is scan-chain */ +void +add_mux_scff_conf_bits_to_llist(int mux_size, + t_sram_orgz_info* cur_sram_orgz_info, + int num_mux_sram_bits, int* mux_sram_bits, + t_spice_model* mux_spice_model) { + int ibit, cur_mem_bit; + t_conf_bit** sram_bit = NULL; + + /* Assert*/ + assert(NULL != cur_sram_orgz_info); + assert(NULL != mux_spice_model); + + cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Depend on the design technology of mux_spice_model + * Fill the conf_bits information */ + switch (mux_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + case SPICE_MODEL_DESIGN_RRAM: + /* Count how many configuration bits need to program + * Scan-chain needs to know each memory bit whatever it is 0 or 1 + */ + /* Allocate the array */ + sram_bit = (t_conf_bit**)my_malloc(num_mux_sram_bits * sizeof(t_conf_bit*)); + for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { + sram_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + } + /* Fill the array: sram_bit */ + for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { + sram_bit[ibit]->addr = cur_mem_bit + ibit; + sram_bit[ibit]->val = mux_sram_bits[ibit]; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", + __FILE__, __LINE__ ); + exit(1); + } + + /* Fill the linked list */ + for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { + cur_sram_orgz_info->conf_bit_head = + add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, cur_mem_bit + ibit, + sram_bit[ibit], NULL, NULL, + mux_spice_model); + } + + /* Free */ + my_free(sram_bit); + + return; +} + +/* add configuration bits of a MUX to linked-list + * when SRAM organization type is scan-chain */ +void +add_mux_membank_conf_bits_to_llist(int mux_size, + t_sram_orgz_info* cur_sram_orgz_info, + int num_mux_sram_bits, int* mux_sram_bits, + t_spice_model* mux_spice_model) { + int ibit, cur_mem_bit, num_conf_bits, cur_bit, cur_bl, cur_wl; + int ilevel; + int num_bl_enabled, num_wl_enabled; + t_conf_bit** wl_bit = NULL; + t_conf_bit** bl_bit = NULL; + + /* Assert*/ + assert(NULL != cur_sram_orgz_info); + assert(NULL != mux_spice_model); + + cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + + /* Depend on the design technology of mux_spice_model + * Fill the conf_bits information */ + switch (mux_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + /* Count how many configuration bits need to program + * Assume all the SRAMs are zero initially. + * only Configuration to bit 1 requires a programming operation + */ + num_conf_bits = num_mux_sram_bits; + /* Allocate the array */ + bl_bit = (t_conf_bit**)my_malloc(num_mux_sram_bits * sizeof(t_conf_bit*)); + wl_bit = (t_conf_bit**)my_malloc(num_mux_sram_bits * sizeof(t_conf_bit*)); + for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { + bl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + wl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + } + /* SRAMs are typically organized in an array where BLs and WLs are efficiently shared + * Actual BL/WL address in the array is hard to predict here, + * they will be handled in the top_netlist and top_testbench generation + */ + for (ibit = 0; ibit < num_mux_sram_bits; ibit++) { + bl_bit[ibit]->addr = cur_mem_bit + ibit; + bl_bit[ibit]->val = mux_sram_bits[ibit]; + wl_bit[ibit]->addr = cur_mem_bit + ibit; + wl_bit[ibit]->val = 1; /* We always assume WL is the write enable signal of a SRAM */ + } + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Count how many configuration bits need to program + * only BL and WL are both 1 requires a programming operation + * Each level of a MUX requires 1 RRAM to be configured. + * Therefore, the number of configuration bits should be num_mux_levels + */ + num_bl_enabled = 0; + /* Check how many Bit lines are 1 */ + for (ibit = 0; ibit < num_mux_sram_bits/2; ibit++) { + if (1 == mux_sram_bits[ibit]) { + num_bl_enabled++; + } + } + num_wl_enabled = 0; + /* Check how many Word lines are 1 */ + for (ibit = 0; ibit < num_mux_sram_bits/2; ibit++) { + if (1 == mux_sram_bits[ibit + num_mux_sram_bits/2]) { + num_wl_enabled++; + } + } + /* The number of enabled Bit and Word lines should be the same */ + assert(num_bl_enabled == num_wl_enabled); + /* Assign num_conf_bits */ + num_conf_bits = num_bl_enabled; + /* Allocate the array */ + bl_bit = (t_conf_bit**)my_malloc(num_conf_bits * sizeof(t_conf_bit*)); + wl_bit = (t_conf_bit**)my_malloc(num_conf_bits * sizeof(t_conf_bit*)); + for (ibit = 0; ibit < num_conf_bits; ibit++) { + bl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + wl_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + } + /* For one-level RRAM MUX: + * There should be only 1 BL and 1 WL whose value is 1 + * First half of mux_sram_bits are BL, the rest are WL + * For multi-level RRAM MUX: + * There could be more than 1 BL and 1 WL whose value is 1 + * We need to divde the mux_sram_bits into small part, + * each part has only 1 BL and 1 WL whose value is 1 + */ + /* Assign bit lines address and values */ + cur_bit = 0; + /* We slice the BL part of array mux_sram_bits to N=num_conf_bits parts */ + for (ilevel = 0; ilevel < num_conf_bits; ilevel++) { + for (ibit = ilevel * num_mux_sram_bits/(2*num_conf_bits); /* Start address of each slice*/ + ibit < (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits); /* End address of each slice*/ + ibit++) { + if (0 == mux_sram_bits[ibit]) { + continue; /* Skip non-zero bits */ + } + assert(1 == mux_sram_bits[ibit]); + if (ibit == (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits) - 1) { + bl_bit[cur_bit]->addr = cur_bl + ilevel; + /* Last conf_bit should use a new BL/WL */ + } else { + /* First part of conf_bit should use reserved BL/WL */ + bl_bit[cur_bit]->addr = ibit; + } + bl_bit[cur_bit]->val = mux_sram_bits[ibit]; + cur_bit++; + } + } + assert(num_conf_bits == cur_bit); + /* Assign Word lines address and values */ + cur_bit = 0; + for (ilevel = 0; ilevel < num_conf_bits; ilevel++) { + for (ibit = num_mux_sram_bits/2 + ilevel * num_mux_sram_bits/(2*num_conf_bits); /* Start address of each slice*/ + ibit < num_mux_sram_bits/2 + (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits); /* End address of each slice*/ + ibit++) { + if (0 == mux_sram_bits[ibit]) { + continue; /* Skip non-zero bits */ + } + assert(1 == mux_sram_bits[ibit]); + if (ibit == num_mux_sram_bits/2 + (ilevel + 1) * num_mux_sram_bits/(2*num_conf_bits) - 1) { + wl_bit[cur_bit]->addr = cur_wl + ilevel; + /* Last conf_bit should use a new BL/WL */ + } else { + /* First part of conf_bit should use reserved BL/WL */ + wl_bit[cur_bit]->addr = ibit; + } + wl_bit[cur_bit]->val = mux_sram_bits[ibit]; + cur_bit++; + } + } + assert(num_conf_bits == cur_bit); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", + __FILE__, __LINE__ ); + exit(1); + } + + /* Fill the linked list */ + for (ibit = 0; ibit < num_conf_bits; ibit++) { + cur_sram_orgz_info->conf_bit_head = + add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, cur_mem_bit + ibit, + NULL, bl_bit[ibit], wl_bit[ibit], + mux_spice_model); + } + + /* Free */ + my_free(bl_bit); + my_free(wl_bit); + + return; +} + +/* Should we return a value ? */ +void +add_mux_conf_bits_to_llist(int mux_size, + t_sram_orgz_info* cur_sram_orgz_info, + int num_mux_sram_bits, int* mux_sram_bits, + t_spice_model* mux_spice_model) { + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + add_mux_scff_conf_bits_to_llist(mux_size, cur_sram_orgz_info, + num_mux_sram_bits, mux_sram_bits, + mux_spice_model); + break; + case SPICE_SRAM_MEMORY_BANK: + add_mux_membank_conf_bits_to_llist(mux_size, cur_sram_orgz_info, + num_mux_sram_bits, mux_sram_bits, + mux_spice_model); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Add SCFF configutration bits to a linked list*/ +void +add_sram_scff_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, + int num_sram_bits, int* sram_bits) { + int ibit, cur_mem_bit; + t_conf_bit** sram_bit = NULL; + t_spice_model* cur_sram_spice_model = NULL; + + /* Assert*/ + assert(NULL != cur_sram_orgz_info); + + cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_sram_spice_model); + assert(NULL != cur_sram_spice_model); + + /* Count how many configuration bits need to program + * Scan-chain needs to know each memory bit whatever it is 0 or 1 + */ + /* Allocate the array */ + sram_bit = (t_conf_bit**)my_malloc(num_sram_bits * sizeof(t_conf_bit*)); + for (ibit = 0; ibit < num_sram_bits; ibit++) { + sram_bit[ibit] = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + } + /* Fill the array: sram_bit */ + for (ibit = 0; ibit < num_sram_bits; ibit++) { + sram_bit[ibit]->addr = cur_mem_bit + ibit; + sram_bit[ibit]->val = sram_bits[ibit]; + } + + /* Fill the linked list */ + for (ibit = 0; ibit < num_sram_bits; ibit++) { + cur_sram_orgz_info->conf_bit_head = + add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, cur_mem_bit + ibit, + sram_bit[ibit], NULL, NULL, + cur_sram_spice_model); + } + + /* Free */ + my_free(sram_bit); + + return; +} + + +/* Add SRAM configuration bits in memory bank organization to a linked list */ +void add_sram_membank_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, + int num_bls, int num_wls, + int* bl_conf_bits, int* wl_conf_bits) { + int ibit, cur_bl, cur_wl, cur_mem_bit; + t_spice_model* cur_sram_spice_model = NULL; + t_conf_bit* bl_bit = NULL; + t_conf_bit* wl_bit = NULL; + int bit_cnt = 0; + + /* Assert*/ + assert(NULL != cur_sram_orgz_info); + + /* Get current counter of sram_spice_model */ + cur_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + + /* Get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_sram_spice_model); + assert(NULL != cur_sram_spice_model); + + /* Malloc */ + bl_bit = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + wl_bit = (t_conf_bit*)my_malloc(sizeof(t_conf_bit)); + + /* Depend on the memory technology, we have different configuration bits */ + switch (cur_sram_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + assert((1 == num_bls)&&(1 == num_wls)); + bl_bit->addr = mem_index; + wl_bit->addr = mem_index; + bl_bit->val = bl_conf_bits[0]; + wl_bit->val = wl_conf_bits[0]; + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Fill information */ + bit_cnt = 0; /* Check counter */ + for (ibit = 0; ibit < num_bls; ibit++) { + /* Bypass zero bit */ + if (0 == bl_conf_bits[ibit]) { + continue; + } + /* Check if this bit is in reserved bls */ + if (ibit == num_bls - 1) { + /* Last bit is always independent */ + bl_bit->addr = mem_index; + bl_bit->val = 1; + } else { + /* Other bits are shared */ + bl_bit->addr = ibit; + bl_bit->val = 1; + } + /* Update check counter */ + bit_cnt++; + } + /* Check */ + assert(1 == bit_cnt); + + bit_cnt = 0; /* Check counter */ + for (ibit = 0; ibit < num_wls; ibit++) { + /* Bypass zero bit */ + if (0 == wl_conf_bits[ibit]) { + continue; + } + /* Check if this bit is in reserved bls */ + if (ibit == num_wls - 1) { + /* Last bit is always independent */ + wl_bit->addr = mem_index; + wl_bit->val = 1; + } else { + /* Other bits are shared */ + wl_bit->addr = ibit; + wl_bit->val = 1; + } + /* Update check counter */ + bit_cnt++; + } + /* Check */ + assert(1 == bit_cnt); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", + __FILE__, __LINE__); + exit(1); + } + + /* Fill the linked list */ + cur_sram_orgz_info->conf_bit_head = + add_conf_bit_info_to_llist(cur_sram_orgz_info->conf_bit_head, mem_index, + NULL, bl_bit, wl_bit, + cur_sram_spice_model); + + return; +} + +/* Add SRAM configuration bits to a linked list */ +void +add_sram_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, + int num_sram_bits, int* sram_bits) { + int num_bls, num_wls; + int* bl_conf_bits = NULL; + int* wl_conf_bits = NULL; + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + add_sram_scff_conf_bits_to_llist(cur_sram_orgz_info, + num_sram_bits, sram_bits); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Initialize parameters */ + /* Number of BLs should be same as WLs */ + num_bls = num_sram_bits/2; + num_wls = num_sram_bits/2; + /* Convention: first part of Array (sram_bits) is BL configuration bits, + * second part is WL configuration bits. + */ + bl_conf_bits = sram_bits; + wl_conf_bits = sram_bits + num_bls; + add_sram_membank_conf_bits_to_llist(cur_sram_orgz_info, mem_index, + num_bls, num_wls, + bl_conf_bits, wl_conf_bits); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__); + exit(1); + } + + return; +} + + +/* Decode BL and WL bits for a SRAM + * SRAM could be + * 1. NV SRAM + * or + * 2. SRAM + */ +void decode_memory_bank_sram(t_spice_model* cur_sram_spice_model, int sram_bit, + int bl_len, int wl_len, int bl_offset, int wl_offset, + int* bl_conf_bits, int* wl_conf_bits) { + int i; + + /* Check */ + assert(NULL != cur_sram_spice_model); + assert(NULL != bl_conf_bits); + assert(NULL != wl_conf_bits); + assert((1 == sram_bit)||(0 == sram_bit)); + + /* All the others should be zero */ + for (i = 0; i < bl_len; i++) { + bl_conf_bits[i] = 0; + } + for (i = 0; i < wl_len; i++) { + wl_conf_bits[i] = 0; + } + + /* Depending on the design technology of SRAM */ + switch (cur_sram_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + /* CMOS SRAM */ + /* Make sure there is only 1 BL and 1 WL */ + assert((1 == bl_len)&&(1 == wl_len)); + /* We always assume that WL is a write-enable signal + * While BL contains what data will be written into SRAM + */ + bl_conf_bits[0] = sram_bit; + wl_conf_bits[0] = 1; + break; + case SPICE_MODEL_DESIGN_RRAM: + /* NV SRAM (RRAM-based) */ + /* We need at least 2 BLs and 2 WLs but no more than 3, See schematic in manual */ + /* Whatever the number of BLs and WLs, (RRAM0) + * when sram bit is 1, last bit of BL should be enabled + * while first bit of WL should be enabled at the same time + * when sram bit is 0, last bit of WL should be enabled + * while first bit of BL should be enabled at the same time + */ + assert((1 < bl_len)&&(bl_len < 4)); + assert((1 < wl_len)&&(wl_len < 4)); + assert((-1 < bl_offset)&&(bl_offset < bl_len)); + assert((-1 < wl_offset)&&(wl_offset < wl_len)); + /* In addition, we will may need two programing cycles. + * The first cycle is dedicated to programming RRAM0 + * The second cycle is dedicated to programming RRAM1 + */ + if (1 == sram_bit) { + bl_conf_bits[bl_len-1] = 1; + wl_conf_bits[0 + wl_offset] = 1; + } else { + assert(0 == sram_bit); + bl_conf_bits[0 + bl_offset] = 1; + wl_conf_bits[wl_len-1] = 1; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for SRAM!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Decode one SRAM bit for memory-bank-style configuration circuit, and add it to linked list */ +void +decode_and_add_sram_membank_conf_bit_to_llist(t_sram_orgz_info* cur_sram_orgz_info, + int mem_index, + int num_bl_per_sram, int num_wl_per_sram, + int cur_sram_bit) { + int j; + int* conf_bits_per_sram = NULL; + t_spice_model* mem_model = NULL; + + /* Check */ + assert( SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type ); + + /* Get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + /* Malloc/Calloc */ + conf_bits_per_sram = (int*)my_calloc(num_bl_per_sram + num_wl_per_sram, sizeof(int)); + + /* Depend on the memory technology, we have different configuration bits */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + /* Check */ + assert((1 == num_bl_per_sram) && (1 == num_wl_per_sram)); + /* For CMOS SRAM */ + decode_memory_bank_sram(mem_model, cur_sram_bit, + num_bl_per_sram, num_wl_per_sram, 0, 0, + conf_bits_per_sram, conf_bits_per_sram + num_bl_per_sram); + /* Use memory model here! Design technology of memory model determines the decoding strategy, instead of LUT model*/ + add_sram_conf_bits_to_llist(cur_sram_orgz_info, mem_index, + num_bl_per_sram + num_wl_per_sram, conf_bits_per_sram); + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Decode the SRAM bits to BL/WL bits. + * first half part is BL, the other half part is WL + */ + /* Store the configuraion bit to linked-list */ + assert(num_bl_per_sram == num_wl_per_sram); + /* When the number of BL/WL is more than 1, we need multiple programming cycles to configure a SRAM */ + /* ONLY valid for NV SRAM !!!*/ + for (j = 0; j < num_bl_per_sram - 1; j++) { + if (0 == j) { + /* Store the configuraion bit to linked-list */ + decode_memory_bank_sram(mem_model, cur_sram_bit, + num_bl_per_sram, num_wl_per_sram, j, j, + conf_bits_per_sram, conf_bits_per_sram + num_bl_per_sram); + } else { + /* Store the configuraion bit to linked-list */ + decode_memory_bank_sram(mem_model, 1 - cur_sram_bit, + num_bl_per_sram, num_wl_per_sram, j, j, + conf_bits_per_sram, conf_bits_per_sram + num_bl_per_sram); + } + /* Use memory model here! Design technology of memory model determines the decoding strategy, instead of LUT model*/ + add_sram_conf_bits_to_llist(cur_sram_orgz_info, mem_index, + num_bl_per_sram + num_wl_per_sram, conf_bits_per_sram); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", + __FILE__, __LINE__); + exit(1); + } + + /* Free */ + my_free(conf_bits_per_sram); + + return; +} + +void determine_blwl_decoder_size(INP t_sram_orgz_info* cur_sram_orgz_info, + OUTP int* num_array_bl, OUTP int* num_array_wl, + OUTP int* bl_decoder_size, OUTP int* wl_decoder_size) { + t_spice_model* mem_model = NULL; + int num_mem_bit; + int num_reserved_bl, num_reserved_wl; + + /* Check */ + assert(SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type); + + num_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, num_array_bl, num_array_wl); + get_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, &num_reserved_bl, &num_reserved_wl); + + /* Sizes of decodes depend on the Memory technology */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + switch (mem_model->design_tech) { + /* CMOS SRAM*/ + case SPICE_MODEL_DESIGN_CMOS: + /* SRAMs can efficiently share BLs and WLs, + * Actual number of BLs and WLs will be sqrt(num_bls) and sqrt(num_wls) + */ + assert(0 == num_reserved_bl); + assert(0 == num_reserved_wl); + (*num_array_bl) = ceil(sqrt(*num_array_bl)); + (*num_array_wl) = ceil(sqrt(*num_array_wl)); + (*bl_decoder_size) = determine_decoder_size(*num_array_bl); + (*wl_decoder_size) = determine_decoder_size(*num_array_wl); + break; + /* RRAM */ + case SPICE_MODEL_DESIGN_RRAM: + /* Currently we do not have more efficient way to share the BLs and WLs as CMOS SRAMs */ + (*bl_decoder_size) = determine_decoder_size(*num_array_bl); + (*wl_decoder_size) = determine_decoder_size(*num_array_wl); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology [CMOS|RRAM] for memory technology!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +void init_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch) { + + /* We have linked list whichs stores spice model information of multiplexer*/ + t_llist* muxes_head = NULL; + t_llist* temp = NULL; + t_spice_mux_model* cur_spice_mux_model = NULL; + int max_routing_mux_size = -1; + + /* Alloc the muxes*/ + muxes_head = stats_spice_muxes(num_switch, switches, spice, routing_arch); + + temp = muxes_head; + while(temp) { + assert(NULL != temp->dptr); + cur_spice_mux_model = (t_spice_mux_model*)(temp->dptr); + /* Exclude LUT MUX from this statistics */ + if ((SPICE_MODEL_MUX == cur_spice_mux_model->spice_model->type) + &&((-1 == max_routing_mux_size)||(max_routing_mux_size < cur_spice_mux_model->size))) { + max_routing_mux_size = cur_spice_mux_model->size; + } + /* Move on to the next*/ + temp = temp->next; + } + + try_update_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, + max_routing_mux_size, max_routing_mux_size); + + vpr_printf(TIO_MESSAGE_INFO,"Detected %d reserved BLs and% d reserved WLs...\n", + max_routing_mux_size, max_routing_mux_size); + + /* remember to free the linked list*/ + free_muxes_llist(muxes_head); + + return; +} + +void add_one_conf_bit_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info) { + int cur_num_sram = 0; + int cur_bl, cur_wl; + + /* Get current index of SRAM module */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + /* Update the counter */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, + cur_num_sram + 1); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, + cur_bl + 1, + cur_wl + 1); + break; + case SPICE_SRAM_STANDALONE: + /* Update the counter */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, + cur_num_sram + 1); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* Update the counter */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, + cur_num_sram + 1); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +void add_sram_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_spice_model) { + int i; + int num_sram; + + /* Synchronize the internal counters of sram_orgz_info with generated bitstreams*/ + num_sram = count_num_sram_bits_one_spice_model(cur_spice_model, -1); + for (i = 0; i < num_sram; i++) { + add_one_conf_bit_to_sram_orgz_info(cur_sram_orgz_info); /* use the mem_model in cur_sram_orgz_info */ + } + + return; +} + +void add_mux_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* mux_spice_model, int mux_size) { + int i; + int num_mux_sram_bits, num_mux_conf_bits; + int cur_num_sram, cur_bl, cur_wl; + + /* cur_num_sram = sram_verilog_model->cnt; */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + + /* Get the number of configuration bits required by this MUX */ + num_mux_sram_bits = count_num_sram_bits_one_spice_model(mux_spice_model, mux_size); + + num_mux_conf_bits = count_num_conf_bits_one_spice_model(mux_spice_model, + cur_sram_orgz_info->type, + mux_size); + + /* Synchronize sram_orgz_info by incrementing its internal counters */ + switch (mux_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + /* SRAM-based MUX required dumping SRAMs! */ + for (i = 0; i < num_mux_sram_bits; i++) { + add_one_conf_bit_to_sram_orgz_info(cur_sram_orgz_info); /* use the mem_model in sram_verilog_orgz_info */ + } + break; + case SPICE_MODEL_DESIGN_RRAM: + /* RRAM-based MUX does not need any SRAM dumping + * But we have to get the number of configuration bits required by this MUX + * and update the number of memory bits + */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, + cur_bl + num_mux_conf_bits, + cur_wl + num_mux_conf_bits); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", + __FILE__, __LINE__, mux_spice_model->name); + } + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h new file mode 100644 index 000000000..a63af4565 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.h @@ -0,0 +1,80 @@ + +int determine_decoder_size(int num_addr_out); + +int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model, + int mux_size); + +int count_num_conf_bits_one_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size); + +int count_num_mode_bits_one_spice_model(t_spice_model* cur_spice_model); + +int count_num_reserved_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type); + +int count_num_reserved_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size); + +int count_num_reserved_conf_bits_one_rram_sram_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type); + +int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model, + enum e_sram_orgz cur_sram_orgz_type, + int mux_size); + +void +add_mux_scff_conf_bits_to_llist(int mux_size, + t_sram_orgz_info* cur_sram_orgz_info, + int num_mux_sram_bits, int* mux_sram_bits, + t_spice_model* mux_spice_model); + +void +add_mux_membank_conf_bits_to_llist(int mux_size, + t_sram_orgz_info* cur_sram_orgz_info, + int num_mux_sram_bits, int* mux_sram_bits, + t_spice_model* mux_spice_model); + +void +add_mux_conf_bits_to_llist(int mux_size, + t_sram_orgz_info* cur_sram_orgz_info, + int num_mux_sram_bits, int* mux_sram_bits, + t_spice_model* mux_spice_model); + +void add_sram_membank_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, + int num_bls, int num_wls, + int* bl_conf_bits, int* wl_conf_bits); + +void +add_sram_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, + int num_sram_bits, int* sram_bits); + + +void decode_memory_bank_sram(t_spice_model* cur_sram_spice_model, int sram_bit, + int bl_len, int wl_len, int bl_offset, int wl_offset, + int* bl_conf_bits, int* wl_conf_bits); + +void +decode_and_add_sram_membank_conf_bit_to_llist(t_sram_orgz_info* cur_sram_orgz_info, + int mem_index, + int num_bl_per_sram, int num_wl_per_sram, + int cur_sram_bit); + +void determine_blwl_decoder_size(INP t_sram_orgz_info* cur_sram_orgz_info, + OUTP int* num_array_bl, OUTP int* num_array_wl, + OUTP int* bl_decoder_size, OUTP int* wl_decoder_size) ; + +void init_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch); + +void add_one_conf_bit_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info) ; + +void add_sram_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_spice_model) ; + +void add_mux_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* mux_spice_model, int mux_size) ; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_globals.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_globals.c similarity index 83% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_globals.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_globals.c index 60e727c27..25049237d 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_globals.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_globals.c @@ -5,7 +5,7 @@ #include #include "spice_types.h" #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" /* Global variables to be shared by different tools of FPGA-SPICE */ /* SRAM SPICE MODEL should be set as global*/ @@ -40,3 +40,10 @@ boolean run_parasitic_net_estimation = TRUE; boolean run_testbench_load_extraction = TRUE; char* renaming_report_postfix = "_io_renaming.rpt"; +char* fpga_spice_bitstream_output_file_postfix = ".bitstream"; +char* fpga_spice_bitstream_logic_block_log_file_postfix = "_lb_bitstream.log"; +char* fpga_spice_bitstream_routing_log_file_postfix = "_routing_bitstream.log"; +char* default_sdc_folder = "SDC/"; + + + diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_globals.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_globals.h similarity index 86% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_globals.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_globals.h index 4081bee9c..8e8a4ef1d 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_globals.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_globals.h @@ -30,14 +30,7 @@ extern t_llist* global_ports_head; /* Linked list for verilog and spice syntax char */ extern t_llist* reserved_syntax_char_head; -/* Enumeration */ -enum e_pin2pin_interc_type { - INPUT2INPUT_INTERC, OUTPUT2OUTPUT_INTERC -}; - - extern char* renaming_report_postfix; - -#define PRIMITIVE_WIRED_LUT -1 -#define PRIMITIVE_IDLE 1 -#define PRIMITIVE_NORMAL 0 +extern char* fpga_spice_bitstream_output_file_postfix; +extern char* fpga_spice_bitstream_logic_block_log_file_postfix; +extern char* fpga_spice_bitstream_routing_log_file_postfix; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.c new file mode 100644 index 000000000..251d55cce --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.c @@ -0,0 +1,751 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "quicksort.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_lut_utils.h" + + +char* complete_truth_table_line(int lut_size, + char* input_truth_table_line) { + char* ret = NULL; + int num_token = 0; + char** tokens = NULL; + int cover_len = 0; + int j; + + /* Due to the size of truth table may be less than the lut size. + * i.e. in LUT-6 architecture, there exists LUT1-6 in technology-mapped netlists + * So, in truth table line, there may be 10- 1 + * In this case, we should complete it by --10- 1 + */ + /*Malloc the completed truth table, lut_size + space + truth_val + '\0'*/ + ret = (char*)my_malloc(sizeof(char)*lut_size + 3); + /* Split one line of truth table line*/ + tokens = fpga_spice_strtok(input_truth_table_line, " ", &num_token); + /* Check, only 2 tokens*/ + /* Sometimes, the truth table is ' 0' or ' 1', which corresponds to a constant */ + if (1 == num_token) { + /* restore the token[0]*/ + tokens = (char**)realloc(tokens, 2 * sizeof(char*)); + tokens[1] = tokens[0]; + tokens[0] = my_strdup("-"); + num_token = 2; + } + + /* In Most cases, there should be 2 tokens. */ + assert(2 == num_token); + /* We may have two truth table from two LUTs which contain both 0 and 1*/ + /* + if ((0 != strcmp(tokens[1], "1"))&&(0 != strcmp(tokens[1], "0"))) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Last token of truth table line should be [0|1]!\n", + __FILE__, __LINE__); + exit(1); + } + */ + /* Complete the truth table line*/ + cover_len = strlen(tokens[0]); + assert((cover_len < lut_size)||(cover_len == lut_size)); + + /* Copy the original truth table line */ + for (j = 0; j < cover_len; j++) { + ret[j] = tokens[0][j]; + } + /* Add the number of '-' we should add in the back !!! */ + for (j = cover_len; j < lut_size; j++) { + ret[j] = '-'; + } + + /* Copy the original truth table line */ + sprintf(ret + lut_size, " %s", tokens[1]); + + /* Free */ + for (j = 0; j < num_token; j++) { + my_free(tokens[j]); + } + + return ret; +} + +/* For each lut_bit_lines, we should recover the truth table, + * and then set the sram bits to "1" if the truth table defines so. + * Start_point: the position we start decode recursively + */ +void configure_lut_sram_bits_per_line_rec(int** sram_bits, + int lut_size, + char* truth_table_line, + int start_point) { + int i; + int num_sram_bit = (int)pow(2., (double)(lut_size)); + char* temp_line = my_strdup(truth_table_line); + int do_config = 1; + int sram_id = 0; + + /* Check the length of sram bits and truth table line */ + //assert((sizeof(int)*num_sram_bit) == sizeof(*sram_bits)); /*TODO: fix this assert*/ + if ((unsigned)(lut_size + 1 + 1) != strlen(truth_table_line)){ /* lut_size + space + '1' */ + assert((unsigned)(lut_size + 1 + 1) == strlen(truth_table_line)); /* lut_size + space + '1' */ + } + /* End of truth_table_line should be "space" and "1" */ + assert((0 == strcmp(" 1", truth_table_line + lut_size))||(0 == strcmp(" 0", truth_table_line + lut_size))); + /* Make sure before start point there is no '-' */ + for (i = 0; i < start_point; i++) { + assert('-' != truth_table_line[i]); + } + + /* Configure sram bits recursively */ + for (i = start_point; i < lut_size; i++) { + if ('-' == truth_table_line[i]) { + do_config = 0; + /* if we find a dont_care, we don't do configure now but recursively*/ + /* '0' branch */ + temp_line[i] = '0'; + configure_lut_sram_bits_per_line_rec(sram_bits, lut_size, temp_line, start_point + 1); + /* '1' branch */ + temp_line[i] = '1'; + configure_lut_sram_bits_per_line_rec(sram_bits, lut_size, temp_line, start_point + 1); + break; + } + } + + /* do_config*/ + if (do_config) { + for (i = 0; i < lut_size; i++) { + /* Should be either '0' or '1' */ + switch (truth_table_line[i]) { + case '0': + /* We assume the 1-lut pass sram1 when input = 0 */ + sram_id += (int)pow(2., (double)(i)); + break; + case '1': + /* We assume the 1-lut pass sram0 when input = 1 */ + break; + case '-': + assert('-' != truth_table_line[i]); /* Make sure there is no dont_care */ + default : + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid truth_table bit(%c), should be [0|1|'-]!\n", + __FILE__, __LINE__, truth_table_line[i]); + exit(1); + } + } + /* Set the sram bit to '1'*/ + assert((-1 < sram_id) && (sram_id < num_sram_bit)); + if (0 == strcmp(" 1", truth_table_line + lut_size)) { + (*sram_bits)[sram_id] = 1; /* on set*/ + } else if (0 == strcmp(" 0", truth_table_line + lut_size)) { + (*sram_bits)[sram_id] = 0; /* off set */ + } else { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid truth_table_line ending(=%s)!\n", + __FILE__, __LINE__, truth_table_line + lut_size); + exit(1); + } + } + + /* Free */ + my_free(temp_line); + + return; +} + +/* Determine if the truth table of a LUT is a on-set or a off-set */ +int determine_lut_truth_table_on_set(int truth_table_len, + char** truth_table) { + int on_set = 0; + int off_set = 0; + int i, tt_line_len; + + for (i = 0; i < truth_table_len; i++) { + tt_line_len = strlen(truth_table[i]); + switch (truth_table[i][tt_line_len - 1]) { + case '1': + on_set = 1; + break; + case '0': + off_set = 1; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid truth_table_line ending(=%c)!\n", + __FILE__, __LINE__, truth_table[i][tt_line_len - 1]); + exit(1); + } + } + + /* Prefer on_set if both are true */ + if (2 == (on_set + off_set)) { + on_set = 1; off_set = 0; + } + + return on_set; +} + +/* Generate the LUT SRAM bits for a given truth table + * As truth tables may come from different logic blocks, truth tables could be in on and off sets + * We first build a base SRAM bits, where different parts are set to tbe on/off sets + * Then, we can decode SRAM bits as regular process + */ +int* generate_lut_sram_bits(int truth_table_len, + char** truth_table, + int lut_size, + int default_sram_bit_value) { + int num_sram = (int)pow(2.,(double)(lut_size)); + int* ret = (int*)my_calloc(num_sram, sizeof(int)); + char** completed_truth_table = (char**)my_malloc(sizeof(char*)*truth_table_len); + int on_set = 0; + int off_set = 0; + int i; + + /* if No truth_table, do default*/ + if (0 == truth_table_len) { + switch (default_sram_bit_value) { + case 0: + off_set = 0; + on_set = 1; + break; + case 1: + off_set = 1; + on_set = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid default_signal_init_value(=%d)!\n", + __FILE__, __LINE__, default_sram_bit_value); + exit(1); + } + } else { + on_set = determine_lut_truth_table_on_set(truth_table_len, truth_table); + off_set = 1 - on_set; + } + + /* Read in truth table lines, decode one by one */ + for (i = 0; i < truth_table_len; i++) { + /* Complete the truth table line by line*/ + //printf("truth_table[%d] = %s\n", i, truth_table[i]); + completed_truth_table[i] = complete_truth_table_line(lut_size, truth_table[i]); + //printf("Completed_truth_table[%d] = %s\n", i, completed_truth_table[i]); + } + + if (1 == on_set) { + /* Initial all sram bits to 0*/ + for (i = 0 ; i < num_sram; i++) { + ret[i] = 0; + } + } else if (1 == off_set) { + /* Initial all sram bits to 1*/ + for (i = 0 ; i < num_sram; i++) { + ret[i] = 1; + } + } + + for (i = 0; i < truth_table_len; i++) { + /* Update the truth table, sram_bits */ + configure_lut_sram_bits_per_line_rec(&ret, lut_size, completed_truth_table[i], 0); + } + + /* Free */ + for (i = 0; i < truth_table_len; i++) { + my_free(completed_truth_table[i]); + } + + return ret; +} + +/* Generate the base SRAM bits: + * Check type of truth table of each mapped logical block + * if it is on-set, we give a all 0 base sram-bit + * if it is off-set, we give a all 1 base sram-bit */ +int* generate_frac_lut_sram_bits(t_phy_pb* lut_phy_pb, + int* truth_table_length, + char*** truth_table, + int default_sram_bit_value) { + int num_sram, lut_size; + int* sram_bits = NULL; + int* temp_sram_bits = NULL; + int ilb; + int lut_frac_level, lut_output_mask; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int offset, len_to_cpy; + + /* Find the input ports for LUT size */ + input_ports = find_spice_model_ports(lut_phy_pb->pb_graph_node->pb_type->spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + assert(1 == num_input_port); + lut_size = input_ports[0]->size; + num_sram = (int)pow(2.,(double)(lut_size)); + sram_bits = (int*)my_calloc(num_sram, sizeof(int)); + + /* Initialization */ + for (ilb = 0; ilb < num_sram; ilb++) { + sram_bits[ilb] = default_sram_bit_value; + } + + for (ilb = 0; ilb < lut_phy_pb->num_logical_blocks; ilb++) { + /* find the corresponding SPICE model output port and assoicated lut_output_mask */ + lut_frac_level = get_pb_graph_pin_lut_frac_level(lut_phy_pb->lut_output_pb_graph_pin[ilb]); + lut_output_mask = get_pb_graph_pin_lut_output_mask(lut_phy_pb->lut_output_pb_graph_pin[ilb]); + /* Decode lut sram bits */ + temp_sram_bits = generate_lut_sram_bits(truth_table_length[ilb], truth_table[ilb], lut_size, default_sram_bit_value); + /* Depending on the frac-level, we get the location(starting/end points) of sram bits */ + len_to_cpy = (int)pow(2., (double)(lut_frac_level)); + offset = len_to_cpy * lut_output_mask; + /*TODO: copy to the sram_bits to return: + * Should check if we will overwrite anything! + */ + memcpy(sram_bits + offset, temp_sram_bits + offset, + len_to_cpy * sizeof(int)); + /* Free */ + my_free(temp_sram_bits); + } + + /* Free */ + my_free(input_ports); + + return sram_bits; +} + + +/* Provide the truth table of a mapped logical block + * 1. Reorgainze the truth table to be consistent with the mapped nets of a LUT + * 2. Allocate the truth table in a clean char array and return + */ +char** assign_lut_truth_table(t_logical_block* mapped_logical_block, + int* truth_table_length) { + char** truth_table = NULL; + t_linked_vptr* head = NULL; + int cur = 0; + + if (NULL == mapped_logical_block) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid mapped_logical_block!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Count the lines of truth table*/ + head = mapped_logical_block->truth_table; + while(head) { + (*truth_table_length)++; + head = head->next; + } + /* Allocate truth_tables */ + truth_table = (char**)my_malloc(sizeof(char*)*(*truth_table_length)); + /* Fill truth_tables*/ + cur = 0; + head = mapped_logical_block->truth_table; + while(head) { + truth_table[cur] = my_strdup((char*)(head->data_vptr)); + head = head->next; + cur++; + } + assert(cur == (*truth_table_length)); + + return truth_table; +} + +/* Return the truth table of a wired LUT */ +char** get_wired_lut_truth_table() { + char** tt = (char**) my_malloc(sizeof(char*)); + tt[0] = my_strdup("1 1"); + + return tt; +} + +/* Adapt the truth from the actual connection from the input nets of a LUT, + */ +char** assign_post_routing_wired_lut_truth_table(int lut_output_vpack_net_num, + int lut_size, int* lut_pin_vpack_net_num, + int* truth_table_length) { + int inet, iport; + char** tt = (char**) my_malloc(sizeof(char*)); + + /* truth_table_length will be always 1*/ + (*truth_table_length) = 1; + + /* Malloc */ + tt[0] = (char*)my_malloc((lut_size + 3) * sizeof(char)); + /* Fill the truth table !!! */ + for (inet = 0; inet < lut_size; inet++) { + /* Find the vpack_num in the lut_input_pin, we fix it to be 1 */ + if (lut_output_vpack_net_num == lut_pin_vpack_net_num[inet]) { + tt[0][inet] = '1'; + } else { + /* Otherwise it should be don't care */ + tt[0][inet] = '-'; + } + } + memcpy(tt[0] + lut_size, " 1", 3); + + return tt; +} + +/* Provide the truth table of a mapped logical block + * 1. Reorgainze the truth table to be consistent with the mapped nets of a LUT + * 2. Allocate the truth table in a clean char array and return + */ +char** assign_post_routing_lut_truth_table(t_logical_block* mapped_logical_block, + int lut_size, int* lut_pin_vpack_net_num, + int* truth_table_length) { + char** truth_table = NULL; + t_linked_vptr* head = NULL; + int cur = 0; + int inet, jnet; + int* lut_to_lb_net_mapping = NULL; + int num_lb_pin = 0; + int* lb_pin_vpack_net_num = NULL; + int lb_truth_table_size = 0; + + if (NULL == mapped_logical_block) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid mapped_logical_block!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Allocate */ + lut_to_lb_net_mapping = (int*) my_malloc (sizeof(int) * lut_size); + /* Find nets mapped to a logical block */ + get_lut_logical_block_input_pin_vpack_net_num(mapped_logical_block, + &num_lb_pin, &lb_pin_vpack_net_num); + /* Create a pin-to-pin net_num mapping */ + for (inet = 0; inet < lut_size; inet++) { + lut_to_lb_net_mapping[inet] = OPEN; + /* Bypass open nets */ + if (OPEN == lut_pin_vpack_net_num[inet]) { + continue; + } + assert (OPEN != lut_pin_vpack_net_num[inet]); + /* Find the position (offset) of each vpack_net_num in lb_pins */ + for (jnet = 0; jnet < num_lb_pin; jnet++) { + if (lut_pin_vpack_net_num[inet] == lb_pin_vpack_net_num[jnet]) { + lut_to_lb_net_mapping[inet] = jnet; + break; + } + } + /* Not neccesary to find a one, some luts just share part of their pins */ + } + + /* Initialization */ + (*truth_table_length) = 0; + /* Count the lines of truth table*/ + head = mapped_logical_block->truth_table; + while(head) { + (*truth_table_length)++; + head = head->next; + } + /* Allocate truth_tables */ + truth_table = (char**)my_malloc(sizeof(char*)*(*truth_table_length)); + /* Fill truth_tables*/ + cur = 0; + head = mapped_logical_block->truth_table; + while(head) { + /* Handle the truth table pin remapping */ + truth_table[cur] = (char*) my_malloc((lut_size + 3) * sizeof(char)); + /* Initialize */ + lb_truth_table_size = strlen((char*)(head->data_vptr)); + strcpy(truth_table[cur] + lut_size, (char*)(head->data_vptr) + lb_truth_table_size - 2); + truth_table[cur][lut_size + 2] = '\0'; + /* Add */ + for (inet = 0; inet < lut_size; inet++) { + /* Open net implies a don't care, or some nets are not in the list */ + if ((OPEN == lut_pin_vpack_net_num[inet]) + || (OPEN == lut_to_lb_net_mapping[inet])) { + truth_table[cur][inet] = '-'; + continue; + } + /* Find the desired truth table bit */ + truth_table[cur][inet] = ((char*)(head->data_vptr))[lut_to_lb_net_mapping[inet]]; + } + + head = head->next; + cur++; + } + assert(cur == (*truth_table_length)); + + return truth_table; +} + +/* Find the output port of LUT that this logical block is mapped to */ +t_pb_graph_pin* get_mapped_lut_phy_pb_output_pin(t_phy_pb* lut_phy_pb, + t_logical_block* lut_logical_block) { + int iport, ipin; + int num_lut_output_ports; + int* num_lut_output_pins; + int** lut_output_vpack_net_num; + int pin_rr_node_index; + t_pb_graph_pin* ret_pin = NULL; /* The pin to return */ + int found_num_pins = 0; + + /* Find the vpack_net_num of the output of the lut_logical_block */ + get_logical_block_output_vpack_net_num(lut_logical_block, + &num_lut_output_ports, + &num_lut_output_pins, + &lut_output_vpack_net_num); + + /* Check */ + assert ( 1 == num_lut_output_ports); + assert ( 1 == num_lut_output_pins[0]); + assert ( OPEN != lut_output_vpack_net_num[0][0]); + + /* Search the output pins of lut_phy_pb in rr_graph in find */ + for (iport = 0; iport < lut_phy_pb->pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < lut_phy_pb->pb_graph_node->num_output_pins[iport]; ipin++) { + /* Get the rr_node index of the pin */ + pin_rr_node_index = lut_phy_pb->pb_graph_node->output_pins[iport][ipin].rr_node_index_physical_pb; + /* Get the vpack_net_num in the local rr_graph, see if we have a match */ + if (lut_output_vpack_net_num[0][0] != lut_phy_pb->rr_graph->rr_node[pin_rr_node_index].vpack_net_num) { + continue; + } + /* Reach here, it means we have a match! */ + ret_pin = &(lut_phy_pb->pb_graph_node->output_pins[iport][ipin]); + found_num_pins++; + } + } + + /* We should have only one match! */ + assert (1 == found_num_pins); + + /* Free */ + my_free(num_lut_output_pins); + for (iport = 0; iport < num_lut_output_ports; iport++) { + my_free(lut_output_vpack_net_num); + } + + return ret_pin; +} + +/* Get LUT fracturable level of a pb_graph_pin */ +int get_pb_graph_pin_lut_frac_level(t_pb_graph_pin* out_pb_graph_pin) { + /* search the corresponding spice_model_port */ + return out_pb_graph_pin->port->spice_model_port->lut_frac_level; +} + +/* Get LUT output mask of a pb_graph_pin */ +int get_pb_graph_pin_lut_output_mask(t_pb_graph_pin* out_pb_graph_pin) { + int pin_number = out_pb_graph_pin->pin_number; + /* search the corresponding spice_model_port */ + return out_pb_graph_pin->port->spice_model_port->lut_output_mask[pin_number]; +} + +/* Adapt truth table for a fracturable LUT + * Determine fixed input bits for this truth table: + * 1. input bits within frac_level (all '-' if not specified) + * 2. input bits outside frac_level, decoded to its output mask (0 -> first part -> all '1') + */ +void adapt_truth_table_for_frac_lut(t_pb_graph_pin* lut_out_pb_graph_pin, + int truth_table_length, + char** truth_table) { + int lut_frac_level; + int lut_output_mask; + int i, lut_size, num_mask_bits; + int temp; + char* mask_bits = NULL; + + /* Find the output port of LUT that this logical block is mapped to */ + assert(NULL != lut_out_pb_graph_pin); + /* find the corresponding SPICE model output port and assoicated lut_output_mask */ + lut_frac_level = get_pb_graph_pin_lut_frac_level(lut_out_pb_graph_pin); + lut_output_mask = get_pb_graph_pin_lut_output_mask(lut_out_pb_graph_pin); + + /* Apply modification to the truth table */ + for (i = 0; i < truth_table_length; i++) { + /* Last two chars are fixed */ + lut_size = strlen(truth_table[i]) - 2; + /* Get the number of bits to be masked (modified) */ + num_mask_bits = lut_size - lut_frac_level; + /* Check if we need to modify any bits */ + assert (-1 < num_mask_bits); + if ( 0 == num_mask_bits ) { + continue; + } + /* Modify bits starting from lut_frac_level */ + /* decode the lut_output_mask to LUT input codes */ + temp = pow(2., num_mask_bits) - 1 - lut_output_mask; + mask_bits = my_itobin(temp, num_mask_bits); + /* copy the bits to the truth table line */ + memcpy(truth_table[i] + lut_frac_level, mask_bits, num_mask_bits); + /* free */ + my_free(mask_bits); + } + + return; +} + +int determine_lut_path_id(int lut_size, + int* lut_inputs) { + int path_id = 0; + int i; + + for (i = 0; i < lut_size; i++) { + switch (lut_inputs[i]) { + case 0: + path_id += (int)pow(2., (double)(i)); + break; + case 1: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid sram_bits[%d]!\n", + __FILE__, __LINE__, i); + exit(1); + } + } + + return path_id; +} + +/* Identify if this is an unallocated pb that is used as a wired LUT */ +boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* cur_pb_type, + t_rr_node* pb_rr_graph) { + boolean is_used = FALSE; + + is_used = is_pb_used_for_wiring(cur_pb_graph_node, + cur_pb_type, + pb_rr_graph); + /* Return TRUE if this block is not used and it is a LUT ! */ + if ((TRUE == is_used) + && (LUT_CLASS == cur_pb_type->class_type)) { + return TRUE; + } + + return FALSE; +} + +/* Find and return the net_name that this LUT is wiring*/ +int get_wired_lut_net_name(t_pb_graph_node* lut_pb_graph_node, + t_pb_type* lut_pb_type, + t_rr_node* pb_rr_graph) { + int iport, ipin; + int num_used_lut_input_pins = 0; + int num_used_lut_output_pins = 0; + int temp_rr_node_index; + int wired_lut_net_num = OPEN; + + /* Return if this is not a LUT */ + if ((LUT_CLASS != lut_pb_type->class_type) + || (LUT_CLASS != lut_pb_graph_node->pb_type->class_type)) { + return OPEN; + } + + num_used_lut_input_pins = 0; + /* Find the used input pin of this LUT and rr_node in the graph */ + for (iport = 0; iport < lut_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < lut_pb_graph_node->num_input_pins[iport]; ipin++) { + temp_rr_node_index = lut_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + if (OPEN != pb_rr_graph[temp_rr_node_index].net_num) { + num_used_lut_input_pins++; + wired_lut_net_num = pb_rr_graph[temp_rr_node_index].net_num; + } + } + } + /* Make sure we only have 1 used input pin */ + assert (1 == num_used_lut_input_pins); + + /* Find the used output*/ + num_used_lut_output_pins = 0; + /* Find the used output pin of this LUT and rr_node in the graph */ + for (iport = 0; iport < lut_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < lut_pb_graph_node->num_output_pins[iport]; ipin++) { + temp_rr_node_index = lut_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; + if (wired_lut_net_num == pb_rr_graph[temp_rr_node_index].net_num) { + num_used_lut_output_pins++; + } + } + } + /* Make sure we only have 1 used output pin */ + assert (1 == num_used_lut_output_pins); + + assert (OPEN != wired_lut_net_num); + + return wired_lut_net_num; +} + +/* This function aims to allocate and load pbs for wired LUTs + * 1. if the pbs are not allocated at all, allocate and load the full array + * Otherwise just allocate the specific pb + * 2. Get the net_name that this LUT is wiring + * and load it to the pb + */ +void allocate_wired_lut_pbs(t_pb*** wired_lut_pbs, + int num_pb_type_children, + int num_pbs, + int wired_lut_child_id, + int wired_lut_pb_id) { + int ipb; + + /* 1. if the pbs are not allocated at all, allocate and load the full array */ + if (NULL == (*wired_lut_pbs)) { + (*wired_lut_pbs) = (t_pb**) my_calloc(num_pb_type_children, sizeof(t_pb*)); + for (ipb = 0 ; ipb < num_pb_type_children; ipb++) { + (*wired_lut_pbs)[ipb] = (t_pb*) my_calloc(num_pbs, sizeof(t_pb)); + } + } else if (NULL == (*wired_lut_pbs)[wired_lut_child_id]) { + /* 2. if the pb row is not allocated, just allocate that row */ + (*wired_lut_pbs)[wired_lut_child_id] = (t_pb*) my_calloc(num_pbs, sizeof(t_pb)); + } else if (NULL == (*wired_lut_pbs)[wired_lut_child_id][wired_lut_pb_id].name) { + /* 3. if this pb is allocated, we do nothing */ + } + + /* Find the net_name this LUT is wiring */ + + return; +} + +/* 1. Find the net_name that this wire LUT is mapped to + * 2. Give a name to the pb + * 3. Update the mapping information (net_num) in the rr_graph of pb + * 4. Create the wired LUTs in logical block array + * 5. Create new vpack & clb nets to rewire the logical blocks + * 6. Update the vpack_to_clb_net_mapping and clb_to_vpack_net_mapping !!! + */ +void load_wired_lut_pbs(t_pb* lut_pb, + t_pb_graph_node* lut_pb_graph_node, + t_pb_type* lut_pb_type, + t_rr_node* pb_rr_graph, + int* L_num_logical_blocks, t_net** L_logical_block, + int* L_num_vpack_nets, t_net** L_vpack_net) { + int lut_wire_net_name = OPEN; + + /* 1. Find the net_name that this wire LUT is mapped to */ + lut_wire_net_name = get_wired_lut_net_name(lut_pb_graph_node, + lut_pb_type, + pb_rr_graph); + assert (OPEN != lut_wire_net_name); + + /* Fill basic information */ + lut_pb->pb_graph_node = lut_pb_graph_node; + lut_pb->rr_graph = pb_rr_graph; + + /* Check and give a new name to this pb */ + + /* Update rr_graph, + * 1. find the downstream logical blocks and their pbs + * 2. Update their rr_nodes with new net_name + * 3. backtrace all the rr_nodes and update net_name + */ + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.h new file mode 100644 index 000000000..3571d3df3 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_lut_utils.h @@ -0,0 +1,59 @@ +/* Useful functions for LUT decoding */ +char* complete_truth_table_line(int lut_size, + char* input_truth_table_line); + +void configure_lut_sram_bits_per_line_rec(int** sram_bits, + int lut_size, + char* truth_table_line, + int start_point); + +int* generate_lut_sram_bits(int truth_table_len, + char** truth_table, + int lut_size, + int default_sram_bit_value); + +int* generate_frac_lut_sram_bits(t_phy_pb* lut_phy_pb, + int* truth_table_length, + char*** truth_table, + int default_sram_bit_value); + +char** assign_lut_truth_table(t_logical_block* mapped_logical_block, + int* truth_table_length); + +char** get_wired_lut_truth_table(); + +char** assign_post_routing_wired_lut_truth_table(int lut_output_vpack_net_num, + int lut_size, int* lut_pin_vpack_net_num, + int* truth_table_length); + +char** assign_post_routing_lut_truth_table(t_logical_block* mapped_logical_block, + int num_lut_pins, int* lut_pin_vpack_net_num, + int* truth_table_length); + +t_pb_graph_pin* get_mapped_lut_phy_pb_output_pin(t_phy_pb* lut_phy_pb, + t_logical_block* lut_logical_block); + +int get_pb_graph_pin_lut_frac_level(t_pb_graph_pin* out_pb_graph_pin); + +int get_pb_graph_pin_lut_output_mask(t_pb_graph_pin* out_pb_graph_pin); + +void adapt_truth_table_for_frac_lut(t_pb_graph_pin* lut_out_pb_graph_pin, + int truth_table_length, + char** truth_table); + +int determine_lut_path_id(int lut_size, + int* lut_inputs); + +boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* cur_pb_type, + t_rr_node* pb_rr_graph); + +int get_wired_lut_net_name(t_pb_graph_node* lut_pb_graph_node, + t_pb_type* lut_pb_type, + t_rr_node* pb_rr_graph); + +void allocate_wired_lut_pbs(t_pb*** wired_lut_pbs, + int num_pb_type_children, + int num_pbs, + int wired_lut_child_id, + int wired_lut_pb_id); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c new file mode 100644 index 000000000..6ea99ef52 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c @@ -0,0 +1,1099 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "quicksort.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" + +/* Determine the number of SRAM bit for a basis subckt of a multiplexer + * In general, the number of SRAM bits should be same as the number of inputs per level + * with one exception: + * When multiplexing structure is tree-like, there should be only 1 SRAM bit + */ +int determine_num_sram_bits_mux_basis_subckt(t_spice_model* mux_spice_model, + int mux_size, + int num_input_per_level, + boolean special_basis) { + int num_sram_bits; + + /* General cases */ + switch (mux_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_TREE: + num_sram_bits = 1; + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + num_sram_bits = num_input_per_level; + if (2 == num_input_per_level) { + num_sram_bits = 1; + } + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + num_sram_bits = num_input_per_level; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + __FILE__, __LINE__, mux_spice_model->name); + exit(1); + } + + /* For special cases: overide the results */ + if (TRUE == special_basis) { + num_sram_bits = num_input_per_level; + } + + return num_sram_bits; +} + +/* Determine the level of multiplexer + */ +int determine_tree_mux_level(int mux_size) { + int level = 0; + + /* Do log2(mux_size), have a basic number*/ + level = (int)(log((double)mux_size)/log(2.)); + /* Fix the error, i.e. mux_size=5, level = 2, we have to complete */ + while (mux_size > pow(2.,(double)level)) { + level++; + } + + return level; +} + +int determine_num_input_basis_multilevel_mux(int mux_size, + int mux_level) { + int num_input_per_unit = 2; + + /* Special Case: mux_size = 2 */ + if (2 == mux_size) { + return mux_size; + } + + if (1 == mux_level) { + return mux_size; + } + + if (2 == mux_level) { + num_input_per_unit = (int)sqrt(mux_size); + while (num_input_per_unit*num_input_per_unit < mux_size) { + num_input_per_unit++; + } + return num_input_per_unit; + } + + assert(2 < mux_level); + + + while(pow((double)num_input_per_unit, (double)mux_level) < mux_size) { + num_input_per_unit++; + } + + if (num_input_per_unit < 2) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Number of inputs of each basis should be at least 2!\n", + __FILE__, __LINE__); + exit(1); + } + + return num_input_per_unit; +} + +/*Determine the number inputs required at the last level*/ +int tree_mux_last_level_input_num(int num_level, + int mux_size) { + int ret = 0; + + ret = (int)(pow(2., (double)num_level)) - mux_size; + + if (0 < ret) { + ret = (int)(2.*(mux_size - pow(2., (double)(num_level-1)))); + } else if (0 > ret) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])num_level(%d) is wrong with mux_size(%d)!\n", + __FILE__, __LINE__, num_level, mux_size); + exit(1); + } else { + ret = mux_size; + } + + return ret; +} + +int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit, + int mux_size) { + int ret = 0; + int num_basis_last_level = (int)(mux_size/num_input_per_unit); + int num_potential_special_inputs = 0; + int num_special_basis = 0; + int num_input_special_basis = 0; + + ret = mux_size - num_basis_last_level * num_input_per_unit; + assert((0 == ret)||(0 < ret)); + + /* Special Case: mux_size = 2 */ + if (2 == mux_size) { + return mux_size; + } + + if (0 < ret) { + /* Check if we need a special basis at last level, + * differ : the number of input of the last-2 level will be used + */ + num_potential_special_inputs = (num_basis_last_level + ret) - pow((double)(num_input_per_unit), (double)(num_level-1)); + /* should be smaller than the num_input_per_unit */ + assert((!(0 > num_potential_special_inputs))&&(num_potential_special_inputs < num_input_per_unit)); + /* We need a speical basis */ + num_special_basis = pow((double)(num_input_per_unit), (double)(num_level - 1)) - num_basis_last_level; + if (ret == num_special_basis) { + num_input_special_basis = 0; + } else if (1 == num_special_basis) { + num_input_special_basis = ret; + } else { + assert ( 1 < num_special_basis ); + num_input_special_basis = ret - 1; + } + ret = num_input_special_basis + num_basis_last_level * num_input_per_unit; + } else { + ret = mux_size; + } + + return ret; +} + +/* Decoding a one-level MUX: + * SPICE/Verilog model declare the sram port sequence as follows: + * sel0, sel1, ... , selN, + * which control the pass-gate logic connected to + * in0, in1, ... , inN + * When decode the SRAM bits, we initialize every bits to zero + * And then set the sel signal corresponding to the input to be 1. + * TODO: previously the decoding is not correct, need to check any bug in SPICE part + */ +int* decode_onelevel_mux_sram_bits(int fan_in, + int mux_level, + int path_id) { + int* ret = (int*)my_malloc(sizeof(int)*fan_in); + int i; + + /* Check */ + assert( (!(0 > path_id)) && (path_id < fan_in) ); + + for (i = 0; i < fan_in; i++) { + ret[i] = 0; + } + ret[path_id] = 1; + /* ret[fan_in - 1 - path_id] = 1; */ + return ret; +} + +int* decode_multilevel_mux_sram_bits(int fan_in, + int mux_level, + int path_id) { + int* ret = NULL; + int i, j, path_differ, temp; + int num_last_level_input, active_mux_level, active_path_id, num_input_basis; + + /* Check */ + assert((0 == path_id)||(0 < path_id)); + assert(path_id < fan_in); + + /* determine the number of input of basis */ + switch (mux_level) { + case 1: + /* Special: 1-level should be have special care !!! */ + return decode_onelevel_mux_sram_bits(fan_in, mux_level, path_id); + default: + assert(1 < mux_level); + num_input_basis = determine_num_input_basis_multilevel_mux(fan_in, mux_level); + break; + } + + ret = (int*)my_malloc(sizeof(int)*(num_input_basis * mux_level)); + + /* Determine last level input */ + num_last_level_input = multilevel_mux_last_level_input_num(mux_level, num_input_basis, fan_in); + + /* Initialize */ + for (i = 0; i < (num_input_basis*mux_level); i++) { + ret[i] = 0; + } + + /* When last level input number is less than the 2**mux_level, + * There are some input at the level: (mux_level-1) + */ + active_mux_level = mux_level; + active_path_id = path_id; + if (num_last_level_input < fan_in) { + if (path_id > num_last_level_input - 1) { + active_mux_level = mux_level - 1; + active_path_id = (int)pow((double)num_input_basis,(double)(active_mux_level)) - (fan_in - path_id); + } + } else { + assert(num_last_level_input == fan_in); + } + /* + if ((41 == fan_in) && (40 == path_id)) { + printf("num_last_level_input=%d, active_mux_lvl=%d, active_path_id=%d\n", + num_last_level_input, active_mux_level, active_path_id); + } + */ + temp = active_path_id; + for (i = mux_level - 1; i > (mux_level - active_mux_level - 1); i--) { + for (j = 0; j < num_input_basis; j++) { + path_differ = (j + 1) * (int)pow((double)num_input_basis,(double)(i+active_mux_level-mux_level)); + if (temp < path_differ) { + /* This is orignal one for SPICE, but not work for VerilogGen + * I comment it here + ret[i*num_input_basis + j] = 1; + */ + ret[(mux_level - 1 - i)*num_input_basis + j] = 1; + /* Reduce the min. start index of this basis */ + temp -= j * (int)pow((double)num_input_basis,(double)(i+active_mux_level-mux_level)); + break; /* Touch the boundry, stop and move onto the next level */ + } + } + } + + /* Check */ + assert(0 == temp); + + return ret; +} + +/* Decode the configuration to sram_bits + * A path_id is in the range of [0..fan_in-1] + * sram + * input0 -----| + * |----- output + * input1 -----| + * Here, we assume (fix) the mux2to1 pass input0 when sram = 1 (vdd), and pass input1 when sram = 0(gnd) + * To generate the sram bits, we can determine the in each level of MUX, + * the path id is on the upper path(sram = 1) or the lower path (sram = 0), by path_id > 2**mux_level + */ +int* decode_tree_mux_sram_bits(int fan_in, + int mux_level, + int path_id) { + int* ret = (int*)my_malloc(sizeof(int)*mux_level); + int i = 0; + int path_differ = 0; + int temp = 0; + int num_last_level_input = 0; + int active_mux_level = 0; + int active_path_id = 0; + + /* Check */ + assert((0 == path_id)||(0 < path_id)); + assert(path_id < fan_in); + + /* Determine last level input */ + num_last_level_input = tree_mux_last_level_input_num(mux_level, fan_in); + + /* Initialize */ + for (i = 0; i < mux_level; i++) { + ret[i] = 0; + } + + /* When last level input number is less than the 2**mux_level, + * There are some input at the level: (mux_level-1) + */ + active_mux_level = mux_level; + active_path_id = path_id; + if (num_last_level_input < fan_in) { + if (path_id > num_last_level_input) { + active_mux_level = mux_level - 1; + active_path_id = (int)pow(2.,(double)(active_mux_level)) - (fan_in - path_id); + } + } else { + assert(num_last_level_input == fan_in); + } + + temp = active_path_id; + for (i = mux_level - 1; i > (mux_level - active_mux_level - 1); i--) { + path_differ = (int)pow(2.,(double)(i + active_mux_level - mux_level)); + if (temp < path_differ) { + ret[i] = 1; + } else { + temp = temp - path_differ; + ret[i] = 0; + } + } + + /* Check */ + assert(0 == temp); + + return ret; +} + +int get_mux_default_path_id(t_spice_model* mux_spice_model, + int mux_size, int path_id) { + int default_path_id; + + assert(SPICE_MODEL_MUX == mux_spice_model->type); + + if (TRUE == mux_spice_model->design_tech_info.mux_info->add_const_input) { + default_path_id = mux_size; /* When there is a constant input, use the last path */ + } else { + default_path_id = DEFAULT_MUX_PATH_ID; /* When there is no constant input, use the default one */ + } + + return default_path_id; +} + +int get_mux_full_input_size(t_spice_model* mux_spice_model, + int mux_size) { + int full_input_size = mux_size; + + assert ((SPICE_MODEL_MUX == mux_spice_model->type) + || (SPICE_MODEL_LUT == mux_spice_model->type)); + + if (SPICE_MODEL_LUT == mux_spice_model->type) { + return full_input_size; + } + + if (TRUE == mux_spice_model->design_tech_info.mux_info->add_const_input) { + full_input_size = mux_size + 1; + } + + return full_input_size; +} + +void decode_cmos_mux_sram_bits(t_spice_model* mux_spice_model, + int mux_size, int path_id, + int* bit_len, int** conf_bits, int* mux_level) { + int num_mux_input = 0; + int datapath_id = path_id; + + /* Check */ + assert(NULL != mux_level); + assert(NULL != bit_len); + assert(NULL != conf_bits); + assert(SPICE_MODEL_MUX == mux_spice_model->type); + assert(SPICE_MODEL_DESIGN_CMOS == mux_spice_model->design_tech); + + /* Handle DEFAULT PATH ID */ + if (DEFAULT_PATH_ID == path_id) { + datapath_id = get_mux_default_path_id(mux_spice_model, mux_size, path_id); + } else { + assert((DEFAULT_PATH_ID < datapath_id)&&(datapath_id < mux_size)); + } + + /* We have an additional input (last input) connected to a constant */ + num_mux_input = get_mux_full_input_size(mux_spice_model, mux_size); + + /* Initialization */ + (*bit_len) = 0; + (*conf_bits) = NULL; + + /* Special for MUX-2: whatever structure it is, it has always one-level and one configuration bit */ + if (2 == num_mux_input) { + (*bit_len) = 1; + (*mux_level) = 1; + (*conf_bits) = decode_tree_mux_sram_bits(num_mux_input, (*mux_level), datapath_id); + return; + } + /* Other general cases */ + switch (mux_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_TREE: + (*mux_level) = determine_tree_mux_level(num_mux_input); + (*bit_len) = (*mux_level); + (*conf_bits) = decode_tree_mux_sram_bits(num_mux_input, (*mux_level), datapath_id); + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + (*mux_level) = 1; + (*bit_len) = num_mux_input; + (*conf_bits) = decode_onelevel_mux_sram_bits(num_mux_input, (*mux_level), datapath_id); + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + (*mux_level) = mux_spice_model->design_tech_info.mux_info->mux_num_level; + (*bit_len) = determine_num_input_basis_multilevel_mux(num_mux_input, (*mux_level)) * (*mux_level); + (*conf_bits) = decode_multilevel_mux_sram_bits(num_mux_input, (*mux_level), datapath_id); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for mux_spice_model (%s)!\n", + __FILE__, __LINE__, mux_spice_model->name); + exit(1); + } + return; +} + +/** Decode 1-level 4T1R MUX + */ +void decode_one_level_4t1r_mux(int path_id, + int bit_len, int* conf_bits) { + int i; + + /* Check */ + assert(0 < bit_len); + assert(NULL != conf_bits); + assert((-1 < path_id)&&((path_id < bit_len/2 - 1)||(path_id == bit_len/2 - 1))); + + /* All the others should be zero */ + for (i = 0; i < bit_len; i++) { + conf_bits[i] = 0; + } + + /* Last bit of WL should be 1 */ + conf_bits[bit_len-1] = 1; + /* determine which BL should be 1*/ + conf_bits[path_id] = 1; + + return; +} + +/** Decode multi-level 4T1R MUX + */ +void decode_multilevel_4t1r_mux(int num_level, int num_input_basis, + int mux_size, int path_id, + int bit_len, int* conf_bits) { + int i, active_basis_path_id; + + /* Check */ + assert(0 < bit_len); + assert(NULL != conf_bits); + /* assert((-1 < path_id)&&(path_id < bit_len/2 - 1)); */ + /* Start from first level to the last level */ + active_basis_path_id = path_id; + for (i = 0; i < num_level; i++) { + /* Treat each basis as a 1-level 4T1R MUX */ + active_basis_path_id = active_basis_path_id % num_input_basis; + /* Last bit of WL should be 1 */ + conf_bits[bit_len/2 + (num_input_basis+1)*(i+1) - 1] = 1; + /* determine which BL should be 1*/ + conf_bits[(num_input_basis+1)*i + active_basis_path_id] = 1; + } + + return; +} + +/** Decode the configuration bits for a 4T1R-based MUX + * Determine the number of configuration bits + * Configuration bits are decoded depending on the MUX structure: + * 1. 1-level; 2. multi-level (tree-like); + */ +void decode_rram_mux(t_spice_model* mux_spice_model, + int mux_size, int path_id, + int* bit_len, int** conf_bits, int* mux_level) { + int num_level, num_input_basis, num_mux_input; + int datapath_id = path_id; + + /* Check */ + assert(NULL != mux_level); + assert(NULL != bit_len); + assert(NULL != conf_bits); + assert(SPICE_MODEL_MUX == mux_spice_model->type); + assert(SPICE_MODEL_DESIGN_RRAM == mux_spice_model->design_tech); + + /* Handle DEFAULT PATH ID */ + if (DEFAULT_PATH_ID == datapath_id) { + datapath_id = get_mux_default_path_id(mux_spice_model, mux_size, path_id); + } else { + assert((DEFAULT_PATH_ID < datapath_id)&&(datapath_id < mux_size)); + } + + /* We have an additional input (last input) connected to a constant */ + num_mux_input = get_mux_full_input_size(mux_spice_model, mux_size); + + /* Initialization */ + (*mux_level) = 0; + (*bit_len) = 0; + (*conf_bits) = NULL; + + (*bit_len) = 2 * count_num_sram_bits_one_spice_model(mux_spice_model, num_mux_input); + + /* Switch cases: MUX structure */ + switch (mux_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_ONELEVEL: + /* Number of configuration bits is 2*(input_size+1) */ + num_level = 1; + break; + case SPICE_MODEL_STRUCTURE_TREE: + /* Number of configuration bits is num_level* 2*(basis+1) */ + num_level = determine_tree_mux_level(num_mux_input); + num_input_basis = 2; + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + /* Number of configuration bits is num_level* 2*(basis+1) */ + num_level = mux_spice_model->design_tech_info.mux_info->mux_num_level; + num_input_basis = determine_num_input_basis_multilevel_mux(num_mux_input, num_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid MUX structure!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Malloc configuration bits */ + (*conf_bits) = (int*)my_calloc((*bit_len), sizeof(int)); + + /* Decode configuration bits : BL & WL*/ + /* Switch cases: MUX structure */ + switch (mux_spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_ONELEVEL: + decode_one_level_4t1r_mux(datapath_id, (*bit_len), (*conf_bits)); + break; + case SPICE_MODEL_STRUCTURE_TREE: + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + decode_multilevel_4t1r_mux(num_level, num_input_basis, num_mux_input, + datapath_id, (*bit_len), (*conf_bits)); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid MUX structure!\n", + __FILE__, __LINE__); + exit(1); + } + + (*mux_level) = num_level; + + return; +} + +/* Useful functions for MUX architecture */ +void init_spice_mux_arch(t_spice_model* spice_model, + t_spice_mux_arch* spice_mux_arch, + int mux_size) { + int cur; + int i; + /* Make sure we have a valid pointer*/ + if (NULL == spice_mux_arch) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,LINE[%d])Invalid spice_mux_arch!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Basic info*/ + spice_mux_arch->structure = spice_model->design_tech_info.mux_info->structure; + spice_mux_arch->num_data_input = mux_size; + /* We create an additional input for MUX, which is connected to a constant VDD|GND */ + spice_mux_arch->num_input = get_mux_full_input_size(spice_model, mux_size); + + /* For different structure */ + switch (spice_model->design_tech_info.mux_info->structure) { + case SPICE_MODEL_STRUCTURE_TREE: + spice_mux_arch->num_level = determine_tree_mux_level(spice_mux_arch->num_input); + spice_mux_arch->num_input_basis = 2; + /* Determine the level and index of per MUX inputs*/ + spice_mux_arch->num_input_last_level = tree_mux_last_level_input_num(spice_mux_arch->num_level, + spice_mux_arch->num_input); + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + spice_mux_arch->num_level = 1; + spice_mux_arch->num_input_basis = spice_mux_arch->num_input; + /* Determine the level and index of per MUX inputs*/ + spice_mux_arch->num_input_last_level = spice_mux_arch->num_input; + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + /* Handle speical case: input size is 2 */ + if (2 == spice_mux_arch->num_input) { + spice_mux_arch->num_level = 1; + } else { + spice_mux_arch->num_level = spice_model->design_tech_info.mux_info->mux_num_level; + } + spice_mux_arch->num_input_basis = determine_num_input_basis_multilevel_mux(spice_mux_arch->num_input, + spice_mux_arch->num_level); + /* Determine the level and index of per MUX inputs*/ + spice_mux_arch->num_input_last_level = multilevel_mux_last_level_input_num(spice_mux_arch->num_level, + spice_mux_arch->num_input_basis, + spice_mux_arch->num_input); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + __FILE__, __LINE__, spice_model->name); + exit(1); + } + + /* Alloc*/ + spice_mux_arch->num_input_per_level = (int*) my_malloc(sizeof(int)*spice_mux_arch->num_level); + spice_mux_arch->input_level = (int*)my_malloc(sizeof(int)*spice_mux_arch->num_input); + spice_mux_arch->input_offset = (int*)my_malloc(sizeof(int)*spice_mux_arch->num_input); + + /* Assign inputs info for the last level first */ + for (i = 0; i < spice_mux_arch->num_input_last_level; i++) { + spice_mux_arch->input_level[i] = spice_mux_arch->num_level; + spice_mux_arch->input_offset[i] = i; + } + /* For the last second level*/ + if (spice_mux_arch->num_input > spice_mux_arch->num_input_last_level) { + cur = ceil((double)spice_mux_arch->num_input_last_level / (double)spice_mux_arch->num_input_basis); + /* Start from the input ports that are not occupied by the last level + * last level has (cur) outputs + */ + /* + printf("size:%d, cur:%d, num_input_last_level=%d, num_input_basis=%d\n", + spice_mux_arch->num_input, cur, + spice_mux_arch->num_input_last_level, spice_mux_arch->num_input_basis); + */ + for (i = spice_mux_arch->num_input_last_level; i < spice_mux_arch->num_input; i++) { + spice_mux_arch->input_level[i] = spice_mux_arch->num_level - 1; + spice_mux_arch->input_offset[i] = cur; + cur++; + } + assert((cur < (int)pow((double)spice_mux_arch->num_input_basis, (double)(spice_mux_arch->num_level-1))) + ||(cur == (int)pow((double)spice_mux_arch->num_input_basis, (double)(spice_mux_arch->num_level-1)))); + } + /* Fill the num_input_per_level*/ + for (i = 0; i < spice_mux_arch->num_level; i++) { + cur = i + 1; + spice_mux_arch->num_input_per_level[i] = (int)pow((double)spice_mux_arch->num_input_basis, (double)cur); + if ((cur == spice_mux_arch->num_level) + &&(spice_mux_arch->num_input_last_level < spice_mux_arch->num_input_per_level[i])) { + spice_mux_arch->num_input_per_level[i] = spice_mux_arch->num_input_last_level; + } + } + + return; +} + +/* Determine if we need a speical basis. + * If we need one, we give the MUX size of this special basis + */ +int find_spice_mux_arch_special_basis_size(t_spice_mux_arch spice_mux_arch) { + int im; + int mux_size = spice_mux_arch.num_input; + int num_input_basis = spice_mux_arch.num_input_basis; + int num_input_special_basis = 0; + int special_basis_start = 0; + + /* For different structure */ + switch (spice_mux_arch.structure) { + case SPICE_MODEL_STRUCTURE_TREE: + break; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + special_basis_start = mux_size - mux_size % num_input_basis; + for (im = special_basis_start; im < mux_size; im++) { + if (spice_mux_arch.num_level == spice_mux_arch.input_level[im]) { + num_input_special_basis++; + } + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice_mux_arch!\n", + __FILE__, __LINE__); + exit(1); + } + + return num_input_special_basis; +} + +/* Search the linked list, if we have the same mux size and spice_model + * return 1, if not we return 0 + */ +t_llist* search_mux_linked_list(t_llist* mux_head, + int mux_size, + t_spice_model* spice_model) { + t_llist* temp = mux_head; + t_spice_mux_model* cur_mux = NULL; + /* traversal the linked list*/ + while(temp) { + cur_mux = (t_spice_mux_model*)(temp->dptr); + if ((cur_mux->size == mux_size) + &&(spice_model == cur_mux->spice_model)) { + return temp; + } + /* next */ + temp = temp->next; + } + + return NULL; +} + + +/* Check the linked list if we have a mux stored with same spice model + * if not, we create a new one. + */ +void check_and_add_mux_to_linked_list(t_llist** muxes_head, + int mux_size, + t_spice_model* spice_model) { + t_spice_mux_model* cur_mux = NULL; + t_llist* temp = NULL; + + /* Check code: to avoid mistake, we should check the mux size + * the mux_size should be at least 2 so that we need a mux + */ + if (mux_size < 2) { + printf("Warning:(File:%s,LINE[%d]) ilegal mux size (%d), expect to be at least 2!\n", + __FILE__, __LINE__, mux_size); + return; + } + + /* Search the linked list */ + if (NULL != search_mux_linked_list((*muxes_head),mux_size,spice_model)) { + /* We find one, there is no need to create a new one*/ + return; + } + /*Create a linked list, if head is NULL*/ + if (NULL == (*muxes_head)) { + (*muxes_head) = create_llist(1); + (*muxes_head)->dptr = my_malloc(sizeof(t_spice_mux_model)); + cur_mux = (t_spice_mux_model*)((*muxes_head)->dptr); + } else { + /* We have to create a new elment in linked list*/ + temp = insert_llist_node((*muxes_head)); + temp->dptr = my_malloc(sizeof(t_spice_mux_model)); + cur_mux = (t_spice_mux_model*)(temp->dptr); + } + /* Fill the new SPICE MUX Model*/ + cur_mux->size = mux_size; + cur_mux->spice_model = spice_model; + cur_mux->cnt = 1; /* Initialize the counter*/ + + return; +} + +/* Free muxes linked list + */ +void free_muxes_llist(t_llist* muxes_head) { + t_llist* temp = muxes_head; + while(temp) { + /* Free the mux_spice_model, remember to set the pointer to NULL */ + free(temp->dptr); + temp->dptr = NULL; + /* Move on to the next pointer*/ + temp = temp->next; + } + free_llist(muxes_head); + return; +} + +/* For LUTs without SPICE netlist defined, we can create a SPICE netlist + * In this case, we need a MUX + */ +void stats_lut_spice_mux(t_llist** muxes_head, + t_spice_model* spice_model) { + int lut_mux_size = 0; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + + if (NULL == spice_model) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid Spice_model pointer!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert(SPICE_MODEL_LUT == spice_model->type); + + /* Get input ports */ + input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + assert(1 == num_input_port); + lut_mux_size = (int)pow(2.,(double)(input_ports[0]->size)); + + /* MUX size = 2^lut_size */ + check_and_add_mux_to_linked_list(muxes_head, lut_mux_size, spice_model); + + return; +} + + + +/* Stats the multiplexer sizes and structure in the global routing architecture*/ +void stats_spice_muxes_routing_arch(t_llist** muxes_head, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch) { + int inode; + t_rr_node* node; + t_spice_model* sb_switch_spice_model = NULL; + t_spice_model* cb_switch_spice_model = NULL; + + /* Current Version: Support Uni-directional routing architecture only*/ + if (UNI_DIRECTIONAL != routing_arch->directionality) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d])Spice Modeling Only support uni-directional routing architecture.\n",__FILE__, __LINE__); + exit(1); + } + + /* The routing path is. + * OPIN ----> CHAN ----> ... ----> CHAN ----> IPIN + * Each edge is a switch, for IPIN, the switch is a connection block, + * for the rest is a switch box + */ + /* Count the sizes of muliplexers in routing architecture */ + /* Visit the global variable : num_rr_nodes, rr_node */ + for (inode = 0; inode < num_rr_nodes; inode++) { + node = &rr_node[inode]; + switch (node->type) { + case IPIN: + /* Have to consider the fan_in only, it is a connection box(multiplexer)*/ + assert((node->fan_in > 0)||(0 == node->fan_in)); + if ((0 == node->fan_in)||(1 == node->fan_in)) { + break; + } + /* Find the spice_model for multiplexers in connection blocks */ + cb_switch_spice_model = switches[node->driver_switch].spice_model; + /* we should select a spice model for the connection box*/ + assert(NULL != cb_switch_spice_model); + check_and_add_mux_to_linked_list(muxes_head, node->fan_in,cb_switch_spice_model); + break; + case CHANX: + case CHANY: + /* Channels are the same, have to consider the fan_in as well, + * it could be a switch box if previous rr_node is a channel + * or it could be a connection box if previous rr_node is a IPIN or OPIN + */ + assert((node->fan_in > 0)||(0 == node->fan_in)); + if ((0 == node->fan_in)||(1 == node->fan_in)) { + break; + } + /* Find the spice_model for multiplexers in switch blocks*/ + sb_switch_spice_model = switches[node->driver_switch].spice_model; + /* we should select a spice model for the Switch box*/ + assert(NULL != sb_switch_spice_model); + check_and_add_mux_to_linked_list(muxes_head, node->fan_in,sb_switch_spice_model); + break; + case OPIN: + /* Actually, in single driver routing architecture, the OPIN, source of a routing path, + * is directly connected to Switch Box multiplexers + */ + break; + default: + break; + } + } + + return; +} + +/* Recursively do statistics for the + * multiplexer spice models inside pb_types + */ +void stats_mux_spice_model_pb_type_rec(t_llist** muxes_head, + t_pb_type* cur_pb_type) { + + int imode, ichild, jinterc; + t_spice_model* interc_spice_model = NULL; + + if (NULL == cur_pb_type) { + vpr_printf(TIO_MESSAGE_WARNING,"(File:%s,LINE[%d])cur_pb_type is null pointor!\n",__FILE__,__LINE__); + return; + } + + /* If there is spice_model_name, this is a leaf node!*/ + if ((NULL != cur_pb_type->spice_model_name) + || (NULL != cur_pb_type->physical_pb_type_name)) { + /* What annoys me is VPR create a sub pb_type for each lut which suppose to be a leaf node + * This may bring software convience but ruins SPICE modeling + */ + assert(NULL != cur_pb_type->phy_pb_type->spice_model); + return; + } + /* Traversal the hierarchy*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Then we have to statisitic the interconnections*/ + for (jinterc = 0; jinterc < cur_pb_type->modes[imode].num_interconnect; jinterc++) { + /* Check the num_mux and fan_in*/ + assert((0 == cur_pb_type->modes[imode].interconnect[jinterc].num_mux) + ||(0 < cur_pb_type->modes[imode].interconnect[jinterc].num_mux)); + if (0 == cur_pb_type->modes[imode].interconnect[jinterc].num_mux) { + continue; + } + interc_spice_model = cur_pb_type->modes[imode].interconnect[jinterc].spice_model; + assert(NULL != interc_spice_model); + check_and_add_mux_to_linked_list(muxes_head, + cur_pb_type->modes[imode].interconnect[jinterc].fan_in, + interc_spice_model); + } + for (ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ichild++) { + stats_mux_spice_model_pb_type_rec(muxes_head, + &cur_pb_type->modes[imode].pb_type_children[ichild]); + } + } + return; +} + +/* Statistics the MUX SPICE MODEL with the help of pb_graph + * Not the most efficient function to finish the job + * Abandon it. But remains a good framework that could be re-used in connecting + * spice components together + */ +void stats_mux_spice_model_pb_node_rec(t_llist** muxes_head, + t_pb_graph_node* cur_pb_node) { + int imode, ipb, ichild, iport, ipin; + t_pb_type* cur_pb_type = cur_pb_node->pb_type; + t_spice_model* interc_spice_model = NULL; + enum e_interconnect pin_interc_type; + + if (NULL == cur_pb_node) { + vpr_printf(TIO_MESSAGE_WARNING,"(File:%s,LINE[%d])cur_pb_node is null pointor!\n",__FILE__,__LINE__); + return; + } + + if (NULL == cur_pb_type) { + vpr_printf(TIO_MESSAGE_WARNING,"(File:%s,LINE[%d])cur_pb_type is null pointor!\n",__FILE__,__LINE__); + return; + } + + /* If there is 0 mode, this is a leaf node!*/ + if (NULL != cur_pb_type->blif_model) { + assert(0 == cur_pb_type->num_modes); + assert(NULL == cur_pb_type->modes); + /* Ensure there is blif_model, and spice_model*/ + assert(NULL != cur_pb_type->model); + assert(NULL != cur_pb_type->spice_model_name); + assert(NULL != cur_pb_type->spice_model); + return; + } + /* Traversal the hierarchy*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Then we have to statisitic the interconnections*/ + /* See the input ports*/ + for (iport = 0; iport < cur_pb_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_node->num_input_pins[iport]; ipin++) { + /* Ensure this is an input port */ + assert(IN_PORT == cur_pb_node->input_pins[iport][ipin].port->type); + /* See the edges, if the interconnetion type infer a MUX, we go next step*/ + pin_interc_type = find_pb_graph_pin_in_edges_interc_type(cur_pb_node->input_pins[iport][ipin]); + if ((COMPLETE_INTERC != pin_interc_type)&&(MUX_INTERC != pin_interc_type)) { + continue; + } + /* We shoule check the size of inputs, in some case of complete, the input_edge is one...*/ + if ((COMPLETE_INTERC == pin_interc_type)&&(1 == cur_pb_node->input_pins[iport][ipin].num_input_edges)) { + continue; + } + /* Note: i do care the input_edges only! They may infer multiplexers*/ + interc_spice_model = find_pb_graph_pin_in_edges_interc_spice_model(cur_pb_node->input_pins[iport][ipin]); + check_and_add_mux_to_linked_list(muxes_head, + cur_pb_node->input_pins[iport][ipin].num_input_edges, + interc_spice_model); + } + } + /* See the output ports*/ + for (iport = 0; iport < cur_pb_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_node->num_output_pins[iport]; ipin++) { + /* Ensure this is an input port */ + assert(OUT_PORT == cur_pb_node->output_pins[iport][ipin].port->type); + /* See the edges, if the interconnetion type infer a MUX, we go next step*/ + pin_interc_type = find_pb_graph_pin_in_edges_interc_type(cur_pb_node->output_pins[iport][ipin]); + if ((COMPLETE_INTERC != pin_interc_type)&&(MUX_INTERC != pin_interc_type)) { + continue; + } + /* We shoule check the size of inputs, in some case of complete, the input_edge is one...*/ + if ((COMPLETE_INTERC == pin_interc_type)&&(1 == cur_pb_node->output_pins[iport][ipin].num_input_edges)) { + continue; + } + /* Note: i do care the input_edges only! They may infer multiplexers*/ + interc_spice_model = find_pb_graph_pin_in_edges_interc_spice_model(cur_pb_node->output_pins[iport][ipin]); + check_and_add_mux_to_linked_list(muxes_head, + cur_pb_node->output_pins[iport][ipin].num_input_edges, + interc_spice_model); + } + } + /* See the clock ports*/ + for (iport = 0; iport < cur_pb_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_node->num_clock_pins[iport]; ipin++) { + /* Ensure this is an input port */ + assert(IN_PORT == cur_pb_node->clock_pins[iport][ipin].port->type); + /* See the edges, if the interconnetion type infer a MUX, we go next step*/ + pin_interc_type = find_pb_graph_pin_in_edges_interc_type(cur_pb_node->clock_pins[iport][ipin]); + if ((COMPLETE_INTERC != pin_interc_type)&&(MUX_INTERC != pin_interc_type)) { + continue; + } + /* We shoule check the size of inputs, in some case of complete, the input_edge is one...*/ + if ((COMPLETE_INTERC == pin_interc_type)&&(1 == cur_pb_node->clock_pins[iport][ipin].num_input_edges)) { + continue; + } + /* Note: i do care the input_edges only! They may infer multiplexers*/ + interc_spice_model = find_pb_graph_pin_in_edges_interc_spice_model(cur_pb_node->clock_pins[iport][ipin]); + check_and_add_mux_to_linked_list(muxes_head, + cur_pb_node->clock_pins[iport][ipin].num_input_edges, + interc_spice_model); + } + } + for (ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ichild++) { + /* num_pb is the number of such pb_type in a mode*/ + for (ipb = 0; ipb < cur_pb_type->modes[imode].pb_type_children[ichild].num_pb; ipb++) { + /* child_pb_grpah_nodes: [0..num_modes-1][0..num_pb_type_in_mode-1][0..num_pb_type-1]*/ + stats_mux_spice_model_pb_node_rec(muxes_head, + &cur_pb_node->child_pb_graph_nodes[imode][ichild][ipb]); + } + } + } + return; +} + + +/* Statistic for all the multiplexers in FPGA + * We determine the sizes and its structure (according to spice_model) for each type of multiplexers + * We search multiplexers in Switch Blocks, Connection blocks and Configurable Logic Blocks + * In additional to multiplexers, this function also consider crossbars. + * All the statistics are stored in a linked list, as a return value + */ +t_llist* stats_spice_muxes(int num_switches, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch) { + int itype; + int imodel; + /* Linked-list to store the information of Multiplexers*/ + t_llist* muxes_head = NULL; + + /* Step 1: We should check the multiplexer spice models defined in routing architecture.*/ + stats_spice_muxes_routing_arch(&muxes_head, num_switches, switches, spice, routing_arch); + + /* Statistics after search routing resources */ + /* + temp = muxes_head; + while(temp) { + t_spice_mux_model* spice_mux_model = (t_spice_mux_model*)temp->dptr; + vpr_printf(TIO_MESSAGE_INFO,"Routing multiplexers: size=%d\n",spice_mux_model->size); + temp = temp->next; + } + */ + + /* Step 2: Count the sizes of multiplexers in complex logic blocks */ + for (itype = 0; itype < num_types; itype++) { + if (NULL != type_descriptors[itype].pb_type) { + stats_mux_spice_model_pb_type_rec(&muxes_head,type_descriptors[itype].pb_type); + } + } + + /* Step 3: count the size of multiplexer that will be used in LUTs*/ + for (imodel = 0; imodel < spice->num_spice_model; imodel++) { + /* For those LUTs that netlists are not provided. We create a netlist and thus need a MUX*/ + if ((SPICE_MODEL_LUT == spice->spice_models[imodel].type) + &&(NULL == spice->spice_models[imodel].model_netlist)) { + stats_lut_spice_mux(&muxes_head, &(spice->spice_models[imodel])); + } + } + + /* Statistics after search routing resources */ + /* + temp = muxes_head; + while(temp) { + t_spice_mux_model* spice_mux_model = (t_spice_mux_model*)temp->dptr; + vpr_printf(TIO_MESSAGE_INFO,"Pb_types multiplexers: size=%d\n",spice_mux_model->size); + temp = temp->next; + } + */ + + return muxes_head; +} + + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h new file mode 100644 index 000000000..0ea801cfd --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h @@ -0,0 +1,85 @@ + +int determine_num_sram_bits_mux_basis_subckt(t_spice_model* mux_spice_model, + int mux_size, + int num_input_per_level, + boolean special_basis); + +int determine_tree_mux_level(int mux_size); + +int determine_num_input_basis_multilevel_mux(int mux_size, + int mux_level); + +int tree_mux_last_level_input_num(int num_level, + int mux_size); + +int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit, + int mux_size); + +int* decode_onelevel_mux_sram_bits(int fan_in, + int mux_level, + int path_id); + +int* decode_multilevel_mux_sram_bits(int fan_in, + int mux_level, + int path_id); + +int* decode_tree_mux_sram_bits(int fan_in, + int mux_level, + int path_id); + +int get_mux_default_path_id(t_spice_model* mux_spice_model, + int mux_size, int path_id); + +int get_mux_full_input_size(t_spice_model* mux_spice_model, + int mux_size); + +void decode_cmos_mux_sram_bits(t_spice_model* mux_spice_model, + int mux_size, int path_id, + int* bit_len, int** conf_bits, int* mux_level); + +void decode_one_level_4t1r_mux(int path_id, + int bit_len, int* conf_bits); + +void decode_rram_mux(t_spice_model* mux_spice_model, + int mux_size, int path_id, + int* bit_len, int** conf_bits, int* mux_level); + +void init_spice_mux_arch(t_spice_model* spice_model, + t_spice_mux_arch* spice_mux_arch, + int mux_size); + +int find_spice_mux_arch_special_basis_size(t_spice_mux_arch spice_mux_arch); + +t_llist* search_mux_linked_list(t_llist* mux_head, + int mux_size, + t_spice_model* spice_model); + +void check_and_add_mux_to_linked_list(t_llist** muxes_head, + int mux_size, + t_spice_model* spice_model); + +void free_muxes_llist(t_llist* muxes_head); + +void stats_lut_spice_mux(t_llist** muxes_head, + t_spice_model* spice_model); + + +void stats_spice_muxes_routing_arch(t_llist** muxes_head, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch); + +void stats_mux_spice_model_pb_type_rec(t_llist** muxes_head, + t_pb_type* cur_pb_type); + +void stats_mux_spice_model_pb_node_rec(t_llist** muxes_head, + t_pb_graph_node* cur_pb_node); + +t_llist* stats_spice_muxes(int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch); + + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c new file mode 100644 index 000000000..a363a140a --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c @@ -0,0 +1,3153 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_lut_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_globals.h" + +/* Make sure the edge has only one input pin and output pin*/ +void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge) { + assert(1 == pb_graph_edge.num_input_pins); + assert(1 == pb_graph_edge.num_output_pins); + + return; +} + +/* Check all the edges for a given pb_graph_pin*/ +void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin) { + int iedge; + + for (iedge = 0; iedge < pb_graph_pin.num_input_edges; iedge++) { + check_pb_graph_edge(*(pb_graph_pin.input_edges[iedge])); + } + + for (iedge = 0; iedge < pb_graph_pin.num_output_edges; iedge++) { + check_pb_graph_edge(*(pb_graph_pin.output_edges[iedge])); + } + + return; +} + +void backup_one_pb_rr_node_pack_prev_node_edge(t_rr_node* pb_rr_node) { + + pb_rr_node->prev_node_in_pack = pb_rr_node->prev_node; + pb_rr_node->prev_edge_in_pack = pb_rr_node->prev_edge; + pb_rr_node->net_num_in_pack = pb_rr_node->net_num; + pb_rr_node->prev_node = OPEN; + pb_rr_node->prev_edge = OPEN; + + return; +} + +int find_parent_pb_type_child_index(t_pb_type* parent_pb_type, + int mode_index, + t_pb_type* child_pb_type) { + int i; + + assert(NULL != parent_pb_type); + assert(NULL != child_pb_type); + assert((!(0 > mode_index))&&(mode_index < parent_pb_type->num_modes)); + + for (i = 0; i < parent_pb_type->modes[mode_index].num_pb_type_children; i++) { + if (child_pb_type == &(parent_pb_type->modes[mode_index].pb_type_children[i])) { + assert(0 == strcmp(child_pb_type->name, parent_pb_type->modes[mode_index].pb_type_children[i].name)); + return i; + } + } + + return -1; +} + +/* Rule in generating a unique name: + * name of current pb = _[index] + */ +void gen_spice_name_tag_phy_pb_rec(t_phy_pb* cur_phy_pb, + char* prefix) { + char* prefix_rec = NULL; + int ipb, jpb, mode_index; + + mode_index = cur_phy_pb->mode; + + /* Free previous name_tag if there is */ + /* my_free(cur_pb->spice_name_tag); */ + + /* Generate the name_tag */ + if ((0 < cur_phy_pb->pb_graph_node->pb_type->num_modes) + &&(NULL == cur_phy_pb->pb_graph_node->pb_type->spice_model_name)) { + prefix_rec = (char*)my_malloc(sizeof(char)*(strlen(prefix) + 1 + + strlen(cur_phy_pb->pb_graph_node->pb_type->name) + 1 + + strlen(my_itoa(cur_phy_pb->pb_graph_node->placement_index)) + 7 + + strlen(cur_phy_pb->pb_graph_node->pb_type->modes[mode_index].name) + 2 )); + sprintf(prefix_rec, "%s_%s[%d]_mode[%s]", + prefix, cur_phy_pb->pb_graph_node->pb_type->name, cur_phy_pb->pb_graph_node->placement_index, cur_phy_pb->pb_graph_node->pb_type->modes[mode_index].name); + cur_phy_pb->spice_name_tag = my_strdup(prefix_rec); + } else { + assert((0 == cur_phy_pb->pb_graph_node->pb_type->num_modes) + ||(NULL != cur_phy_pb->pb_graph_node->pb_type->spice_model_name)); + prefix_rec = (char*)my_malloc(sizeof(char)*(strlen(prefix) + 1 + + strlen(cur_phy_pb->pb_graph_node->pb_type->name) + 1 + + strlen(my_itoa(cur_phy_pb->pb_graph_node->placement_index)) + 2 )); + sprintf(prefix_rec, "%s_%s[%d]", + prefix, cur_phy_pb->pb_graph_node->pb_type->name, cur_phy_pb->pb_graph_node->placement_index); + cur_phy_pb->spice_name_tag = my_strdup(prefix_rec); + } + + /* When reach the leaf, we directly return */ + /* Recursive until reach the leaf */ + if ((0 == cur_phy_pb->pb_graph_node->pb_type->num_modes) + ||(NULL == cur_phy_pb->child_pbs)) { + return; + } + for (ipb = 0; ipb < cur_phy_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_phy_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + //if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + /* Try to simplify the name tag... to avoid exceeding the length of SPICE name (up to 1024 chars) */ + /* gen_spice_name_tag_pb_rec(&(cur_pb->child_pbs[ipb][jpb]),prefix); */ + gen_spice_name_tag_phy_pb_rec(&(cur_phy_pb->child_pbs[ipb][jpb]),prefix_rec); + //} + } + } + + my_free(prefix_rec); + + return; +} + + +/* Rule in generating a unique name: + * name of current pb = _[index] + */ +void gen_spice_name_tag_pb_rec(t_pb* cur_pb, + char* prefix) { + char* prefix_rec = NULL; + int ipb, jpb, mode_index; + + mode_index = cur_pb->mode; + + /* Free previous name_tag if there is */ + /* my_free(cur_pb->spice_name_tag); */ + + /* Generate the name_tag */ + if ((0 < cur_pb->pb_graph_node->pb_type->num_modes) + &&(NULL == cur_pb->pb_graph_node->pb_type->spice_model_name)) { + prefix_rec = (char*)my_malloc(sizeof(char)*(strlen(prefix) + 1 + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 + + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) + 7 + strlen(cur_pb->pb_graph_node->pb_type->modes[mode_index].name) + 2 )); + sprintf(prefix_rec, "%s_%s[%d]_mode[%s]", + prefix, cur_pb->pb_graph_node->pb_type->name, cur_pb->pb_graph_node->placement_index, cur_pb->pb_graph_node->pb_type->modes[mode_index].name); + cur_pb->spice_name_tag = my_strdup(prefix_rec); + } else { + assert((0 == cur_pb->pb_graph_node->pb_type->num_modes) + ||(NULL != cur_pb->pb_graph_node->pb_type->spice_model_name)); + prefix_rec = (char*)my_malloc(sizeof(char)*(strlen(prefix) + 1 + strlen(cur_pb->pb_graph_node->pb_type->name) + 1 + + strlen(my_itoa(cur_pb->pb_graph_node->placement_index)) + 2 )); + sprintf(prefix_rec, "%s_%s[%d]", + prefix, cur_pb->pb_graph_node->pb_type->name, cur_pb->pb_graph_node->placement_index); + cur_pb->spice_name_tag = my_strdup(prefix_rec); + } + + /* When reach the leaf, we directly return */ + /* Recursive until reach the leaf */ + if ((0 == cur_pb->pb_graph_node->pb_type->num_modes) + ||(NULL == cur_pb->child_pbs)) { + return; + } + for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + //if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + /* Try to simplify the name tag... to avoid exceeding the length of SPICE name (up to 1024 chars) */ + /* gen_spice_name_tag_pb_rec(&(cur_pb->child_pbs[ipb][jpb]),prefix); */ + gen_spice_name_tag_pb_rec(&(cur_pb->child_pbs[ipb][jpb]),prefix_rec); + //} + } + } + + my_free(prefix_rec); + + return; +} + +/* Generate a unique name tag for each pb, + * to identify it in both SPICE netlist and Power Modeling. + */ +void gen_spice_name_tags_all_pbs() { + int iblk; + char* prefix = NULL; + + for (iblk = 0; iblk < num_blocks; iblk++) { + prefix = (char*)my_malloc(sizeof(char)*(5 + strlen(my_itoa(block[iblk].x)) + 2 + strlen(my_itoa(block[iblk].y)) + 2 + strlen(my_itoa(block[iblk].z)) + 2)); + sprintf(prefix, "grid[%d][%d][%d]", block[iblk].x, block[iblk].y, block[iblk].z); + gen_spice_name_tag_pb_rec(block[iblk].pb, prefix); + my_free(prefix); + } + + return; +} + +/* Generate a unique name tag for each pb, + * to identify it in both SPICE netlist and Power Modeling. + */ +void gen_spice_name_tags_all_phy_pbs() { + int iblk; + char* prefix = NULL; + + for (iblk = 0; iblk < num_blocks; iblk++) { + prefix = (char*)my_malloc(sizeof(char)*(5 + strlen(my_itoa(block[iblk].x)) + 2 + strlen(my_itoa(block[iblk].y)) + 2)); + sprintf(prefix, "grid[%d][%d]", block[iblk].x, block[iblk].y); + gen_spice_name_tag_phy_pb_rec((t_phy_pb*)block[iblk].phy_pb, prefix); + my_free(prefix); + } + + return; +} + + +int find_pb_mapped_logical_block_rec(t_pb* cur_pb, + t_spice_model* pb_spice_model, + char* pb_spice_name_tag) { + int logical_block_index = OPEN; + int mode_index, ipb, jpb; + + assert(NULL != cur_pb); + + if ((pb_spice_model == cur_pb->pb_graph_node->pb_type->spice_model) + &&(0 == strcmp(cur_pb->spice_name_tag, pb_spice_name_tag))) { + /* Return the logic block we may find */ + switch (pb_spice_model->type) { + case SPICE_MODEL_LUT : + /* Special for LUT... They have sub modes!!!*/ + assert(NULL != cur_pb->child_pbs); + return cur_pb->child_pbs[0][0].logical_block; + case SPICE_MODEL_FF: + assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model); + return cur_pb->logical_block; + case SPICE_MODEL_HARDLOGIC: + if (NULL != cur_pb->child_pbs) { + return cur_pb->child_pbs[0][0].logical_block; + } else { + assert(pb_spice_model == logical_block[cur_pb->logical_block].mapped_spice_model); + return cur_pb->logical_block; + } + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid spice model type!\n", + __FILE__, __LINE__); + exit(1); + } + } + + /* Go recursively ... */ + mode_index = cur_pb->mode; + if (0 == cur_pb->pb_graph_node->pb_type->num_modes) { + return logical_block_index; + } + for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + logical_block_index = + find_pb_mapped_logical_block_rec(&(cur_pb->child_pbs[ipb][jpb]), pb_spice_model, pb_spice_name_tag); + if (OPEN != logical_block_index) { + return logical_block_index; + } + } + } + } + + return logical_block_index; +} + +int find_grid_mapped_logical_block(int x, int y, + t_spice_model* pb_spice_model, + char* pb_spice_name_tag) { + int logical_block_index = OPEN; + int iblk; + + /* Find the grid usage */ + if (0 == grid[x][y].usage) { + return logical_block_index; + } else { + assert(0 < grid[x][y].usage); + /* search each block */ + for (iblk = 0; iblk < grid[x][y].usage; iblk++) { + /* Get the pb */ + logical_block_index = find_pb_mapped_logical_block_rec(block[grid[x][y].blocks[iblk]].pb, + pb_spice_model, pb_spice_name_tag); + if (OPEN != logical_block_index) { + return logical_block_index; + } + } + } + + return logical_block_index; +} + +void stats_pb_graph_node_port_pin_numbers(t_pb_graph_node* cur_pb_graph_node, + int* num_inputs, + int* num_outputs, + int* num_clock_pins) { + int iport; + + assert(NULL != cur_pb_graph_node); + + (*num_inputs) = 0; + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + (*num_inputs) += cur_pb_graph_node->num_input_pins[iport]; + } + (*num_outputs) = 0; + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + (*num_outputs) += cur_pb_graph_node->num_output_pins[iport]; + } + (*num_clock_pins) = 0; + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + (*num_clock_pins) += cur_pb_graph_node->num_clock_pins[iport]; + } + + return; +} + +int find_pb_type_idle_mode_index(t_pb_type cur_pb_type) { + int idle_mode_index = 0; + int imode = 0; + int num_idle_mode = 0; + + /* if we touch the leaf node */ + if (NULL != cur_pb_type.blif_model) { + return 0; + } + + if (0 == cur_pb_type.num_modes) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Intend to find the idle mode while cur_pb_type has 0 modes!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Corner case: + * If there is only 1 mode available, it will be the idle_mode by default! + */ + if (1 == cur_pb_type.num_modes) { + idle_mode_index = 0; + num_idle_mode++; + return idle_mode_index; + } + + /* Normal Condition: */ + for (imode = 0; imode < cur_pb_type.num_modes; imode++) { + if (1 == cur_pb_type.modes[imode].define_idle_mode) { + idle_mode_index = imode; + num_idle_mode++; + } + } + + assert(1 == num_idle_mode); + + return idle_mode_index; +} + +/* Find the physical mode index */ +int find_pb_type_physical_mode_index(t_pb_type cur_pb_type) { + int phy_mode_index = 0; + int imode = 0; + int num_phy_mode = 0; + + /* if we touch the leaf node */ + if (NULL != cur_pb_type.blif_model) { + return 0; + } + + if (0 == cur_pb_type.num_modes) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Intend to find the physical mode while cur_pb_type has 0 modes!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Corner case: + * If there is only 1 mode available, it will be the physical_mode by default! + */ + if (1 == cur_pb_type.num_modes) { + phy_mode_index = 0; + num_phy_mode++; + return phy_mode_index; + } + + /* Normal Condition: */ + for (imode = 0; imode < cur_pb_type.num_modes; imode++) { + if (1 == cur_pb_type.modes[imode].define_physical_mode) { + phy_mode_index = imode; + num_phy_mode++; + } + } + if (1 != num_phy_mode) { + assert(1 == num_phy_mode); + } + + return phy_mode_index; +} + +void mark_grid_type_pb_graph_node_pins_temp_net_num(int x, int y) { + int iport, ipin, type_pin_index, class_id, pin_global_rr_node_id; + t_type_ptr type = NULL; + t_pb_graph_node* top_pb_graph_node = NULL; + int mode_index, ipb, jpb; + + /* Assert */ + assert((!(x < 0))&&(x < (nx + 2))); + assert((!(y < 0))&&(y < (ny + 2))); + + type = grid[x][y].type; + + if (EMPTY_TYPE == type) { + return; /* Bypass empty grid */ + } + + top_pb_graph_node = type->pb_graph_head; + /* Input ports */ + for (iport = 0; iport < top_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_input_pins[iport]; ipin++) { + top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; + type_pin_index = top_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + class_id = type->pin_class[type_pin_index]; + assert(RECEIVER == type->class_inf[class_id].type); + /* Find the pb net_num and update OPIN net_num */ + pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); + if (OPEN == rr_node[pin_global_rr_node_id].net_num) { + top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; + continue; + } + top_pb_graph_node->input_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; + } + } + /* clock ports */ + for (iport = 0; iport < top_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_clock_pins[iport]; ipin++) { + top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; + type_pin_index = top_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster; + class_id = type->pin_class[type_pin_index]; + assert(RECEIVER == type->class_inf[class_id].type); + /* Find the pb net_num and update OPIN net_num */ + pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); + if (OPEN == rr_node[pin_global_rr_node_id].net_num) { + top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; + continue; + } + top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; + } + } + + /* Go recursively ... */ + mode_index = find_pb_type_idle_mode_index(*(top_pb_graph_node->pb_type)); + for (ipb = 0; ipb < top_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < top_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Mark pb_graph_node temp_net_num */ + rec_mark_pb_graph_node_temp_net_num(&(top_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb])); + } + } + + /* Output ports */ + for (iport = 0; iport < top_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_output_pins[iport]; ipin++) { + top_pb_graph_node->output_pins[iport][ipin].temp_net_num = OPEN; + type_pin_index = top_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; + class_id = type->pin_class[type_pin_index]; + assert(DRIVER == type->class_inf[class_id].type); + /* Find the pb net_num and update OPIN net_num */ + pin_global_rr_node_id = get_rr_node_index(x, y, OPIN, type_pin_index, rr_node_indices); + if (OPEN == rr_node[pin_global_rr_node_id].net_num) { + top_pb_graph_node->output_pins[iport][ipin].temp_net_num = OPEN; + continue; + } + top_pb_graph_node->output_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; + } + } + + /* Run again to handle feedback loop */ + /* Input ports */ + for (iport = 0; iport < top_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_input_pins[iport]; ipin++) { + top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; + type_pin_index = top_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + class_id = type->pin_class[type_pin_index]; + assert(RECEIVER == type->class_inf[class_id].type); + /* Find the pb net_num and update OPIN net_num */ + pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); + if (OPEN == rr_node[pin_global_rr_node_id].net_num) { + top_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; + continue; + } + top_pb_graph_node->input_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; + } + } + /* clock ports */ + for (iport = 0; iport < top_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_clock_pins[iport]; ipin++) { + top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; + type_pin_index = top_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster; + class_id = type->pin_class[type_pin_index]; + assert(RECEIVER == type->class_inf[class_id].type); + /* Find the pb net_num and update OPIN net_num */ + pin_global_rr_node_id = get_rr_node_index(x, y, IPIN, type_pin_index, rr_node_indices); + if (OPEN == rr_node[pin_global_rr_node_id].net_num) { + top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; + continue; + } + top_pb_graph_node->clock_pins[iport][ipin].temp_net_num = clb_to_vpack_net_mapping[rr_node[pin_global_rr_node_id].net_num]; + } + } + + return; +} + +/* Assign the temp_net_num by considering the first incoming edge that belongs to the correct operating mode */ +void assign_pb_graph_node_pin_temp_net_num_by_mode_index(t_pb_graph_pin* cur_pb_graph_pin, + int mode_index) { + int iedge; + + /* IMPORTANT: I assume by default the index of selected edge is 0 + * Make sure this input edge comes from the default mode + */ + for (iedge = 0; iedge < cur_pb_graph_pin->num_input_edges; iedge++) { + if (mode_index != cur_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode_index) { + continue; + } + cur_pb_graph_pin->temp_net_num = cur_pb_graph_pin->input_edges[iedge]->input_pins[0]->temp_net_num; + break; + } + + return; +} + +void mark_pb_graph_node_input_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, + int mode_index) { + int iport, ipin; + + assert(NULL != cur_pb_graph_node); + + /* Input ports */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + cur_pb_graph_node->input_pins[iport][ipin].temp_net_num = OPEN; + /* IMPORTANT: I assume by default the index of selected edge is 0 + * Make sure this input edge comes from the default mode + */ + assign_pb_graph_node_pin_temp_net_num_by_mode_index(&(cur_pb_graph_node->input_pins[iport][ipin]), mode_index); + } + } + + return; +} + +void mark_pb_graph_node_clock_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, + int mode_index) { + int iport, ipin; + + assert(NULL != cur_pb_graph_node); + + /* Clock ports */ + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + cur_pb_graph_node->clock_pins[iport][ipin].temp_net_num = OPEN; + assign_pb_graph_node_pin_temp_net_num_by_mode_index(&(cur_pb_graph_node->clock_pins[iport][ipin]), mode_index); + } + } + + return; +} + +void mark_pb_graph_node_output_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, + int mode_index) { + int iport, ipin; + + assert(NULL != cur_pb_graph_node); + + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + cur_pb_graph_node->output_pins[iport][ipin].temp_net_num = OPEN; + /* IMPORTANT: I assume by default the index of selected edge is 0 + * Make sure this input edge comes from the default mode + */ + assign_pb_graph_node_pin_temp_net_num_by_mode_index(&(cur_pb_graph_node->output_pins[iport][ipin]), mode_index); + } + } + + return; +} + +/* Mark temp_net_num in current pb_graph_node from the parent pb_graph_node */ +void rec_mark_pb_graph_node_temp_net_num(t_pb_graph_node* cur_pb_graph_node) { + int mode_index, ipb, jpb; + + assert(NULL != cur_pb_graph_node); + + /* Find the default mode */ + mode_index = find_pb_type_idle_mode_index(*(cur_pb_graph_node->pb_type)); + + mark_pb_graph_node_input_pins_temp_net_num(cur_pb_graph_node, mode_index); + + mark_pb_graph_node_clock_pins_temp_net_num(cur_pb_graph_node, mode_index); + + if (TRUE == is_primitive_pb_type(cur_pb_graph_node->pb_type)) { + return; + } + + /* Go recursively ... */ + mode_index = find_pb_type_idle_mode_index(*(cur_pb_graph_node->pb_type)); + for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Mark pb_graph_node temp_net_num */ + rec_mark_pb_graph_node_temp_net_num(&(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb])); + } + } + + /* IMPORTANT: update the temp_net of Output ports after recursion is done! + * the outputs of sub pb_graph_node should be updated first + */ + mark_pb_graph_node_output_pins_temp_net_num(cur_pb_graph_node, mode_index); + + /* Do this again to handle feedback loops ! */ + mark_pb_graph_node_input_pins_temp_net_num(cur_pb_graph_node, mode_index); + + mark_pb_graph_node_clock_pins_temp_net_num(cur_pb_graph_node, mode_index); + + return; +} + +void load_one_pb_graph_pin_temp_net_num_from_pb(t_phy_pb* cur_pb, + t_pb_graph_pin* cur_pb_graph_pin) { + int node_index; + t_rr_node* pb_rr_nodes = NULL; + + assert(NULL != cur_pb); + assert(NULL != cur_pb->pb_graph_node); + + /* Get the selected edge of current pin*/ + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_pin->rr_node_index_physical_pb; + cur_pb_graph_pin->temp_net_num = pb_rr_nodes[node_index].vpack_net_num; + + return; +} + +/* According to the vpack_net_num in cur_pb + * assign it to the corresponding pb_graph_pins + */ +void load_pb_graph_node_temp_net_num_from_pb(t_phy_pb* cur_pb) { + int iport, ipin; + + assert(NULL != cur_pb); + assert(NULL != cur_pb->pb_graph_node); + + /* Input ports */ + for (iport = 0; iport < cur_pb->pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb->pb_graph_node->num_input_pins[iport]; ipin++) { + load_one_pb_graph_pin_temp_net_num_from_pb(cur_pb, + &(cur_pb->pb_graph_node->input_pins[iport][ipin])); + } + } + + /* Clock ports */ + for (iport = 0; iport < cur_pb->pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb->pb_graph_node->num_clock_pins[iport]; ipin++) { + load_one_pb_graph_pin_temp_net_num_from_pb(cur_pb, + &(cur_pb->pb_graph_node->clock_pins[iport][ipin])); + } + } + + /* Output ports */ + for (iport = 0; iport < cur_pb->pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb->pb_graph_node->num_output_pins[iport]; ipin++) { + load_one_pb_graph_pin_temp_net_num_from_pb(cur_pb, + &(cur_pb->pb_graph_node->output_pins[iport][ipin])); + } + } + + return; +} + +/* Recursively traverse the hierachy of a pb, + * store parasitic nets in the temp_net_num of the assoicated pb_graph_node + */ +void rec_mark_one_pb_unused_pb_graph_node_temp_net_num(t_phy_pb* cur_pb) { + int ipb, jpb; + int mode_index; + + /* Check */ + assert(NULL != cur_pb); + + if (TRUE == is_primitive_pb_type(cur_pb->pb_graph_node->pb_type)) { + return; + } + + /* Go recursively ... */ + mode_index = cur_pb->mode; + for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + rec_mark_one_pb_unused_pb_graph_node_temp_net_num(&(cur_pb->child_pbs[ipb][jpb])); + } else { + /* Print idle graph_node muxes */ + load_pb_graph_node_temp_net_num_from_pb(cur_pb); + /* We should update the net_num */ + rec_mark_pb_graph_node_temp_net_num(cur_pb->child_pbs[ipb][jpb].pb_graph_node); + } + } + } + + return; +} + +void update_pb_vpack_net_num_from_temp_net_num(t_phy_pb* cur_pb, + t_pb_graph_pin* cur_pb_graph_pin) { + int node_index; + t_rr_node* pb_rr_nodes = NULL; + + assert(NULL != cur_pb); + assert(NULL != cur_pb->pb_graph_node); + + /* Get the selected edge of current pin*/ + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_pin->rr_node_index_physical_pb; + + /* Avoid mistakenly modification */ + if (OPEN != pb_rr_nodes[node_index].vpack_net_num) { + return; + } + /* Only modify when original vpack_net_num is open!!! */ + pb_rr_nodes[node_index].vpack_net_num = cur_pb_graph_pin->temp_net_num; + + return; +} + +void update_pb_graph_node_temp_net_num_to_pb(t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb) { + int iport, ipin; + + assert(NULL != cur_pb->pb_graph_node); + assert(NULL != cur_pb); + + /* Input ports */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + update_pb_vpack_net_num_from_temp_net_num(cur_pb, + &(cur_pb_graph_node->input_pins[iport][ipin])); + } + } + + /* Clock ports */ + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + update_pb_vpack_net_num_from_temp_net_num(cur_pb, + &(cur_pb_graph_node->clock_pins[iport][ipin])); + } + } + + /* Output ports */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + update_pb_vpack_net_num_from_temp_net_num(cur_pb, + &(cur_pb_graph_node->output_pins[iport][ipin])); + } + } + + return; +} + +void rec_load_unused_pb_graph_node_temp_net_num_to_pb(t_phy_pb* cur_pb) { + int ipb, jpb; + int mode_index; + + /* Check */ + assert(NULL != cur_pb); + + if (NULL != cur_pb->pb_graph_node->pb_type->spice_model) { + return; + } + /* Go recursively ... */ + mode_index = cur_pb->mode; + if (!(0 < cur_pb->pb_graph_node->pb_type->num_modes)) { + return; + } + for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + rec_load_unused_pb_graph_node_temp_net_num_to_pb(&(cur_pb->child_pbs[ipb][jpb])); + } else { + update_pb_graph_node_temp_net_num_to_pb(cur_pb->child_pbs[ipb][jpb].pb_graph_node, + cur_pb); + } + } + } + + return; +} + +void mark_one_pb_parasitic_nets(t_phy_pb* cur_pb) { + + /* By go recursively, parasitic net num are stored in the temp_net_num in pb_graph_node */ + rec_mark_one_pb_unused_pb_graph_node_temp_net_num(cur_pb); + + /* Load the temp_net_num to vpack_net_num in the current pb! */ + rec_load_unused_pb_graph_node_temp_net_num_to_pb(cur_pb); + + return; +} + +int count_num_conf_bit_one_interc(t_interconnect* cur_interc, + enum e_sram_orgz cur_sram_orgz_type) { + int fan_in = 0; + enum e_interconnect spice_interc_type = DIRECT_INTERC; + + int num_conf_bits = 0; + + /* 1. identify pin interconnection type, + * 2. Identify the number of fan-in (Consider interconnection edges of only selected mode) + * 3. Select and print the SPICE netlist + */ + if (NULL == cur_interc) { + return num_conf_bits; + } else { + fan_in = cur_interc->fan_in; + if (0 == fan_in) { + return num_conf_bits; + } + } + /* Initialize the interconnection type that will be implemented in SPICE netlist*/ + switch (cur_interc->type) { + case DIRECT_INTERC: + assert(cur_interc->fan_out == fan_in); + spice_interc_type = DIRECT_INTERC; + break; + case COMPLETE_INTERC: + if (1 == fan_in) { + spice_interc_type = DIRECT_INTERC; + } else { + assert((2 == fan_in)||(2 < fan_in)); + spice_interc_type = MUX_INTERC; + } + break; + case MUX_INTERC: + assert((2 == fan_in)||(2 < fan_in)); + spice_interc_type = MUX_INTERC; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + /* This time, (2nd round), count the number of configuration bits, according to interc type*/ + switch (spice_interc_type) { + case DIRECT_INTERC: + /* Check : + * 1. Direct interc has only one fan-in! + */ + assert((cur_interc->fan_out == fan_in) + ||((COMPLETE_INTERC == cur_interc->type)&&(1 == fan_in))); + break; + case COMPLETE_INTERC: + case MUX_INTERC: + /* Check : + * MUX should have at least 2 fan_in + */ + assert((2 == fan_in)||(2 < fan_in)); + assert((1 == cur_interc->fan_out)||(1 < cur_interc->fan_out)); + /* 2. spice_model is a wire */ + assert(NULL != cur_interc->spice_model); + assert(SPICE_MODEL_MUX == cur_interc->spice_model->type); + num_conf_bits = count_num_conf_bits_one_spice_model(cur_interc->spice_model, + cur_sram_orgz_type, fan_in); + /* FOR COMPLETE_INTERC: we should consider fan_out number ! */ + num_conf_bits = num_conf_bits * cur_interc->fan_out; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + return num_conf_bits; +} + +/* Count the number of configuration bits of interconnection inside a pb_type in its default mode */ +int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode, + enum e_sram_orgz cur_sram_orgz_type) { + int num_conf_bits = 0; + int jinterc = 0; + + for (jinterc = 0; jinterc < cur_pb_type_mode->num_interconnect; jinterc++) { + num_conf_bits += count_num_conf_bit_one_interc(&(cur_pb_type_mode->interconnect[jinterc]), + cur_sram_orgz_type); + } + + return num_conf_bits; +} + +/* Count the number of configuration bits of interconnection inside a pb_type in its default mode */ +int count_num_reserved_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode, + enum e_sram_orgz cur_sram_orgz_type) { + int num_reserved_conf_bits = 0; + int temp_num_reserved_conf_bits = 0; + int jinterc = 0; + + for (jinterc = 0; jinterc < cur_pb_type_mode->num_interconnect; jinterc++) { + /* num of reserved configuration bits is determined by the largest one */ + temp_num_reserved_conf_bits = + count_num_reserved_conf_bit_one_interc(&(cur_pb_type_mode->interconnect[jinterc]), + cur_sram_orgz_type); + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + } + + return num_reserved_conf_bits; +} + +/* Count the number of configuration bits of a grid (type_descriptor) in default mode */ +int rec_count_num_conf_bits_pb_type_default_mode(t_pb_type* cur_pb_type, + t_sram_orgz_info* cur_sram_orgz_info) { + int mode_index, ipb, jpb; + int sum_num_conf_bits = 0; + int num_reserved_conf_bits = 0; + int temp_num_reserved_conf_bits = 0; + + cur_pb_type->default_mode_num_conf_bits = 0; + + /* Recursively finish all the child pb_types*/ + if ((NULL == cur_pb_type->spice_model_name) + && (NULL == cur_pb_type->physical_pb_type_name)) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + rec_count_num_conf_bits_pb_type_default_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb]), cur_sram_orgz_info); + } + } + } + + /* Check if this has defined a spice_model*/ + if ((NULL != cur_pb_type->spice_model_name) + || (NULL != cur_pb_type->physical_pb_type_name)) { + sum_num_conf_bits = count_num_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, cur_sram_orgz_info->type, 0); + cur_pb_type->default_mode_num_conf_bits = sum_num_conf_bits; + /* calculate the number of reserved configuration bits */ + cur_pb_type->default_mode_num_reserved_conf_bits = + count_num_reserved_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, + cur_sram_orgz_info->type, 0); + } else { /* Count the sum of configuration bits of all the children pb_types */ + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_conf_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_conf_bits; + temp_num_reserved_conf_bits = + cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_reserved_conf_bits; + /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + } + } + /* Count the number of configuration bits of interconnection */ + sum_num_conf_bits += count_num_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), cur_sram_orgz_info->type); + /* Count the number of reserved_configuration bits of interconnection */ + temp_num_reserved_conf_bits = + count_num_reserved_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), + cur_sram_orgz_info->type); + /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + /* Update the info in pb_type */ + cur_pb_type->default_mode_num_reserved_conf_bits = num_reserved_conf_bits; + cur_pb_type->default_mode_num_conf_bits = sum_num_conf_bits; + } + + return sum_num_conf_bits; +} + +/* Count the number of configuration bits of a grid (type_descriptor) in default mode */ +int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, + t_sram_orgz_info* cur_sram_orgz_info) { + int mode_index, ipb, jpb; + int sum_num_conf_bits = 0; + int num_reserved_conf_bits = 0; + int temp_num_reserved_conf_bits = 0; + + cur_pb_type->physical_mode_num_conf_bits = 0; + + /* Recursively finish all the child pb_types*/ + if ((NULL == cur_pb_type->spice_model_name) + && (NULL == cur_pb_type->physical_pb_type_name)) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + rec_count_num_conf_bits_pb_type_physical_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb]), cur_sram_orgz_info); + } + } + } + + /* Check if this has defined a spice_model*/ + if ((NULL != cur_pb_type->spice_model_name) + || (NULL != cur_pb_type->physical_pb_type_name)) { + sum_num_conf_bits = count_num_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, cur_sram_orgz_info->type, 0); + cur_pb_type->physical_mode_num_conf_bits = sum_num_conf_bits; + /* calculate the number of reserved configuration bits */ + cur_pb_type->physical_mode_num_reserved_conf_bits = + count_num_reserved_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, + cur_sram_orgz_info->type, 0); + } else { /* Count the sum of configuration bits of all the children pb_types */ + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_conf_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_conf_bits; + temp_num_reserved_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_reserved_conf_bits; + + /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + } + } + /* Count the number of configuration bits of interconnection */ + sum_num_conf_bits += count_num_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), + cur_sram_orgz_info->type); + /* Count the number of reserved_configuration bits of interconnection */ + temp_num_reserved_conf_bits = + count_num_reserved_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), + cur_sram_orgz_info->type); + /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + /* Update the info in pb_type */ + cur_pb_type->physical_mode_num_reserved_conf_bits = num_reserved_conf_bits; + cur_pb_type->physical_mode_num_conf_bits = sum_num_conf_bits; + } + + return sum_num_conf_bits; +} + + +/* Count the number of configuration bits of a pb_graph_node */ +int rec_count_num_conf_bits_pb(t_pb* cur_pb, + t_sram_orgz_info* cur_sram_orgz_info) { + int mode_index, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + t_pb_graph_node* cur_pb_graph_node = NULL; + int sum_num_conf_bits = 0; + int num_reserved_conf_bits = 0; + int temp_num_reserved_conf_bits = 0; + + /* Check cur_pb_graph_node*/ + if (NULL == cur_pb) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb.\n", + __FILE__, __LINE__); + exit(1); + } + cur_pb_graph_node = cur_pb->pb_graph_node; + cur_pb_type = cur_pb_graph_node->pb_type; + mode_index = cur_pb->mode; + + cur_pb->num_conf_bits = 0; + + /* Recursively finish all the child pb_types*/ + if ((NULL == cur_pb_type->spice_model_name) + &&(NULL == cur_pb_type->physical_pb_type_name)) { + /* recursive for the child_pbs*/ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + rec_count_num_conf_bits_pb(&(cur_pb->child_pbs[ipb][jpb]), cur_sram_orgz_info); + } else { + /* Check if this pb has no children, no children mean idle*/ + rec_count_num_conf_bits_pb_type_default_mode(cur_pb->child_pbs[ipb][jpb].pb_graph_node->pb_type, + cur_sram_orgz_info); + } + } + } + } + + /* Check if this has defined a spice_model*/ + if ((NULL != cur_pb_type->spice_model_name) + ||(NULL != cur_pb_type->physical_pb_type_name)) { + sum_num_conf_bits += count_num_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, + cur_sram_orgz_info->type, 0); + cur_pb->num_conf_bits = sum_num_conf_bits; + /* calculate the number of reserved configuration bits */ + cur_pb->num_reserved_conf_bits = + count_num_reserved_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, + cur_sram_orgz_info->type, 0); + + } else { + /* Definition ends*/ + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + /* Count in the number of configuration bits of on child pb */ + sum_num_conf_bits += cur_pb->child_pbs[ipb][jpb].num_conf_bits; + temp_num_reserved_conf_bits = cur_pb->child_pbs[ipb][jpb].num_reserved_conf_bits; + } else { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_conf_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_conf_bits; + temp_num_reserved_conf_bits = + cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_reserved_conf_bits; + } + /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + } + } + /* Count the number of configuration bits of interconnection */ + sum_num_conf_bits += count_num_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), + cur_sram_orgz_info->type); + /* Count the number of reserved_configuration bits of interconnection */ + temp_num_reserved_conf_bits = + count_num_reserved_conf_bits_pb_type_mode_interc(&(cur_pb_type->modes[mode_index]), + cur_sram_orgz_info->type); + /* number of reserved conf. bits is deteremined by the largest number of reserved conf. bits !*/ + if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { + num_reserved_conf_bits = temp_num_reserved_conf_bits; + } + /* Update the info in pb_type */ + cur_pb->num_reserved_conf_bits = num_reserved_conf_bits; + cur_pb->num_conf_bits = sum_num_conf_bits; + } + + return sum_num_conf_bits; +} + +/* Initialize the number of configuraion bits for one grid */ +void init_one_grid_num_conf_bits(int ix, int iy, + t_sram_orgz_info* cur_sram_orgz_info) { + int iz; + int capacity; + + /* Check */ + assert((!(0 > ix))&&(!(ix > (nx + 1)))); + assert((!(0 > iy))&&(!(iy > (ny + 1)))); + + if ((NULL == grid[ix][iy].type) + ||(EMPTY_TYPE == grid[ix][iy].type) + ||(0 != grid[ix][iy].offset)) { + /* Empty grid, directly return */ + return; + } + capacity= grid[ix][iy].type->capacity; + assert(0 < capacity); + + /* check capacity and if this has been mapped */ + for (iz = 0; iz < capacity; iz++) { + /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ + rec_count_num_conf_bits_pb_type_physical_mode(grid[ix][iy].type->pb_type, cur_sram_orgz_info); + } + + return; +} + +/* Initialize the number of configuraion bits for all grids */ +void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info) { + int ix, iy; + + /* Core grid */ + vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of configuration bits of Core grids...\n"); + for (ix = 1; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); + } + } + + /* Consider the IO pads */ + vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of configuration bits of I/O grids...\n"); + /* Top side : x = 1 .. nx + 1, y = nx + 1 */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); + } + + /* Right side : x = nx + 1, y = 1 .. ny*/ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); + } + + /* Bottom side : x = 1 .. nx + 1, y = 0 */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); + } + + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_conf_bits(ix, iy, cur_sram_orgz_info); + } + + return; +} + +/* With given spice_model_port, find the pb_type port with same name and type*/ +t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, + t_spice_model_port* spice_model_port) { + int iport; + t_port* ret = NULL; + + /* Search ports */ + for (iport = 0; iport < pb_type->num_ports; iport++) { + /* Match the name and port size*/ + if ((0 == strcmp(pb_type->ports[iport].name, spice_model_port->prefix)) + &&(pb_type->ports[iport].num_pins == spice_model_port->size)) { + /* Match the type*/ + switch (spice_model_port->type) { + case SPICE_MODEL_PORT_INPUT: + if ((IN_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + if (NULL != ret) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", + __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); + exit(1); + } + ret = &(pb_type->ports[iport]); + } + break; + case SPICE_MODEL_PORT_OUTPUT: + if (OUT_PORT == pb_type->ports[iport].type) { + if (NULL != ret) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", + __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); + exit(1); + } + ret = &(pb_type->ports[iport]); + } + break; + case SPICE_MODEL_PORT_CLOCK: + if ((IN_PORT == pb_type->ports[iport].type)&&(1 == pb_type->ports[iport].is_clock)) { + if (NULL != ret) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", + __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); + exit(1); + } + ret = &(pb_type->ports[iport]); + } + break; + case SPICE_MODEL_PORT_INOUT : + if ((INOUT_PORT == pb_type->ports[iport].type)&&(0 == pb_type->ports[iport].is_clock)) { + if (NULL != ret) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", + __FILE__, __LINE__, pb_type->name, spice_model_port->prefix); + exit(1); + } + ret = &(pb_type->ports[iport]); + } + break; + case SPICE_MODEL_PORT_SRAM: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for spice_model_port(%s)!\n", + __FILE__, __LINE__, spice_model_port->prefix); + exit(1); + } + } + } + + return ret; +} + +t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type, + enum e_spice_model_port_type port_type, + int* port_num) { + int iport, cur; + t_port** ret = NULL; + + /* Check codes*/ + assert(NULL != port_num); + assert(NULL != pb_type); + + /* Count the number of ports that match*/ + (*port_num) = 0; + for (iport = 0; iport < pb_type->num_ports; iport++) { + switch (port_type) { + case SPICE_MODEL_PORT_INPUT: /* TODO: support is_non_clock_global*/ + if ((IN_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + (*port_num)++; + } + break; + case SPICE_MODEL_PORT_OUTPUT: + if ((OUT_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + (*port_num)++; + } + break; + case SPICE_MODEL_PORT_INOUT: + if ((INOUT_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + (*port_num)++; + } + break; + case SPICE_MODEL_PORT_CLOCK: + if ((IN_PORT == pb_type->ports[iport].type) + &&(1 == pb_type->ports[iport].is_clock)) { + (*port_num)++; + } + break; + case SPICE_MODEL_PORT_SRAM: + /* Original VPR don't support this*/ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for port!\n", + __FILE__, __LINE__); + exit(1); + } + } + + /* Initial the return pointers*/ + ret = (t_port**)my_malloc(sizeof(t_port*)*(*port_num)); + memset(ret, 0 , sizeof(t_port*)*(*port_num)); + + /* Fill the return pointers*/ + cur = 0; + + for (iport = 0; iport < pb_type->num_ports; iport++) { + switch (port_type) { + case SPICE_MODEL_PORT_INPUT : /* TODO: support is_non_clock_global*/ + if ((IN_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + ret[cur] = &(pb_type->ports[iport]); + cur++; + } + break; + case SPICE_MODEL_PORT_OUTPUT: + if ((OUT_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + ret[cur] = &(pb_type->ports[iport]); + cur++; + } + break; + case SPICE_MODEL_PORT_INOUT: + if ((INOUT_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + ret[cur] = &(pb_type->ports[iport]); + cur++; + } + break; + case SPICE_MODEL_PORT_CLOCK: + if ((IN_PORT == pb_type->ports[iport].type) + &&(1 == pb_type->ports[iport].is_clock)) { + ret[cur] = &(pb_type->ports[iport]); + cur++; + } + break; + case SPICE_MODEL_PORT_SRAM: + /* Original VPR don't support this*/ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for port!\n", + __FILE__, __LINE__); + exit(1); + } + } + + /* Check correctness*/ + assert(cur == (*port_num)); + + return ret; +} + + +int find_path_id_between_pb_rr_nodes(t_rr_node* local_rr_graph, + int src_node, + int des_node) { + int path_id = -1; + int prev_edge = -1; + int path_count = 0; + int iedge; + t_interconnect* cur_interc = NULL; + + /* Check */ + assert(NULL != local_rr_graph); + assert((0 == src_node)||(0 < src_node)); + assert((0 == des_node)||(0 < des_node)); + + prev_edge = local_rr_graph[des_node].prev_edge; + check_pb_graph_edge(*(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge])); + assert(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge]->output_pins[0] == local_rr_graph[des_node].pb_graph_pin); + + cur_interc = local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge]->interconnect; + /* Search des_node input edges */ + for (iedge = 0; iedge < local_rr_graph[des_node].pb_graph_pin->num_input_edges; iedge++) { + if (local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]->input_pins[0] + == local_rr_graph[src_node].pb_graph_pin) { + /* Strict check */ + assert(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge] + == local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]); + path_id = path_count; + break; + } + if (cur_interc == local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]->interconnect) { + path_count++; + } + } + + return path_id; +} + +/* Find the interconnection type of pb_graph_pin edges*/ +enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin) { + enum e_interconnect interc_type; + int def_interc_type = 0; + int iedge; + + for (iedge = 0; iedge < pb_graph_pin.num_input_edges; iedge++) { + /* Make sure all edges are legal: 1 input_pin, 1 output_pin*/ + check_pb_graph_edge(*(pb_graph_pin.input_edges[iedge])); + /* Make sure all the edges interconnect type is the same*/ + if (0 == def_interc_type) { + interc_type = pb_graph_pin.input_edges[iedge]->interconnect->type; + } else if (interc_type != pb_graph_pin.input_edges[iedge]->interconnect->type) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d])Interconnection type are not same for port(%s),pin(%d).\n", + __FILE__, __LINE__, pb_graph_pin.port->name,pb_graph_pin.pin_number); + exit(1); + } + } + + return interc_type; +} + +/* Find the interconnection type of pb_graph_pin edges*/ +t_spice_model* find_pb_graph_pin_in_edges_interc_spice_model(t_pb_graph_pin pb_graph_pin) { + t_spice_model* interc_spice_model; + int def_interc_model = 0; + int iedge; + + for (iedge = 0; iedge < pb_graph_pin.num_input_edges; iedge++) { + /* Make sure all edges are legal: 1 input_pin, 1 output_pin*/ + check_pb_graph_edge(*(pb_graph_pin.input_edges[iedge])); + /* Make sure all the edges interconnect type is the same*/ + if (0 == def_interc_model) { + interc_spice_model= pb_graph_pin.input_edges[iedge]->interconnect->spice_model; + } else if (interc_spice_model != pb_graph_pin.input_edges[iedge]->interconnect->spice_model) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d])Interconnection spice_model are not same for port(%s),pin(%d).\n", + __FILE__, __LINE__, pb_graph_pin.port->name, pb_graph_pin.pin_number); + exit(1); + } + } + + return interc_spice_model; +} + +void find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, + t_mode* cur_mode, + t_interconnect** cur_interc, + int* fan_in) { + int iedge; + + (*cur_interc) = NULL; + (*fan_in) = 0; + + /* Search the input edges only, stats on the size of MUX we may need (fan-in) */ + for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { + /* 1. First, we should make sure this interconnect is in the selected mode!!!*/ + if (cur_mode == des_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode) { + /* Check this edge*/ + check_pb_graph_edge(*(des_pb_graph_pin->input_edges[iedge])); + /* Record the interconnection*/ + if (NULL == (*cur_interc)) { + (*cur_interc) = des_pb_graph_pin->input_edges[iedge]->interconnect; + } else { /* Make sure the interconnections for this pin is the same!*/ + assert((*cur_interc) == des_pb_graph_pin->input_edges[iedge]->interconnect); + } + /* Search the input_pins of input_edges only*/ + (*fan_in) += des_pb_graph_pin->input_edges[iedge]->num_input_pins; + } + } + + return; +} + +void find_interc_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, + int cur_mode_index, + t_interconnect** cur_interc) { + int iedge; + + (*cur_interc) = NULL; + + /* Search the input edges only, stats on the size of MUX we may need (fan-in) */ + for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { + /* 1. First, we should make sure this interconnect is in the selected mode!!!*/ + if (cur_mode_index == des_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode_index) { + /* Check this edge*/ + check_pb_graph_edge(*(des_pb_graph_pin->input_edges[iedge])); + /* Record the interconnection*/ + if (NULL == (*cur_interc)) { + (*cur_interc) = des_pb_graph_pin->input_edges[iedge]->interconnect; + } else { /* Make sure the interconnections for this pin is the same!*/ + assert((*cur_interc) == des_pb_graph_pin->input_edges[iedge]->interconnect); + } + } + } + + return; +} + + +/* Return a child_pb if it is mapped.*/ +t_pb* get_child_pb_for_phy_pb_graph_node(t_pb* cur_pb, int ipb, int jpb) { + t_pb* child_pb = NULL; + + /* TODO: more check ? */ + + if (NULL == cur_pb) { + return NULL; + } + + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + child_pb = &(cur_pb->child_pbs[ipb][jpb]); + } + + return child_pb; +} + +/* Return a child_phy_pb if it is mapped.*/ +t_phy_pb* get_phy_child_pb_for_phy_pb_graph_node(t_phy_pb* cur_phy_pb, + int ipb, int jpb) { + t_phy_pb* child_phy_pb = NULL; + + /* TODO: more check ? */ + + if (NULL == cur_phy_pb) { + return NULL; + } + + if ((NULL != cur_phy_pb->child_pbs[ipb])&&(NULL != cur_phy_pb->child_pbs[ipb][jpb].name)) { + child_phy_pb = &(cur_phy_pb->child_pbs[ipb][jpb]); + } + + return child_phy_pb; +} + + +/* Count the number of inpad and outpad of a grid (type_descriptor) in default mode */ +void rec_count_num_iopads_pb_type_physical_mode(t_pb_type* cur_pb_type) { + int mode_index, ipb, jpb; + int sum_num_iopads = 0; + + cur_pb_type->physical_mode_num_iopads = 0; + + /* Recursively finish all the child pb_types*/ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + rec_count_num_iopads_pb_type_physical_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb])); + } + } + } + + /* Check if this has defined a spice_model*/ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + if (SPICE_MODEL_IOPAD == cur_pb_type->phy_pb_type->spice_model->type) { + sum_num_iopads = 1; + cur_pb_type->physical_mode_num_iopads = sum_num_iopads; + } + } else { /* Count the sum of configuration bits of all the children pb_types */ + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_iopads += cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_iopads; + } + } + /* Count the number of configuration bits of interconnection */ + /* Update the info in pb_type */ + cur_pb_type->physical_mode_num_iopads = sum_num_iopads; + } + + return; +} + +/* Count the number of inpad and outpad of a grid (type_descriptor) in default mode */ +void rec_count_num_iopads_pb_type_default_mode(t_pb_type* cur_pb_type) { + int mode_index, ipb, jpb; + int sum_num_iopads = 0; + + cur_pb_type->default_mode_num_iopads = 0; + + /* Recursively finish all the child pb_types*/ + if ((NULL == cur_pb_type->spice_model_name) + && (NULL == cur_pb_type->physical_pb_type_name)) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + rec_count_num_iopads_pb_type_default_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb])); + sum_num_iopads += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_iopads; + cur_pb_type->default_mode_num_iopads = sum_num_iopads; + } + } + } + + /* Check if this has defined a spice_model*/ + if ((NULL != cur_pb_type->spice_model_name) + && (NULL != cur_pb_type->physical_pb_type_name)) { + if (SPICE_MODEL_IOPAD == cur_pb_type->phy_pb_type->spice_model->type) { + sum_num_iopads = 1; + cur_pb_type->default_mode_num_iopads = sum_num_iopads; + } + } + + return; +} + +/* Count the number of configuration bits of a pb_graph_node */ +void rec_count_num_iopads_pb(t_pb* cur_pb) { + int mode_index, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + t_pb_graph_node* cur_pb_graph_node = NULL; + + int sum_num_iopads = 0; + + /* Check cur_pb_graph_node*/ + if (NULL == cur_pb) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb.\n", + __FILE__, __LINE__); + exit(1); + } + cur_pb_graph_node = cur_pb->pb_graph_node; + cur_pb_type = cur_pb_graph_node->pb_type; + mode_index = cur_pb->mode; + + cur_pb->num_iopads = 0; + + /* Recursively finish all the child pb_types*/ + if ((NULL == cur_pb_type->spice_model_name) + &&(NULL == cur_pb_type->physical_pb_type_name)) { + /* recursive for the child_pbs*/ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + rec_count_num_iopads_pb(&(cur_pb->child_pbs[ipb][jpb])); + } else { + /* Check if this pb has no children, no children mean idle*/ + rec_count_num_iopads_pb_type_default_mode(cur_pb->child_pbs[ipb][jpb].pb_graph_node->pb_type); + } + } + } + } + + /* Check if this has defined a spice_model*/ + if ((NULL != cur_pb_type->spice_model) + ||(NULL != cur_pb_type->physical_pb_type_name)) { + if (SPICE_MODEL_IOPAD == cur_pb_type->phy_pb_type->spice_model->type) { + sum_num_iopads = 1; + cur_pb->num_iopads = sum_num_iopads; + } + } else { + /* Definition ends*/ + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + /* Count in the number of configuration bits of on child pb */ + sum_num_iopads += cur_pb->child_pbs[ipb][jpb].num_iopads; + } else { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_iopads += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_iopads; + } + } + } + /* Count the number of configuration bits of interconnection */ + /* Update the info in pb_type */ + cur_pb->num_iopads = sum_num_iopads; + } + + return; +} + +/* Initialize the number of configuraion bits for one grid */ +void init_one_grid_num_iopads(int ix, int iy) { + int iz; + int capacity; + + /* Check */ + assert((!(0 > ix))&&(!(ix > (nx + 1)))); + assert((!(0 > iy))&&(!(iy > (ny + 1)))); + + if ((NULL == grid[ix][iy].type) + ||(EMPTY_TYPE == grid[ix][iy].type) + ||(0 != grid[ix][iy].offset)) { + /* Empty grid, directly return */ + return; + } + capacity= grid[ix][iy].type->capacity; + assert(0 < capacity); + + /* check capacity and if this has been mapped */ + for (iz = 0; iz < capacity; iz++) { + /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ + rec_count_num_iopads_pb_type_physical_mode(grid[ix][iy].type->pb_type); + } + + return; +} + +/* Initialize the number of configuraion bits for all grids */ +void init_grids_num_iopads() { + int ix, iy; + + /* Core grid */ + vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of I/O pads in Core grids...\n"); + for (ix = 1; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + init_one_grid_num_iopads(ix, iy); + } + } + + /* Consider the IO pads */ + vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of I/O pads in I/O grids...\n"); + /* Top side : x = 1 .. nx + 1, y = nx + 1 */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_iopads(ix, iy); + } + /* Right side : x = nx + 1, y = 1 .. ny*/ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_iopads(ix, iy); + } + /* Bottom side : x = 1 .. nx + 1, y = 0 */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_iopads(ix, iy); + } + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_iopads(ix, iy); + } + + return; +} + +/* Count the number of mode configuration bits of a grid (type_descriptor) in default mode */ +void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type) { + int mode_index, ipb, jpb; + int sum_num_mode_bits = 0; + + cur_pb_type->default_mode_num_mode_bits = 0; + + /* Recursively finish all the child pb_types*/ + if (NULL == cur_pb_type->spice_model) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + rec_count_num_mode_bits_pb_type_default_mode(&(cur_pb_type->modes[mode_index].pb_type_children[ipb])); + } + } + } + + /* Check if this has defined a spice_model*/ + if (NULL != cur_pb_type->spice_model) { + if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { + sum_num_mode_bits = 1; + cur_pb_type->default_mode_num_mode_bits = sum_num_mode_bits; + } + } else { /* Count the sum of configuration bits of all the children pb_types */ + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_mode_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_mode_bits; + } + } + /* Count the number of configuration bits of interconnection */ + /* Update the info in pb_type */ + cur_pb_type->default_mode_num_mode_bits = sum_num_mode_bits; + } + + return; +} + +/* Count the number of configuration bits of a pb_graph_node */ +void rec_count_num_mode_bits_pb(t_pb* cur_pb) { + int mode_index, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + t_pb_graph_node* cur_pb_graph_node = NULL; + + int sum_num_mode_bits = 0; + + /* Check cur_pb_graph_node*/ + if (NULL == cur_pb) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb.\n", + __FILE__, __LINE__); + exit(1); + } + cur_pb_graph_node = cur_pb->pb_graph_node; + cur_pb_type = cur_pb_graph_node->pb_type; + mode_index = cur_pb->mode; + + cur_pb->num_mode_bits = 0; + + /* Recursively finish all the child pb_types*/ + if (NULL == cur_pb_type->spice_model) { + /* recursive for the child_pbs*/ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + rec_count_num_mode_bits_pb(&(cur_pb->child_pbs[ipb][jpb])); + } else { + /* Check if this pb has no children, no children mean idle*/ + rec_count_num_mode_bits_pb_type_default_mode(cur_pb->child_pbs[ipb][jpb].pb_graph_node->pb_type); + } + } + } + } + + /* Check if this has defined a spice_model*/ + if (NULL != cur_pb_type->spice_model) { + if (SPICE_MODEL_IOPAD == cur_pb_type->spice_model->type) { + sum_num_mode_bits = 1; + cur_pb->num_mode_bits = sum_num_mode_bits; + } + } else { + /* Definition ends*/ + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); + if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { + /* Count in the number of configuration bits of on child pb */ + sum_num_mode_bits += cur_pb->child_pbs[ipb][jpb].num_mode_bits; + } else { + /* Count in the number of configuration bits of on child pb_type */ + sum_num_mode_bits += cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_mode_bits; + } + } + } + /* Count the number of configuration bits of interconnection */ + /* Update the info in pb_type */ + cur_pb->num_mode_bits = sum_num_mode_bits; + } + + return; +} + +/* Initialize the number of configuraion bits for one grid */ +void init_one_grid_num_mode_bits(int ix, int iy) { + t_block* mapped_block = NULL; + int iz; + int cur_block_index = 0; + int capacity; + + /* Check */ + assert((!(0 > ix))&&(!(ix > (nx + 1)))); + assert((!(0 > iy))&&(!(iy > (ny + 1)))); + + if ((NULL == grid[ix][iy].type)||(0 != grid[ix][iy].offset)) { + /* Empty grid, directly return */ + return; + } + capacity= grid[ix][iy].type->capacity; + assert(0 < capacity); + + /* check capacity and if this has been mapped */ + for (iz = 0; iz < capacity; iz++) { + /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ + mapped_block = search_mapped_block(ix, iy, iz); + /* Comments: Grid [x][y]*/ + if (NULL == mapped_block) { + /* Print a consider a idle pb_type ...*/ + rec_count_num_mode_bits_pb_type_default_mode(grid[ix][iy].type->pb_type); + } else { + if (iz == mapped_block->z) { + // assert(mapped_block == &(block[grid[ix][iy].blocks[cur_block_index]])); + cur_block_index++; + } + rec_count_num_mode_bits_pb(mapped_block->pb); + } + } + + assert(cur_block_index == grid[ix][iy].usage); + + return; +} + +/* Initialize the number of configuraion bits for all grids */ +void init_grids_num_mode_bits() { + int ix, iy; + + /* Core grid */ + vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of mode configuraiton bits of Core grids...\n"); + for (ix = 1; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + init_one_grid_num_mode_bits(ix, iy); + } + } + + /* Consider the IO pads */ + vpr_printf(TIO_MESSAGE_INFO, "INFO: Initializing number of mode configuration bits of I/O grids...\n"); + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_mode_bits(ix, iy); + } + /* Right side : x = nx + 1, y = 1 .. ny*/ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_mode_bits(ix, iy); + } + /* Bottom side : x = 1 .. nx + 1, y = 0 */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_mode_bits(ix, iy); + } + /* Top side : x = 1 .. nx + 1, y = nx + 1 */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + init_one_grid_num_mode_bits(ix, iy); + } + + return; +} + +/* Return the child_pb of a LUT pb + * Because the mapping information is stored in the child_pb!!! + */ +t_pb* get_lut_child_pb(t_pb* cur_lut_pb, + int mode_index) { + + assert(SPICE_MODEL_LUT == cur_lut_pb->pb_graph_node->pb_type->phy_pb_type->spice_model->type); + + assert(1 == cur_lut_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children); + + return (&(cur_lut_pb->child_pbs[0][0])); +} + +/* Return the child_pb of a LUT pb + * Because the mapping information is stored in the child_pb!!! + */ +t_phy_pb* get_lut_child_phy_pb(t_phy_pb* cur_lut_pb, + int mode_index) { + + assert(SPICE_MODEL_LUT == cur_lut_pb->pb_graph_node->pb_type->spice_model->type); + + assert(1 == cur_lut_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children); + assert(1 == cur_lut_pb->pb_graph_node->pb_type->num_pb); + + return (&(cur_lut_pb->child_pbs[0][0])); +} + + +/* Return the child_pb of a hardlogic pb + * Because the mapping information is stored in the child_pb!!! + */ +t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb, + int mode_index) { + + assert(SPICE_MODEL_HARDLOGIC == cur_hardlogic_pb->pb_graph_node->pb_type->phy_pb_type->spice_model->type); + + assert(1 == cur_hardlogic_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children); + assert(1 == cur_hardlogic_pb->pb_graph_node->pb_type->num_pb); + + return (&(cur_hardlogic_pb->child_pbs[0][0])); +} + +int get_grid_pin_height(int grid_x, int grid_y, int pin_index) { + int pin_height; + t_type_ptr grid_type = NULL; + + /* Get type */ + grid_type = grid[grid_x][grid_y].type; + + /* Return if this is an empty type */ + if ((NULL == grid_type) + ||(EMPTY_TYPE == grid_type)) { + pin_height = 0; + return pin_height; + } + + /* Check if the pin index is in the range */ + assert ( ((0 == pin_index) || (0 < pin_index)) + &&(pin_index < grid_type->num_pins) ); + + /* Find the pin_height */ + pin_height = grid_type->pin_height[pin_index]; + + return pin_height; +} + +int get_grid_pin_side(int grid_x, int grid_y, int pin_index) { + int pin_height, side, pin_side; + t_type_ptr grid_type = NULL; + + /* Get type */ + grid_type = grid[grid_x][grid_y].type; + + /* Return if this is an empty type */ + if ((NULL == grid_type) + ||(EMPTY_TYPE == grid_type)) { + return -1; + } + + /* Check if the pin index is in the range */ + assert ( ((0 == pin_index) || (0 < pin_index)) + &&(pin_index < grid_type->num_pins) ); + + /* Find the pin_height */ + pin_height = get_grid_pin_height(grid_x, grid_y, pin_index); + + pin_side = -1; + for (side = 0; side < 4; side++) { + /* Bypass corner cases */ + /* Pin can only locate on BOTTOM side, when grid is on TOP border */ + if ((ny + 1 == grid_y)&&(BOTTOM != side)) { + continue; + } + /* Pin can only locate on LEFT side, when grid is on RIGHT border */ + if ((nx + 1 == grid_x)&&(LEFT != side)) { + continue; + } + /* Pin can only locate on the TOP side, when grid is on BOTTOM border */ + if ((0 == grid_y)&&(TOP != side)) { + continue; + } + /* Pin can only locate on the RIGHT side, when grid is on LEFT border */ + if ((0 == grid_x)&&(RIGHT != side)) { + continue; + } + if (1 == grid_type->pinloc[pin_height][side][pin_index]) { + if (-1 != pin_side) { + vpr_printf(TIO_MESSAGE_ERROR, "(%s, [LINE%d]) Duplicated pin(index:%d) on two sides: %s and %s of type (name=%s)!\n", + __FILE__, __LINE__, + pin_index, + convert_side_index_to_string(pin_side), + convert_side_index_to_string(side), + grid_type->name); + exit(1); + } + pin_side = side; + } + } + + return pin_side; +} + +/* Decode mode bits "01..." to a SRAM bits array */ +int* decode_mode_bits(char* mode_bits, int* num_sram_bits) { + int* sram_bits = NULL; + int i; + + assert(NULL != mode_bits); + (*num_sram_bits) = strlen(mode_bits); + + sram_bits = (int*)my_calloc((*num_sram_bits), sizeof(int)); + + for (i = 0; i < (*num_sram_bits); i++) { + switch(mode_bits[i]) { + case '1': + sram_bits[i] = 1; + break; + case '0': + sram_bits[i] = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid mode_bits(%s)!\n", + __FILE__, __LINE__, mode_bits); + exit(1); + } + } + + return sram_bits; +} + +enum e_interconnect determine_actual_pb_interc_type(t_interconnect* def_interc, + int fan_in) { + enum e_interconnect actual_interc_type = DIRECT_INTERC; + + /* Check */ + assert ((NULL != def_interc) && (0 != fan_in)); + + /* Initialize the interconnection type that will be implemented in SPICE netlist*/ + switch (def_interc->type) { + case DIRECT_INTERC: + assert(1 == fan_in); + actual_interc_type = DIRECT_INTERC; + break; + case COMPLETE_INTERC: + if (1 == fan_in) { + actual_interc_type = DIRECT_INTERC; + } else { + assert((2 == fan_in)||(2 < fan_in)); + actual_interc_type = MUX_INTERC; + } + break; + case MUX_INTERC: + assert((2 == fan_in)||(2 < fan_in)); + actual_interc_type = MUX_INTERC; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, def_interc->name, def_interc->line_num); + exit(1); + } + + return actual_interc_type; +} + + +/* Count the number of pins in a pb_graph node */ +int count_pin_number_one_port_pb_graph_node(int num_ports, int* num_pins) { + int total_pins = 0; + int iport; + + for (iport = 0; iport < num_ports; iport++) { + total_pins += num_pins[iport]; + } + + return total_pins; +} + +/* Count the number of pins in a pb_graph node */ +int count_pin_number_one_pb_graph_node(t_pb_graph_node* cur_pb_graph_node) { + int total_pins = 0; + + /* INPUT port */ + total_pins += count_pin_number_one_port_pb_graph_node(cur_pb_graph_node->num_input_ports, + cur_pb_graph_node->num_input_pins); + + /* OUTPUT port */ + total_pins += count_pin_number_one_port_pb_graph_node(cur_pb_graph_node->num_output_ports, + cur_pb_graph_node->num_output_pins); + + /* CLOCK port */ + total_pins += count_pin_number_one_port_pb_graph_node(cur_pb_graph_node->num_clock_ports, + cur_pb_graph_node->num_clock_pins); + + + return total_pins; +} + +/* find the number of pb_graph edges with a given physical mode index */ +int count_pb_graph_node_input_edge_in_phy_mode(t_pb_graph_pin* cur_pb_graph_pin, + int phy_mode_index) { + int cnt = 0; + int iedge; + + for (iedge = 0; iedge < cur_pb_graph_pin->num_input_edges; iedge++) { + if (phy_mode_index == cur_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode_index) { + cnt++; + } + } + return cnt; +} + +int count_pb_graph_node_output_edge_in_phy_mode(t_pb_graph_pin* cur_pb_graph_pin, + int phy_mode_index) { + int cnt = 0; + int iedge; + + for (iedge = 0; iedge < cur_pb_graph_pin->num_output_edges; iedge++) { + if (phy_mode_index == cur_pb_graph_pin->output_edges[iedge]->interconnect->parent_mode_index) { + cnt++; + } + } + return cnt; +} + +/* With a given name, find the pb_type by recursively traversing the pb_type_tree */ +t_pb_type* rec_get_pb_type_by_name(t_pb_type* cur_pb_type, + char* pb_type_name) { + int imode, ipb; + t_pb_type* ret_pb_type = NULL; + t_pb_type* found_pb_type = NULL; + + /* Check the name of this pb_type */ + if (0 == strcmp(cur_pb_type->name, pb_type_name)) { + ret_pb_type = cur_pb_type; + } + + /* return when we meet the primitive node */ + if ( (NULL != cur_pb_type->physical_pb_type_name) + || (NULL != cur_pb_type->spice_model_name)) { + return ret_pb_type; + } + + /* We cannot find what we want this level, go recursively */ + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + found_pb_type = rec_get_pb_type_by_name(&(cur_pb_type->modes[imode].pb_type_children[ipb]), pb_type_name); + if (NULL == found_pb_type) { /* See if we have found anything*/ + continue; + } + /* We find something, check if we have a overlap in naming */ + if (NULL != ret_pb_type) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Duplicated pb_type name(%s) is not allowed in pb_types!\n", + __FILE__, __LINE__, pb_type_name); + exit(1); + } else { /* We are free of naming conflict, assign the return value */ + ret_pb_type = found_pb_type; + } + } + } + + return ret_pb_type; +} + +/* Decode an annotation (a string): [:] */ +void decode_physical_mode_pin_annotation(int phy_pb_type_port_size, + char* phy_mode_pin, + char** port_name, + int* pin_msb, int* pin_lsb) { + int itoken; + int num_tokens = 0; + char** token = NULL; + + token = fpga_spice_strtok(phy_mode_pin, "[:]", &num_tokens); + + /* 1 == num_token */ + switch (num_tokens) { + case 1: + (*port_name) = my_strdup(phy_mode_pin); + (*pin_msb) = phy_pb_type_port_size - 1; + (*pin_lsb) = 0; + break; + case 2: + (*port_name) = my_strdup(token[0]); + (*pin_msb) = my_atoi(token[1]); + (*pin_lsb) = (*pin_msb); + break; + case 3: + (*port_name) = my_strdup(token[0]); + (*pin_msb) = my_atoi(token[1]); + (*pin_lsb) = my_atoi(token[2]); + /* Identify which is larger: pin_msb and pin_lsb */ + (*pin_msb) = ((*pin_msb) > (*pin_lsb)) ? (*pin_msb) : (*pin_lsb); + (*pin_msb) = ((*pin_msb) > (*pin_lsb)) ? (*pin_lsb) : (*pin_msb); + break; + default: + /* Error out! */ + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Invalid physical_mode_pin: %s!\n", + __FILE__, __LINE__, phy_mode_pin); + exit(1); + } + + /* Free tokens */ + for (itoken = 0; itoken < num_tokens; itoken++) { + my_free(token[itoken]); + } + my_free(token); + + return; +} + +/* Decode the physical_mode_pin definition in cur_pb_type_port + * Annotate it to the ports of phy_pb_type + */ +void annotate_physical_mode_pin_to_pb_type(t_port* cur_pb_type_port, + t_pb_type* phy_pb_type) { + int iport; + char* phy_port_name = NULL; + int msb, lsb; + int port_matched = 0; + + /* Check */ + assert ( TRUE == phy_pb_type->parent_mode->define_physical_mode ); + + /* Search phy_pb_port ports */ + for (iport = 0; iport < phy_pb_type->num_ports; iport++) { + /* Decode the physical_mode_pin */ + decode_physical_mode_pin_annotation(phy_pb_type->ports[iport].num_pins, + cur_pb_type_port->physical_mode_pin, + &phy_port_name, &msb, &lsb); + if (0 == strcmp(phy_port_name, phy_pb_type->ports[iport].name)) { + /* We got a match! Give the lsb, msb and create a link */ + cur_pb_type_port->phy_pb_type_port = &(phy_pb_type->ports[iport]); + cur_pb_type_port->phy_pb_type_port_msb = msb; + cur_pb_type_port->phy_pb_type_port_lsb = lsb; + port_matched++; + } + /* free */ + my_free(phy_port_name); + } + + /* Check if the port is unique */ + if (0 == port_matched) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Unable to match the port (%s) of %s in its physical pb_type %s!\n", + __FILE__, __LINE__, + cur_pb_type_port->name, cur_pb_type_port->parent_pb_type->name, + phy_pb_type->name); + exit(1); + } + if (1 < port_matched) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])More than 1 port is matched for the port (%s) of %s in its physical pb_type %s!\n", + __FILE__, __LINE__, + cur_pb_type_port->name, cur_pb_type_port->parent_pb_type->name, + phy_pb_type->name); + exit(1); + } + assert (1 == port_matched ); + + /* Check if the pin number match */ + assert(cur_pb_type_port->phy_pb_type_port->num_pins > + (cur_pb_type_port->phy_pb_type_port_msb - cur_pb_type_port->phy_pb_type_port_lsb)); + + return; +} + +/* Annotate the port-to-port definition from cur_pb_type to a physical pb_type */ +void annotate_pb_type_port_to_phy_pb_type(t_pb_type* cur_pb_type, + t_pb_type* phy_pb_type) { + int iport; + + /* Check */ + assert ( TRUE == phy_pb_type->parent_mode->define_physical_mode ); + assert ( NULL != cur_pb_type->phy_pb_type ); + + /* Check each port of cur_pb_type */ + for (iport = 0; iport < cur_pb_type->num_ports; iport++) { + annotate_physical_mode_pin_to_pb_type(&(cur_pb_type->ports[iport]), phy_pb_type); + } + + return; +} + +/* Find a pb_graph_node with a given pb_type_name in placement_index_in_top */ +t_pb_graph_node* rec_get_pb_graph_node_by_pb_type_and_placement_index_in_top_node(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* target_pb_type, + int target_placement_index) { + int imode, ipb, jpb; + t_pb_graph_node* ret_pb_graph_node = NULL; + t_pb_graph_node* found_pb_graph_node = NULL; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + + /* Check if pb_type matches and also the placement_index */ + if (( target_pb_type == cur_pb_graph_node->pb_type ) + &&( target_placement_index == cur_pb_graph_node->placement_index_in_top_node )) { + ret_pb_graph_node = cur_pb_graph_node; + } + + /* We cannot find what we want this level, go recursively */ + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + found_pb_graph_node = rec_get_pb_graph_node_by_pb_type_and_placement_index_in_top_node(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + target_pb_type, target_placement_index); + + if (NULL == found_pb_graph_node) { /* See if we have found anything*/ + continue; + } + /* We find something, check if we have a overlap in naming */ + if (NULL != ret_pb_graph_node) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Duplicated pb_graph_node name %s[%d] is not allowed in pb_graph_node!\n", + __FILE__, __LINE__, target_pb_type->name, target_placement_index); + exit(1); + } else { /* We are free of naming conflict, assign the return value */ + ret_pb_graph_node = found_pb_graph_node; + } + } + } + } + + return ret_pb_graph_node; +} + +/* Check if the pin_number of cur_pb_graph_pin matches the phycial pb_graph_pin */ +boolean check_pin_number_match_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph_pin, + t_pb_graph_pin* phy_pb_graph_pin) { + boolean pin_number_match = FALSE; + + /* Consider the rotation of cur_pb_graph_pin in pin_number */ + if ( (cur_pb_graph_pin->port->phy_pb_type_port == phy_pb_graph_pin->port) + &&(cur_pb_graph_pin->pin_number + + cur_pb_graph_pin->port->phy_pb_type_port_lsb + + cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc + == phy_pb_graph_pin->pin_number )) { + pin_number_match = TRUE; + } + return pin_number_match; +} + +/* Link a port in the pb_graph_node to its physical_pb_graph_node port */ +void link_one_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph_pin, + t_pb_graph_node* phy_pb_graph_node) { + t_pb_graph_pin* phy_pb_graph_pin = NULL; + int iport, ipin; + + /* Get the name match pin in the phy_graph_node */ + for (iport = 0; iport < phy_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < phy_pb_graph_node->num_input_pins[iport]; ipin++) { + if (FALSE == check_pin_number_match_phy_pb_graph_pin(cur_pb_graph_pin, &(phy_pb_graph_node->input_pins[iport][ipin]))) { + continue; + } + if (NULL == phy_pb_graph_pin) { + phy_pb_graph_pin = &(phy_pb_graph_node->input_pins[iport][ipin]); + } else { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) More than one matched pin number found for %s[%d] in %s!\n", + __FILE__, __LINE__, cur_pb_graph_pin->port->name, cur_pb_graph_pin->pin_number, phy_pb_graph_node->pb_type->name); + exit(1); + } + } + } + + for (iport = 0; iport < phy_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < phy_pb_graph_node->num_output_pins[iport]; ipin++) { + if (FALSE == check_pin_number_match_phy_pb_graph_pin(cur_pb_graph_pin, &(phy_pb_graph_node->output_pins[iport][ipin]))) { + continue; + } + if (NULL == phy_pb_graph_pin) { + phy_pb_graph_pin = &(phy_pb_graph_node->output_pins[iport][ipin]); + } else { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) More than one matched pin number found for %s[%d] in %s!\n", + __FILE__, __LINE__, cur_pb_graph_pin->port->name, cur_pb_graph_pin->pin_number, phy_pb_graph_node->pb_type->name); + exit(1); + } + + } + } + + for (iport = 0; iport < phy_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < phy_pb_graph_node->num_clock_pins[iport]; ipin++) { + if (FALSE == check_pin_number_match_phy_pb_graph_pin(cur_pb_graph_pin, &(phy_pb_graph_node->clock_pins[iport][ipin]))) { + continue; + } + if (NULL == phy_pb_graph_pin) { + phy_pb_graph_pin = &(phy_pb_graph_node->clock_pins[iport][ipin]); + } else { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) More than one matched pin number found for %s[%d] in %s!\n", + __FILE__, __LINE__, cur_pb_graph_pin->port->name, cur_pb_graph_pin->pin_number, phy_pb_graph_node->pb_type->name); + exit(1); + } + + } + } + + /* We should find one! */ + if (NULL == phy_pb_graph_pin) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) No matched pin number found for %s[%d] in %s!\n", + __FILE__, __LINE__, + cur_pb_graph_pin->port->name, + cur_pb_graph_pin->pin_number, + phy_pb_graph_node->pb_type->name); + exit(1); + } + /* Create the link */ + cur_pb_graph_pin->physical_pb_graph_pin = phy_pb_graph_pin; + vpr_printf (TIO_MESSAGE_INFO, " match pin (%s[%d]->%s[%d]) to (%s[%d]->%s[%d]) rotate_offset_acc=%d\n", + cur_pb_graph_pin->parent_node->pb_type->name, + cur_pb_graph_pin->parent_node->placement_index, + cur_pb_graph_pin->port->name, cur_pb_graph_pin->pin_number, + phy_pb_graph_pin->parent_node->pb_type->name, + phy_pb_graph_pin->parent_node->placement_index, + phy_pb_graph_pin->port->name, phy_pb_graph_pin->pin_number, + cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc + ); + /* Accumulate the phy_mode_pin offset when we have a matched */ + if (0 != cur_pb_graph_pin->port->physical_mode_pin_rotate_offset) { + cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc += cur_pb_graph_pin->port->physical_mode_pin_rotate_offset; + } + /* Reset to lsb when we exceed the msb */ + /* TODO: this line should be thorougly checked, to avoid any bug */ + if (cur_pb_graph_pin->port->phy_pb_type_port_msb < + cur_pb_graph_pin->pin_number + cur_pb_graph_pin->port->phy_pb_type_port_lsb + + cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc) { + cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc = 0; + } + + return; +} + +/* Link the pb_graph_pins of a pb_graph_node to its physical pb_graph_node by the annotation in pb_type ports + * pb_graph_node A contains the annotation, while pb_graph_node B is the physical_pb_graph_node */ +void link_pb_graph_node_pins_to_phy_pb_graph_pins(t_pb_graph_node* cur_pb_graph_node, + t_pb_graph_node* phy_pb_graph_node) { + int iport, ipin; + + /* Search each port of cur_pb_graph_node and + * check matched port name in phy_pb_graph_node + */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + link_one_pb_graph_node_pin_to_phy_pb_graph_pin(&(cur_pb_graph_node->input_pins[iport][ipin]), + phy_pb_graph_node); + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + link_one_pb_graph_node_pin_to_phy_pb_graph_pin(&(cur_pb_graph_node->output_pins[iport][ipin]), + phy_pb_graph_node); + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + link_one_pb_graph_node_pin_to_phy_pb_graph_pin(&(cur_pb_graph_node->clock_pins[iport][ipin]), + phy_pb_graph_node); + } + } + + return; +} + +void rec_reset_pb_graph_node_rr_node_index_physical_pb(t_pb_graph_node* cur_pb_graph_node) { + int imode, iport, ipin, ipb, jpb; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + cur_pb_graph_node->input_pins[iport][ipin].rr_node_index_physical_pb = OPEN; + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + cur_pb_graph_node->output_pins[iport][ipin].rr_node_index_physical_pb = OPEN; + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + cur_pb_graph_node->clock_pins[iport][ipin].rr_node_index_physical_pb = OPEN; + } + } + + /* END until primitive node */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + return; + } + + /* We cannot find what we want this level, go recursively */ + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + rec_reset_pb_graph_node_rr_node_index_physical_pb(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb])); + } + } + } + + return; +} + +/* Allocate empty child_phy_pbs according to a pb_graph_node */ +void rec_alloc_phy_pb_children(t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_phy_pb) { + int ipb, jpb; + int phy_mode_index; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + char* phy_pb_name = NULL; + + phy_pb_name = (char*) my_malloc(sizeof(char) * (strlen(cur_pb_graph_node->pb_type->name) + + 1 + strlen(my_itoa(cur_pb_graph_node->placement_index_in_top_node)) + + 2)); + sprintf(phy_pb_name, "%s[%d]", + cur_pb_graph_node->pb_type->name, cur_pb_graph_node->placement_index_in_top_node); + + /* Initialize */ + cur_phy_pb->pb_graph_node = cur_pb_graph_node; + cur_phy_pb->name = phy_pb_name; + cur_phy_pb->num_logical_blocks = 0; + cur_phy_pb->logical_block = NULL; + cur_phy_pb->lut_size = NULL; + cur_phy_pb->lut_pin_remap = NULL; + cur_phy_pb->mode_bits = my_strdup(cur_pb_type->mode_bits); /* copy the default mode_bits */ + + /* Return if we reach the primitive node */ + if (NULL != cur_pb_type->spice_model) { + return; + } + + /* Assign the mode */ + phy_mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + cur_phy_pb->mode = phy_mode_index; + /* Contine recursively */ + /* Allocate */ + cur_phy_pb->child_pbs = (t_phy_pb**) my_calloc(cur_pb_type->modes[phy_mode_index].num_pb_type_children, sizeof(t_phy_pb*)); + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[phy_mode_index].num_pb_type_children; ipb++) { + /* Allocate */ + cur_phy_pb->child_pbs[ipb] = (t_phy_pb*) my_calloc(cur_pb_type->modes[phy_mode_index].pb_type_children[ipb].num_pb, sizeof(t_phy_pb)); + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_pb_type->modes[phy_mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Assign parent_pb */ + cur_phy_pb->child_pbs[ipb][jpb].parent_pb = cur_phy_pb; + cur_phy_pb->child_pbs[ipb][jpb].rr_graph = cur_phy_pb->rr_graph; + /* Contine recursively */ + rec_alloc_phy_pb_children(&(cur_pb_graph_node->child_pb_graph_nodes[phy_mode_index][ipb][jpb]), + &(cur_phy_pb->child_pbs[ipb][jpb])); + } + } + + return; +} + +/* With a given name, find the pb_type by recursively traversing the pb_type_tree */ +t_phy_pb* rec_get_phy_pb_by_name(t_phy_pb* cur_phy_pb, + char* phy_pb_name) { + int ipb, jpb; + t_phy_pb* ret_phy_pb = NULL; + t_phy_pb* found_phy_pb = NULL; + + /* Check the name of this pb_type */ + if (0 == strcmp(cur_phy_pb->name, phy_pb_name)) { + ret_phy_pb = cur_phy_pb; + } + + /* return when we meet the primitive node */ + if (NULL != cur_phy_pb->pb_graph_node->pb_type->spice_model) { + return ret_phy_pb; + } + + for (ipb = 0; ipb < cur_phy_pb->pb_graph_node->pb_type->modes[cur_phy_pb->mode].num_pb_type_children; ipb++) { + /* Each child may exist multiple times in the hierarchy*/ + for (jpb = 0; jpb < cur_phy_pb->pb_graph_node->pb_type->modes[cur_phy_pb->mode].pb_type_children[ipb].num_pb; jpb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + found_phy_pb = rec_get_phy_pb_by_name(&(cur_phy_pb->child_pbs[ipb][jpb]), phy_pb_name); + if (NULL == found_phy_pb) { /* See if we have found anything*/ + continue; + } + /* We find something, check if we have a overlap in naming */ + if (NULL != ret_phy_pb) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])Duplicated phy_pb name(%s) is not allowed in phy_pb!\n", + __FILE__, __LINE__, phy_pb_name); + exit(1); + } else { /* We are free of naming conflict, assign the return value */ + ret_phy_pb = found_phy_pb; + } + } + } + + return ret_phy_pb; +} + +int get_pb_graph_node_wired_lut_logical_block_index(t_pb_graph_node* cur_pb_graph_node, + t_rr_node* op_pb_rr_graph) { + int iport, ipin; + int wired_lut_lb_index = OPEN; + int num_used_lut_input_pins = 0; + int num_used_lut_output_pins = 0; + int temp_rr_node_index; + int lut_output_vpack_net_num = OPEN; + + num_used_lut_input_pins = 0; + /* Find the used input pin of this LUT and rr_node in the graph */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + temp_rr_node_index = cur_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + if (OPEN != op_pb_rr_graph[temp_rr_node_index].vpack_net_num) { + num_used_lut_input_pins++; + lut_output_vpack_net_num = op_pb_rr_graph[temp_rr_node_index].vpack_net_num; + } + } + } + /* Make sure we only have 1 used input pin */ + assert ((1 == num_used_lut_input_pins) + && (OPEN != lut_output_vpack_net_num)); + vpr_printf(TIO_MESSAGE_INFO, "Wired LUT output vpack_net_num is %d\n", lut_output_vpack_net_num); + + /* Find the used output*/ + num_used_lut_output_pins = 0; + /* Find the used output pin of this LUT and rr_node in the graph */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + temp_rr_node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; + if (lut_output_vpack_net_num == op_pb_rr_graph[temp_rr_node_index].vpack_net_num) { /* TODO: Shit... I do not why the vpack_net_num is not synchronized to the net_num !!! */ + num_used_lut_output_pins++; + } + } + } + /* Make sure we only have 1 used output pin */ + vpr_printf(TIO_MESSAGE_INFO, "Wired LUT num_used_lut_output_pins is %d\n", num_used_lut_output_pins); + assert (1 == num_used_lut_output_pins); + + /* The logical block is the driver for this vpack_net( node_block[0] )*/ + wired_lut_lb_index = vpack_net[lut_output_vpack_net_num].node_block[0]; + assert (OPEN != wired_lut_lb_index); + + return wired_lut_lb_index; +} + +void rec_sync_wired_lut_to_one_phy_pb(t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_phy_pb, + t_rr_node* op_pb_rr_graph) { + int imode, ipb, jpb; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + char* phy_pb_name = NULL; + t_phy_pb* phy_pb_to_sync = NULL; + + + /* Copy LUT information if this is a leaf node */ + if ((TRUE == is_primitive_pb_type(cur_pb_type)) + && (LUT_CLASS == cur_pb_type->class_type)) { + /* Check */ + assert(NULL != cur_pb_type->phy_pb_type); + assert(NULL != cur_pb_graph_node->physical_pb_graph_node); + /* Generate the name */ + phy_pb_name = (char*) my_malloc(sizeof(char) * (strlen(cur_pb_type->phy_pb_type->name) + + 1 + strlen(my_itoa(cur_pb_graph_node->physical_pb_graph_node->placement_index_in_top_node)) + + 2)); + sprintf(phy_pb_name, "%s[%d]", + cur_pb_type->phy_pb_type->name, cur_pb_graph_node->physical_pb_graph_node->placement_index_in_top_node); + /* find the child_pb in the current physical pb (cur_phy_pb) */ + phy_pb_to_sync = rec_get_phy_pb_by_name(cur_phy_pb, phy_pb_name); + + /* Copy the mode bits */ + if (NULL != phy_pb_to_sync->mode_bits) { /* Free the default mode bits if we have any */ + my_free(phy_pb_to_sync->mode_bits); + } + phy_pb_to_sync->mode_bits = my_strdup(cur_pb_type->mode_bits); + /* Re-allocate logical_block array mapped to this pb */ + phy_pb_to_sync->num_logical_blocks++; + phy_pb_to_sync->logical_block = (int*) my_realloc(phy_pb_to_sync->logical_block, sizeof(int) * phy_pb_to_sync->num_logical_blocks); + phy_pb_to_sync->is_wired_lut = (boolean*) my_realloc(phy_pb_to_sync->is_wired_lut, sizeof(boolean) * phy_pb_to_sync->num_logical_blocks); + phy_pb_to_sync->lut_size = (int*) my_realloc(phy_pb_to_sync->lut_size, sizeof(int) * phy_pb_to_sync->num_logical_blocks); + phy_pb_to_sync->lut_output_pb_graph_pin = (t_pb_graph_pin**) my_realloc(phy_pb_to_sync->lut_output_pb_graph_pin, sizeof(t_pb_graph_pin*) * phy_pb_to_sync->num_logical_blocks); + + /* Synchronize the logic block information */ + assert (LUT_CLASS == cur_pb_type->class_type); + /* check */ + assert (LUT_CLASS == cur_pb_type->phy_pb_type->class_type); + assert ( 1 == cur_pb_graph_node->num_input_ports ); + /* TODO: find the wired LUT logical block! */ + phy_pb_to_sync->logical_block[phy_pb_to_sync->num_logical_blocks - 1] = get_pb_graph_node_wired_lut_logical_block_index(cur_pb_graph_node, op_pb_rr_graph); + phy_pb_to_sync->is_wired_lut[phy_pb_to_sync->num_logical_blocks - 1] = TRUE; + /* Update the actual input size of this LUT */ + phy_pb_to_sync->lut_size[phy_pb_to_sync->num_logical_blocks - 1] = cur_pb_graph_node->num_input_pins[0]; + + /* Find the physical pb_graph_pin that this output is mapped to. + * ease LUT truth table decoding + */ + assert (1 == cur_pb_graph_node->num_output_ports); + assert (1 == cur_pb_graph_node->num_output_pins[0]); + phy_pb_to_sync->lut_output_pb_graph_pin[phy_pb_to_sync->num_logical_blocks - 1] = cur_pb_graph_node->output_pins[0][0].physical_pb_graph_pin; + + /* Finish here */ + return; + } + + /* Go recursively */ + assert (FALSE == is_primitive_pb_type(cur_pb_type)); + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + /* We care only those have been used for wiring */ + if (FALSE == is_pb_used_for_wiring(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + &(cur_pb_type->modes[imode].pb_type_children[ipb]), + op_pb_rr_graph)) { + continue; + } + rec_sync_wired_lut_to_one_phy_pb(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + cur_phy_pb, + op_pb_rr_graph); + } + } + } + + return; +} + +/* Synchronize the mapped information from operating pb cur_pb to phy_pb */ +void rec_sync_op_pb_mapping_to_phy_pb_children(t_pb* cur_op_pb, + t_phy_pb* cur_phy_pb) { + int ipb, jpb; + t_pb_graph_node* cur_pb_graph_node = cur_op_pb->pb_graph_node; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + int mode_index = cur_op_pb->mode; + t_pb* child_pb = NULL; + char* phy_pb_name = NULL; + t_phy_pb* phy_pb_to_sync = NULL; + + /* Return if we reach the primitive node */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + /* Check */ + assert(NULL != cur_pb_type->phy_pb_type); + assert(NULL != cur_pb_graph_node->physical_pb_graph_node); + /* Generate the name */ + phy_pb_name = (char*) my_malloc(sizeof(char) * (strlen(cur_pb_type->phy_pb_type->name) + + 1 + strlen(my_itoa(cur_pb_graph_node->physical_pb_graph_node->placement_index_in_top_node)) + + 2)); + sprintf(phy_pb_name, "%s[%d]", + cur_pb_type->phy_pb_type->name, cur_pb_graph_node->physical_pb_graph_node->placement_index_in_top_node); + /* find the child_pb in the current physical pb (cur_phy_pb) */ + phy_pb_to_sync = rec_get_phy_pb_by_name(cur_phy_pb, phy_pb_name); + /* Check */ + /* Copy the mode bits */ + if (NULL != phy_pb_to_sync->mode_bits) { /* Free the default mode bits if we have any */ + my_free(phy_pb_to_sync->mode_bits); + } + phy_pb_to_sync->mode_bits = my_strdup(cur_pb_type->mode_bits); + /* Re-allocate logical_block array mapped to this pb */ + phy_pb_to_sync->num_logical_blocks++; + phy_pb_to_sync->logical_block = (int*) my_realloc(phy_pb_to_sync->logical_block, sizeof(int) * phy_pb_to_sync->num_logical_blocks); + phy_pb_to_sync->is_wired_lut = (boolean*) my_realloc(phy_pb_to_sync->is_wired_lut, sizeof(boolean) * phy_pb_to_sync->num_logical_blocks); + phy_pb_to_sync->lut_size = (int*) my_realloc(phy_pb_to_sync->lut_size, sizeof(int) * phy_pb_to_sync->num_logical_blocks); + phy_pb_to_sync->lut_output_pb_graph_pin = (t_pb_graph_pin**) my_realloc(phy_pb_to_sync->lut_output_pb_graph_pin, sizeof(t_pb_graph_pin*) * phy_pb_to_sync->num_logical_blocks); + /* Synchronize the logic block information */ + switch (cur_pb_type->class_type) { + case LUT_CLASS: + /* Give phy_pb_type a LUT CLASS */ + child_pb = get_lut_child_pb(cur_op_pb, mode_index); + /* check */ + assert (LUT_CLASS == cur_pb_type->phy_pb_type->class_type); + assert (VPACK_COMB == logical_block[child_pb->logical_block].type); + assert ( 1 == cur_pb_graph_node->num_input_ports ); + /* Find the physical pb_graph_pin that this output is mapped to. + * ease LUT truth table decoding + */ + assert (1 == cur_pb_graph_node->num_output_ports); + assert (1 == cur_pb_graph_node->num_output_pins[0]); + phy_pb_to_sync->lut_output_pb_graph_pin[phy_pb_to_sync->num_logical_blocks - 1] = cur_pb_graph_node->output_pins[0][0].physical_pb_graph_pin; + /* Branch on the operating mode of this LUT + * Mode 0 means this LUT is in wired mode while Mode 1 implies this is a regular LUT + */ + if (WIRED_LUT_MODE_INDEX == mode_index) { + phy_pb_to_sync->logical_block[phy_pb_to_sync->num_logical_blocks - 1] = child_pb->logical_block; + phy_pb_to_sync->is_wired_lut[phy_pb_to_sync->num_logical_blocks - 1] = TRUE; + } else { + assert (NORMAL_LUT_MODE_INDEX == mode_index); + phy_pb_to_sync->logical_block[phy_pb_to_sync->num_logical_blocks - 1] = child_pb->logical_block; + phy_pb_to_sync->is_wired_lut[phy_pb_to_sync->num_logical_blocks - 1] = FALSE; + /* Give the number of LUT inputs of operating pb_graph_node */ + if (OPEN == child_pb->logical_block) { + phy_pb_to_sync->num_logical_blocks--; + } + } + /* Update the actual input size of this LUT */ + phy_pb_to_sync->lut_size[phy_pb_to_sync->num_logical_blocks - 1] = cur_pb_graph_node->num_input_pins[0]; + break; + case LATCH_CLASS: + /* Comment this as FF maybe a black box*/ + /* assert (VPACK_LATCH == logical_block[cur_op_pb->logical_block].type); */ + phy_pb_to_sync->logical_block[phy_pb_to_sync->num_logical_blocks - 1] = cur_op_pb->logical_block; + if (OPEN == cur_op_pb->logical_block) { + phy_pb_to_sync->num_logical_blocks--; + } + break; + case MEMORY_CLASS: + /* TODO: some memory pb has OPEN logical block .... Find out why + * To be safe, we identify if the logical block index is valid here + */ + child_pb = get_hardlogic_child_pb(cur_op_pb, mode_index); + phy_pb_to_sync->logical_block[phy_pb_to_sync->num_logical_blocks - 1] = child_pb->logical_block; + if (OPEN == child_pb->logical_block) { + phy_pb_to_sync->num_logical_blocks--; + } + break; + case UNKNOWN_CLASS: + /* Could be adder/hetergenous block/IOs + assert ((VPACK_INPAD == logical_block[cur_op_pb->logical_block].type) + ||(VPACK_OUTPAD == logical_block[cur_op_pb->logical_block].type)); + */ + phy_pb_to_sync->logical_block[phy_pb_to_sync->num_logical_blocks - 1] = cur_op_pb->logical_block; + if (OPEN == cur_op_pb->logical_block) { + phy_pb_to_sync->num_logical_blocks--; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", + __FILE__, __LINE__, cur_pb_type->name); + exit(1); + } + + /* Free */ + my_free(phy_pb_name); + return; + } + + /* Recursive*/ + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_op_pb->child_pbs[ipb])&&(NULL != cur_op_pb->child_pbs[ipb][jpb].name)) { + rec_sync_op_pb_mapping_to_phy_pb_children(&(cur_op_pb->child_pbs[ipb][jpb]), cur_phy_pb); + } else if (TRUE == is_pb_used_for_wiring(&(cur_op_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), + cur_op_pb->rr_graph)) { + /* We need to extend this part: + * Some open op_pb contains wired LUTs + * We need go further into the hierarchy and find out the wired LUTs + */ + rec_sync_wired_lut_to_one_phy_pb(&(cur_op_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + cur_phy_pb, + cur_op_pb->rr_graph); + } + } + } + + return; +} + + +/* Allocate pb children for a physical pb, according to the results in cur_pb*/ +void alloc_and_load_phy_pb_children_for_one_mapped_block(t_pb* cur_op_pb, + t_phy_pb* cur_phy_pb) { + + /* allocate empty child pbs according to pb_graph_node */ + rec_alloc_phy_pb_children(cur_phy_pb->pb_graph_node, cur_phy_pb); + + /* Synchronize the cur_pb to cur_phy_pb */ + rec_sync_op_pb_mapping_to_phy_pb_children(cur_op_pb, cur_phy_pb); + + return; +} + +/* Get the vpack_net_num of all the input pins of a LUT physical pb */ +void get_mapped_lut_phy_pb_input_pin_vpack_net_num(t_phy_pb* lut_phy_pb, + int* num_lut_pin, int** lut_pin_net) { + + int ipin, inode; + + /* Check */ + assert (1 == lut_phy_pb->pb_graph_node->num_input_ports); + (*num_lut_pin) = lut_phy_pb->pb_graph_node->num_input_pins[0]; + + /* Allocate */ + (*lut_pin_net) = (int*) my_malloc ((*num_lut_pin) * sizeof(int)); + /* Fill the array */ + for (ipin = 0; ipin < (*num_lut_pin); ipin++) { + inode = lut_phy_pb->pb_graph_node->input_pins[0][ipin].rr_node_index_physical_pb; + (*lut_pin_net)[ipin] = lut_phy_pb->rr_graph->rr_node[inode].vpack_net_num; + } + + return; +} + +/* Get the vpack_net_num of all the input pins of a LUT physical pb */ +void get_mapped_lut_pb_input_pin_vpack_net_num(t_pb* lut_pb, + int* num_lut_pin, int** lut_pin_net) { + int ipin, inode; + + /* Check */ + assert (1 == lut_pb->pb_graph_node->num_input_ports); + (*num_lut_pin) = lut_pb->pb_graph_node->num_input_pins[0]; + + /* Allocate */ + (*lut_pin_net) = (int*) my_malloc ((*num_lut_pin) * sizeof(int)); + /* Fill the array */ + for (ipin = 0; ipin < (*num_lut_pin); ipin++) { + inode = lut_pb->pb_graph_node->input_pins[0][ipin].rr_node_index_physical_pb; + (*lut_pin_net)[ipin] = lut_pb->rr_graph[inode].vpack_net_num; + } + + return; +} + +/* Get the vpack_net_num of all the input pins of a LUT physical pb */ +void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_block, + int* num_lut_pin, int** lut_pin_net) { + int ipin; + + /* Check */ + assert (NULL == lut_logical_block->model->inputs[0].next); + (*num_lut_pin) = lut_logical_block->model->inputs[0].size; + + /* Allocate */ + (*lut_pin_net) = (int*) my_malloc ((*num_lut_pin) * sizeof(int)); + /* Fill the array */ + for (ipin = 0; ipin < (*num_lut_pin); ipin++) { + (*lut_pin_net)[ipin] = lut_logical_block->input_nets[0][ipin]; + } + + return; +} + +/* Reset the temp_placement_index in pb_type to be 0 */ +void rec_reset_pb_type_temp_placement_index(t_pb_type* cur_pb_type) { + int imode, ipb; + + cur_pb_type->temp_placement_index = 0; + + /* See when we reach the primitive */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + return; + } + + /* We cannot find what we want this level, go recursively */ + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + rec_reset_pb_type_temp_placement_index(&(cur_pb_type->modes[imode].pb_type_children[ipb])); + } + } + + return; +} + +/* Reset the phy_pb_type in pb_type to be 0 */ +void rec_reset_pb_type_phy_pb_type(t_pb_type* cur_pb_type) { + int imode, ipb; + + cur_pb_type->phy_pb_type = NULL; + + /* See when we reach the primitive */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + return; + } + + /* We cannot find what we want this level, go recursively */ + /* Check each mode*/ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Quote all child pb_types */ + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + /* we should make sure this placement index == child_pb_type[jpb]*/ + rec_reset_pb_type_phy_pb_type(&(cur_pb_type->modes[imode].pb_type_children[ipb])); + } + } + + return; +} + +/* Identify if this child_pb is actually used for wiring!!! */ +boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* cur_pb_type, + t_rr_node* pb_rr_graph) { + boolean is_used = FALSE; + int node_index; + int port_index = 0; + int iport, ipin; + + for (iport = 0; iport < cur_pb_type->num_ports && !is_used; iport++) { + if (OUT_PORT == cur_pb_type->ports[iport].type) { + for (ipin = 0; ipin < cur_pb_type->ports[iport].num_pins; ipin++) { + node_index = cur_pb_graph_node->output_pins[port_index][ipin].pin_count_in_cluster; + if ((OPEN != pb_rr_graph[node_index].net_num) + || (OPEN != pb_rr_graph[node_index].vpack_net_num)) { + return TRUE; + } + } + port_index++; + } + } + + return is_used; +} + +char* get_pb_graph_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node) { + char* full_name = NULL; + char* cur_name = NULL; + t_pb_graph_node* temp = cur_pb_graph_node; + + while (NULL != temp) { + cur_name = (char*)my_malloc(1 + strlen(temp->pb_type->name) + 1 + + strlen(my_itoa(temp->placement_index)) + 2); + /* For top node, we do not put a slash at the beginning */ + if (NULL == temp->parent_pb_graph_node) { + sprintf(cur_name, "%s[%d]", + temp->pb_type->name, + temp->placement_index); + } else { + sprintf(cur_name, "/%s[%d]", + temp->pb_type->name, + temp->placement_index); + } + if (NULL != full_name) { + full_name = my_strcat(cur_name, full_name); + } else { + full_name = my_strdup(cur_name); + } + temp = temp->parent_pb_graph_node; + my_free(cur_name); + } + + return full_name; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h new file mode 100644 index 000000000..67f6ac6ef --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h @@ -0,0 +1,242 @@ +void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge); + +void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin); + +void backup_one_pb_rr_node_pack_prev_node_edge(t_rr_node* pb_rr_node); + +int find_parent_pb_type_child_index(t_pb_type* parent_pb_type, + int mode_index, + t_pb_type* child_pb_type); + +void gen_spice_name_tag_phy_pb_rec(t_phy_pb* cur_phy_pb, + char* prefix); + +void gen_spice_name_tag_pb_rec(t_pb* cur_pb, + char* prefix); + +void gen_spice_name_tags_all_pbs(); + +void gen_spice_name_tags_all_phy_pbs(); + +int find_pb_mapped_logical_block_rec(t_pb* cur_pb, + t_spice_model* pb_spice_model, + char* pb_spice_name_tag); + +int find_grid_mapped_logical_block(int x, int y, + t_spice_model* pb_spice_model, + char* pb_spice_name_tag); + +void stats_pb_graph_node_port_pin_numbers(t_pb_graph_node* cur_pb_graph_node, + int* num_inputs, + int* num_outputs, + int* num_clock_pins); + +int find_pb_type_idle_mode_index(t_pb_type cur_pb_type); + +int find_pb_type_physical_mode_index(t_pb_type cur_pb_type); + +void mark_grid_type_pb_graph_node_pins_temp_net_num(int x, int y); + +void assign_pb_graph_node_pin_temp_net_num_by_mode_index(t_pb_graph_pin* cur_pb_graph_pin, + int mode_index); + +void mark_pb_graph_node_input_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, + int mode_index); + +void mark_pb_graph_node_clock_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, + int mode_index); + +void mark_pb_graph_node_output_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, + int mode_index); + +void rec_mark_pb_graph_node_temp_net_num(t_pb_graph_node* cur_pb_graph_node); + +void load_one_pb_graph_pin_temp_net_num_from_pb(t_phy_pb* cur_pb, + t_pb_graph_pin* cur_pb_graph_pin); + +void load_pb_graph_node_temp_net_num_from_pb(t_phy_pb* cur_pb); + +void rec_mark_one_pb_unused_pb_graph_node_temp_net_num(t_phy_pb* cur_pb); + +void update_pb_vpack_net_num_from_temp_net_num(t_phy_pb* cur_pb, + t_pb_graph_pin* cur_pb_graph_pin); + +void update_pb_graph_node_temp_net_num_to_pb(t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb); + +void rec_load_unused_pb_graph_node_temp_net_num_to_pb(t_phy_pb* cur_pb); + +void mark_one_pb_parasitic_nets(t_phy_pb* cur_pb); + +int count_num_conf_bit_one_interc(t_interconnect* cur_interc, + enum e_sram_orgz cur_sram_orgz_type); + +int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc, + enum e_sram_orgz cur_sram_orgz_type); + +int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode, + enum e_sram_orgz cur_sram_orgz_type); + +int rec_count_num_conf_bits_pb_type_default_mode(t_pb_type* cur_pb_type, + t_sram_orgz_info* cur_sram_orgz_info); + +int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, + t_sram_orgz_info* cur_sram_orgz_info); + +int rec_count_num_conf_bits_pb(t_pb* cur_pb, + t_sram_orgz_info* cur_sram_orgz_info); + +void init_one_grid_num_conf_bits(int ix, int iy, + t_sram_orgz_info* cur_sram_orgz_info); + +void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info); + +void map_clb_pins_to_pb_graph_pins(); + +t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, + t_spice_model_port* spice_model_port); + +t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type, + enum e_spice_model_port_type port_type, + int* port_num); + + +enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin); + +t_spice_model* find_pb_graph_pin_in_edges_interc_spice_model(t_pb_graph_pin pb_graph_pin); + +int find_path_id_between_pb_rr_nodes(t_rr_node* local_rr_graph, + int src_node, + int des_node); + +t_pb* get_child_pb_for_phy_pb_graph_node(t_pb* cur_pb, int ipb, int jpb); + +t_phy_pb* get_phy_child_pb_for_phy_pb_graph_node(t_phy_pb* cur_phy_pb, int ipb, int jpb); + +enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin) ; + +t_spice_model* find_pb_graph_pin_in_edges_interc_model(t_pb_graph_pin pb_graph_pin) ; + +void find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, + t_mode* cur_mode, + t_interconnect** cur_interc, + int* fan_in) ; + +void find_interc_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, + int cur_mode, + t_interconnect** cur_interc); + +void rec_count_num_iopads_pb_type_physical_mode(t_pb_type* cur_pb_type); + +void rec_count_num_iopads_pb_type_default_mode(t_pb_type* cur_pb_type); + +void rec_count_num_iopads_pb(t_pb* cur_pb); + +void init_one_grid_num_iopads(int ix, int iy); + +void init_grids_num_iopads(); + +void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type); + +void rec_count_num_mode_bits_pb(t_pb* cur_pb); + +void init_one_grid_num_mode_bits(int ix, int iy); + +void init_grids_num_mode_bits(); + +t_pb* get_lut_child_pb(t_pb* cur_lut_pb, + int mode_index); + +t_phy_pb* get_lut_child_phy_pb(t_phy_pb* cur_lut_pb, + int mode_index); + +t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb, + int mode_index); + +int get_grid_pin_height(int grid_x, int grid_y, int pin_index); + +int get_grid_pin_side(int grid_x, int grid_y, int pin_index); + +int* decode_mode_bits(char* mode_bits, int* num_sram_bits); + +enum e_interconnect determine_actual_pb_interc_type(t_interconnect* def_interc, + int fan_in) ; + +int count_pin_number_one_port_pb_graph_node(int num_ports, int* num_pins); + +int count_pin_number_one_pb_graph_node(t_pb_graph_node* cur_pb_graph_node); + +int count_pb_graph_node_input_edge_in_phy_mode(t_pb_graph_pin* cur_pb_graph_pin, + int phy_mode_index); + +int count_pb_graph_node_output_edge_in_phy_mode(t_pb_graph_pin* cur_pb_graph_pin, + int phy_mode_index); + +t_pb_type* rec_get_pb_type_by_name(t_pb_type* cur_pb_type, + char* pb_type_name); + +void decode_physical_mode_pin_annotation(int phy_pb_type_port_size, + char* phy_mode_pin, + char** port_name, + int* pin_msb, int* pin_lsb); + +void annotate_physical_mode_pin_to_pb_type(t_port* cur_pb_type_port, + t_pb_type* phy_pb_type); + +void annotate_pb_type_port_to_phy_pb_type(t_pb_type* cur_pb_type, + t_pb_type* phy_pb_type); + +t_pb_graph_node* rec_get_pb_graph_node_by_pb_type_and_placement_index_in_top_node(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* target_pb_type, + int target_placement_index); + +boolean check_pin_number_match_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph_pin, + t_pb_graph_pin* phy_pb_graph_pin); + +void link_one_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph_pin, + t_pb_graph_node* phy_pb_graph_node); + +void link_pb_graph_node_pins_to_phy_pb_graph_pins(t_pb_graph_node* cur_pb_graph_node, + t_pb_graph_node* phy_pb_graph_node); + +void rec_reset_pb_graph_node_rr_node_index_physical_pb(t_pb_graph_node* cur_pb_graph_node); + +void rec_alloc_phy_pb_children(t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_phy_pb); + +t_phy_pb* rec_get_phy_pb_by_name(t_phy_pb* cur_phy_pb, + char* phy_pb_name); + +int get_pb_graph_node_wired_lut_logical_block_index(t_pb_graph_node* cur_pb_graph_node, + t_rr_node* op_pb_rr_graph); + +void rec_reset_pb_graph_node_rr_node_index_physical_pb(t_pb_graph_node* cur_pb_graph_node); + +void sync_wired_lut_to_one_phy_pb(t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_phy_pb, + t_rr_node* op_pb_rr_graph); + +void rec_sync_op_pb_mapping_to_phy_pb_children(t_pb* cur_op_pb, + t_phy_pb* cur_phy_pb); + +void alloc_and_load_phy_pb_children_for_one_mapped_block(t_pb* cur_pb, + t_phy_pb* cur_phy_pb); + +void get_mapped_lut_phy_pb_input_pin_vpack_net_num(t_phy_pb* lut_phy_pb, + int* num_lut_pin, int** lut_pin_net); + +void get_mapped_lut_pb_input_pin_vpack_net_num(t_pb* lut_pb, + int* num_lut_pin, int** lut_pin_net); + +void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_block, + int* num_lut_pin, int** lut_pin_net); + +void rec_reset_pb_type_temp_placement_index(t_pb_type* cur_pb_type); + +void rec_reset_pb_type_phy_pb_type(t_pb_type* cur_pb_type); + +boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* cur_pb_type, + t_rr_node* pb_rr_graph); + +char* get_pb_graph_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c new file mode 100644 index 000000000..e3e6b416f --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c @@ -0,0 +1,1157 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_rr_graph_utils.h" + +/* Initial rr_graph */ +void init_rr_graph(INOUTP t_rr_graph* local_rr_graph) { + /* Give zero and NULL to all the contents */ + local_rr_graph->num_rr_nodes = 0; + local_rr_graph->rr_node = NULL; + local_rr_graph->rr_node_indices = NULL; + + local_rr_graph->num_switch_inf = 0; + local_rr_graph->switch_inf = NULL; + local_rr_graph->delayless_switch_index = 0; + + local_rr_graph->num_nets = 0; + local_rr_graph->net = NULL; + local_rr_graph->net_to_vpack_net_mapping = NULL; + local_rr_graph->net_num_sources = NULL; + local_rr_graph->net_num_sinks = NULL; + + local_rr_graph->net_rr_sources = NULL; + local_rr_graph->net_rr_sinks = NULL; + local_rr_graph->net_rr_terminals = NULL; + memset(&(local_rr_graph->rr_mem_ch), 0, sizeof(t_chunk)); + + local_rr_graph->num_rr_indexed_data = 0; + local_rr_graph->rr_indexed_data = NULL; + + local_rr_graph->rr_node_route_inf = NULL; + local_rr_graph->route_bb = NULL; + + local_rr_graph->trace_head = NULL; + local_rr_graph->trace_tail = NULL; + local_rr_graph->trace_free_head = NULL; + memset(&(local_rr_graph->trace_ch), 0, sizeof(t_chunk)); + + local_rr_graph->heap = NULL; + local_rr_graph->heap_size = 0; + local_rr_graph->heap_tail = 0; + + local_rr_graph->heap_free_head = NULL; + memset(&(local_rr_graph->heap_ch), 0, sizeof(t_chunk)); + + local_rr_graph->rr_modified_head = NULL; + local_rr_graph->linked_f_pointer_free_head = NULL; + + //local_rr_graph->linked_f_pointer_ch = {NULL, 0, NULL}; + memset(&(local_rr_graph->linked_f_pointer_ch), 0, sizeof(t_chunk)); + + #ifdef DEBUG + local_rr_graph->num_trace_allocated = 0; + local_rr_graph->num_heap_allocated = 0; + local_rr_graph->num_linked_f_pointer_allocated = 0; + #endif + + return; +} + +void alloc_rr_graph_net_rr_sources_and_sinks(t_rr_graph* local_rr_graph) { + int inet, isrc, isink, inode; + int num_sources_in_rr_graph, num_sinks_in_rr_graph; + + local_rr_graph->net_num_sources = (int *) my_calloc(local_rr_graph->num_nets, sizeof(int)); + local_rr_graph->net_num_sinks = (int *) my_calloc(local_rr_graph->num_nets, sizeof(int)); + + local_rr_graph->net_rr_sources = (int **) my_calloc(local_rr_graph->num_nets, sizeof(int*)); + local_rr_graph->net_rr_sinks = (int **) my_calloc(local_rr_graph->num_nets, sizeof(int*)); + + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + /* Count how many SINKs we have in the rr_graph that is mapped to this net */ + num_sources_in_rr_graph = 0; + num_sinks_in_rr_graph = 0; + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + /* Only care the rr_node mapped to this net */ + if (inet != local_rr_graph->rr_node[inode].net_num) { + continue; + } + if (SOURCE == local_rr_graph->rr_node[inode].type) { + num_sources_in_rr_graph++; + } + if (SINK == local_rr_graph->rr_node[inode].type) { + num_sinks_in_rr_graph++; + } + } + local_rr_graph->net_num_sources[inet] = num_sources_in_rr_graph; + local_rr_graph->net_num_sinks[inet] = num_sinks_in_rr_graph; + /* Consider the SOURCE (index=0), a special SINK */ + local_rr_graph->net_rr_sources[inet] = (int *) my_malloc(num_sources_in_rr_graph * sizeof(int)); + local_rr_graph->net_rr_sinks[inet] = (int *) my_malloc(num_sinks_in_rr_graph * sizeof(int)); + /* Initialize all terminal to be OPEN */ + for (isrc = 0; isrc < local_rr_graph->net_num_sources[inet]; isrc++) { + local_rr_graph->net_rr_sources[inet][isrc] = OPEN; + } + for (isink = 0; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + local_rr_graph->net_rr_sinks[inet][isink] = OPEN; + } + } + + return; +} + +void alloc_rr_graph_net_rr_terminals(t_rr_graph* local_rr_graph) { + int inet, isink, inode, num_sinks_in_rr_graph; + + local_rr_graph->net_rr_terminals = (int **) my_malloc(local_rr_graph->num_nets * sizeof(int *)); + local_rr_graph->net_num_sinks = (int *) my_calloc(local_rr_graph->num_nets, sizeof(int)); + + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + /* Count how many SINKs we have in the rr_graph that is mapped to this net */ + num_sinks_in_rr_graph = 0; + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + if ((SINK == local_rr_graph->rr_node[inode].type) + && (inet == local_rr_graph->rr_node[inode].net_num)) { + num_sinks_in_rr_graph++; + } + } + local_rr_graph->net_num_sinks[inet] = num_sinks_in_rr_graph; + /* Consider the SOURCE (index=0), a special SINK */ + local_rr_graph->net_rr_terminals[inet] = (int *) my_chunk_malloc((num_sinks_in_rr_graph + 1) * sizeof(int), + &local_rr_graph->rr_mem_ch); + /* Initialize all terminal to be OPEN */ + local_rr_graph->net_rr_terminals[inet][0] = OPEN; + for (isink = 1; isink < local_rr_graph->net_num_sinks[inet] + 1; isink++) { + local_rr_graph->net_rr_terminals[inet][isink] = OPEN; + } + } + + return; +} + +void alloc_rr_graph_route_static_structs(t_rr_graph* local_rr_graph, + int heap_size) { + local_rr_graph->trace_head = (t_trace **) my_calloc(local_rr_graph->num_nets, sizeof(t_trace*)); + local_rr_graph->trace_tail = (t_trace **) my_malloc(local_rr_graph->num_nets * sizeof(t_trace*)); + + local_rr_graph->heap_size = heap_size; + local_rr_graph->heap = (t_heap **) my_malloc(local_rr_graph->heap_size * sizeof(t_heap*)); + local_rr_graph->heap--; /* heap stores from [1..heap_size] */ + local_rr_graph->heap_tail = 1; + + local_rr_graph->route_bb = (t_bb *) my_malloc(local_rr_graph->num_nets * sizeof(t_bb)); + + return; +} + +void alloc_and_load_rr_graph_rr_node(INOUTP t_rr_graph* local_rr_graph, + int local_num_rr_nodes) { + local_rr_graph->num_rr_nodes = local_num_rr_nodes; + /* Allocate rr_graph */ + local_rr_graph->rr_node = (t_rr_node*) my_calloc(local_rr_graph->num_rr_nodes, sizeof(t_rr_node)); + + return; +} + +/* Returns the segment number at which the segment this track lies on * + * started. */ +int get_rr_graph_seg_start(INP t_seg_details * seg_details, INP int itrack, + INP int chan_num, INP int seg_num) { + + int seg_start, length, start; + + seg_start = 1; + if (FALSE == seg_details[itrack].longline) { + + length = seg_details[itrack].length; + start = seg_details[itrack].start; + + /* Start is guaranteed to be between 1 and length. Hence adding length to * + * the quantity in brackets below guarantees it will be nonnegative. */ + /* Original VPR */ + assert(start > 0); + /* end */ + /* mrFPGA: Xifan TANG */ + /* assert(is_stack ? start >= 0: start > 0); */ + /* end */ + assert(start <= length); + + /* NOTE: Start points are staggered between different channels. + * The start point must stagger backwards as chan_num increases. + * Unidirectional routing expects this to allow the N-to-N + * assumption to be made with respect to ending wires in the core. */ + /* mrFPGA: Xifan TANG */ + /* + seg_start = seg_num - (seg_num - (is_stack ? 1 : 0) + length + chan_num - start) % length; + seg_start = std::max(seg_start, is_stack ? 0 : 1); + */ + /* end */ + /* Original VPR */ + seg_start = seg_num - (seg_num + length + chan_num - start) % length; + if (seg_start < 1) { + seg_start = 1; + } + /* end */ + } + + return seg_start; +} + + +void load_rr_graph_chan_rr_indices(t_rr_graph* local_rr_graph, + INP int nodes_per_chan, INP int chan_len, + INP int num_chans, INP t_rr_type type, INP t_seg_details * seg_details, + INOUTP int *index) { + int chan, seg, track, start, inode; + + local_rr_graph->rr_node_indices[type] = (t_ivec **) my_malloc(sizeof(t_ivec *) * num_chans); + for (chan = 0; chan < num_chans; ++chan) { + local_rr_graph->rr_node_indices[type][chan] = (t_ivec *) my_malloc(sizeof(t_ivec) * chan_len); + + local_rr_graph->rr_node_indices[type][chan][0].nelem = 0; + local_rr_graph->rr_node_indices[type][chan][0].list = NULL; + + for (seg = 1; seg < chan_len; ++seg) { + /* Alloc the track inode lookup list */ + local_rr_graph->rr_node_indices[type][chan][seg].nelem = nodes_per_chan; + local_rr_graph->rr_node_indices[type][chan][seg].list = (int *) my_malloc( + sizeof(int) * nodes_per_chan); + for (track = 0; track < nodes_per_chan; ++track) { + local_rr_graph->rr_node_indices[type][chan][seg].list[track] = OPEN; + } + } + } + + /* Original VPR */ + for (chan = 0; chan < num_chans; ++chan) { + for (seg = 1; seg < chan_len; ++seg) { + /* end */ + /* mrFPGA: Xifan TANG */ + /* + for (chan = (is_stack ? 1 : 0); chan < num_chans; ++chan) { + for (seg = (is_stack ? 0 : 1); seg < chan_len; ++seg) { + */ + /* end */ + /* Assign an inode to the starts of tracks */ + for (track = 0; track < local_rr_graph->rr_node_indices[type][chan][seg].nelem; ++track) { + start = get_rr_graph_seg_start(seg_details, track, chan, seg); + /* Original VPR */ + /* If the start of the wire doesn't have a inode, + * assign one to it. */ + inode = local_rr_graph->rr_node_indices[type][chan][start].list[track]; + if (OPEN == inode) { + inode = *index; + ++(*index); + + local_rr_graph->rr_node_indices[type][chan][start].list[track] = inode; + } + /* end */ + /* Assign inode of start of wire to current position */ + local_rr_graph->rr_node_indices[type][chan][seg].list[track] = inode; + } + } + } + return; +} + + +void alloc_and_load_rr_graph_rr_node_indices(t_rr_graph* local_rr_graph, + INP int nodes_per_chan, + INP int L_nx, INP int L_ny, t_grid_tile** L_grid, + INOUTP int *index, INP t_seg_details * seg_details) { + + /* Allocates and loads all the structures needed for fast lookups of the * + * index of an rr_node. rr_node_indices is a matrix containing the index * + * of the *first* rr_node at a given (i,j) location. */ + + int i, j, k, ofs; + t_ivec tmp; + t_type_ptr type; + + /* Alloc the lookup table */ + local_rr_graph->rr_node_indices = (t_ivec ***) my_malloc(sizeof(t_ivec **) * NUM_RR_TYPES); + local_rr_graph->rr_node_indices[IPIN] = (t_ivec **) my_malloc(sizeof(t_ivec *) * (L_nx + 2)); + local_rr_graph->rr_node_indices[SINK] = (t_ivec **) my_malloc(sizeof(t_ivec *) * (L_nx + 2)); + for (i = 0; i <= (L_nx + 1); ++i) { + local_rr_graph->rr_node_indices[IPIN][i] = (t_ivec *) my_malloc(sizeof(t_ivec) * (L_ny + 2)); + local_rr_graph->rr_node_indices[SINK][i] = (t_ivec *) my_malloc(sizeof(t_ivec) * (L_ny + 2)); + for (j = 0; j <= (L_ny + 1); ++j) { + local_rr_graph->rr_node_indices[IPIN][i][j].nelem = 0; + local_rr_graph->rr_node_indices[IPIN][i][j].list = NULL; + + local_rr_graph->rr_node_indices[SINK][i][j].nelem = 0; + local_rr_graph->rr_node_indices[SINK][i][j].list = NULL; + } + } + + /* Count indices for block nodes */ + for (i = 0; i <= (L_nx + 1); i++) { + for (j = 0; j <= (L_ny + 1); j++) { + ofs = L_grid[i][j].offset; + if (0 == ofs) { + type = L_grid[i][j].type; + + /* Load the pin class lookups. The ptc nums for SINK and SOURCE + * are disjoint so they can share the list. */ + tmp.nelem = type->num_class; + tmp.list = NULL; + if (tmp.nelem > 0) { + tmp.list = (int *) my_malloc(sizeof(int) * tmp.nelem); + for (k = 0; k < tmp.nelem; ++k) { + tmp.list[k] = *index; + ++(*index); + } + } + local_rr_graph->rr_node_indices[SINK][i][j] = tmp; + + /* Load the pin lookups. The ptc nums for IPIN and OPIN + * are disjoint so they can share the list. */ + tmp.nelem = type->num_pins; + tmp.list = NULL; + if (tmp.nelem > 0) { + tmp.list = (int *) my_malloc(sizeof(int) * tmp.nelem); + for (k = 0; k < tmp.nelem; ++k) { + tmp.list[k] = *index; + ++(*index); + } + } + local_rr_graph->rr_node_indices[IPIN][i][j] = tmp; + } + } + } + + /* Point offset blocks of a large block to base block */ + for (i = 0; i <= (L_nx + 1); i++) { + for (j = 0; j <= (L_ny + 1); j++) { + ofs = L_grid[i][j].offset; + if (ofs > 0) { + /* NOTE: this only supports vertical large blocks */ + local_rr_graph->rr_node_indices[SINK][i][j] = local_rr_graph->rr_node_indices[SINK][i][j - ofs]; + local_rr_graph->rr_node_indices[IPIN][i][j] = local_rr_graph->rr_node_indices[IPIN][i][j - ofs]; + } + } + } + + /* SOURCE and SINK have unique ptc values so their data can be shared. + * IPIN and OPIN have unique ptc values so their data can be shared. */ + local_rr_graph->rr_node_indices[SOURCE] = local_rr_graph->rr_node_indices[SINK]; + local_rr_graph->rr_node_indices[OPIN] = local_rr_graph->rr_node_indices[IPIN]; + + /* Original VPR */ + /* Load the data for x and y channels */ + load_rr_graph_chan_rr_indices(local_rr_graph, nodes_per_chan, L_nx + 1, L_ny + 1, CHANX, seg_details, + index); + load_rr_graph_chan_rr_indices(local_rr_graph, nodes_per_chan, L_ny + 1, L_nx + 1, CHANY, seg_details, + index); + /* end */ + /* mrFPGA : Xifan TANG */ + /* + load_rr_graph_chan_rr_indices(local_rr_graph, nodes_per_chan, (is_stack ? L_ny + 1 : L_nx + 1), (is_stack ? L_nx + 1 : L_ny + 1), + CHANX, seg_details, index); + load_rr_graph_chan_rr_indices(local_rr_graph, nodes_per_chan, (is_stack ? L_nx + 1 : L_ny + 1), (is_stack ? L_ny + 1 : L_nx + 1), + CHANY, seg_details, index); + */ + /* end */ + return; +} + + + +void alloc_and_load_rr_graph_switch_inf(INOUTP t_rr_graph* local_rr_graph, + int num_switch_inf, + INP t_switch_inf* switch_inf) { + local_rr_graph->num_switch_inf = num_switch_inf; + /* Allocate memory */ + local_rr_graph->switch_inf = (t_switch_inf*) my_calloc(local_rr_graph->num_switch_inf, sizeof(t_switch_inf)); + /* Create a local copy */ + memcpy(local_rr_graph->switch_inf, switch_inf, sizeof(t_switch_inf)); + + return; +} + +/* Allocate a LL_rr_node route structs for a given rr_graph + * This is function is a copy of alloc_and_load_rr_node_route_structs + * The major difference lies in removing the use of global variables + */ +void alloc_and_load_rr_graph_route_structs(t_rr_graph* local_rr_graph) { + /* Allocates some extra information about each LL_rr_node that is used only * + * during routing. */ + + int inode; + + local_rr_graph->rr_node_route_inf = (t_rr_node_route_inf *) my_malloc(local_rr_graph->num_rr_nodes * sizeof(t_rr_node_route_inf)); + + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + local_rr_graph->rr_node_route_inf[inode].prev_node = NO_PREVIOUS; + local_rr_graph->rr_node_route_inf[inode].prev_edge = NO_PREVIOUS; + local_rr_graph->rr_node_route_inf[inode].pres_cost = 1.; + local_rr_graph->rr_node_route_inf[inode].acc_cost = 1.; + local_rr_graph->rr_node_route_inf[inode].path_cost = HUGE_POSITIVE_FLOAT; + local_rr_graph->rr_node_route_inf[inode].target_flag = 0; + } + + return; +} + +t_heap * get_rr_graph_heap_head(t_rr_graph* local_rr_graph) { + + /* Returns a pointer to the smallest element on the heap, or NULL if the * + * heap is empty. Invalid (index == OPEN) entries on the heap are never * + * returned -- they are just skipped over. */ + + int ito, ifrom; + t_heap *heap_head, *temp_ptr; + + do { + if (local_rr_graph->heap_tail == 1) { /* Empty heap. */ + /* + vpr_printf(TIO_MESSAGE_WARNING, "Empty heap occurred in get_heap_head.\n"); + vpr_printf(TIO_MESSAGE_WARNING, "Some blocks are impossible to connect in this architecture.\n"); + */ + return (NULL); + } + + heap_head = local_rr_graph->heap[1]; /* Smallest element. */ + + /* Now fix up the heap */ + + local_rr_graph->heap_tail--; + local_rr_graph->heap[1] = local_rr_graph->heap[local_rr_graph->heap_tail]; + ifrom = 1; + ito = 2 * ifrom; + + while (ito < local_rr_graph->heap_tail) { + if (local_rr_graph->heap[ito + 1]->cost < local_rr_graph->heap[ito]->cost) + ito++; + if (local_rr_graph->heap[ito]->cost > local_rr_graph->heap[ifrom]->cost) + break; + temp_ptr = local_rr_graph->heap[ito]; + local_rr_graph->heap[ito] = local_rr_graph->heap[ifrom]; + local_rr_graph->heap[ifrom] = temp_ptr; + ifrom = ito; + ito = 2 * ifrom; + } + + } while (heap_head->index == OPEN); /* Get another one if invalid entry. */ + + return (heap_head); +} + +t_linked_f_pointer* alloc_rr_graph_linked_f_pointer(t_rr_graph* local_rr_graph) { + + /* This routine returns a linked list element with a float pointer as * + * the node data. */ + + /*int i;*/ + t_linked_f_pointer *temp_ptr; + + if (local_rr_graph->linked_f_pointer_free_head == NULL) { + /* No elements on the free list */ + local_rr_graph->linked_f_pointer_free_head = (t_linked_f_pointer *) my_chunk_malloc(sizeof(t_linked_f_pointer), &local_rr_graph->linked_f_pointer_ch); + local_rr_graph->linked_f_pointer_free_head->next = NULL; + } + + temp_ptr = local_rr_graph->linked_f_pointer_free_head; + local_rr_graph->linked_f_pointer_free_head = local_rr_graph->linked_f_pointer_free_head->next; + +#ifdef DEBUG + local_rr_graph->num_linked_f_pointer_allocated++; +#endif + + return (temp_ptr); +} + + +void add_to_rr_graph_mod_list(t_rr_graph* local_rr_graph, + float *fptr) { + + /* This routine adds the floating point pointer (fptr) into a * + * linked list that indicates all the pathcosts that have been * + * modified thus far. */ + + t_linked_f_pointer *mod_ptr; + + mod_ptr = alloc_rr_graph_linked_f_pointer(local_rr_graph); + + /* Add this element to the start of the modified list. */ + + mod_ptr->next = local_rr_graph->rr_modified_head; + mod_ptr->fptr = fptr; + local_rr_graph->rr_modified_head = mod_ptr; +} + +void free_rr_graph_heap_data(t_rr_graph* local_rr_graph, + t_heap *hptr) { + + hptr->u.next = local_rr_graph->heap_free_head; + local_rr_graph->heap_free_head = hptr; +#ifdef DEBUG + local_rr_graph->num_heap_allocated--; +#endif +} + +t_trace* alloc_rr_graph_trace_data(t_rr_graph* local_rr_graph) { + + t_trace *temp_ptr; + + if (local_rr_graph->trace_free_head == NULL) { /* No elements on the free list */ + local_rr_graph->trace_free_head = (t_trace *) my_chunk_malloc(sizeof(t_trace), &local_rr_graph->trace_ch); + local_rr_graph->trace_free_head->next = NULL; + } + temp_ptr = local_rr_graph->trace_free_head; + local_rr_graph->trace_free_head = local_rr_graph->trace_free_head->next; +#ifdef DEBUG + local_rr_graph->num_trace_allocated++; +#endif + return (temp_ptr); +} + +void empty_rr_graph_heap(t_rr_graph* local_rr_graph) { + + int i; + + for (i = 1; i < local_rr_graph->heap_tail; i++) + free_rr_graph_heap_data(local_rr_graph, local_rr_graph->heap[i]); + + local_rr_graph->heap_tail = 1; + + return; +} + +void reset_rr_graph_rr_node_route_structs(t_rr_graph* local_rr_graph) { + + /* Allocates some extra information about each rr_node that is used only * + * during routing. */ + + int inode; + + assert(local_rr_graph->rr_node_route_inf != NULL); + + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + local_rr_graph->rr_node_route_inf[inode].prev_node = NO_PREVIOUS; + local_rr_graph->rr_node_route_inf[inode].prev_edge = NO_PREVIOUS; + local_rr_graph->rr_node_route_inf[inode].pres_cost = 1.; + local_rr_graph->rr_node_route_inf[inode].acc_cost = 1.; + local_rr_graph->rr_node_route_inf[inode].path_cost = HUGE_POSITIVE_FLOAT; + local_rr_graph->rr_node_route_inf[inode].target_flag = 0; + } + + return; +} + + +t_trace* update_rr_graph_traceback(t_rr_graph* local_rr_graph, + t_heap *hptr, int inet) { + + /* This routine adds the most recently finished wire segment to the * + * traceback linked list. The first connection starts with the net SOURCE * + * and begins at the structure pointed to by trace_head[inet]. Each * + * connection ends with a SINK. After each SINK, the next connection * + * begins (if the net has more than 2 pins). The first element after the * + * SINK gives the routing node on a previous piece of the routing, which is * + * the link from the existing net to this new piece of the net. * + * In each traceback I start at the end of a path and trace back through * + * its predecessors to the beginning. I have stored information on the * + * predecesser of each node to make traceback easy -- this sacrificies some * + * memory for easier code maintenance. This routine returns a pointer to * + * the first "new" node in the traceback (node not previously in trace). */ + + struct s_trace *tptr, *prevptr, *temptail, *ret_ptr; + int inode; + short iedge; + +#ifdef DEBUG + t_rr_type rr_type; +#endif + + inode = hptr->index; + +#ifdef DEBUG + rr_type = local_rr_graph->rr_node[inode].type; + if (rr_type != SINK) { + vpr_printf(TIO_MESSAGE_ERROR, "in update_traceback. Expected type = SINK (%d).\n", SINK); + vpr_printf(TIO_MESSAGE_ERROR, "\tGot type = %d while tracing back net %d.\n", rr_type, inet); + exit(1); + } +#endif + + tptr = alloc_rr_graph_trace_data(local_rr_graph); /* SINK on the end of the connection */ + tptr->index = inode; + tptr->iswitch = OPEN; + tptr->next = NULL; + temptail = tptr; /* This will become the new tail at the end */ + /* of the routine. */ + + /* Now do it's predecessor. */ + + inode = hptr->u.prev_node; + iedge = hptr->prev_edge; + + while (inode != NO_PREVIOUS) { + prevptr = alloc_rr_graph_trace_data(local_rr_graph); + prevptr->index = inode; + prevptr->iswitch = local_rr_graph->rr_node[inode].switches[iedge]; + prevptr->next = tptr; + tptr = prevptr; + + iedge = local_rr_graph->rr_node_route_inf[inode].prev_edge; + inode = local_rr_graph->rr_node_route_inf[inode].prev_node; + } + + if (local_rr_graph->trace_tail[inet] != NULL) { + local_rr_graph->trace_tail[inet]->next = tptr; /* Traceback ends with tptr */ + ret_ptr = tptr->next; /* First new segment. */ + } else { /* This was the first "chunk" of the net's routing */ + local_rr_graph->trace_head[inet] = tptr; + ret_ptr = tptr; /* Whole traceback is new. */ + } + + local_rr_graph->trace_tail[inet] = temptail; + return (ret_ptr); +} + + +void reset_rr_graph_path_costs(t_rr_graph* local_rr_graph) { + + /* The routine sets the path_cost to HUGE_POSITIVE_FLOAT for all channel segments * + * touched by previous routing phases. */ + + t_linked_f_pointer *mod_ptr; + +#ifdef DEBUG + int num_mod_ptrs; +#endif + + /* The traversal method below is slightly painful to make it faster. */ + + if (local_rr_graph->rr_modified_head != NULL) { + mod_ptr = local_rr_graph->rr_modified_head; + +#ifdef DEBUG + num_mod_ptrs = 1; +#endif + + while (mod_ptr->next != NULL) { + *(mod_ptr->fptr) = HUGE_POSITIVE_FLOAT; + mod_ptr = mod_ptr->next; +#ifdef DEBUG + num_mod_ptrs++; +#endif + } + *(mod_ptr->fptr) = HUGE_POSITIVE_FLOAT; /* Do last one. */ + + /* Reset the modified list and put all the elements back in the free * + * list. */ + + mod_ptr->next = local_rr_graph->linked_f_pointer_free_head; + local_rr_graph->linked_f_pointer_free_head = local_rr_graph->rr_modified_head; + local_rr_graph->rr_modified_head = NULL; + +#ifdef DEBUG + local_rr_graph->num_linked_f_pointer_allocated -= num_mod_ptrs; +#endif + } + + return; +} + +void alloc_rr_graph_rr_indexed_data(t_rr_graph* local_rr_graph, int L_num_rr_indexed_data) { + local_rr_graph->num_rr_indexed_data = L_num_rr_indexed_data; + local_rr_graph->rr_indexed_data = (t_rr_indexed_data *) my_calloc(L_num_rr_indexed_data, sizeof(t_rr_indexed_data)); + + return; +} + +/* a copy of get_rr_cong_cost, + * I remove all the use of global variables */ +float get_rr_graph_rr_cong_cost(t_rr_graph* local_rr_graph, + int rr_node_index) { + + /* Returns the *congestion* cost of using this rr_node. */ + + short cost_index; + float cost; + + cost_index = local_rr_graph->rr_node[rr_node_index].cost_index; + cost = local_rr_graph->rr_indexed_data[cost_index].base_cost + * local_rr_graph->rr_node_route_inf[rr_node_index].acc_cost + * local_rr_graph->rr_node_route_inf[rr_node_index].pres_cost; + return (cost); +} + +t_heap * alloc_rr_graph_heap_data(t_rr_graph* local_rr_graph) { + + t_heap *temp_ptr; + + if (local_rr_graph->heap_free_head == NULL) { /* No elements on the free list */ + local_rr_graph->heap_free_head = (t_heap *) my_chunk_malloc(sizeof(t_heap), &(local_rr_graph->heap_ch)); + local_rr_graph->heap_free_head->u.next = NULL; + } + + temp_ptr = local_rr_graph->heap_free_head; + local_rr_graph->heap_free_head = local_rr_graph->heap_free_head->u.next; +#ifdef DEBUG + local_rr_graph->num_heap_allocated++; +#endif + return (temp_ptr); +} + +void add_heap_node_to_rr_graph_heap(t_rr_graph* local_rr_graph, + t_heap *hptr) { + + /* Adds an item to the heap, expanding the heap if necessary. */ + + int ito, ifrom; + t_heap *temp_ptr; + + if (local_rr_graph->heap_tail > local_rr_graph->heap_size) { /* Heap is full */ + local_rr_graph->heap_size *= 2; + local_rr_graph->heap = (t_heap **) my_realloc((void *) (local_rr_graph->heap + 1), + local_rr_graph->heap_size * sizeof(t_heap *)); + local_rr_graph->heap--; /* heap goes from [1..heap_size] */ + } + + local_rr_graph->heap[local_rr_graph->heap_tail] = hptr; + ifrom = local_rr_graph->heap_tail; + ito = ifrom / 2; + local_rr_graph->heap_tail++; + + while ((ito >= 1) && (local_rr_graph->heap[ifrom]->cost < local_rr_graph->heap[ito]->cost)) { + temp_ptr = local_rr_graph->heap[ito]; + local_rr_graph->heap[ito] = local_rr_graph->heap[ifrom]; + local_rr_graph->heap[ifrom] = temp_ptr; + ifrom = ito; + ito = ifrom / 2; + } + return; +} + + +void add_node_to_rr_graph_heap(t_rr_graph* local_rr_graph, + int inode, float cost, int prev_node, int prev_edge, + float backward_path_cost, float R_upstream) { + + /* Puts an rr_node on the heap, if the new cost given is lower than the * + * current path_cost to this channel segment. The index of its predecessor * + * is stored to make traceback easy. The index of the edge used to get * + * from its predecessor to it is also stored to make timing analysis, etc. * + * easy. The backward_path_cost and R_upstream values are used only by the * + * timing-driven router -- the breadth-first router ignores them. */ + + struct s_heap *hptr; + + if (cost >= local_rr_graph->rr_node_route_inf[inode].path_cost) { + return; + } + + hptr = alloc_rr_graph_heap_data(local_rr_graph); + hptr->index = inode; + hptr->cost = cost; + hptr->u.prev_node = prev_node; + hptr->prev_edge = prev_edge; + hptr->backward_path_cost = backward_path_cost; + hptr->R_upstream = R_upstream; + add_heap_node_to_rr_graph_heap(local_rr_graph, hptr); + + return; +} + +void mark_rr_graph_sinks(t_rr_graph* local_rr_graph, + int inet, int start_isink, boolean* net_sink_routed) { + + /* Mark all the SINKs of this net as targets by setting their target flags * + * to the number of times the net must connect to each SINK. Note that * + * this number can occassionally be greater than 1 -- think of connecting * + * the same net to two inputs of an and-gate (and-gate inputs are logically * + * equivalent, so both will connect to the same SINK). */ + + int isink, inode; + + for (isink = start_isink; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + /* Bypass routed sinks */ + if (TRUE == net_sink_routed[isink]) { + continue; + } + inode = local_rr_graph->net_rr_sinks[inet][isink]; + if (OPEN == inode) { + continue; + } + local_rr_graph->rr_node_route_inf[inode].target_flag++; + if ( ! ((local_rr_graph->rr_node_route_inf[inode].target_flag > 0) + && (local_rr_graph->rr_node_route_inf[inode].target_flag <= local_rr_graph->rr_node[inode].capacity))) { + assert((local_rr_graph->rr_node_route_inf[inode].target_flag > 0) + && (local_rr_graph->rr_node_route_inf[inode].target_flag <= local_rr_graph->rr_node[inode].capacity)); + } + } + + return; +} + +void mark_rr_graph_ends(t_rr_graph* local_rr_graph, + int inet) { + + /* Mark all the SINKs of this net as targets by setting their target flags * + * to the number of times the net must connect to each SINK. Note that * + * this number can occassionally be greater than 1 -- think of connecting * + * the same net to two inputs of an and-gate (and-gate inputs are logically * + * equivalent, so both will connect to the same SINK). */ + + int ipin, inode; + + for (ipin = 1; ipin < local_rr_graph->net_num_sinks[inet] + 1; ipin++) { + inode = local_rr_graph->net_rr_terminals[inet][ipin]; + if (inode == OPEN) { + continue; + } + local_rr_graph->rr_node_route_inf[inode].target_flag++; + assert((local_rr_graph->rr_node_route_inf[inode].target_flag > 0) + && (local_rr_graph->rr_node_route_inf[inode].target_flag <= local_rr_graph->rr_node[inode].capacity)); + } + + return; +} + +void invalidate_rr_graph_heap_entries(t_rr_graph* local_rr_graph, + int sink_node, int ipin_node) { + + /* Marks all the heap entries consisting of sink_node, where it was reached * + * via ipin_node, as invalid (OPEN). Used only by the breadth_first router * + * and even then only in rare circumstances. */ + + int i; + + for (i = 1; i < local_rr_graph->heap_tail; i++) { + if ((local_rr_graph->heap[i]->index == sink_node) + && (local_rr_graph->heap[i]->u.prev_node == ipin_node)) { + local_rr_graph->heap[i]->index = OPEN; /* Invalid. */ + } + } + + return; +} + +float get_rr_graph_rr_node_pack_intrinsic_cost(t_rr_graph* local_rr_graph, + int inode) { + /* This is a tie breaker to avoid using nodes with more edges whenever possible */ + float value; + value = local_rr_graph->rr_node[inode].pack_intrinsic_cost; + return value; +} + +/* Free rr_graph data structs */ +void free_rr_graph_rr_nodes(t_rr_graph* local_rr_graph) { + int i; + + /* Free edges and switches of all the rr_nodes */ + for (i = 0; i < local_rr_graph->num_rr_nodes; i++) { + my_free(local_rr_graph->rr_node[i].edges); + my_free(local_rr_graph->rr_node[i].switches); + my_free(local_rr_graph->rr_node[i].drive_rr_nodes); + } + /* Free the rr_node list */ + my_free(local_rr_graph->rr_node); + + return; +} + +void free_rr_graph_switch_inf(INOUTP t_rr_graph* local_rr_graph) { + + my_free(local_rr_graph->switch_inf); + + return; +} + +void free_rr_graph_route_structs(t_rr_graph* local_rr_graph) { /* [0..num_rr_nodes-1] */ + + /* Frees the extra information about each LL_rr_node that is needed only * + * during routing. */ + + free(local_rr_graph->rr_node_route_inf); + local_rr_graph->rr_node_route_inf = NULL; /* Mark as free */ + + return; +} + +void free_rr_graph_trace_data(t_rr_graph* local_rr_graph, + t_trace *tptr) { + + /* Puts the traceback structure pointed to by tptr on the free list. */ + + tptr->next = local_rr_graph->trace_free_head; + local_rr_graph->trace_free_head = tptr; +#ifdef DEBUG + local_rr_graph->num_trace_allocated--; +#endif +} + +void free_rr_graph_traceback(t_rr_graph* local_rr_graph, + int inet) { + + /* Puts the entire traceback (old routing) for this net on the free list * + * and sets the trace_head pointers etc. for the net to NULL. */ + + t_trace *tptr, *tempptr; + + if( local_rr_graph->trace_head == NULL) { + return; + } + + tptr = local_rr_graph->trace_head[inet]; + + while (tptr != NULL) { + tempptr = tptr->next; + free_rr_graph_trace_data(local_rr_graph, tptr); + tptr = tempptr; + } + + local_rr_graph->trace_head[inet] = NULL; + local_rr_graph->trace_tail[inet] = NULL; +} + +/* TODO: Fully free a rr_graph data struct */ +void free_rr_graph(t_rr_graph* local_rr_graph) { + /* Free the internal data structs one by one */ + free_rr_graph_rr_nodes(local_rr_graph); + free_rr_graph_switch_inf(local_rr_graph); + free_rr_graph_route_structs(local_rr_graph); + + return; +} + +void build_prev_node_list_rr_nodes(int LL_num_rr_nodes, + t_rr_node* LL_rr_node) { + int inode, iedge, to_node, cur; + int* cur_index = (int*)my_malloc(sizeof(int)*LL_num_rr_nodes); + + for (inode = 0; inode < LL_num_rr_nodes; inode++) { + /* Malloc */ + LL_rr_node[inode].num_drive_rr_nodes = LL_rr_node[inode].fan_in; + if (0 == LL_rr_node[inode].fan_in) { + continue; + } + LL_rr_node[inode].drive_rr_nodes = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*LL_rr_node[inode].num_drive_rr_nodes); + LL_rr_node[inode].drive_switches = (int*)my_malloc(sizeof(int)*LL_rr_node[inode].num_drive_rr_nodes); + } + /* Initialize */ + for (inode = 0; inode < LL_num_rr_nodes; inode++) { + cur_index[inode] = 0; + for (iedge = 0; iedge < LL_rr_node[inode].num_drive_rr_nodes; iedge++) { + LL_rr_node[inode].drive_rr_nodes[iedge] = NULL; + LL_rr_node[inode].drive_switches[iedge] = -1; + } + } + /* Fill */ + for (inode = 0; inode < LL_num_rr_nodes; inode++) { + for (iedge = 0; iedge < LL_rr_node[inode].num_edges; iedge++) { + to_node = LL_rr_node[inode].edges[iedge]; + cur = cur_index[to_node]; + LL_rr_node[to_node].drive_rr_nodes[cur] = &(LL_rr_node[inode]); + LL_rr_node[to_node].drive_switches[cur] = LL_rr_node[inode].switches[iedge]; + /* Update cur_index[to_node]*/ + assert(NULL != LL_rr_node[to_node].drive_rr_nodes[cur]); + cur_index[to_node]++; + } + } + /* Check */ + for (inode = 0; inode < LL_num_rr_nodes; inode++) { + assert(cur_index[inode] == LL_rr_node[inode].num_drive_rr_nodes); + } + + return; +} + +void alloc_and_load_prev_node_list_rr_graph_rr_nodes(t_rr_graph* local_rr_graph) { + build_prev_node_list_rr_nodes(local_rr_graph->num_rr_nodes, local_rr_graph->rr_node); + + return; +} + +void backannotate_rr_graph_routing_results_to_net_name(t_rr_graph* local_rr_graph) { + int inode, inet; + int next_node, iedge; + t_trace* tptr; + t_rr_type rr_type; + + /* 1st step: Set all the configurations to default. + * rr_nodes select edge[0] + */ + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + local_rr_graph->rr_node[inode].prev_node = OPEN; + /* set 0 if we want print all unused mux!!!*/ + local_rr_graph->rr_node[inode].prev_edge = OPEN; + /* Initial all the net_num*/ + local_rr_graph->rr_node[inode].net_num = OPEN; + local_rr_graph->rr_node[inode].vpack_net_num = OPEN; + } + /* + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + if (0 == local_rr_graph->rr_node[inode].num_edges) { + continue; + } + assert(0 < local_rr_graph->rr_node[inode].num_edges); + for (iedge = 0; iedge < local_rr_graph->rr_node[inode].num_edges; iedge++) { + jnode = local_rr_graph->rr_node[inode].edges[iedge]; + if (&(local_rr_graph->rr_node[inode]) == local_rr_graph->rr_node[jnode].drive_rr_nodes[0]) { + local_rr_graph->rr_node[jnode].prev_node = inode; + local_rr_graph->rr_node[jnode].prev_edge = iedge; + } + } + } + */ + /* 2nd step: With the help of trace, we back-annotate */ + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + /* + if (TRUE == local_rr_graph->net[inet]->is_global) { + continue; + } + */ + tptr = local_rr_graph->trace_head[inet]; + while (tptr != NULL) { + inode = tptr->index; + rr_type = local_rr_graph->rr_node[inode].type; + /* Net num */ + local_rr_graph->rr_node[inode].net_num = inet; + local_rr_graph->rr_node[inode].vpack_net_num = local_rr_graph->net_to_vpack_net_mapping[inet]; + /* assert(OPEN != local_rr_graph->rr_node[inode].net_num); */ + assert(OPEN != local_rr_graph->rr_node[inode].vpack_net_num); + switch (rr_type) { + case SINK: + /* Nothing should be done. This supposed to the end of a trace*/ + break; + case IPIN: + case CHANX: + case CHANY: + case OPIN: + case INTRA_CLUSTER_EDGE: + case SOURCE: + /* SINK(IO/Pad) is the end of a routing path. Should configure its prev_edge and prev_node*/ + /* We care the next rr_node, this one is driving, which we have to configure + */ + assert(NULL != tptr->next); + next_node = tptr->next->index; + assert((!(0 > next_node))&&(next_node < local_rr_graph->num_rr_nodes)); + /* Prev_node */ + local_rr_graph->rr_node[next_node].prev_node = inode; + /* Prev_edge */ + local_rr_graph->rr_node[next_node].prev_edge = OPEN; + for (iedge = 0; iedge < local_rr_graph->rr_node[inode].num_edges; iedge++) { + if (next_node == local_rr_graph->rr_node[inode].edges[iedge]) { + local_rr_graph->rr_node[next_node].prev_edge = iedge; + break; + } + } + assert(OPEN != local_rr_graph->rr_node[next_node].prev_edge); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid traceback element type.\n", + __FILE__, __LINE__); + exit(1); + } + tptr = tptr->next; + } + } + + return; +} + +int get_rr_graph_net_vpack_net_index(t_rr_graph* local_rr_graph, + int net_index) { + return local_rr_graph->net_to_vpack_net_mapping[net_index]; +} + +int get_rr_graph_net_index_with_vpack_net(t_rr_graph* local_rr_graph, + int vpack_net_index) { + int inet, ret; + int num_found = 0; + + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + if (vpack_net_index == local_rr_graph->net_to_vpack_net_mapping[inet]) { + num_found = 0; + ret = inet; + } + } + /* assert */ + assert ((0 == num_found ) || (1 == num_found)); + + return ret; +} + +void get_chan_rr_node_start_coordinate(t_rr_node* chan_rr_node, + int* x_start, int* y_start) { + assert ( (CHANX == chan_rr_node->type) + ||(CHANY == chan_rr_node->type)); + + switch (chan_rr_node->direction) { + case INC_DIRECTION: + (*x_start) = chan_rr_node->xlow; + (*y_start) = chan_rr_node->ylow; + break; + case DEC_DIRECTION: + (*x_start) = chan_rr_node->xhigh; + (*y_start) = chan_rr_node->yhigh; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File: %s [LINE%d]) Invalid direction of chan_rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + + return; +} + +void get_chan_rr_node_end_coordinate(t_rr_node* chan_rr_node, + int* x_end, int* y_end) { + assert ( (CHANX == chan_rr_node->type) + ||(CHANY == chan_rr_node->type)); + + switch (chan_rr_node->direction) { + case INC_DIRECTION: + (*x_end) = chan_rr_node->xhigh; + (*y_end) = chan_rr_node->yhigh; + break; + case DEC_DIRECTION: + (*x_end) = chan_rr_node->xlow; + (*y_end) = chan_rr_node->ylow; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File: %s [LINE%d]) Invalid direction of chan_rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + + return; +} + +int get_rr_node_wire_length(t_rr_node* src_rr_node) { + assert ( (CHANX == src_rr_node->type) + || (CHANY == src_rr_node->type)); + + return (abs(src_rr_node->xlow - src_rr_node->xhigh + src_rr_node->ylow - src_rr_node->yhigh) + 1); +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.h new file mode 100644 index 000000000..defd3e569 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.h @@ -0,0 +1,108 @@ + +void init_rr_graph(INOUTP t_rr_graph* local_rr_graph); + +void alloc_rr_graph_net_rr_sources_and_sinks(t_rr_graph* local_rr_graph); + +void alloc_rr_graph_net_rr_terminals(t_rr_graph* local_rr_graph); + +void alloc_rr_graph_route_static_structs(t_rr_graph* local_rr_graph, + int heap_size); + +void load_rr_graph_chan_rr_indices(t_rr_graph* local_rr_graph, + INP int nodes_per_chan, INP int chan_len, + INP int num_chans, INP t_rr_type type, INP t_seg_details * seg_details, + INOUTP int *index); + +void alloc_and_load_rr_graph_rr_node(INOUTP t_rr_graph* local_rr_graph, + int local_num_rr_nodes); + +void alloc_and_load_rr_graph_rr_node_indices(t_rr_graph* local_rr_graph, + INP int nodes_per_chan, + INP int L_nx, INP int L_ny, t_grid_tile** L_grid, + INOUTP int *index, INP t_seg_details * seg_details); + +void alloc_and_load_rr_graph_switch_inf(INOUTP t_rr_graph* local_rr_graph, + int num_switch_inf, + INP t_switch_inf* switch_inf); + +void alloc_and_load_rr_graph_route_structs(t_rr_graph* local_rr_graph); + +t_trace* alloc_rr_graph_trace_data(t_rr_graph* local_rr_graph); + +t_heap * get_rr_graph_heap_head(t_rr_graph* local_rr_graph); + +t_linked_f_pointer* alloc_rr_graph_linked_f_pointer(t_rr_graph* local_rr_graph); + +t_heap * alloc_rr_graph_heap_data(t_rr_graph* local_rr_graph); + +void add_to_rr_graph_mod_list(t_rr_graph* local_rr_graph, + float *fptr); + +void empty_rr_graph_heap(t_rr_graph* local_rr_graph); + +void reset_rr_graph_rr_node_route_structs(t_rr_graph* local_rr_graph); + +t_trace* update_rr_graph_traceback(t_rr_graph* local_rr_graph, + t_heap *hptr, int inet); + +void reset_rr_graph_path_costs(t_rr_graph* local_rr_graph); + +void alloc_rr_graph_rr_indexed_data(t_rr_graph* local_rr_graph, int L_num_rr_indexed_data); + +float get_rr_graph_rr_cong_cost(t_rr_graph* local_rr_graph, + int rr_node_index); + + +void add_heap_node_to_rr_graph_heap(t_rr_graph* local_rr_graph, + t_heap *hptr); + +void add_node_to_rr_graph_heap(t_rr_graph* local_rr_graph, + int inode, float cost, int prev_node, int prev_edge, + float backward_path_cost, float R_upstream); + +void mark_rr_graph_sinks(t_rr_graph* local_rr_graph, + int inet, int start_isink, boolean* net_sink_routed); + +void mark_rr_graph_ends(t_rr_graph* local_rr_graph, + int inet); + +void invalidate_rr_graph_heap_entries(t_rr_graph* local_rr_graph, + int sink_node, int ipin_node); + +float get_rr_graph_rr_node_pack_intrinsic_cost(t_rr_graph* local_rr_graph, + int inode); + +void free_rr_graph_rr_nodes(t_rr_graph* local_rr_graph); + +void free_rr_graph_switch_inf(INOUTP t_rr_graph* local_rr_graph); + +void free_rr_graph_route_structs(t_rr_graph* local_rr_graph); + +void free_rr_graph(t_rr_graph* local_rr_graph); + +void free_rr_graph_heap_data(t_rr_graph* local_rr_graph, + t_heap *hptr); + +void free_rr_graph_traceback(t_rr_graph* local_rr_graph, + int inet); + +void build_prev_node_list_rr_nodes(int LL_num_rr_nodes, + t_rr_node* LL_rr_node); + +void alloc_and_load_prev_node_list_rr_graph_rr_nodes(t_rr_graph* local_rr_graph); + +void backannotate_rr_graph_routing_results_to_net_name(t_rr_graph* local_rr_graph); + +int get_rr_graph_net_vpack_net_index(t_rr_graph* local_rr_graph, + int net_index); + +int get_rr_graph_net_index_with_vpack_net(t_rr_graph* local_rr_graph, + int vpack_net_index); + +void get_chan_rr_node_start_coordinate(t_rr_node* chan_rr_node, + int* x_start, int* y_start); + +void get_chan_rr_node_end_coordinate(t_rr_node* chan_rr_node, + int* x_end, int* y_end); + +int get_rr_node_wire_length(t_rr_node* src_rr_node); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_setup.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c similarity index 88% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_setup.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c index 419d8eee8..8c828ac71 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_setup.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c @@ -20,15 +20,18 @@ #include "vpr_utils.h" #include "path_delay.h" #include "stats.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_timing_utils.h" -#include "fpga_spice_backannotate_utils.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_timing_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_pbtypes_utils.h" #include "verilog_api.h" -#include "fpga_spice_setup.h" +#include "fpga_x2p_setup.h" /***** Subroutines Declarations *****/ static @@ -152,49 +155,30 @@ void match_pb_types_spice_model_rec(t_pb_type* cur_pb_type, return; } - /* If there is a spice_model_name, this is a leaf node!*/ - if (NULL != cur_pb_type->spice_model_name) { + /* If there is a spice_model_name or refer to a physical pb type , this is a leaf node!*/ + if ((NULL != cur_pb_type->spice_model_name) || (NULL != cur_pb_type->physical_pb_type_name)) { /* What annoys me is VPR create a sub pb_type for each lut which suppose to be a leaf node * This may bring software convience but ruins SPICE modeling */ + /* if this is not a physical pb_type, we do not care the spice model name and associated checking */ + if (NULL != cur_pb_type->physical_pb_type_name) { + vpr_printf(TIO_MESSAGE_INFO, "(File:%s,LINE[%d]) Bypass spice model checking for pb_type(%s)!\n", + __FILE__, __LINE__, cur_pb_type->name); + return; + } /* Let's find a matched spice model!*/ printf("INFO: matching cur_pb_type=%s with spice_model_name=%s...\n",cur_pb_type->name, cur_pb_type->spice_model_name); assert(NULL == cur_pb_type->spice_model); cur_pb_type->spice_model = find_name_matched_spice_model(cur_pb_type->spice_model_name, num_spice_model, spice_models); if (NULL == cur_pb_type->spice_model) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Fail to find a defined SPICE model called %s, in pb_type(%s)!\n",__FILE__, __LINE__, cur_pb_type->spice_model_name, cur_pb_type->name); + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,LINE[%d]) Fail to find a defined SPICE model called %s, in pb_type(%s)!\n", + __FILE__, __LINE__, cur_pb_type->spice_model_name, cur_pb_type->name); exit(1); } /* Map pb_type ports to SPICE model ports*/ map_pb_type_port_to_spice_model_ports(cur_pb_type,cur_pb_type->spice_model); return; - } else { - /* Find default spice model if this is a primitive block */ - if (LUT_CLASS == cur_pb_type->class_type) { - cur_pb_type->spice_model = get_default_spice_model(SPICE_MODEL_LUT, num_spice_model, spice_models); - /* Complete the name */ - cur_pb_type->spice_model_name = my_strdup(cur_pb_type->spice_model->name); - if (NULL == cur_pb_type->spice_model) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Fail to find a defined SPICE model called %s, in pb_type(%s)!\n",__FILE__, __LINE__, cur_pb_type->spice_model_name, cur_pb_type->name); - exit(1); - } - /* Map pb_type ports to SPICE model ports*/ - map_pb_type_port_to_spice_model_ports(cur_pb_type,cur_pb_type->spice_model); - return; - } else if (LATCH_CLASS == cur_pb_type->class_type) { - cur_pb_type->spice_model = get_default_spice_model(SPICE_MODEL_FF, num_spice_model, spice_models); - /* Complete the name */ - cur_pb_type->spice_model_name = my_strdup(cur_pb_type->spice_model->name); - if (NULL == cur_pb_type->spice_model) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d]) Fail to find a defined SPICE model called %s, in pb_type(%s)!\n",__FILE__, __LINE__, cur_pb_type->spice_model_name, cur_pb_type->name); - exit(1); - } - /* Map pb_type ports to SPICE model ports*/ - map_pb_type_port_to_spice_model_ports(cur_pb_type,cur_pb_type->spice_model); - return; - } } - /* Traversal the hierarchy*/ for (imode = 0; imode < cur_pb_type->num_modes; imode++) { /* Task 1: Find the interconnections and match the spice_model */ @@ -219,11 +203,23 @@ void match_pb_types_spice_model_rec(t_pb_type* cur_pb_type, } else { cur_pb_type->modes[imode].interconnect[jinterc].spice_model = get_default_spice_model(SPICE_MODEL_MUX,num_spice_model,spice_models); + if (NULL != cur_pb_type->modes[imode].interconnect[jinterc].loop_breaker_string) { + if (NULL == cur_pb_type->modes[imode].interconnect[jinterc].spice_model->input_buffer) { + vpr_printf(TIO_MESSAGE_INFO,"Line[%d] Cannot disable an interconnect without input buffering", + cur_pb_type->modes[imode].interconnect[jinterc].line_num); + } + } } break; case MUX_INTERC: cur_pb_type->modes[imode].interconnect[jinterc].spice_model = get_default_spice_model(SPICE_MODEL_MUX,num_spice_model,spice_models); + if (NULL != cur_pb_type->modes[imode].interconnect[jinterc].loop_breaker_string) { + if (NULL == cur_pb_type->modes[imode].interconnect[jinterc].spice_model->input_buffer) { + vpr_printf(TIO_MESSAGE_INFO,"Line[%d] Cannot disable an interconnect without input buffering", + cur_pb_type->modes[imode].interconnect[jinterc].line_num); + } + } break; default: break; @@ -262,6 +258,12 @@ void match_pb_types_spice_model_rec(t_pb_type* cur_pb_type, exit(1); } } + if (NULL != cur_pb_type->modes[imode].interconnect[jinterc].loop_breaker_string) { + if (NULL == cur_pb_type->modes[imode].interconnect[jinterc].spice_model->input_buffer) { + vpr_printf(TIO_MESSAGE_INFO,"Line[%d] Cannot disable an interconnect without input buffering", + cur_pb_type->modes[imode].interconnect[jinterc].line_num); + } + } break; case MUX_INTERC: if (SPICE_MODEL_MUX != cur_pb_type->modes[imode].interconnect[jinterc].spice_model->type) { @@ -269,6 +271,12 @@ void match_pb_types_spice_model_rec(t_pb_type* cur_pb_type, __FILE__, __LINE__, cur_pb_type->modes[imode].interconnect[jinterc].spice_model_name, cur_pb_type->name); exit(1); } + if (NULL != cur_pb_type->modes[imode].interconnect[jinterc].loop_breaker_string) { + if (NULL == cur_pb_type->modes[imode].interconnect[jinterc].spice_model->input_buffer) { + vpr_printf(TIO_MESSAGE_INFO,"Line[%d] Cannot disable an interconnect without input buffering", + cur_pb_type->modes[imode].interconnect[jinterc].line_num); + } + } break; default: break; @@ -600,14 +608,94 @@ void init_check_arch_spice_models(t_arch* arch, } } - /* 7. Create timing graph for spice models */ - for (i = 0; i < arch->spice->num_spice_model; i++) { - /* See if we need a timing graph */ - if (0 == arch->spice->spice_models[i].num_delay_info) { - continue; - } - annotate_spice_model_timing(&(arch->spice->spice_models[i])); - } + /* 7. Create timing graph for spice models */ + for (i = 0; i < arch->spice->num_spice_model; i++) { + /* See if we need a timing graph */ + if (0 == arch->spice->spice_models[i].num_delay_info) { + continue; + } + annotate_spice_model_timing(&(arch->spice->spice_models[i])); + } + + return; +} + +/* Recursively traverse pb_type graph and mark idle mode + * Only one idle mode is allowed under each pb_type + */ +static +void rec_identify_pb_type_idle_mode(t_pb_type* cur_pb_type) { + int imode, ichild, idle_mode_idx; + + /* Do it only when we have modes */ + if ( 0 < cur_pb_type->num_modes) { + /* Find idle mode index */ + idle_mode_idx = find_pb_type_idle_mode_index(*cur_pb_type); + cur_pb_type->modes[idle_mode_idx].define_idle_mode = TRUE; + return; + } + + /* Traverse all the modes for identifying idle mode */ + for (imode = 0; cur_pb_type->num_modes; imode++) { + /* Check each pb_type_child */ + for (ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ichild++) { + rec_identify_pb_type_idle_mode(&(cur_pb_type->modes[imode].pb_type_children[ichild])); + } + } + + return; +} + + +/* Recursively traverse pb_type graph and mark idle and physical mode + * Only one idle mode and one physical mode is allowed under each pb_type + * In particular, a physical mode should appear only when its parent is a physical mode. + */ +static +void rec_identify_pb_type_phy_mode(t_pb_type* cur_pb_type) { + int imode, ichild, phy_mode_idx; + + /* Only try to find physical mode when parent is a physical mode or this is the top cur_pb_type! */ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + if ((NULL == cur_pb_type->parent_mode) + || (TRUE == cur_pb_type->parent_mode->define_physical_mode)) { + /* Find physical mode index */ + phy_mode_idx = find_pb_type_physical_mode_index(*cur_pb_type); + cur_pb_type->modes[phy_mode_idx].define_physical_mode = TRUE; + } else { + /* The parent must not be a physical mode*/ + assert (FALSE == cur_pb_type->parent_mode->define_physical_mode); + phy_mode_idx = -1; + /* Traverse all the modes for identifying idle mode */ + for (imode = 0; cur_pb_type->num_modes; imode++) { + cur_pb_type->modes[imode].define_physical_mode = FALSE; + } + } + return; + } + + /* Traverse all the modes for identifying idle mode */ + for (imode = 0; cur_pb_type->num_modes; imode++) { + /* Check each pb_type_child */ + for (ichild = 0; ichild < cur_pb_type->modes[imode].num_pb_type_children; ichild++) { + rec_identify_pb_type_phy_mode(&(cur_pb_type->modes[imode].pb_type_children[ichild])); + } + } + + return; +} + +/* Identify physical mode of pb_types in each defined complex block */ +static +void init_check_arch_pb_type_idle_and_phy_mode(t_arch* Arch) { + int itype; + + for (itype = 0; itype < num_types; itype++) { + if (type_descriptors[itype].pb_type) { + rec_identify_pb_type_idle_mode(type_descriptors[itype].pb_type); + rec_identify_pb_type_phy_mode(type_descriptors[itype].pb_type); + } + } return; } @@ -667,9 +755,9 @@ void rec_add_pb_type_keywords_to_list(t_pb_type* cur_pb_type, if (NULL == cur_pb_type->modes[imode].pb_type_children[jpb].spice_model) { rec_add_pb_type_keywords_to_list(&(cur_pb_type->modes[imode].pb_type_children[jpb]), cur, keywords, pass_on_prefix); - my_free(pass_on_prefix); } } + my_free(pass_on_prefix); } } @@ -872,7 +960,6 @@ void check_keywords_conflict(t_arch Arch) { static t_llist* check_and_add_one_global_port_to_llist(t_llist* old_head, t_spice_model_port* candidate_port) { - boolean is_new_global_port = TRUE; t_llist* temp = old_head; t_llist* new_head = NULL; @@ -880,7 +967,6 @@ t_llist* check_and_add_one_global_port_to_llist(t_llist* old_head, if (0 == strcmp(candidate_port->prefix, ((t_spice_model_port*)(temp->dptr))->prefix) ) { /* Find a same global port name, we do nothing, return directly */ - is_new_global_port = FALSE; return old_head; } /* Go to the next */ @@ -1167,8 +1253,7 @@ int check_and_rename_logical_block_and_net_names(t_llist* LL_reserved_syntax_cha fprintf(fp, "-------VPACK_NET renaming report END ----------\n"); if ((0 < num_violations) && ( FALSE == rename_illegal_port )) { - vpr_printf(TIO_MESSAGE_ERROR, "Detect %d port violate syntax rules while renaming port is disabled\n", num_violations); - exit(1); + vpr_printf(TIO_MESSAGE_WARNING, "Detect %d port violate syntax rules while renaming port is disabled\n", num_violations); } /* close fp */ @@ -1209,16 +1294,16 @@ void spice_net_info_add_density_weight(float signal_density_weight) { } } -void fpga_spice_free(t_arch* Arch) { +void fpga_x2p_free(t_arch* Arch) { /* Free index low and high */ free_spice_model_grid_index_low_high(Arch->spice->num_spice_model, Arch->spice->spice_models); free_spice_model_routing_index_low_high(Arch->spice->num_spice_model, Arch->spice->spice_models); } /* Top-level function of FPGA-SPICE setup */ -void fpga_spice_setup(t_vpr_setup vpr_setup, +void fpga_x2p_setup(t_vpr_setup vpr_setup, t_arch* Arch) { - + int num_rename_violation = 0; int num_clocks = 0; float vpr_crit_path_delay = 0.; float vpr_clock_freq = 0.; @@ -1230,6 +1315,9 @@ void fpga_spice_setup(t_vpr_setup vpr_setup, /* Initialize Arch SPICE MODELS*/ init_check_arch_spice_models(Arch, &(vpr_setup.RoutingArch)); + /* Initialize idle mode and physical mode of each pb_type and pb_graph_node */ + init_check_arch_pb_type_idle_and_phy_mode(Arch); + /* Create and initialize a linked list for global ports */ global_ports_head = init_llist_global_ports(Arch->spice); vpr_printf(TIO_MESSAGE_INFO, "Detect %d global ports...\n", @@ -1248,41 +1336,60 @@ void fpga_spice_setup(t_vpr_setup vpr_setup, reserved_syntax_char_head); - /* Check and rename io names to avoid violating SPICE or Verilog syntax */ + /* Check and rename io names to avoid violating SPICE or Verilog syntax + * Only valid when Verilog generator or SPICE generator is enabled + */ + num_rename_violation = check_and_rename_logical_block_and_net_names(reserved_syntax_char_head, vpr_setup.FileNameOpts.CircuitName, vpr_setup.FPGA_SPICE_Opts.rename_illegal_port, num_logical_blocks, logical_block, num_nets, clb_net, num_logical_nets, vpack_net); - - /* Check Activity file is valid */ - if (TRUE == vpr_setup.FPGA_SPICE_Opts.read_act_file) { - if (1 == try_access_file(vpr_setup.FileNameOpts.ActFile)) { - vpr_printf(TIO_MESSAGE_ERROR,"Activity file (%s) does not exists! Please provide a valid file path!\n", - vpr_setup.FileNameOpts.ActFile); - exit(1); - } else { - vpr_printf(TIO_MESSAGE_INFO,"Check Activity file (%s) is a valid file path!\n", - vpr_setup.FileNameOpts.ActFile); - } + /* Violation is not allowed for SPICE and Verilog Generator! */ + if (((0 < num_rename_violation) && (FALSE == vpr_setup.FPGA_SPICE_Opts.rename_illegal_port)) + && ((TRUE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice) + || (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog))) { + vpr_printf(TIO_MESSAGE_ERROR, "Port name syntax violations is not allowed for SPICE and Verilog Generators!\n"); + exit(1); } /* Update global options: * 1. run_parasitic_net_estimation * 2. run_testbench_load_extraction */ - if (TRUE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation_off) { + run_parasitic_net_estimation = TRUE; + if (FALSE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation) { run_parasitic_net_estimation = FALSE; } - if (TRUE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_testbench_load_extraction_off) { + + run_testbench_load_extraction = TRUE; + if (FALSE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_testbench_load_extraction) { run_testbench_load_extraction = FALSE; vpr_printf(TIO_MESSAGE_WARNING, "SPICE testbench load extraction is turned off...Accuracy loss may be expected!\n"); } + /* Check Activity file is valid */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.read_act_file) { + if (1 == try_access_file(vpr_setup.FileNameOpts.ActFile)) { + vpr_printf(TIO_MESSAGE_ERROR,"Activity file (%s) does not exists! Please provide a valid file path!\n", + vpr_setup.FileNameOpts.ActFile); + exit(1); + } else { + vpr_printf(TIO_MESSAGE_INFO,"Check Activity file (%s) is a valid file path!\n", + vpr_setup.FileNameOpts.ActFile); + } + } + /* Backannotation for post routing information */ spice_backannotate_vpr_post_route_info(vpr_setup.RoutingArch, - vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation_off); + vpr_setup.FPGA_SPICE_Opts.read_act_file, + vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation); + + /* Not should be done when read_act_file is disabled */ + if (FALSE == vpr_setup.FPGA_SPICE_Opts.read_act_file) { + return; + } /* Auto check the density and recommend sim_num_clock_cylce */ vpr_crit_path_delay = get_critical_path_delay()/1e9; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_setup.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.h similarity index 71% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_setup.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.h index 2a375c0c5..63d6949ea 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_setup.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.h @@ -4,7 +4,7 @@ void init_check_arch_spice_models(t_arch* arch, void check_keywords_conflict(t_arch Arch); -void fpga_spice_free(t_arch* Arch); +void fpga_x2p_free(t_arch* Arch); -void fpga_spice_setup(t_vpr_setup vpr_setup, +void fpga_x2p_setup(t_vpr_setup vpr_setup, t_arch* Arch); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_timing_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c similarity index 99% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_timing_utils.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c index 311d1c968..db867daa1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_timing_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c @@ -28,8 +28,8 @@ /* Include SPICE support headers*/ #include "quicksort.h" #include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" /* Build the list of spice_model_ports provided in the cur_spice_model delay_info */ t_spice_model_port** get_spice_model_delay_info_ports(t_spice_model* cur_spice_model, @@ -41,7 +41,7 @@ t_spice_model_port** get_spice_model_delay_info_ports(t_spice_model* cur_spice_m t_spice_model_port** port = NULL; /* Get input ports */ - tokens = my_strtok(port_list, " ", &num_token); + tokens = fpga_spice_strtok(port_list, " ", &num_token); /* allocate in_port */ port = (t_spice_model_port**) my_malloc(sizeof(t_spice_model_port*) * num_token); /* Find corresponding spice_model_port */ diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_timing_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_timing_utils.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.h diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_types.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_types.h new file mode 100644 index 000000000..6a53c32c9 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_types.h @@ -0,0 +1,137 @@ +/* Define the basic data structures used for FPGA-SPICE */ + +/* Default ID of switch used in rr_node */ +#define DEFAULT_SWITCH_ID 0 + +/* Default prev_node ID of a rr_node */ +#define DEFAULT_PREV_NODE -1 + +/* Default path ID of a unused multiplexer */ +#define DEFAULT_PATH_ID -1 + +/* Default path ID of a unused multiplexer when there are no constant inputs*/ +#define DEFAULT_MUX_PATH_ID 0 + +/* Index of logical block indicating a wired LUT */ +#define WIRED_LUT_LOGICAL_BLOCK_ID -2 + +#define BLIF_LUT_KEYWORD "names" + +/* Mode Index of a LUT: + * 0 indicates a wired mode (a buffer) + * 0 indicates a regular mode (a buffer) + */ +#define WIRED_LUT_MODE_INDEX 0 +#define NORMAL_LUT_MODE_INDEX 1 + +/* Key data structure for router: routing resource graph + * This data structure store the key parameters that + * models a routing resource graph used by router. + * 1. number of routing resource nodes in the graph + * 2. all the routing resource nodes + * 3. router information for each routing resource node + */ +typedef struct fpga_spice_rr_graph t_rr_graph; +struct fpga_spice_rr_graph { + /* Routing Resource nodes */ + int num_rr_nodes; + t_rr_node* rr_node; + t_ivec*** rr_node_indices; + + /* Switches between routing resource nodes */ + int num_switch_inf; + t_switch_inf* switch_inf; + int delayless_switch_index; + + int num_nets; /* number of nets to route */ + t_net** net; /* nets to route, this is pointer to the existing nets */ + int* net_to_vpack_net_mapping; + int* net_num_sources; + int* net_num_sinks; + + /* Gives the rr_node indices of net terminals. */ + int **net_rr_sources; /* [0..num_nets-1][0..num_pins-1] */ + int **net_rr_sinks; /* [0..num_nets-1][0..num_pins-1] */ + int **net_rr_terminals; /* [0..num_nets-1][0..num_pins-1] */ + t_chunk rr_mem_ch; + + /* Routing statisitics */ + int num_rr_indexed_data; + t_rr_indexed_data *rr_indexed_data; /* [0..(num_rr_indexed_data-1)] */ + + t_rr_node_route_inf* rr_node_route_inf; + t_bb *route_bb; /* [0..num_nets-1]. Limits area in which each */ + + /* Linked list start pointers. Define the routing. */ + t_trace **trace_head; /* [0..(num_nets-1)] */ + t_trace **trace_tail; /* [0..(num_nets-1)] */ + t_trace *trace_free_head; + t_chunk trace_ch; + + /**************** Static variables local to route_common.c ******************/ + t_heap **heap; /* Indexed from [1..heap_size] */ + int heap_size; /* Number of slots in the heap array */ + int heap_tail; /* Index of first unused slot in the heap array */ + + /* For managing my own list of currently free heap data structures. */ + t_heap *heap_free_head; + /* For keeping track of the sudo malloc memory for the heap*/ + t_chunk heap_ch; + + t_linked_f_pointer *rr_modified_head; + t_linked_f_pointer *linked_f_pointer_free_head; + + t_chunk linked_f_pointer_ch; + + #ifdef DEBUG + int num_trace_allocated; /* To watch for memory leaks. */ + int num_heap_allocated; + int num_linked_f_pointer_allocated; + #endif + +}; + +/* Key data structure for physical pb + * This data structure store the key parameters that + * models a physical_pb. + * This is a simplified copy of original t_pb + * except the rr_graph part + */ +typedef struct fpga_spice_phy_pb t_phy_pb; +struct fpga_spice_phy_pb { + char *name; /* Name of this physical block */ + t_pb_graph_node *pb_graph_node; /* pointer to pb_graph_node this pb corresponds to */ + int num_logical_blocks; + int* logical_block; /* If this is a terminating pb, gives the logical (netlist) block that it contains */ + boolean* is_wired_lut; /* Specify if this is a wired LUT (used as buffer) */ + t_pb_graph_pin** lut_output_pb_graph_pin; + int* lut_size; + + int mode; /* mode that this pb is set to */ + char* mode_bits; /* Mode bits for the logical block */ + + t_phy_pb **child_pbs; /* children pbs attached to this pb [0..num_child_pb_types - 1][0..child_type->num_pb - 1] */ + t_phy_pb *parent_pb; /* pointer to parent node */ + + /* Xifan TANG: FPGA-SPICE*/ + t_rr_graph* rr_graph; + /* END */ + t_phy_pb **rr_node_to_pb_mapping; /* [0..num_local_rr_nodes-1] pointer look-up of which pb this rr_node belongs based on index, NULL if pb does not exist */ + + int *lut_pin_remap; /* [0..num_lut_inputs-1] applies only to LUT primitives, stores how LUT inputs were swapped during CAD flow, + LUT inputs can be swapped by changing the logic in the LUT, this is useful because the fastest LUT input compared to the slowest is often significant (2-5x), + so this optimization is crucial for handling LUT based FPGAs. + */ + + /* Xifan TANG: SPICE model support*/ + char* spice_name_tag; + + /* Xifan TANG: FPGA-SPICE and SynVerilog */ + int num_reserved_conf_bits; + int num_conf_bits; + int num_mode_bits; + int num_inpads; + int num_outpads; + int num_iopads; +}; + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c new file mode 100644 index 000000000..b76bf91d2 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c @@ -0,0 +1,3514 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" + +/* Include SPICE support headers*/ +#include "quicksort.h" +#include "linkedlist.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" + +enum e_dir_err { + E_DIR_NOT_EXIST, + E_EXIST_BUT_NOT_DIR, + E_DIR_EXIST +}; + +/***** Subroutines *****/ +char* my_gettime() { + time_t current_time; + char* c_time_string; + + /* Obtain current time as seconds elapsed since the Epoch*/ + current_time = time(NULL); + + if (current_time == ((time_t)-1)) { + vpr_printf(TIO_MESSAGE_ERROR,"Failure to compute the current time.\n"); + exit(1); + } + + /* Convert to local time format*/ + c_time_string = ctime(¤t_time); + if (NULL == c_time_string) { + vpr_printf(TIO_MESSAGE_ERROR,"Failure to convert the current time.\n"); + exit(1); + } + /* Return it*/ + return c_time_string; +} + +char* format_dir_path(char* dir_path) { + int len = strlen(dir_path); /* String length without the last "\0"*/ + int i; + char* ret = (char*)my_malloc(sizeof(char)*(len+2)); + + strcpy(ret,dir_path); + /* Replace all the "\" to "/"*/ + for (i=0; i -1; i--) { + if (split_token == local_copy[i]) { + split_pos = i; + break; + } + } + + /* Get the path and prog_name*/ + if (-1 == split_pos) { + /* In this case, the prog_path actually contains only the program name*/ + path = my_strdup("./");; + prog_name = my_strdup(local_copy); + } else if (len == split_pos) { + /* In this case the progrom name is NULL... actually the prog_path is a directory*/ + path = my_strdup(local_copy); + prog_name = NULL; + } else { + /* We have to split it!*/ + local_copy[split_pos] = '\0'; + path = my_strdup(local_copy); + prog_name = my_strdup(local_copy + split_pos + 1); + } + + /*Copy it to the return*/ + (*ret_path) = my_strdup(path); + (*ret_prog_name) = my_strdup(prog_name); + + /* Free useless resources */ + my_free(local_copy); + my_free(path); + my_free(prog_name); + + return 1; +} + +char* chomp_file_name_postfix(char* file_name) { + char* ret = NULL; + char* postfix = NULL; + + split_path_prog_name(file_name, '.', &ret, &postfix); + + my_free(postfix); + + return ret; +} + + +/* Print SRAM bits, typically in a comment line */ +void fprint_commented_sram_bits(FILE* fp, + int num_sram_bits, int* sram_bits) { + int i; + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d]) FileHandle is NULL!\n",__FILE__,__LINE__); + exit(1); + } + + for (i = 0; i < num_sram_bits; i++) { + fprintf(fp, "%d", sram_bits[i]); + } + + return; +} + + +/* With a given spice_model_name, find the spice model and return its pointer + * If we find nothing, return NULL + */ +t_spice_model* find_name_matched_spice_model(char* spice_model_name, + int num_spice_model, + t_spice_model* spice_models) { + t_spice_model* ret = NULL; + int imodel; + int num_found = 0; + + for (imodel = 0; imodel < num_spice_model; imodel++) { + if (0 == strcmp(spice_model_name, spice_models[imodel].name)) { + ret = &(spice_models[imodel]); + num_found++; + } + } + + if (0 == num_found) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d])Fail to find a spice model match name: %s !\n", + __FILE__ ,__LINE__, spice_model_name); + exit(1); + } + + assert(1 == num_found); + + return ret; +} + +/* Get the default spice_model*/ +t_spice_model* get_default_spice_model(enum e_spice_model_type default_spice_model_type, + int num_spice_model, + t_spice_model* spice_models) { + t_spice_model* ret = NULL; + int i; + + for (i = 0; i < num_spice_model; i++) { + /* Find a MUX and it is set as default*/ + if ((default_spice_model_type == spice_models[i].type)&&(1 == spice_models[i].is_default)) { + /* Check if we have multiple default*/ + if (NULL != ret) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,LINE[%d])Both SPICE model(%s and %s) are set as default!\n", + __FILE__, __LINE__, ret->name, spice_models[i].name); + exit(1); + } else { + ret = &(spice_models[i]); + } + } + } + + return ret; +} + +/* Tasks: + * 1. Search the inv_spice_model_name of each ports of a spice_model + * 2. Copy the information from inverter spice model to higher level spice_models + */ +void config_spice_model_port_inv_spice_model(int num_spice_models, + t_spice_model* spice_model) { + int i, iport; + t_spice_model* inv_spice_model = NULL; + + for (i = 0; i < num_spice_models; i++) { + /* By pass inverters and buffers */ + if (SPICE_MODEL_INVBUF == spice_model[i].type) { + continue; + } + for (iport = 0; iport < spice_model[i].num_port; iport++) { + /* Now we bypass non BL/WL ports */ + if ((SPICE_MODEL_PORT_BL != spice_model[i].ports[iport].type) + && (SPICE_MODEL_PORT_BLB != spice_model[i].ports[iport].type) + && (SPICE_MODEL_PORT_WL != spice_model[i].ports[iport].type) + && (SPICE_MODEL_PORT_WLB != spice_model[i].ports[iport].type)) { + continue; + } + if (NULL == spice_model[i].ports[iport].inv_spice_model_name) { + inv_spice_model = get_default_spice_model(SPICE_MODEL_INVBUF, + num_spice_models, spice_model); + } else { + inv_spice_model = find_name_matched_spice_model(spice_model[i].ports[iport].inv_spice_model_name, + num_spice_models, spice_model); + /* We should find a buffer spice_model*/ + if (NULL == inv_spice_model) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find inv_spice_model to the port(name=%s) of spice_model(name=%s)!\n", + __FILE__, __LINE__, spice_model[i].ports[iport].prefix, spice_model[i].name); + exit(1); + } + } + /* Config */ + spice_model[i].ports[iport].inv_spice_model = inv_spice_model; + } + } + return; +} + +/* Find a spice model port by given name */ +t_spice_model_port* find_spice_model_port_by_name(t_spice_model* cur_spice_model, + char* port_name) { + int iport; + t_spice_model_port* port = NULL; + int cnt = 0; + + for (iport = 0; iport < cur_spice_model->num_port; iport++) { + if (0 == strcmp(cur_spice_model->ports[iport].prefix, port_name)) { + port = &(cur_spice_model->ports[iport]); + cnt++; + } + } + + assert ((0 == cnt) || (1 == cnt)); + + return port; +} + +void config_one_spice_model_buffer(int num_spice_models, + t_spice_model* spice_model, + t_spice_model* cur_spice_model, + t_spice_model_buffer* cur_spice_model_buffer) { + t_spice_model* buf_spice_model = NULL; + char* location_map = NULL; + + /* Check if this spice model has input buffers */ + if (1 == cur_spice_model_buffer->exist) { + buf_spice_model = find_name_matched_spice_model(cur_spice_model_buffer->spice_model_name, + num_spice_models, spice_model); + /* We should find a buffer spice_model*/ + if (NULL == buf_spice_model) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find inv/buffer spice_model to the input buffer of spice_model(name=%s)!\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + /* Backup location map */ + location_map = cur_spice_model_buffer->location_map; + /* Copy the information from found spice model to current spice model*/ + memcpy(cur_spice_model_buffer, buf_spice_model->design_tech_info.buffer_info, sizeof(t_spice_model_buffer)); + /* Recover the spice_model_name and exist */ + cur_spice_model_buffer->exist = 1; + cur_spice_model_buffer->spice_model_name = my_strdup(buf_spice_model->name); + cur_spice_model_buffer->spice_model = buf_spice_model; + cur_spice_model_buffer->location_map = location_map; + } + + return; +} + +/* Tasks: + * 1. Search the spice_model_name of input and output buffer and link to the spice_model + * 2. Copy the information from input/output buffer spice model to higher level spice_models + */ +void config_spice_model_input_output_buffers_pass_gate(int num_spice_models, + t_spice_model* spice_model) { + int i; + t_spice_model* inv_spice_model = NULL; + t_spice_model* buf_spice_model = NULL; + t_spice_model* pgl_spice_model = NULL; + + for (i = 0; i < num_spice_models; i++) { + /* By pass inverters and buffers */ + if (SPICE_MODEL_INVBUF == spice_model[i].type) { + continue; + } + + /* Check if this spice model has input buffers */ + config_one_spice_model_buffer(num_spice_models, spice_model, + &(spice_model[i]), spice_model[i].input_buffer); + + /* Check if this spice model has output buffers */ + config_one_spice_model_buffer(num_spice_models, spice_model, + &(spice_model[i]), spice_model[i].output_buffer); + + /* If this spice_model is a LUT, check the lut_input_buffer */ + if (SPICE_MODEL_LUT == spice_model[i].type) { + assert(1 == spice_model[i].lut_input_buffer->exist); + assert(1 == spice_model[i].lut_input_inverter->exist); + + config_one_spice_model_buffer(num_spice_models, spice_model, + &(spice_model[i]), spice_model[i].lut_input_buffer); + + config_one_spice_model_buffer(num_spice_models, spice_model, + &(spice_model[i]), spice_model[i].lut_input_inverter); + + config_one_spice_model_buffer(num_spice_models, spice_model, + &(spice_model[i]), spice_model[i].lut_intermediate_buffer); + } + + + /* Check pass_gate logic only for LUT and MUX */ + if ((SPICE_MODEL_LUT == spice_model[i].type) + ||(SPICE_MODEL_MUX == spice_model[i].type)) { + pgl_spice_model = find_name_matched_spice_model(spice_model[i].pass_gate_logic->spice_model_name, + num_spice_models, spice_model); + /* We should find a buffer spice_model*/ + if (NULL == pgl_spice_model) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to find pass_gate spice_model to the pass_gate_logic of spice_model(name=%s)!\n", + __FILE__, __LINE__, spice_model[i].name); + exit(1); + } + /* Copy the information from found spice model to current spice model*/ + memcpy(spice_model[i].pass_gate_logic, pgl_spice_model->design_tech_info.pass_gate_info, sizeof(t_spice_model_pass_gate_logic)); + /* Recover the spice_model_name */ + spice_model[i].pass_gate_logic->spice_model_name = my_strdup(pgl_spice_model->name); + spice_model[i].pass_gate_logic->spice_model = pgl_spice_model; + } + } + + return; +} + +/* Return the SPICE model ports wanted + * ATTENTION: we use the pointer of spice model here although we don't modify anything of spice_model + * but we have return input ports, whose pointer will be lost if the input is not the pointor of spice_model + * BECAUSE spice_model will be a local copy if it is not a pointer. And it will be set free when this function + * finishes. So the return pointers become invalid ! + */ +t_spice_model_port** find_spice_model_ports(t_spice_model* spice_model, + enum e_spice_model_port_type port_type, + int* port_num, boolean ignore_global_port) { + int iport, cur; + t_spice_model_port** ret = NULL; + + /* Check codes*/ + assert(NULL != port_num); + assert(NULL != spice_model); + + /* Count the number of ports that match*/ + (*port_num) = 0; + for (iport = 0; iport < spice_model->num_port; iport++) { + /* ignore global port if user specified */ + if ((TRUE == ignore_global_port) + &&(TRUE == spice_model->ports[iport].is_global)) { + continue; + } + if (port_type == spice_model->ports[iport].type) { + (*port_num)++; + } + } + + /* Initial the return pointers*/ + ret = (t_spice_model_port**)my_malloc(sizeof(t_spice_model_port*)*(*port_num)); + memset(ret, 0 , sizeof(t_spice_model_port*)*(*port_num)); + + /* Fill the return pointers*/ + cur = 0; + for (iport = 0; iport < spice_model->num_port; iport++) { + /* ignore global port if user specified */ + if ((TRUE == ignore_global_port) + &&(TRUE == spice_model->ports[iport].is_global)) { + continue; + } + if (port_type == spice_model->ports[iport].type) { + ret[cur] = &(spice_model->ports[iport]); + cur++; + } + } + /* Check correctness*/ + assert(cur == (*port_num)); + + return ret; +} + +/* Find the configure done ports */ +t_spice_model_port** find_spice_model_config_done_ports(t_spice_model* spice_model, + enum e_spice_model_port_type port_type, + int* port_num, boolean ignore_global_port) { + int iport, cur; + t_spice_model_port** ret = NULL; + + /* Check codes*/ + assert(NULL != port_num); + assert(NULL != spice_model); + + /* Count the number of ports that match*/ + (*port_num) = 0; + for (iport = 0; iport < spice_model->num_port; iport++) { + /* ignore global port if user specified */ + if ((TRUE == ignore_global_port) + &&(TRUE == spice_model->ports[iport].is_global)) { + continue; + } + if ((port_type == spice_model->ports[iport].type) + &&(TRUE == spice_model->ports[iport].is_config_enable)) { + (*port_num)++; + } + } + + /* Initial the return pointers*/ + ret = (t_spice_model_port**)my_malloc(sizeof(t_spice_model_port*)*(*port_num)); + memset(ret, 0 , sizeof(t_spice_model_port*)*(*port_num)); + + /* Fill the return pointers*/ + cur = 0; + for (iport = 0; iport < spice_model->num_port; iport++) { + /* ignore global port if user specified */ + if ((TRUE == ignore_global_port) + &&(TRUE == spice_model->ports[iport].is_global)) { + continue; + } + if ((port_type == spice_model->ports[iport].type) + &&(TRUE == spice_model->ports[iport].is_config_enable)) { + ret[cur] = &(spice_model->ports[iport]); + cur++; + } + } + /* Check correctness*/ + assert(cur == (*port_num)); + + return ret; +} + +/* Find the transistor in the tech lib*/ +t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib, + e_spice_trans_type trans_type) { + /* If we did not find return NULL*/ + t_spice_transistor_type* ret = NULL; + int i; + + for (i = 0; i < tech_lib.num_transistor_type; i++) { + if (trans_type == tech_lib.transistor_types[i].type) { + ret = &(tech_lib.transistor_types[i]); + break; + } + } + + return ret; +} + +/* Converter an integer to a binary string */ +char* my_itobin(int in_int, int bin_len) { + char* ret = (char*) my_calloc (bin_len + 1, sizeof(char)); + int i, temp; + + /* Make sure we do not have any overflow! */ + assert ( (-1 < in_int) && (in_int < pow(2., bin_len)) ); + + /* Initialize */ + for (i = 0; i < bin_len - 1; i++) { + ret[i] = '0'; + } + sprintf(ret + bin_len - 1, "%s", "0"); + + temp = in_int; + for (i = 0; i < bin_len; i++) { + if (1 == temp % 2) { + ret[i] = '1'; + } + temp = temp / 2; + } + + return ret; +} + +/* Convert a integer to a string*/ +char* my_itoa(int input) { + char* ret = NULL; + int sign = 0; + int len = 0; + int temp = input; + int cur; + char end_of_str; + + /* Identify input number is positive or negative*/ + if (input < 0) { + sign = 1; /* sign will be '-'*/ + len = 1; + temp = 0 - input; + } else if (0 == input) { + sign = 0; + len = 2; + /* Alloc*/ + ret = (char*)my_malloc(sizeof(char)*len); + /* Lets get the end_of_str, the char is dependent on OS*/ + sprintf(ret,"%s","0"); + return ret; + } + /* Identify the length of string*/ + while(temp > 0) { + len++; + temp = temp/10; + } + /* Total length of string should include '\0' at the end*/ + len = len + 1; + /* Alloc*/ + ret = (char*)my_malloc(sizeof(char)*len); + + /*Fill it*/ + temp = input; + /* Lets get the end_of_str, the char is dependent on OS*/ + sprintf(ret,"%s","-"); + end_of_str = ret[1]; + ret[len-1] = end_of_str; + cur = len - 2; + /* Print the number reversely*/ + while(temp > 0) { + ret[cur] = temp%10 + '0'; /* ASIC II base is '0'*/ + cur--; + temp = temp/10; + } + /* Print the sign*/ + if (1 == sign) { + assert(0 == cur); + ret[cur] = '-'; + temp = 0 - input; + } else { + assert(-1 == cur); + } + + return ret; +} + +/* Generate a filename (string) for a grid subckt SPICE netlist, + * with given x and y coordinates + */ +char* fpga_spice_create_one_subckt_filename(char* file_name_prefix, + int subckt_x, int subckt_y, + char* file_name_postfix) { + char* fname = NULL; + + fname = (char*) my_malloc(sizeof(char) * (strlen(file_name_prefix) + + strlen(my_itoa(subckt_x)) + 1 + strlen(my_itoa(subckt_y)) + + strlen(file_name_postfix) + 1)); + + sprintf(fname, "%s%d_%d%s", + file_name_prefix, subckt_x, subckt_y, file_name_postfix); + + return fname; +} + + +char* chomp_spice_node_prefix(char* spice_node_prefix) { + int len = 0; + char* ret = NULL; + + if (NULL == spice_node_prefix) { + return NULL; + } + + len = strlen(spice_node_prefix); /* String length without the last "\0"*/ + ret = (char*)my_malloc(sizeof(char)*(len+2)); + + /* Don't do anything when input is NULL*/ + if (NULL == spice_node_prefix) { + my_free(ret); + return NULL; + } + + strcpy(ret,spice_node_prefix); + /* If the path end up with "_" we should remove it*/ + if ('_' == ret[len-1]) { + ret[len-1] = ret[len]; + } + + return ret; +} + +char* format_spice_node_prefix(char* spice_node_prefix) { + int len = strlen(spice_node_prefix); /* String length without the last "\0"*/ + char* ret = (char*)my_malloc(sizeof(char)*(len+2)); + + /* Don't do anything when input is NULL*/ + if (NULL == spice_node_prefix) { + my_free(ret); + return NULL; + } + + strcpy(ret,spice_node_prefix); + /* If the path does not end up with "_" we should complete it*/ + if (ret[len-1] != '_') { + strcat(ret, "_"); + } + return ret; +} + +/* Given the co-ordinators of grid, + * Find if there is a block mapped into this grid + */ +t_block* search_mapped_block(int x, int y, int z) { + t_block* ret = NULL; + int iblk = 0; + + /*Valid pointors*/ + assert(NULL != grid); + assert((0 < x)||(0 == x)); + assert((x < (nx + 1))||(x == (nx + 1))); + assert((0 < y)||(0 == y)); + assert((x < (ny + 1))||(x == (ny + 1))); + + /* Search all blocks*/ + for (iblk = 0; iblk < num_blocks; iblk++) { + if ((x == block[iblk].x)&&(y == block[iblk].y)&&(z == block[iblk].z)) { + /* Matched cordinators*/ + ret = &(block[iblk]); + /* Check */ + assert(block[iblk].type == grid[x][y].type); + assert(z < grid[x][y].type->capacity); + assert(0 < grid[x][y].usage); + } + } + + return ret; +} + + + + +/* Change the decimal number to binary + * and return a array of integer*/ +int* my_decimal2binary(int decimal, + int* binary_len) { + int* ret = NULL; + int i = 0; + int code = decimal; + + (*binary_len) = 0; + + while (0 < code) { + (*binary_len)++; + code = code/2; + } + + i = (*binary_len) - 1; + while (0 < code) { + ret[i] = code%2; + i--; + code = code/2; + } + + return ret; +} + +/** + * Split a string with strtok + * Store each token in a char array + * tokens (char**): + * tokens[i] (char*) : pointer to a string split by delims + */ + +char** fpga_spice_strtok(char* str, + char* delims, + int* len) { + char** ret; + char* result; + int cnt=0; + int* lens; + char* tmp; + + if (NULL == str) { + printf("Warning: NULL string found in my_strtok!\n"); + return NULL; + } + + tmp = my_strdup(str); + result = strtok(tmp,delims); + /*First scan to determine the size*/ + while(result != NULL) { + cnt++; + /* strtok split until its buffer is NULL*/ + result = strtok(NULL,delims); + } + //printf("1st scan cnt=%d\n",cnt); + /* Allocate memory*/ + ret = (char**)my_malloc(cnt*sizeof(char*)); + lens = (int*)my_malloc(cnt*sizeof(int)); + /*Second to determine the size of each char*/ + cnt = 0; + memcpy(tmp,str,strlen(str)+1); + result = strtok(tmp,delims); + while(result != NULL) { + lens[cnt] = strlen(result)+1; + //printf("lens[%d]=%d .",cnt,lens[cnt]); + cnt++; + /* strtok split until its buffer is NULL*/ + result = strtok(NULL,delims); + } + //printf("\n"); + /*Third to allocate and copy each char*/ + cnt = 0; + memcpy(tmp,str,strlen(str)+1); + result = strtok(tmp,delims); + while(result != NULL) { + //printf("results[%d] = %s ",cnt,result); + ret[cnt] = my_strdup(result); + cnt++; + /* strtok split until its buffer is NULL*/ + result = strtok(NULL,delims); + } + //printf("\n"); + + (*len) = cnt; + + free(tmp); + + return ret; +} + +int get_opposite_side(int side){ + + switch (side) { + case 0: + return 2; + case 1: + return 3; + case 2: + return 0; + case 3: + return 1; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid side index. Should be [0,3].\n", + __FILE__, __LINE__); + exit(1); + } +} + +char* convert_side_index_to_string(int side) { + switch (side) { + case 0: + return "top"; + case 1: + return "right"; + case 2: + return "bottom"; + case 3: + return "left"; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid side index. Should be [0,3].\n", + __FILE__, __LINE__); + exit(1); + } +} + +char* convert_process_corner_to_string(enum e_process_corner process_corner) { + switch(process_corner) { + case BEST_CORNER: + return "bc"; + case TYPICAL_CORNER: + return "tc"; + case WORST_CORNER: + return "wc"; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d])Invalid process_corner !\n", + __FILE__, __LINE__); + exit(1); + } +} + +char* convert_cb_type_to_string(t_rr_type chan_type) { + switch(chan_type) { + case CHANX: + return "cbx"; + break; + case CHANY: + return "cby"; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); + exit(1); + } +} + + +char* convert_chan_type_to_string(t_rr_type chan_type) { + switch(chan_type) { + case CHANX: + return "chanx"; + break; + case CHANY: + return "chany"; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); + exit(1); + } +} + +char* convert_chan_rr_node_direction_to_string(enum PORTS chan_rr_node_direction) { + switch(chan_rr_node_direction) { + case IN_PORT: + return "in"; + break; + case OUT_PORT: + return "out"; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of port!\n", __FILE__, __LINE__); + exit(1); + } +} + +void init_spice_net_info(t_spice_net_info* spice_net_info) { + if (NULL == spice_net_info) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_net_info!\n", __FILE__, __LINE__); + exit(1); + } + + spice_net_info->density = 0.; + spice_net_info->freq = 0.; + + assert((1 == default_signal_init_value)||(0 == default_signal_init_value)); + spice_net_info->init_val = default_signal_init_value; + spice_net_info->probability = (float)default_signal_init_value; + + spice_net_info->pwl = 0.; + spice_net_info->pwh = 0.; + spice_net_info->slew_rise = 0.; + + return; +} + +t_spice_model* find_iopad_spice_model(int num_spice_model, + t_spice_model* spice_models) { + t_spice_model* ret = NULL; + int imodel; + int num_found = 0; + + for (imodel = 0; imodel < num_spice_model; imodel++) { + if (SPICE_MODEL_IOPAD == spice_models[imodel].type) { + ret = &(spice_models[imodel]); + num_found++; + } + } + + assert(1 == num_found); + + return ret; +} + +/* Check if the grid coorindate given is in the range */ +boolean is_grid_coordinate_in_range(int x_min, + int x_max, + int grid_x) { + /* See if x is in the range */ + if ((x_min > grid_x) + ||(x_max < grid_x)) { + return FALSE; + } + + /* Reach here, means all in the range */ + return TRUE; +} + +char* generate_string_spice_model_type(enum e_spice_model_type spice_model_type) { + char* ret = NULL; + + switch (spice_model_type) { + case SPICE_MODEL_WIRE: + ret = "wire"; + break; + case SPICE_MODEL_MUX: + ret = "Multiplexer"; + break; + case SPICE_MODEL_LUT: + ret = "Look-Up Table"; + break; + case SPICE_MODEL_FF: + ret = "Flip-flop"; + break; + case SPICE_MODEL_SRAM: + ret = "SRAM"; + break; + case SPICE_MODEL_HARDLOGIC: + ret = "hard_logic"; + break; + case SPICE_MODEL_IOPAD: + ret = "iopad"; + break; + case SPICE_MODEL_SCFF: + ret = "Scan-chain Flip-flop"; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); + exit(1); + } + + return ret; +} + +/* Deteremine the side of a io grid */ +int determine_io_grid_side(int x, + int y) { + /* TOP side IO of FPGA */ + if ((ny + 1) == y) { + /* Make sure a valid x, y */ + assert((!(0 > x))&&(x < (nx + 1))); + return BOTTOM; /* Such I/O has only Bottom side pins */ + } else if ((nx + 1) == x) { /* RIGHT side IO of FPGA */ + /* Make sure a valid x, y */ + assert((!(0 > y))&&(y < (ny + 1))); + return LEFT; /* Such I/O has only Left side pins */ + } else if (0 == y) { /* BOTTOM side IO of FPGA */ + /* Make sure a valid x, y */ + assert((!(0 > x))&&(x < (nx + 1))); + return TOP; /* Such I/O has only Top side pins */ + } else if (0 == x) { /* LEFT side IO of FPGA */ + /* Make sure a valid x, y */ + assert((!(0 > y))&&(y < (ny + 1))); + return RIGHT; /* Such I/O has only Right side pins */ + } else { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])I/O Grid is in the center part of FPGA! Currently unsupported!\n", + __FILE__, __LINE__); + exit(1); + } +} + +void find_prev_rr_nodes_with_src(t_rr_node* src_rr_node, + int* num_drive_rr_nodes, + t_rr_node*** drive_rr_nodes, + int** switch_indices) { + int inode, iedge, next_node; + int cur_index, switch_index; + + assert(NULL != src_rr_node); + assert(NULL != num_drive_rr_nodes); + assert(NULL != switch_indices); + + (*num_drive_rr_nodes) = 0; + (*drive_rr_nodes) = NULL; + (*switch_indices) = NULL; + + switch_index = -1; + /* Determine num_drive_rr_node */ + for (inode = 0; inode < num_rr_nodes; inode++) { + for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { + next_node = rr_node[inode].edges[iedge]; + if (src_rr_node == &(rr_node[next_node])) { + /* Get the spice_model */ + if (-1 == switch_index) { + switch_index = rr_node[inode].switches[iedge]; + } else { /* Make sure the switches are the same*/ + assert(switch_index == rr_node[inode].switches[iedge]); + } + (*num_drive_rr_nodes)++; + } + } + } + /* Malloc */ + (*drive_rr_nodes) = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*(*num_drive_rr_nodes)); + (*switch_indices) = (int*)my_malloc(sizeof(int)*(*num_drive_rr_nodes)); + + /* Find all the rr_nodes that drive current_rr_node*/ + cur_index = 0; + for (inode = 0; inode < num_rr_nodes; inode++) { + for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { + next_node = rr_node[inode].edges[iedge]; + if (src_rr_node == &(rr_node[next_node])) { + /* Update drive_rr_nodes list */ + (*drive_rr_nodes)[cur_index] = &(rr_node[inode]); + (*switch_indices)[cur_index] = rr_node[inode].switches[iedge]; + cur_index++; + } + } + } + assert(cur_index == (*num_drive_rr_nodes)); + + return; +} + + +int find_path_id_prev_rr_node(int num_drive_rr_nodes, + t_rr_node** drive_rr_nodes, + t_rr_node* src_rr_node) { + int path_id, inode; + + /* Configuration bits for this MUX*/ + path_id = -1; + for (inode = 0; inode < num_drive_rr_nodes; inode++) { + if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { + path_id = inode; + break; + } + } + assert((-1 != path_id)&&(path_id < src_rr_node->fan_in)); + + return path_id; +} + +int pb_pin_net_num(t_rr_node* pb_rr_graph, + t_pb_graph_pin* pin) { + int net_num = OPEN; + + if (NULL == pb_rr_graph) { + /* Try the temp_net_num in pb_graph_pin */ + net_num = pin->temp_net_num; + } else { + net_num = pb_rr_graph[pin->rr_node_index_physical_pb].net_num; + } + + return net_num; +} + +float pb_pin_density(t_rr_node* pb_rr_graph, + t_pb_graph_pin* pin) { + float density = 0.; + int net_num; + + if (NULL == pb_rr_graph) { + /* Try the temp_net_num in pb_graph_pin */ + net_num = pin->temp_net_num; + if (OPEN != net_num) { + density = vpack_net[net_num].spice_net_info->density; + } + return density; + } + net_num = pb_rr_graph[pin->rr_node_index_physical_pb].net_num; + + if (OPEN != net_num) { + density = vpack_net[net_num].spice_net_info->density; + } + + return density; +} + +float pb_pin_probability(t_rr_node* pb_rr_graph, + t_pb_graph_pin* pin) { + float probability = (float)(default_signal_init_value); + int net_num; + + if (NULL == pb_rr_graph) { + /* Try the temp_net_num in pb_graph_pin */ + net_num = pin->temp_net_num; + if (OPEN != net_num) { + probability = vpack_net[net_num].spice_net_info->probability; + } + return probability; + } + net_num = pb_rr_graph[pin->rr_node_index_physical_pb].net_num; + + if (OPEN != net_num) { + probability = vpack_net[net_num].spice_net_info->probability; + } + + return probability; +} + +int pb_pin_init_value(t_rr_node* pb_rr_graph, + t_pb_graph_pin* pin) { + float init_val = (float)(default_signal_init_value); + int net_num; + + if (NULL == pb_rr_graph) { + /* TODO: we know initialize to vdd could reduce the leakage power od multiplexers! + * But I can this as an option ! + */ + /* Try the temp_net_num in pb_graph_pin */ + net_num = pin->temp_net_num; + if (OPEN != net_num) { + init_val = vpack_net[net_num].spice_net_info->init_val; + } + return init_val; + } + net_num = pb_rr_graph[pin->rr_node_index_physical_pb].net_num; + + if (OPEN != net_num) { + init_val = vpack_net[net_num].spice_net_info->init_val; + } + + return init_val; +} + +float get_rr_node_net_density(t_rr_node node) { + /* If we found this net is OPEN, we assume it zero-density */ + if (OPEN == node.vpack_net_num) { + return 0.; + } else { + return vpack_net[node.vpack_net_num].spice_net_info->density; + } +} + +float get_rr_node_net_probability(t_rr_node node) { + /* If we found this net is OPEN, we assume it zero-probability */ + if (OPEN == node.vpack_net_num) { + /* TODO: we know initialize to vdd could reduce the leakage power od multiplexers! + * But I can this as an option ! + */ + return (float)(default_signal_init_value); + } else { + return vpack_net[node.vpack_net_num].spice_net_info->probability; + } +} + +int get_rr_node_net_init_value(t_rr_node node) { + /* If we found this net is OPEN, we assume it zero-probability */ + if (OPEN == node.vpack_net_num) { + /* TODO: we know initialize to vdd could reduce the leakage power od multiplexers! + * But I can this as an option ! + */ + return (float)(default_signal_init_value); + } else { + return vpack_net[node.vpack_net_num].spice_net_info->init_val; + } +} + + +int recommend_num_sim_clock_cycle(float sim_window_size) { + float avg_density = 0.; + float median_density = 0.; + int recmd_num_sim_clock_cycle = 0; + int inet, jnet; + int net_cnt = 0; + float* density_value = NULL; + int* sort_index = NULL; + int* net_to_sort_index_mapping = NULL; + + float weighted_avg_density = 0.; + float net_weight = 0.; + int weighted_net_cnt = 0; + + /* get the average density of all the nets */ + for (inet = 0; inet < num_logical_nets; inet++) { + assert(NULL != vpack_net[inet].spice_net_info); + if ((FALSE == vpack_net[inet].is_global) + &&(FALSE == vpack_net[inet].is_const_gen) + &&(0. != vpack_net[inet].spice_net_info->density)) { + avg_density += vpack_net[inet].spice_net_info->density; + net_cnt++; + /* Consider the weight of fan-out */ + if (0 == vpack_net[inet].num_sinks) { + net_weight = 1; + } else { + assert( 0 < vpack_net[inet].num_sinks ); + net_weight = vpack_net[inet].num_sinks; + } + weighted_avg_density += vpack_net[inet].spice_net_info->density * net_weight; + weighted_net_cnt += net_weight; + } + } + avg_density = avg_density/net_cnt; + weighted_avg_density = weighted_avg_density/weighted_net_cnt; + + /* Fill the array to be sorted */ + density_value = (float*)my_malloc(sizeof(float)*net_cnt); + sort_index = (int*)my_malloc(sizeof(int)*net_cnt); + net_to_sort_index_mapping = (int*)my_malloc(sizeof(int)*net_cnt); + jnet = 0; + for (inet = 0; inet < num_logical_nets; inet++) { + assert(NULL != vpack_net[inet].spice_net_info); + if ((FALSE == vpack_net[inet].is_global) + &&(FALSE == vpack_net[inet].is_const_gen) + &&(0. != vpack_net[inet].spice_net_info->density)) { + sort_index[jnet] = jnet; + net_to_sort_index_mapping[jnet] = inet; + density_value[jnet] = vpack_net[inet].spice_net_info->density; + jnet++; + } + } + assert(jnet == net_cnt); + /* Sort the density */ + quicksort_float_index(net_cnt, sort_index, density_value); + /* Get the median */ + median_density = vpack_net[sort_index[(int)(0.5*net_cnt)]].spice_net_info->density; + + /* It may be more reasonable to use median + * But, if median density is 0, we use average density + */ + if ((0. == median_density) && (0. == avg_density)) { + recmd_num_sim_clock_cycle = 1; + vpr_printf(TIO_MESSAGE_WARNING, + "All the signal density is zero! No. of clock cycles in simulations are set to be %d!", + recmd_num_sim_clock_cycle); + } else if (0. == avg_density) { + recmd_num_sim_clock_cycle = (int)round(1/median_density); + } else if (0. == median_density) { + recmd_num_sim_clock_cycle = (int)round(1/avg_density); + } else { + /* add a sim window size to balance the weight of average density and median density + * In practice, we find that there could be huge difference between avereage and median values + * For a reasonable number of simulation clock cycles, we do this window size. + */ + recmd_num_sim_clock_cycle = (int)round(1 / (sim_window_size * avg_density + (1 - sim_window_size) * median_density )); + } + + assert( 0 < recmd_num_sim_clock_cycle); + + vpr_printf(TIO_MESSAGE_INFO, "Average net density: %.2f\n", avg_density); + vpr_printf(TIO_MESSAGE_INFO, "Median net density: %.2f\n", median_density); + vpr_printf(TIO_MESSAGE_INFO, "Average net densityi after weighting: %.2f\n", weighted_avg_density); + vpr_printf(TIO_MESSAGE_INFO, "Window size set for Simulation: %.2f\n", sim_window_size); + vpr_printf(TIO_MESSAGE_INFO, "Net density after Window size : %.2f\n", + (sim_window_size * avg_density + (1 - sim_window_size) * median_density)); + vpr_printf(TIO_MESSAGE_INFO, "Recommend no. of clock cycles: %d\n", recmd_num_sim_clock_cycle); + + /* Free */ + my_free(sort_index); + my_free(density_value); + my_free(net_to_sort_index_mapping); + + return recmd_num_sim_clock_cycle; +} + +void auto_select_num_sim_clock_cycle(t_spice* spice, + float sim_window_size) { + int recmd_num_sim_clock_cycle = recommend_num_sim_clock_cycle(sim_window_size); + + /* Auto select number of simulation clock cycles*/ + if (-1 == spice->spice_params.meas_params.sim_num_clock_cycle) { + vpr_printf(TIO_MESSAGE_INFO, "Auto select the no. of clock cycles in simulation: %d\n", recmd_num_sim_clock_cycle); + spice->spice_params.meas_params.sim_num_clock_cycle = recmd_num_sim_clock_cycle; + } else { + vpr_printf(TIO_MESSAGE_INFO, "No. of clock cycles in simulation is forced to be: %d\n", + spice->spice_params.meas_params.sim_num_clock_cycle); + } + + return; +} + +/* Malloc grid_index_low and grid_index_high for a spice_model */ +void alloc_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) { + int ix, iy; + + /* grid_index_low */ + /* x - direction*/ + cur_spice_model->grid_index_low = (int**)my_malloc(sizeof(int*)*(nx + 2)); + /* y - direction*/ + for (ix = 0; ix < (nx + 2); ix++) { + cur_spice_model->grid_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 2)); + } + /* Initialize */ + for (ix = 0; ix < (nx + 2); ix++) { + for (iy = 0; iy < (ny + 2); iy++) { + cur_spice_model->grid_index_low[ix][iy] = 0; + } + } + /* grid_index_high */ + /* x - direction*/ + cur_spice_model->grid_index_high = (int**)my_malloc(sizeof(int*)*(nx + 2)); + /* y - direction*/ + for (ix = 0; ix < (nx + 2); ix++) { + cur_spice_model->grid_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 2)); + } + /* Initialize */ + for (ix = 0; ix < (nx + 2); ix++) { + for (iy = 0; iy < (ny + 2); iy++) { + cur_spice_model->grid_index_high[ix][iy] = 0; + } + } + + return; +} + +void free_one_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) { + int ix; + + for (ix = 0; ix < (nx + 2); ix++) { + my_free(cur_spice_model->grid_index_high[ix]); + my_free(cur_spice_model->grid_index_low[ix]); + } + + my_free(cur_spice_model->grid_index_high); + my_free(cur_spice_model->grid_index_low); + + return; +} + +void free_spice_model_grid_index_low_high(int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + free_one_spice_model_grid_index_low_high(&(spice_model[i])); + } + return; +} + + +void update_one_spice_model_grid_index_low(int x, int y, + t_spice_model* cur_spice_model) { + /* Check */ + assert((!(0 > x))&&(!(x > (nx + 1)))); + assert((!(0 > y))&&(!(y > (ny + 1)))); + assert(NULL != cur_spice_model); + assert(NULL != cur_spice_model->grid_index_low); + assert(NULL != cur_spice_model->grid_index_low[x]); + + /* Assigne the low */ + cur_spice_model->grid_index_low[x][y] = cur_spice_model->cnt; + + return; +} + +void update_spice_models_grid_index_low(int x, int y, + int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + update_one_spice_model_grid_index_low(x, y, &(spice_model[i])); + } + + return; +} + +void update_one_spice_model_grid_index_high(int x, int y, + t_spice_model* cur_spice_model) { + /* Check */ + assert((!(0 > x))&&(!(x > (nx + 1)))); + assert((!(0 > y))&&(!(y > (ny + 1)))); + assert(NULL != cur_spice_model); + assert(NULL != cur_spice_model->grid_index_high); + assert(NULL != cur_spice_model->grid_index_high[x]); + + /* Assigne the low */ + cur_spice_model->grid_index_high[x][y] = cur_spice_model->cnt; + + return; +} + +void update_spice_models_grid_index_high(int x, int y, + int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + update_one_spice_model_grid_index_high(x, y, &(spice_model[i])); + } + + return; +} + +void zero_one_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) { + int ix, iy; + /* Initialize */ + for (ix = 0; ix < (nx + 2); ix++) { + for (iy = 0; iy < (ny + 2); iy++) { + cur_spice_model->grid_index_high[ix][iy] = 0; + cur_spice_model->grid_index_low[ix][iy] = 0; + } + } + return; +} + +void zero_spice_model_grid_index_low_high(int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + zero_one_spice_model_grid_index_low_high(&(spice_model[i])); + } + + return; +} + +char* gen_str_spice_model_structure(enum e_spice_model_structure spice_model_structure) { + switch (spice_model_structure) { + case SPICE_MODEL_STRUCTURE_TREE: + return "tree-like"; + case SPICE_MODEL_STRUCTURE_ONELEVEL: + return "one-level"; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + return "multi-level"; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid spice model structure!\n", + __FILE__, __LINE__); + exit(1); + } +} + +/* Check if the spice model structure is the same with the switch_inf structure */ +boolean check_spice_model_structure_match_switch_inf(t_switch_inf target_switch_inf) { + assert(NULL != target_switch_inf.spice_model); + if (target_switch_inf.structure != target_switch_inf.spice_model->design_tech_info.mux_info->structure) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Structure in spice_model(%s) is different from switch_inf[%s]!\n", + __FILE__, __LINE__, target_switch_inf.spice_model->name, target_switch_inf.name); + return FALSE; + } + return TRUE; +} + + +void init_rr_nodes_vpack_net_num_changed(int LL_num_rr_nodes, + t_rr_node* LL_rr_node) { + int inode; + + for (inode = 0; inode < LL_num_rr_nodes; inode++) { + LL_rr_node[inode].vpack_net_num_changed = FALSE; + } + + return; +} + +void init_rr_nodes_is_parasitic_net(int LL_num_rr_nodes, + t_rr_node* LL_rr_node) { + int inode; + + for (inode = 0; inode < LL_num_rr_nodes; inode++) { + LL_rr_node[inode].is_parasitic_net = FALSE; + } + + return; +} + + +/* Check if this net is connected to a PI*/ +boolean is_net_pi(t_net* cur_net) { + int src_blk_idx; + + assert(NULL != cur_net); + + src_blk_idx = cur_net->node_block[0]; + if (VPACK_INPAD == logical_block[src_blk_idx].type) { + return TRUE; + } + return FALSE; +} + +int check_consistency_logical_block_net_num(t_logical_block* lgk_blk, + int num_inputs, int* input_net_num) { + int i, iport, ipin, net_eq; + int consistency = 1; + int* input_net_num_mapped = (int*)my_calloc(num_inputs, sizeof(int)); + + for (iport = 0; iport < lgk_blk->pb->pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < lgk_blk->pb->pb_graph_node->num_input_pins[iport]; ipin++) { + if (OPEN == lgk_blk->input_nets[iport][ipin]) { + continue; /* bypass unused pins */ + } + /* Initial net_eq */ + net_eq = 0; + /* Check if this net can be found in the input net_num */ + for (i = 0; i < num_inputs; i++) { + if (1 == input_net_num_mapped[i]) { + continue; + } + if (input_net_num[i] == lgk_blk->input_nets[iport][ipin]) { + net_eq = 1; + input_net_num_mapped[i] = 1; + break; + } + } + if (0 == net_eq) { + consistency = 0; + break; + } + } + if (0 == consistency) { + break; + } + } + + /* Free */ + my_free(input_net_num_mapped); + + return consistency; +} + +/* Determine if this rr_node is driving this switch box (x,y) + * For more than length-1 wire, the fan-in of a des_rr_node in a switch box + * contain all the drivers in the switch boxes that it passes through. + * This function is to identify if the src_rr_node is the driver in this switch box + */ +int rr_node_drive_switch_box(t_rr_node* src_rr_node, + t_rr_node* des_rr_node, + int switch_box_x, + int switch_box_y, + int chan_side) { + + /* Make sure a valid src_rr_node and des_rr_node */ + assert(NULL != src_rr_node); + assert(NULL != des_rr_node); + /* The src_rr_node should be either CHANX or CHANY */ + assert((CHANX == des_rr_node->type)||(CHANY == des_rr_node->type)); + /* Valid switch_box coordinator */ + assert((!(0 > switch_box_x))&&(!(switch_box_x > (nx + 1)))); + assert((!(0 > switch_box_y))&&(!(switch_box_y > (ny + 1)))); + /* Valid des_rr_node coordinator */ + assert((!(switch_box_x < (des_rr_node->xlow - 1)))&&(!(switch_box_x > (des_rr_node->xhigh + 1)))); + assert((!(switch_box_y < (des_rr_node->ylow - 1)))&&(!(switch_box_y > (des_rr_node->yhigh + 1)))); + + /* Check the src_rr_node coordinator */ + switch (chan_side) { + case TOP: + /* Following cases: + * | + * / | \ + */ + /* The destination rr_node only have one condition!!! */ + assert((INC_DIRECTION == des_rr_node->direction)&&(CHANY == des_rr_node->type)); + /* depend on the type of src_rr_node */ + switch (src_rr_node->type) { + case OPIN: + if (((switch_box_y + 1) == src_rr_node->ylow) + &&((switch_box_x == src_rr_node->xlow)||((switch_box_x + 1) == src_rr_node->xlow))) { + return 1; + } + break; + case CHANX: + assert(src_rr_node->ylow == src_rr_node->yhigh); + if ((switch_box_y == src_rr_node->ylow) + &&(!(switch_box_x < (src_rr_node->xlow - 1))) + &&(!(switch_box_x > (src_rr_node->xhigh + 1)))) { + return 1; + } + break; + case CHANY: + assert(src_rr_node->xlow == src_rr_node->xhigh); + if ((switch_box_x == src_rr_node->xlow) + &&(!(switch_box_y < src_rr_node->ylow)) + &&(!(switch_box_y > src_rr_node->yhigh))) { + return 1; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case RIGHT: + /* Following cases: + * \ + * --- ---- + * / + */ + /* The destination rr_node only have one condition!!! */ + assert((INC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type)); + /* depend on the type of src_rr_node */ + switch (src_rr_node->type) { + case OPIN: + if (((switch_box_x + 1) == src_rr_node->xlow) + &&((switch_box_y == src_rr_node->ylow)||((switch_box_y + 1) == src_rr_node->ylow))) { + return 1; + } + break; + case CHANX: + assert(src_rr_node->ylow == src_rr_node->yhigh); + if ((switch_box_y == src_rr_node->ylow) + &&(!(switch_box_x < src_rr_node->xlow))&&(!(switch_box_x > src_rr_node->xhigh))) { + return 1; + } + break; + case CHANY: + assert(src_rr_node->xlow == src_rr_node->xhigh); + if ((switch_box_x == src_rr_node->xlow) + &&(!(switch_box_y < (src_rr_node->ylow - 1))) + &&(!(switch_box_y > (src_rr_node->yhigh + 1)))) { + return 1; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case BOTTOM: + /* Following cases: + * | + * \ | / + * | + */ + /* The destination rr_node only have one condition!!! */ + assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANY == des_rr_node->type)); + /* depend on the type of src_rr_node */ + switch (src_rr_node->type) { + case OPIN: + if ((switch_box_y == src_rr_node->ylow) + &&((switch_box_x == src_rr_node->xlow)||((switch_box_x + 1) == src_rr_node->xlow))) { + return 1; + } + break; + case CHANX: + assert(src_rr_node->ylow == src_rr_node->yhigh); + if ((switch_box_y == src_rr_node->ylow) + &&(!(switch_box_x < (src_rr_node->xlow - 1))) + &&(!(switch_box_x > (src_rr_node->xhigh + 1)))) { + return 1; + } + break; + case CHANY: + assert(src_rr_node->xlow == src_rr_node->xhigh); + if ((switch_box_x == src_rr_node->xlow) + &&(!((switch_box_y + 1) < src_rr_node->ylow)) + &&(!((switch_box_y + 1) > src_rr_node->yhigh))) { + return 1; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", + __FILE__, __LINE__); + exit(1); + } + break; + case LEFT: + /* Following cases: + * / + * --- ---- + * \ + */ + /* The destination rr_node only have one condition!!! */ + assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type)); + /* depend on the type of src_rr_node */ + switch (src_rr_node->type) { + case OPIN: + if ((switch_box_x == src_rr_node->xlow) + &&((switch_box_y == src_rr_node->ylow)||((switch_box_y + 1) == src_rr_node->ylow))) { + return 1; + } + break; + case CHANX: + assert(src_rr_node->ylow == src_rr_node->yhigh); + if ((switch_box_y == src_rr_node->ylow) + &&(!((switch_box_x + 1) < src_rr_node->xlow)) + &&(!((switch_box_x + 1) > src_rr_node->xhigh))) { + return 1; + } + break; + case CHANY: + assert(src_rr_node->xlow == src_rr_node->xhigh); + if ((switch_box_x == src_rr_node->xlow) + &&(!(switch_box_y < (src_rr_node->ylow - 1))) + &&(!(switch_box_y > (src_rr_node->yhigh + 1)))) { + return 1; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid src_rr_node type!\n", + __FILE__, __LINE__); + exit(1); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid side!\n", __FILE__, __LINE__); + exit(1); + } + + return 0; +} + +void find_drive_rr_nodes_switch_box(int switch_box_x, + int switch_box_y, + t_rr_node* src_rr_node, + int chan_side, + int return_num_only, + int* num_drive_rr_nodes, + t_rr_node*** drive_rr_nodes, + int* switch_index) { + int cur_index = 0; + //int inode, iedge, next_node; + int inode; + + /* I decide to kill the codes that search all the edges, the running time is huge... */ + /* Determine the num_drive_rr_nodes */ + (*num_drive_rr_nodes) = 0; + (*switch_index) = -1; + + for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) { + if (1 == rr_node_drive_switch_box(src_rr_node->drive_rr_nodes[inode], src_rr_node, + switch_box_x, switch_box_y, chan_side)) { + /* Get the spice_model */ + if (-1 == (*switch_index)) { + (*switch_index) = src_rr_node->drive_switches[inode]; + } else { /* Make sure the switches are the same*/ + assert((*switch_index) == src_rr_node->drive_switches[inode]); + } + (*num_drive_rr_nodes)++; + } + } + + //for (inode = 0; inode < num_rr_nodes; inode++) { + // for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { + // next_node = rr_node[inode].edges[iedge]; + // /* Make sure the coordinator is matched to this switch box*/ + // if ((src_rr_node == &(rr_node[next_node])) + // &&(1 == rr_node_drive_switch_box(&(rr_node[inode]), src_rr_node, switch_box_x, switch_box_y, chan_side))) { + // /* Get the spice_model */ + // if (-1 == (*switch_index)) { + // (*switch_index) = rr_node[inode].switches[iedge]; + // } else { /* Make sure the switches are the same*/ + // assert((*switch_index) == rr_node[inode].switches[iedge]); + // } + // (*num_drive_rr_nodes)++; + // } + // } + //} + + /* Check and malloc*/ + assert((!(0 > (*num_drive_rr_nodes)))&&(!((*num_drive_rr_nodes) > src_rr_node->fan_in))); + if (1 == return_num_only) { + return; + } + (*drive_rr_nodes) = NULL; + if (0 == (*num_drive_rr_nodes)) { + return; + } + (*drive_rr_nodes) = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*(*num_drive_rr_nodes)); + + /* Find all the rr_nodes that drive current_rr_node*/ + cur_index = 0; + (*switch_index) = -1; + + for (inode = 0; inode < src_rr_node->num_drive_rr_nodes; inode++) { + if (1 == rr_node_drive_switch_box(src_rr_node->drive_rr_nodes[inode], src_rr_node, + switch_box_x, switch_box_y, chan_side)) { + /* Update drive_rr_nodes list */ + (*drive_rr_nodes)[cur_index] = src_rr_node->drive_rr_nodes[inode]; + /* Get the spice_model */ + if (-1 == (*switch_index)) { + (*switch_index) = src_rr_node->drive_switches[inode]; + } else { /* Make sure the switches are the same*/ + assert((*switch_index) == src_rr_node->drive_switches[inode]); + } + cur_index++; + } + } + //for (inode = 0; inode < num_rr_nodes; inode++) { + // for (iedge = 0; iedge < rr_node[inode].num_edges; iedge++) { + // next_node = rr_node[inode].edges[iedge]; + // /* Make sure the coordinator is matched to this switch box*/ + // if ((src_rr_node == &(rr_node[next_node])) + // &&(1 == rr_node_drive_switch_box(&(rr_node[inode]), src_rr_node, switch_box_x, switch_box_y, chan_side))) { + // /* Update drive_rr_nodes list */ + // (*drive_rr_nodes)[cur_index] = &(rr_node[inode]); + // /* Get the spice_model */ + // if (-1 == (*switch_index)) { + // (*switch_index) = rr_node[inode].switches[iedge]; + // } else { /* Make sure the switches are the same*/ + // assert((*switch_index) == rr_node[inode].switches[iedge]); + // } + // cur_index++; + // } + // } + //} + /* Verification */ + assert(cur_index == (*num_drive_rr_nodes)); + + return; +} + +/* Reset the counter of each spice_model to be zero */ +void zero_spice_models_cnt(int num_spice_models, t_spice_model* spice_model) { + int imodel = 0; + + for (imodel = 0; imodel < num_spice_models; imodel++) { + spice_model[imodel].cnt = 0; + } + + return; +} + +void zero_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) { + int ix, iy; + /* Initialize */ + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 0; iy < (ny + 1); iy++) { + cur_spice_model->sb_index_low[ix][iy] = 0; + cur_spice_model->cbx_index_low[ix][iy] = 0; + cur_spice_model->cby_index_low[ix][iy] = 0; + cur_spice_model->sb_index_high[ix][iy] = 0; + cur_spice_model->cbx_index_high[ix][iy] = 0; + cur_spice_model->cby_index_high[ix][iy] = 0; + } + } + return; +} + +void zero_spice_models_routing_index_low_high(int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + zero_one_spice_model_routing_index_low_high(&(spice_model[i])); + } + + return; +} + +/* Malloc routing_index_low and routing_index_high for a spice_model */ +void alloc_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) { + int ix; + + /* [cbx|cby|sb]_index_low */ + /* x - direction*/ + cur_spice_model->sb_index_low = (int**)my_malloc(sizeof(int*)*(nx + 1)); + cur_spice_model->cbx_index_low = (int**)my_malloc(sizeof(int*)*(nx + 1)); + cur_spice_model->cby_index_low = (int**)my_malloc(sizeof(int*)*(nx + 1)); + /* y - direction*/ + for (ix = 0; ix < (nx + 1); ix++) { + cur_spice_model->sb_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); + cur_spice_model->cbx_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); + cur_spice_model->cby_index_low[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); + } + + /* grid_index_high */ + /* x - direction*/ + cur_spice_model->sb_index_high = (int**)my_malloc(sizeof(int*)*(nx + 1)); + cur_spice_model->cbx_index_high = (int**)my_malloc(sizeof(int*)*(nx + 1)); + cur_spice_model->cby_index_high = (int**)my_malloc(sizeof(int*)*(nx + 1)); + /* y - direction*/ + for (ix = 0; ix < (nx + 1); ix++) { + cur_spice_model->sb_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); + cur_spice_model->cbx_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); + cur_spice_model->cby_index_high[ix] = (int*)my_malloc(sizeof(int)*(ny + 1)); + } + + zero_one_spice_model_routing_index_low_high(cur_spice_model); + + return; +} + +void free_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) { + int ix; + + /* index_high */ + for (ix = 0; ix < (nx + 1); ix++) { + my_free(cur_spice_model->sb_index_low[ix]); + my_free(cur_spice_model->cbx_index_low[ix]); + my_free(cur_spice_model->cby_index_low[ix]); + + my_free(cur_spice_model->sb_index_high[ix]); + my_free(cur_spice_model->cbx_index_high[ix]); + my_free(cur_spice_model->cby_index_high[ix]); + } + my_free(cur_spice_model->sb_index_low); + my_free(cur_spice_model->cbx_index_low); + my_free(cur_spice_model->cby_index_low); + + my_free(cur_spice_model->sb_index_high); + my_free(cur_spice_model->cbx_index_high); + my_free(cur_spice_model->cby_index_high); + + return; +} + +void free_spice_model_routing_index_low_high(int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + free_one_spice_model_routing_index_low_high(&(spice_model[i])); + } + + return; +} + +void update_one_spice_model_routing_index_high(int x, int y, t_rr_type chan_type, + t_spice_model* cur_spice_model) { + /* Check */ + assert((!(0 > x))&&(!(x > (nx + 1)))); + assert((!(0 > y))&&(!(y > (ny + 1)))); + assert(NULL != cur_spice_model); + assert(NULL != cur_spice_model->sb_index_high); + assert(NULL != cur_spice_model->sb_index_high[x]); + assert(NULL != cur_spice_model->cbx_index_high); + assert(NULL != cur_spice_model->cbx_index_high[x]); + assert(NULL != cur_spice_model->cby_index_high); + assert(NULL != cur_spice_model->cby_index_high[x]); + + /* Assigne the low */ + if (CHANX == chan_type) { + cur_spice_model->cbx_index_high[x][y] = cur_spice_model->cnt; + } else if (CHANY == chan_type) { + cur_spice_model->cby_index_high[x][y] = cur_spice_model->cnt; + } else if (SOURCE == chan_type) { + cur_spice_model->sb_index_high[x][y] = cur_spice_model->cnt; + } + + return; +} + +void update_spice_models_routing_index_high(int x, int y, t_rr_type chan_type, + int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + update_one_spice_model_routing_index_high(x, y, chan_type, &(spice_model[i])); + } + + return; +} + +void update_one_spice_model_routing_index_low(int x, int y, t_rr_type chan_type, + t_spice_model* cur_spice_model) { + /* Check */ + assert((!(0 > x))&&(!(x > (nx + 1)))); + assert((!(0 > y))&&(!(y > (ny + 1)))); + assert(NULL != cur_spice_model); + assert(NULL != cur_spice_model->sb_index_low); + assert(NULL != cur_spice_model->sb_index_low[x]); + assert(NULL != cur_spice_model->cbx_index_low); + assert(NULL != cur_spice_model->cbx_index_low[x]); + assert(NULL != cur_spice_model->cby_index_low); + assert(NULL != cur_spice_model->cby_index_low[x]); + + /* Assigne the low */ + if (CHANX == chan_type) { + cur_spice_model->cbx_index_low[x][y] = cur_spice_model->cnt; + } else if (CHANY == chan_type) { + cur_spice_model->cby_index_low[x][y] = cur_spice_model->cnt; + } else if (SOURCE == chan_type) { + cur_spice_model->sb_index_low[x][y] = cur_spice_model->cnt; + } + + return; +} + +void update_spice_models_routing_index_low(int x, int y, t_rr_type chan_type, + int num_spice_models, + t_spice_model* spice_model) { + int i; + + for (i = 0; i < num_spice_models; i++) { + update_one_spice_model_routing_index_low(x, y, chan_type, &(spice_model[i])); + } + + return; +} + +/* Check if this SPICE model defined as SRAM + * contain necessary ports for its functionality + */ +void check_sram_spice_model_ports(t_spice_model* cur_spice_model, + boolean include_bl_wl) { + int num_input_ports; + t_spice_model_port** input_ports = NULL; + int num_output_ports; + t_spice_model_port** output_ports = NULL; + int num_bl_ports; + t_spice_model_port** bl_ports = NULL; + int num_wl_ports; + t_spice_model_port** wl_ports = NULL; + + int iport; + int num_global_ports = 0; + int num_err = 0; + + /* Check the type of SPICE model */ + assert(SPICE_MODEL_SRAM == cur_spice_model->type); + + /* Check if we has 1 input other than global ports */ + input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_ports, TRUE); + num_global_ports = 0; + for (iport = 0; iport < num_input_ports; iport++) { + if (TRUE == input_ports[iport]->is_global) { + num_global_ports++; + } + } + if (1 != (num_input_ports - num_global_ports)) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have only 1 non-global input port!\n", + __FILE__, __LINE__); + num_err++; + if (1 != input_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have an input port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + /* Check if we has 1 output with size 2 */ + output_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_ports, TRUE); + num_global_ports = 0; + for (iport = 0; iport < num_output_ports; iport++) { + if (TRUE == output_ports[iport]->is_global) { + num_global_ports++; + } + } + if ((1 != (num_output_ports - num_global_ports)) + && (2 != (num_output_ports - num_global_ports))) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have only 1 non-global output port!\n", + __FILE__, __LINE__); + num_err++; + if (1 != output_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have a output port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + if (FALSE == include_bl_wl) { + if (0 == num_err) { + return; + } else { + exit(1); + } + } + /* If bl and wl are required, check their existence */ + bl_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_BL, &num_bl_ports, TRUE); + if (1 != num_bl_ports) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL with BL and WL should have only 1 BL port!\n", + __FILE__, __LINE__); + num_err++; + exit(1); + if (1 != bl_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have a BL port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + + wl_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_WL, &num_wl_ports, TRUE); + if (1 != num_wl_ports) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL with WL and WL should have only 1 WL port!\n", + __FILE__, __LINE__); + num_err++; + exit(1); + if (1 != wl_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SRAM SPICE MODEL should have a WL port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + + if (0 < num_err) { + exit(1); + } + + /* Free */ + my_free(input_ports); + my_free(output_ports); + my_free(bl_ports); + my_free(wl_ports); + + return; +} + +void check_ff_spice_model_ports(t_spice_model* cur_spice_model, + boolean is_scff) { + int iport; + int num_input_ports; + t_spice_model_port** input_ports = NULL; + int num_output_ports; + t_spice_model_port** output_ports = NULL; + int num_clock_ports; + t_spice_model_port** clock_ports = NULL; + + int num_err = 0; + + /* Check the type of SPICE model */ + if (FALSE == is_scff) { + assert(SPICE_MODEL_FF == cur_spice_model->type); + } else { + assert(SPICE_MODEL_SCFF == cur_spice_model->type); + } + /* Check if we have D, Set and Reset */ + input_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_ports, FALSE); + if (TRUE == is_scff) { + if (1 > num_input_ports) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL should at least have an input port!\n", + __FILE__, __LINE__); + num_err++; + } + for (iport = 0; iport < num_input_ports; iport++) { + if (1 != input_ports[iport]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL: each input port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + } else { + if (3 != num_input_ports) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) FF SPICE MODEL should have only 3 input port!\n", + __FILE__, __LINE__); + num_err++; + } + for (iport = 0; iport < num_input_ports; iport++) { + if (1 != input_ports[iport]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) FF SPICE MODEL: each input port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + } + /* Check if we have clock */ + clock_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_CLOCK, &num_clock_ports, FALSE); + if (1 > num_clock_ports) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) [FF|SCFF] SPICE MODEL should have at least 1 clock port!\n", + __FILE__, __LINE__); + num_err++; + } + for (iport = 0; iport < num_clock_ports; iport++) { + if (1 != clock_ports[iport]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) [FF|SCFF] SPICE MODEL: 1 clock port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } + /* Check if we have output */ + output_ports = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_ports, TRUE); + if (FALSE == is_scff) { + if (1 != output_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) FF SPICE MODEL: each output port with size 1!\n", + __FILE__, __LINE__); + num_err++; + } + } else { + if (2 != num_output_ports) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL should have 2 output ports!\n", + __FILE__, __LINE__); + num_err++; + for (iport = 0; iport < num_output_ports; iport++) { + if (1 != output_ports[iport]->size) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) SCFF SPICE MODEL: the output port (%s) should have a size of 1!\n", + __FILE__, __LINE__, output_ports[iport]->prefix); + num_err++; + } + } + } + } + /* Error out if required */ + if (0 < num_err) { + exit(1); + } + + /* Free */ + my_free(input_ports); + my_free(output_ports); + my_free(clock_ports); + + return; +} + +/* Free a conf_bit_info */ +void free_conf_bit(t_conf_bit* conf_bit) { + return; +} + +void free_conf_bit_info(t_conf_bit_info* conf_bit_info) { + free_conf_bit(conf_bit_info->sram_bit); + my_free(conf_bit_info->sram_bit); + + free_conf_bit(conf_bit_info->bl); + my_free(conf_bit_info->bl); + + free_conf_bit(conf_bit_info->wl); + my_free(conf_bit_info->wl); + + return; +} + +/* Fill the information into a confbit_info */ +t_conf_bit_info* +alloc_one_conf_bit_info(int index, + t_conf_bit* sram_val, + t_conf_bit* bl_val, t_conf_bit* wl_val, + t_spice_model* parent_spice_model) { + t_conf_bit_info* new_conf_bit_info = (t_conf_bit_info*)my_malloc(sizeof(t_conf_bit_info)); + + /* Check if we have a valid conf_bit_info */ + if (NULL == new_conf_bit_info) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Fail to malloc a new conf_bit_info!\n", + __FILE__, __LINE__); + exit(1); + } + /* Fill the information */ + new_conf_bit_info->index = index; + new_conf_bit_info->sram_bit = sram_val; + new_conf_bit_info->bl = bl_val; + new_conf_bit_info->wl = wl_val; + new_conf_bit_info->parent_spice_model = parent_spice_model; + new_conf_bit_info->parent_spice_model_index = parent_spice_model->cnt; + + return new_conf_bit_info; +} + +/* Add an element to linked-list */ +t_llist* +add_conf_bit_info_to_llist(t_llist* head, int index, + t_conf_bit* sram_val, t_conf_bit* bl_val, t_conf_bit* wl_val, + t_spice_model* parent_spice_model) { + t_llist* temp = NULL; + t_conf_bit_info* new_conf_bit_info = NULL; + + /* if head is NULL, we create a head */ + if (NULL == head) { + temp = create_llist(1); + new_conf_bit_info = alloc_one_conf_bit_info(index, sram_val, bl_val, wl_val, parent_spice_model); + assert(NULL != new_conf_bit_info); + temp->dptr = (void*)new_conf_bit_info; + assert(NULL == temp->next); + return temp; + } else { + /* If head is a valid pointer, we add a new element to the tail of this linked-list */ + temp = insert_llist_node_before_head(head); + new_conf_bit_info = alloc_one_conf_bit_info(index, sram_val, bl_val, wl_val, parent_spice_model); + assert(NULL != new_conf_bit_info); + temp->dptr = (void*)new_conf_bit_info; + return temp; + } +} + +/* Find BL and WL ports for a SRAM model. + * And check if the number of BL/WL satisfy the technology needs + */ +void find_bl_wl_ports_spice_model(t_spice_model* cur_spice_model, + int* num_bl_ports, t_spice_model_port*** bl_ports, + int* num_wl_ports, t_spice_model_port*** wl_ports) { + int i; + + /* Check */ + assert(NULL != cur_spice_model); + + /* Find BL ports */ + (*bl_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_BL, num_bl_ports, TRUE); + /* Find WL ports */ + (*wl_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_WL, num_wl_ports, TRUE); + + /* port size of BL/WL should be at least 1 !*/ + assert((*num_bl_ports) == (*num_wl_ports)); + + /* Check the size of BL/WL ports */ + switch (cur_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_RRAM: + /* This check may be too tight */ + for (i = 0; i < (*num_bl_ports); i++) { + assert(0 < (*bl_ports)[i]->size); + } + for (i = 0; i < (*num_wl_ports); i++) { + assert(0 < (*wl_ports)[i]->size); + } + break; + case SPICE_MODEL_DESIGN_CMOS: + for (i = 0; i < (*num_bl_ports); i++) { + assert(0 < (*bl_ports)[i]->size); + } + for (i = 0; i < (*num_wl_ports); i++) { + assert(0 < (*wl_ports)[i]->size); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", + __FILE__, __LINE__, cur_spice_model->name); + exit(1); + } + + return; +} + +/* Find BL and WL ports for a SRAM model. + * And check if the number of BL/WL satisfy the technology needs + */ +void find_blb_wlb_ports_spice_model(t_spice_model* cur_spice_model, + int* num_blb_ports, t_spice_model_port*** blb_ports, + int* num_wlb_ports, t_spice_model_port*** wlb_ports) { + /* Check */ + assert(NULL != cur_spice_model); + + /* Find BL ports */ + (*blb_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_BLB, num_blb_ports, TRUE); + /* Find WL ports */ + (*wlb_ports) = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_WLB, num_wlb_ports, TRUE); + + return; +} + + +/* Functions to manipulate struct sram_orgz_info */ +t_sram_orgz_info* alloc_one_sram_orgz_info() { + return (t_sram_orgz_info*)my_malloc(sizeof(t_sram_orgz_info)); +} + +t_mem_bank_info* alloc_one_mem_bank_info() { + return (t_mem_bank_info*)my_malloc(sizeof(t_mem_bank_info)); +} + +void free_one_mem_bank_info(t_mem_bank_info* mem_bank_info) { + return; +} + +t_scff_info* alloc_one_scff_info() { + return (t_scff_info*)my_malloc(sizeof(t_scff_info)); +} + +void free_one_scff_info(t_scff_info* scff_info) { + return; +} + +t_standalone_sram_info* alloc_one_standalone_sram_info() { + return (t_standalone_sram_info*)my_malloc(sizeof(t_standalone_sram_info)); +} + +void free_one_standalone_sram_info(t_standalone_sram_info* standalone_sram_info) { + return; +} + +void init_mem_bank_info(t_mem_bank_info* cur_mem_bank_info, + t_spice_model* cur_mem_model) { + assert(NULL != cur_mem_bank_info); + assert(NULL != cur_mem_model); + cur_mem_bank_info->mem_model = cur_mem_model; + cur_mem_bank_info->num_mem_bit = 0; + cur_mem_bank_info->num_bl = 0; + cur_mem_bank_info->num_wl = 0; + cur_mem_bank_info->reserved_bl = 0; + cur_mem_bank_info->reserved_wl = 0; + + return; +} + +void update_mem_bank_info_num_mem_bit(t_mem_bank_info* cur_mem_bank_info, + int num_mem_bit) { + assert(NULL != cur_mem_bank_info); + + cur_mem_bank_info->num_mem_bit = num_mem_bit; + + return; +} + +void init_scff_info(t_scff_info* cur_scff_info, + t_spice_model* cur_mem_model) { + assert(NULL != cur_scff_info); + assert(NULL != cur_mem_model); + + cur_scff_info->mem_model = cur_mem_model; + cur_scff_info->num_mem_bit = 0; + cur_scff_info->num_scff = 0; + + return; +} + +void update_scff_info_num_mem_bit(t_scff_info* cur_scff_info, + int num_mem_bit) { + assert(NULL != cur_scff_info); + + cur_scff_info->num_mem_bit = num_mem_bit; + + return; +} + +void init_standalone_sram_info(t_standalone_sram_info* cur_standalone_sram_info, + t_spice_model* cur_mem_model) { + assert(NULL != cur_standalone_sram_info); + assert(NULL != cur_mem_model); + + cur_standalone_sram_info->mem_model = cur_mem_model; + cur_standalone_sram_info->num_mem_bit = 0; + cur_standalone_sram_info->num_sram = 0; + + return; +} + +void update_standalone_sram_info_num_mem_bit(t_standalone_sram_info* cur_standalone_sram_info, + int num_mem_bit) { + assert(NULL != cur_standalone_sram_info); + + cur_standalone_sram_info->num_mem_bit = num_mem_bit; + + return; +} + +void init_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + enum e_sram_orgz cur_sram_orgz_type, + t_spice_model* cur_mem_model, + int grid_nx, int grid_ny) { + int i, num_bl_per_sram, num_wl_per_sram; + int num_bl_ports; + t_spice_model_port** bl_port = NULL; + int num_wl_ports; + t_spice_model_port** wl_port = NULL; + + assert(NULL != cur_sram_orgz_info); + + cur_sram_orgz_info->type = cur_sram_orgz_type; + cur_sram_orgz_info->conf_bit_head = NULL; /* Configuration bits will be allocated later */ + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + cur_sram_orgz_info->mem_bank_info = alloc_one_mem_bank_info(); + init_mem_bank_info(cur_sram_orgz_info->mem_bank_info, cur_mem_model); + find_bl_wl_ports_spice_model(cur_mem_model, + &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); + assert(1 == num_bl_ports); + assert(1 == num_wl_ports); + num_bl_per_sram = bl_port[0]->size; + num_wl_per_sram = wl_port[0]->size; + try_update_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, + num_bl_per_sram, num_wl_per_sram); + break; + case SPICE_SRAM_SCAN_CHAIN: + cur_sram_orgz_info->scff_info = alloc_one_scff_info(); + init_scff_info(cur_sram_orgz_info->scff_info, cur_mem_model); + break; + case SPICE_SRAM_STANDALONE: + cur_sram_orgz_info->standalone_sram_info = alloc_one_standalone_sram_info(); + init_standalone_sram_info(cur_sram_orgz_info->standalone_sram_info, cur_mem_model); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + /* Alloc the configuration bit information per grid */ + cur_sram_orgz_info->grid_nx = grid_nx; + cur_sram_orgz_info->grid_ny = grid_ny; + + cur_sram_orgz_info->grid_reserved_conf_bits = (int**)my_malloc(grid_nx*sizeof(int*)); + for (i = 0; i < grid_nx; i++) { + cur_sram_orgz_info->grid_reserved_conf_bits[i] = (int*)my_calloc(grid_ny, sizeof(int)); + } + + cur_sram_orgz_info->grid_conf_bits_lsb = (int**)my_malloc(grid_nx*sizeof(int*)); + for (i = 0; i < grid_nx; i++) { + cur_sram_orgz_info->grid_conf_bits_lsb[i] = (int*)my_calloc(grid_ny, sizeof(int)); + } + + cur_sram_orgz_info->grid_conf_bits_msb = (int**)my_malloc(grid_nx*sizeof(int*)); + for (i = 0; i < grid_nx; i++) { + cur_sram_orgz_info->grid_conf_bits_msb[i] = (int*)my_calloc(grid_ny, sizeof(int)); + } + + return; +} + + +void free_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + enum e_sram_orgz cur_sram_orgz_type) { + int i; + t_llist* temp = NULL; + + if (NULL == cur_sram_orgz_info) { + return; + } + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + free_one_mem_bank_info(cur_sram_orgz_info->mem_bank_info); + break; + case SPICE_SRAM_SCAN_CHAIN: + free_one_scff_info(cur_sram_orgz_info->scff_info); + break; + case SPICE_SRAM_STANDALONE: + free_one_standalone_sram_info(cur_sram_orgz_info->standalone_sram_info); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + /* Free configuration bits linked-list */ + temp = cur_sram_orgz_info->conf_bit_head; + while(NULL != temp) { + free_conf_bit_info((t_conf_bit_info*)(temp->dptr)); + /* Set the data pointor to NULL, then we can call linked list free function */ + temp->dptr = NULL; + /* Go the next */ + temp = temp->next; + } + free_llist(cur_sram_orgz_info->conf_bit_head); + + /* Free the configuration bit information per grid */ + for (i = 0; i < cur_sram_orgz_info->grid_nx; i++) { + my_free(cur_sram_orgz_info->grid_reserved_conf_bits[i]); + } + my_free(cur_sram_orgz_info->grid_reserved_conf_bits); + + for (i = 0; i < cur_sram_orgz_info->grid_nx; i++) { + my_free(cur_sram_orgz_info->grid_conf_bits_lsb[i]); + } + my_free(cur_sram_orgz_info->grid_conf_bits_lsb); + + for (i = 0; i < cur_sram_orgz_info->grid_nx; i++) { + my_free(cur_sram_orgz_info->grid_conf_bits_msb[i]); + } + my_free(cur_sram_orgz_info->grid_conf_bits_msb); + + return; +} + +void update_mem_bank_info_reserved_blwl(t_mem_bank_info* cur_mem_bank_info, + int updated_reserved_bl, int updated_reserved_wl) { + assert(NULL != cur_mem_bank_info); + + cur_mem_bank_info->reserved_bl = updated_reserved_bl; + cur_mem_bank_info->reserved_wl = updated_reserved_wl; + + return; +} + +void get_mem_bank_info_reserved_blwl(t_mem_bank_info* cur_mem_bank_info, + int* num_reserved_bl, int* num_reserved_wl) { + assert(NULL != cur_mem_bank_info); + + (*num_reserved_bl) = cur_mem_bank_info->reserved_bl; + (*num_reserved_wl) = cur_mem_bank_info->reserved_wl; + + return; +} + +void update_mem_bank_info_num_blwl(t_mem_bank_info* cur_mem_bank_info, + int updated_bl, int updated_wl) { + assert(NULL != cur_mem_bank_info); + + cur_mem_bank_info->num_bl = updated_bl; + cur_mem_bank_info->num_wl = updated_wl; + + return; +} + +/* Initialize the number of normal/reserved BLs and WLs, mem_bits in sram_orgz_info + * If the updated_reserved_bl|wl is larger than the existed value, + * we update the reserved_bl|wl + */ +void try_update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int updated_reserved_bl, int updated_reserved_wl) { + t_spice_model* mem_model = NULL; + int cur_bl, cur_wl; + + /* Check */ + assert(updated_reserved_bl == updated_reserved_wl); + + /* get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + break; + case SPICE_SRAM_MEMORY_BANK: + /* CMOS technology does not need to update */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + break; + case SPICE_MODEL_DESIGN_RRAM: + /* get the current number of reserved bls and wls */ + get_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + if ((updated_reserved_bl > cur_bl) || (updated_reserved_wl > cur_wl)) { + update_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, + updated_reserved_bl, updated_reserved_wl); + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, + updated_reserved_bl); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, + updated_reserved_bl, updated_reserved_wl); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of design technology!", + __FILE__, __LINE__ ); + exit(1); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + +} + +/* Force to update the number of reserved BLs and WLs in sram_orgz_info + * we always update the reserved_bl|wl + */ +void update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int updated_reserved_bl, int updated_reserved_wl) { + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + break; + case SPICE_SRAM_MEMORY_BANK: + update_mem_bank_info_reserved_blwl(cur_sram_orgz_info->mem_bank_info, + updated_reserved_bl, updated_reserved_wl); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return; +} + +void get_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int* num_reserved_bl, int* num_reserved_wl) { + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + break; + case SPICE_SRAM_MEMORY_BANK: + get_mem_bank_info_reserved_blwl(cur_sram_orgz_info->mem_bank_info, + num_reserved_bl, num_reserved_wl); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return; +} + +void get_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int* cur_bl, int* cur_wl) { + assert(NULL != cur_bl); + assert(NULL != cur_wl); + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + (*cur_bl) = 0; + (*cur_wl) = 0; + break; + case SPICE_SRAM_MEMORY_BANK: + (*cur_bl) = cur_sram_orgz_info->mem_bank_info->num_bl; + (*cur_wl) = cur_sram_orgz_info->mem_bank_info->num_wl; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return; +} + +int get_sram_orgz_info_num_mem_bit(t_sram_orgz_info* cur_sram_orgz_info) { + + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + return cur_sram_orgz_info->standalone_sram_info->num_mem_bit; + case SPICE_SRAM_SCAN_CHAIN: + return cur_sram_orgz_info->scff_info->num_mem_bit; + case SPICE_SRAM_MEMORY_BANK: + return cur_sram_orgz_info->mem_bank_info->num_mem_bit; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return 0; +} + +void update_sram_orgz_info_num_mem_bit(t_sram_orgz_info* cur_sram_orgz_info, + int new_num_mem_bit) { + + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + update_standalone_sram_info_num_mem_bit(cur_sram_orgz_info->standalone_sram_info, new_num_mem_bit); + break; + case SPICE_SRAM_SCAN_CHAIN: + update_scff_info_num_mem_bit(cur_sram_orgz_info->scff_info, new_num_mem_bit); + break; + case SPICE_SRAM_MEMORY_BANK: + update_mem_bank_info_num_mem_bit(cur_sram_orgz_info->mem_bank_info, new_num_mem_bit); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return; +} + +void update_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info, + int new_bl, int new_wl) { + + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + break; + case SPICE_SRAM_MEMORY_BANK: + update_mem_bank_info_num_blwl(cur_sram_orgz_info->mem_bank_info, new_bl, new_wl); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return; +} + +void get_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model** mem_model_ptr) { + + assert(NULL != cur_sram_orgz_info); + assert(NULL != mem_model_ptr); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + (*mem_model_ptr) = cur_sram_orgz_info->standalone_sram_info->mem_model; + break; + case SPICE_SRAM_SCAN_CHAIN: + (*mem_model_ptr) = cur_sram_orgz_info->scff_info->mem_model; + break; + case SPICE_SRAM_MEMORY_BANK: + (*mem_model_ptr) = cur_sram_orgz_info->mem_bank_info->mem_model; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + assert(NULL != (*mem_model_ptr)); + + return; +} + +void update_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mem_model) { + assert(NULL != cur_sram_orgz_info); + + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + cur_sram_orgz_info->standalone_sram_info->mem_model = cur_mem_model; + break; + case SPICE_SRAM_SCAN_CHAIN: + cur_sram_orgz_info->scff_info->mem_model = cur_mem_model; + break; + case SPICE_SRAM_MEMORY_BANK: + cur_sram_orgz_info->mem_bank_info->mem_model = cur_mem_model; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + return; +} + + +/* Copy from a src sram_orgz_info to a des sram_orgz_info + * The des_orgz_info must be allocated before!!! + */ +void copy_sram_orgz_info(t_sram_orgz_info* des_sram_orgz_info, + t_sram_orgz_info* src_sram_orgz_info) { + t_spice_model* src_mem_model = NULL; + int src_num_bl, src_num_wl; + int ix, iy; + + get_sram_orgz_info_mem_model(src_sram_orgz_info, &src_mem_model); + + /* Start copying */ + des_sram_orgz_info->type = src_sram_orgz_info->type; + update_sram_orgz_info_mem_model(des_sram_orgz_info, src_mem_model); + update_sram_orgz_info_num_mem_bit(des_sram_orgz_info, + get_sram_orgz_info_num_mem_bit(src_sram_orgz_info)); + /* According to the type, we create the diff. */ + switch (des_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + get_sram_orgz_info_num_blwl(src_sram_orgz_info, &src_num_bl, &src_num_wl); + update_sram_orgz_info_num_blwl(des_sram_orgz_info, src_num_bl, src_num_wl); + break; + case SPICE_SRAM_SCAN_CHAIN: + break; + case SPICE_SRAM_STANDALONE: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + /* Copy conf bits */ + for (ix = 0; ix < des_sram_orgz_info->grid_nx; ix++) { + for (iy = 0; iy < des_sram_orgz_info->grid_ny; iy++) { + des_sram_orgz_info->grid_reserved_conf_bits[ix][iy] = src_sram_orgz_info->grid_reserved_conf_bits[ix][iy]; + des_sram_orgz_info->grid_conf_bits_lsb[ix][iy] = src_sram_orgz_info->grid_conf_bits_lsb[ix][iy]; + des_sram_orgz_info->grid_conf_bits_msb[ix][iy] = src_sram_orgz_info->grid_conf_bits_msb[ix][iy]; + } + } + + return; +} + +/* Create a snapshot on the sram_orgz_info, + * return the snapshot + */ +t_sram_orgz_info* snapshot_sram_orgz_info(t_sram_orgz_info* src_sram_orgz_info) { + t_sram_orgz_info* des_sram_orgz_info = NULL; + t_spice_model* src_mem_model = NULL; + + /* allocate the snapshot */ + des_sram_orgz_info = alloc_one_sram_orgz_info(); + + /* initialize the snapshot */ + get_sram_orgz_info_mem_model(src_sram_orgz_info, &src_mem_model); + init_sram_orgz_info(des_sram_orgz_info, src_sram_orgz_info->type, + src_mem_model, src_sram_orgz_info->grid_nx, src_sram_orgz_info->grid_ny); + + /* Start copying */ + copy_sram_orgz_info( des_sram_orgz_info, + src_sram_orgz_info); + + return des_sram_orgz_info; +} + +/* Compare the two sram_orgz_info and store the difference in the sram_orgz_info to return */ +t_sram_orgz_info* diff_sram_orgz_info(t_sram_orgz_info* des_sram_orgz_info, + t_sram_orgz_info* base_sram_orgz_info) { + t_sram_orgz_info* diff_sram_orgz_info = NULL; + t_spice_model* base_mem_model = NULL; + t_spice_model* des_mem_model = NULL; + int des_num_wl, base_num_wl; + int des_num_bl, base_num_bl; + int ix, iy; + + /* Check: we have the same memory organization type */ + assert ( des_sram_orgz_info->type == base_sram_orgz_info->type ); + get_sram_orgz_info_mem_model(base_sram_orgz_info, &base_mem_model); + get_sram_orgz_info_mem_model(des_sram_orgz_info, &des_mem_model); + assert (des_mem_model == base_mem_model); + assert (des_sram_orgz_info->grid_nx == base_sram_orgz_info->grid_nx); + assert (des_sram_orgz_info->grid_ny == base_sram_orgz_info->grid_ny); + + /* allocate the diff copy */ + diff_sram_orgz_info = alloc_one_sram_orgz_info(); + init_sram_orgz_info(diff_sram_orgz_info, des_sram_orgz_info->type, + des_mem_model, des_sram_orgz_info->grid_nx, des_sram_orgz_info->grid_ny); + + /* initialize the diff_copy */ + update_sram_orgz_info_num_mem_bit(diff_sram_orgz_info, + get_sram_orgz_info_num_mem_bit(des_sram_orgz_info) - get_sram_orgz_info_num_mem_bit(base_sram_orgz_info)); + /* According to the type, we create the diff. */ + switch (des_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + get_sram_orgz_info_num_blwl(des_sram_orgz_info, &des_num_bl, &des_num_wl); + get_sram_orgz_info_num_blwl(base_sram_orgz_info, &base_num_bl, &base_num_wl); + update_sram_orgz_info_num_blwl(diff_sram_orgz_info, des_num_bl - base_num_bl, des_num_wl - base_num_wl); + break; + case SPICE_SRAM_SCAN_CHAIN: + break; + case SPICE_SRAM_STANDALONE: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__ ); + exit(1); + } + + /* Copy conf bits */ + for (ix = 0; ix < diff_sram_orgz_info->grid_nx; ix++) { + for (iy = 0; iy < diff_sram_orgz_info->grid_ny; iy++) { + diff_sram_orgz_info->grid_reserved_conf_bits[ix][iy] = des_sram_orgz_info->grid_reserved_conf_bits[ix][iy] - base_sram_orgz_info->grid_reserved_conf_bits[ix][iy]; + diff_sram_orgz_info->grid_conf_bits_lsb[ix][iy] = des_sram_orgz_info->grid_conf_bits_lsb[ix][iy] - base_sram_orgz_info->grid_conf_bits_lsb[ix][iy]; + diff_sram_orgz_info->grid_conf_bits_msb[ix][iy] = des_sram_orgz_info->grid_conf_bits_msb[ix][iy] - base_sram_orgz_info->grid_conf_bits_msb[ix][iy]; + } + } + + return diff_sram_orgz_info; +} + + +/* Manipulating functions for struct t_reserved_syntax_char */ +void init_reserved_syntax_char(t_reserved_syntax_char* cur_reserved_syntax_char, + char cur_syntax_char, boolean cur_verilog_reserved, boolean cur_spice_reserved) { + assert(NULL != cur_reserved_syntax_char); + + cur_reserved_syntax_char->syntax_char = cur_syntax_char; + cur_reserved_syntax_char->verilog_reserved = cur_verilog_reserved; + cur_reserved_syntax_char->spice_reserved = cur_spice_reserved; + + return; +} + +void check_mem_model_blwl_inverted(t_spice_model* cur_mem_model, + enum e_spice_model_port_type blwl_port_type, + boolean* blwl_inverted) { + int num_blwl_ports = 0; + t_spice_model_port** blwl_port = NULL; + + /* Check */ + assert((SPICE_MODEL_PORT_BL == blwl_port_type)||(SPICE_MODEL_PORT_WL == blwl_port_type)); + + /* Find BL and WL ports */ + blwl_port = find_spice_model_ports(cur_mem_model, blwl_port_type, &num_blwl_ports, TRUE); + + /* If we cannot find any return with warnings */ + if (0 == num_blwl_ports) { + (*blwl_inverted) = FALSE; + vpr_printf(TIO_MESSAGE_WARNING, "(FILE:%s,[LINE%d])Unable to find any BL/WL port for memory model(%s)!\n", + __FILE__, __LINE__, cur_mem_model->name); + return; + } + + /* Only 1 port should be found */ + assert(1 == num_blwl_ports); + /* And port size should be at least 1 */ + assert(0 < blwl_port[0]->size); + + /* if default value of a BL/WL port is 0, we do not need an inversion. */ + if (0 == blwl_port[0]->default_val) { + (*blwl_inverted) = FALSE; + } else { + /* if default value of a BL/WL port is 1, we need an inversion! */ + assert(1 == blwl_port[0]->default_val); + (*blwl_inverted) = TRUE; + } + + return; +} + + +/* Check if all the SRAM ports have the correct SPICE MODEL */ +void config_spice_models_sram_port_spice_model(int num_spice_model, + t_spice_model* spice_models, + t_spice_model* default_sram_spice_model) { + int i, iport; + + for (i = 0; i < num_spice_model; i++) { + for (iport = 0; iport < spice_models[i].num_port; iport++) { + /* Bypass non SRAM ports */ + if (SPICE_MODEL_PORT_SRAM != spice_models[i].ports[iport].type) { + continue; + } + /* Write for the default SRAM SPICE model! */ + spice_models[i].ports[iport].spice_model = default_sram_spice_model; + /* Only show warning when we try to override the given spice_model_name ! */ + if (NULL == spice_models[i].ports[iport].spice_model_name) { + continue; + } + /* Give a warning !!! */ + if (0 != strcmp(default_sram_spice_model->name, spice_models[i].ports[iport].spice_model_name)) { + vpr_printf(TIO_MESSAGE_WARNING, + "(FILE:%s, LINE[%d]) Overwrite SRAM SPICE MODEL of SPICE model port (name:%s, port:%s) to be the correct one (name:%s)!\n", + __FILE__ ,__LINE__, + spice_models[i].name, + spice_models[i].ports[iport].prefix, + default_sram_spice_model->name); + } + } + } + + return; +} + +void determine_sb_port_coordinator(t_sb cur_sb_info, int side, + int* port_x, int* port_y) { + /* Check */ + assert ((-1 < side) && (side < 4)); + /* Initialize */ + (*port_x) = -1; + (*port_y) = -1; + + switch (side) { + case TOP: + /* (0 == side) */ + /* 1. Channel Y [x][y+1] inputs */ + (*port_x) = cur_sb_info.x; + (*port_y) = cur_sb_info.y + 1; + break; + case RIGHT: + /* 1 == side */ + /* 2. Channel X [x+1][y] inputs */ + (*port_x) = cur_sb_info.x + 1; + (*port_y) = cur_sb_info.y; + break; + case BOTTOM: + /* 2 == side */ + /* 3. Channel Y [x][y] inputs */ + (*port_x) = cur_sb_info.x; + (*port_y) = cur_sb_info.y; + break; + case LEFT: + /* 3 == side */ + /* 4. Channel X [x][y] inputs */ + (*port_x) = cur_sb_info.x; + (*port_y) = cur_sb_info.y; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid side of sb[%d][%d]!\n", + __FILE__, __LINE__, cur_sb_info.x, cur_sb_info.y, side); + exit(1); + } + + return; +} + +void init_spice_models_tb_cnt(int num_spice_models, + t_spice_model* spice_model) { + int imodel; + + for (imodel = 0; imodel < num_spice_models; imodel++) { + spice_model[imodel].tb_cnt = 0; + } + + return; +} + +void init_spice_models_grid_tb_cnt(int num_spice_models, + t_spice_model* spice_model, + int grid_x, int grid_y) { + int imodel; + + for (imodel = 0; imodel < num_spice_models; imodel++) { + spice_model[imodel].tb_cnt = spice_model[imodel].grid_index_low[grid_x][grid_y]; + } + + return; +} + +void check_spice_models_grid_tb_cnt(int num_spice_models, + t_spice_model* spice_model, + int grid_x, int grid_y, + enum e_spice_model_type spice_model_type_to_check) { + int imodel; + + for (imodel = 0; imodel < num_spice_models; imodel++) { + if (spice_model_type_to_check != spice_model[imodel].type) { + continue; + } + assert(spice_model[imodel].tb_cnt == spice_model[imodel].grid_index_high[grid_x][grid_y]); + } + + return; +} + +boolean check_negative_variation(float avg_val, + t_spice_mc_variation_params variation_params) { + boolean exist_neg_val = FALSE; + + /* Assume only support gaussian variation now */ + if (avg_val < 0.) { + exist_neg_val = TRUE; + } + + return exist_neg_val; +} + +/* Check if this cby_info exists, it may be covered by a heterogenous block */ +boolean is_cb_exist(t_rr_type cb_type, + int cb_x, int cb_y) { + boolean cb_exist = TRUE; + + /* Check */ + assert((!(0 > cb_x))&&(!(cb_x > (nx + 1)))); + assert((!(0 > cb_y))&&(!(cb_y > (ny + 1)))); + + switch (cb_type) { + case CHANX: + /* Border case */ + /* Check the grid under this CB */ + if ((NULL == grid[cb_x][cb_y].type) + ||(EMPTY_TYPE == grid[cb_x][cb_y].type) + ||(1 < grid[cb_x][cb_y].type->height)) { + cb_exist = FALSE; + } + break; + case CHANY: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid CB type! Should be CHANX or CHANY.\n", + __FILE__, __LINE__); + exit(1); + } + + return cb_exist; +} + +/* Count the number of IPIN rr_nodes in a CB_info struct */ +int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info) { + int side; + int cnt = 0; + + for (side = 0; side < cur_cb_info.num_sides; side++) { + cnt += cur_cb_info.num_ipin_rr_nodes[side]; + } + + return cnt; +} + +/* Add a subckt file name to a linked list */ +t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head, + char* subckt_file_path) { + t_llist* new_head = NULL; + + if (NULL == cur_head) { + new_head = create_llist(1); + new_head->dptr = (void*) my_strdup(subckt_file_path); + } else { + new_head = insert_llist_node_before_head(cur_head); + new_head->dptr = (void*) my_strdup(subckt_file_path); + } + + return new_head; +} + +/* Check if SPICE subckt is already created + * (if they exist in a given linked-list + */ +boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head, + char* subckt_file_name) { + t_llist* temp = NULL; + + temp = subckt_llist_head; + while (temp) { + if (0 == strcmp(subckt_file_name, (char*)(temp->dptr))) { + return TRUE; + } + temp = temp->next; + } + + return FALSE; +} + +/* Identify if this is a primitive pb_type */ +boolean is_primitive_pb_type(t_pb_type* cur_pb_type) { + + if ((NULL != cur_pb_type->spice_model_name) + || (NULL != cur_pb_type->physical_pb_type_name)) { + return TRUE; + } + return FALSE; +} + +/* Recursively find all the global ports in the spice_model / sub spice_model + */ +void rec_stats_spice_model_global_ports(t_spice_model* cur_spice_model, + boolean recursive, + t_llist** spice_model_head) { + int iport; + t_llist* temp = NULL; + + /* Check */ + assert(NULL != cur_spice_model); + if (0 < cur_spice_model->num_port) { + assert(NULL != cur_spice_model->ports); + } + + for (iport = 0; iport < cur_spice_model->num_port; iport++) { + /* if this spice model requires customized netlist to be included, we do not go recursively */ + if (TRUE == recursive) { + /* GO recursively first, and meanwhile count the number of global ports */ + /* For the port that requires another spice_model, i.e., SRAM + * We need include any global port in that spice model + */ + if (NULL != cur_spice_model->ports[iport].spice_model) { + rec_stats_spice_model_global_ports(cur_spice_model->ports[iport].spice_model, + recursive, spice_model_head); + } + } + /* By pass non-global ports*/ + if (FALSE == cur_spice_model->ports[iport].is_global) { + continue; + } + /* Now we have a global port, add it to linked list */ + assert (TRUE == cur_spice_model->ports[iport].is_global); + if (NULL == (*spice_model_head)) { + (*spice_model_head) = create_llist(1); + /* Configure the data pointer of linked list */ + (*spice_model_head)->dptr = (void*) (&cur_spice_model->ports[iport]); + /* Check if this ports exists in the linked list */ + } else if (FALSE == check_dptr_exist_in_llist((*spice_model_head), + (void*)(&cur_spice_model->ports[iport]))) { + /* Non-exist in the current linked-list, a new node is required + * Go to the tail of the linked-list and add a new node + */ + temp = search_llist_tail(*spice_model_head); + temp = insert_llist_node(temp); + /* Configure the data pointer of linked list */ + temp->dptr = (void*) (&cur_spice_model->ports[iport]); + } + } + + return; +} + +/* Create a snapshot on spice_model counter */ +int* snapshot_spice_model_counter(int num_spice_models, + t_spice_model* spice_model) { + int i; + int* snapshot = (int*) my_calloc(num_spice_models, sizeof(int)); + + for (i = 0; i < num_spice_models; i++) { + snapshot[i] = spice_model[i].cnt; + } + + return snapshot; +} + + +void set_spice_model_counter(int num_spice_models, + t_spice_model* spice_model, + int* spice_model_counter) { + int i; + + for (i = 0; i < num_spice_models; i++) { + spice_model[i].cnt = spice_model_counter[i]; + } + + return; +} + +/* Find the vpack_net_num of the outputs of the logical_block */ +void get_logical_block_output_vpack_net_num(t_logical_block* cur_logical_block, + int* num_lb_output_ports, int** num_lb_output_pins, + int*** lb_output_vpack_net_num) { + int iport, ipin; + int num_output_ports = 0; + int* num_output_pins = NULL; + t_model_ports* head = NULL; + int** output_vpack_net_num = NULL; + + assert (NULL != cur_logical_block); + + /* Count how many outputs we have */ + head = cur_logical_block->model->outputs; + while (NULL != head) { + num_output_ports++; + head = head->next; + } + /* Allocate */ + num_output_pins = (int*) my_calloc(num_output_ports, sizeof(int)); + output_vpack_net_num = (int**) my_calloc(num_output_ports, sizeof(int*)); + /* Fill the array */ + iport = 0; + head = cur_logical_block->model->outputs; + while (NULL != head) { + num_output_pins[iport] = head->size; + output_vpack_net_num[iport] = (int*) my_calloc(num_output_pins[iport], sizeof(int)); + /* Fill the array */ + for (ipin = 0; ipin < num_output_pins[iport]; ipin++) { + output_vpack_net_num[iport][ipin] = cur_logical_block->output_nets[iport][ipin]; + } + /* Go to the next */ + head = head->next; + /* Update counter */ + iport++; + } + + assert (iport == num_output_ports); + + /* Assign return values */ + (*num_lb_output_ports) = num_output_ports; + (*num_lb_output_pins) = num_output_pins; + (*lb_output_vpack_net_num) = output_vpack_net_num; + + return; +} + +int get_lut_logical_block_index_with_output_vpack_net_num(int target_vpack_net_num) { + int iblk, iport; + int matched_lb_index = OPEN; + int matched_count = 0; + int num_lut_output_ports; + int* num_lut_output_pins; + int** lut_output_vpack_net_num; + + for (iblk = 0; iblk < num_logical_blocks; iblk++) { + /* Bypass the non-LUT logical block */ + if (VPACK_COMB != logical_block[iblk].type) { + continue; + } + if (LUT_CLASS != logical_block[iblk].pb->pb_graph_node->pb_type->class_type) { + continue; + } + /* Reach here it should be a LUT */ + get_logical_block_output_vpack_net_num(&logical_block[iblk], + &num_lut_output_ports, &num_lut_output_pins, + &lut_output_vpack_net_num); + /* Check */ + assert ( 1 == num_lut_output_ports); + assert ( 1 == num_lut_output_pins[0]); + assert ( OPEN != lut_output_vpack_net_num[0][0]); + + if (target_vpack_net_num == lut_output_vpack_net_num[0][0]) { + matched_lb_index = iblk; + matched_count++; + } + + /* Free */ + my_free(num_lut_output_pins); + for (iport = 0; iport < num_lut_output_ports; iport++) { + my_free(lut_output_vpack_net_num); + } + } + + assert ((0 == matched_count) + || (1 == matched_count)); + + return matched_lb_index; +} + +/* Get the operational clock port from the global port linked list */ +void get_fpga_x2p_global_op_clock_ports(t_llist* head, + int* num_clock_ports, + t_spice_model_port*** clock_port) { + t_llist* temp = head; + t_spice_model_port* cur_port = NULL; + int cnt = 0; + + /* Get the number of clock ports */ + while (NULL != temp) { + cur_port = (t_spice_model_port*)(temp->dptr); + if ( (SPICE_MODEL_PORT_CLOCK == cur_port->type) + && (FALSE == cur_port->is_prog)) { + cnt++; + } + /* Go to the next */ + temp = temp->next; + } + + /* Initialize the counter */ + (*num_clock_ports) = cnt; + + /* Malloc */ + (*clock_port) = (t_spice_model_port**)my_calloc((*num_clock_ports), sizeof(t_spice_model_port*)); + + /* Reset the counter */ + temp = head; + cnt = 0; + /* Fill the return array */ + while (NULL != temp) { + cur_port = (t_spice_model_port*)(temp->dptr); + if ( (SPICE_MODEL_PORT_CLOCK == cur_port->type) + && (FALSE == cur_port->is_prog)) { + (*clock_port)[cnt] = cur_port; + cnt++; + } + /* Go to the next */ + temp = temp->next; + } + + assert (cnt == (*num_clock_ports)); + + return; +} + +/* Get all the clock ports from the global port linked list */ +void get_fpga_x2p_global_all_clock_ports(t_llist* head, + int* num_clock_ports, + t_spice_model_port*** clock_port) { + t_llist* temp = head; + t_spice_model_port* cur_port = NULL; + int cnt = 0; + + /* Get the number of clock ports */ + while (NULL != temp) { + cur_port = (t_spice_model_port*)(temp->dptr); + if ( (SPICE_MODEL_PORT_CLOCK == cur_port->type)) { + cnt++; + } + /* Go to the next */ + temp = temp->next; + } + + /* Initialize the counter */ + (*num_clock_ports) = cnt; + + /* Malloc */ + (*clock_port) = (t_spice_model_port**)my_calloc((*num_clock_ports), sizeof(t_spice_model_port*)); + + /* Reset the counter */ + temp = head; + cnt = 0; + /* Fill the return array */ + while (NULL != temp) { + cur_port = (t_spice_model_port*)(temp->dptr); + if ( (SPICE_MODEL_PORT_CLOCK == cur_port->type)) { + (*clock_port)[cnt] = cur_port; + cnt++; + } + /* Go to the next */ + temp = temp->next; + } + + assert (cnt == (*num_clock_ports)); + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h similarity index 51% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h index ff587d22c..b56d08b2a 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h @@ -34,6 +34,11 @@ t_spice_model* get_default_spice_model(enum e_spice_model_type default_spice_mod t_spice_model_port* find_spice_model_port_by_name(t_spice_model* cur_spice_model, char* port_name); +void config_one_spice_model_buffer(int num_spice_models, + t_spice_model* spice_model, + t_spice_model* cur_spice_model, + t_spice_model_buffer* cur_spice_model_buffer); + void config_spice_model_input_output_buffers_pass_gate(int num_spice_models, t_spice_model* spice_model); @@ -49,6 +54,8 @@ t_spice_model_port** find_spice_model_config_done_ports(t_spice_model* spice_mod t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib, e_spice_trans_type trans_type); +char* my_itobin(int in_int, int bin_len); + char* my_itoa(int input); char* fpga_spice_create_one_subckt_filename(char* file_name_prefix, @@ -59,64 +66,29 @@ char* chomp_spice_node_prefix(char* spice_node_prefix); char* format_spice_node_prefix(char* spice_node_prefix); -t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, - t_spice_model_port* spice_model_port); char* format_spice_node_prefix(char* spice_node_prefix); -t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type, - enum e_spice_model_port_type port_type, - int* port_num); t_block* search_mapped_block(int x, int y, int z); -int determine_num_sram_bits_mux_basis_subckt(t_spice_model* mux_spice_model, - int mux_size, - int num_input_per_level, - boolean special_basis); -int determine_tree_mux_level(int mux_size); - -int determine_num_input_basis_multilevel_mux(int mux_size, - int mux_level); - -int tree_mux_last_level_input_num(int num_level, - int mux_size); - -int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit, - int mux_size); - -int determine_lut_path_id(int lut_size, - int* lut_inputs); - -int* decode_onelevel_mux_sram_bits(int fan_in, - int mux_level, - int path_id); - -int* decode_multilevel_mux_sram_bits(int fan_in, - int mux_level, - int path_id); - -int* decode_tree_mux_sram_bits(int fan_in, - int mux_level, - int path_id); - -void decode_cmos_mux_sram_bits(t_spice_model* mux_spice_model, - int mux_size, int path_id, - int* bit_len, int** conf_bits, int* mux_level); - -char** my_strtok(char* str, - char* delims, - int* len); +char** fpga_spice_strtok(char* str, + char* delims, + int* len); int get_opposite_side(int side); char* convert_side_index_to_string(int side); +char* convert_process_corner_to_string(enum e_process_corner process_corner); + char* convert_chan_type_to_string(t_rr_type chan_type); +char* convert_cb_type_to_string(t_rr_type chan_type); + char* convert_chan_rr_node_direction_to_string(enum PORTS chan_rr_node_direction); void init_spice_net_info(t_spice_net_info* spice_net_info); @@ -160,41 +132,6 @@ float get_rr_node_net_probability(t_rr_node node); int get_rr_node_net_init_value(t_rr_node node); - -int find_parent_pb_type_child_index(t_pb_type* parent_pb_type, - int mode_index, - t_pb_type* child_pb_type); - -void gen_spice_name_tag_pb_rec(t_pb* cur_pb, - char* prefix); - -void gen_spice_name_tags_all_pbs(); - -void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge); - -void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin); - -void backup_one_pb_rr_node_pack_prev_node_edge(t_rr_node* pb_rr_node); - -void update_one_grid_pack_prev_node_edge(int x, int y); - -void update_grid_pbs_post_route_rr_graph(); - -int find_pb_mapped_logical_block_rec(t_pb* cur_pb, - t_spice_model* pb_spice_model, - char* pb_spice_name_tag); - -int find_grid_mapped_logical_block(int x, int y, - t_spice_model* pb_spice_model, - char* pb_spice_name_tag); - -void stats_pb_graph_node_port_pin_numbers(t_pb_graph_node* cur_pb_graph_node, - int* num_inputs, - int* num_outputs, - int* num_clock_pins); - -void map_clb_pins_to_pb_graph_pins(); - int recommend_num_sim_clock_cycle(); void auto_select_num_sim_clock_cycle(t_spice* spice, @@ -230,46 +167,13 @@ char* gen_str_spice_model_structure(enum e_spice_model_structure spice_model_str boolean check_spice_model_structure_match_switch_inf(t_switch_inf target_switch_inf); -int find_pb_type_idle_mode_index(t_pb_type cur_pb_type); - -int find_pb_type_physical_mode_index(t_pb_type cur_pb_type); - -void mark_grid_type_pb_graph_node_pins_temp_net_num(int x, int y); - -void assign_pb_graph_node_pin_temp_net_num_by_mode_index(t_pb_graph_pin* cur_pb_graph_pin, - int mode_index); - -void mark_pb_graph_node_input_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, - int mode_index); - -void mark_pb_graph_node_clock_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, - int mode_index); - -void mark_pb_graph_node_output_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node, - int mode_index); - -void rec_mark_pb_graph_node_temp_net_num(t_pb_graph_node* cur_pb_graph_node); - -void load_one_pb_graph_pin_temp_net_num_from_pb(t_pb* cur_pb, - t_pb_graph_pin* cur_pb_graph_pin); - -void load_pb_graph_node_temp_net_num_from_pb(t_pb* cur_pb); - -void rec_mark_one_pb_unused_pb_graph_node_temp_net_num(t_pb* cur_pb); - -void update_pb_vpack_net_num_from_temp_net_num(t_pb* cur_pb, - t_pb_graph_pin* cur_pb_graph_pin); - -void update_pb_graph_node_temp_net_num_to_pb(t_pb_graph_node* cur_pb_graph_node, - t_pb* cur_pb); - -void rec_load_unused_pb_graph_node_temp_net_num_to_pb(t_pb* cur_pb); - -void mark_one_pb_parasitic_nets(t_pb* cur_pb); void init_rr_nodes_vpack_net_num_changed(int LL_num_rr_nodes, t_rr_node* LL_rr_node); +void init_rr_nodes_is_parasitic_net(int LL_num_rr_nodes, + t_rr_node* LL_rr_node); + boolean is_net_pi(t_net* cur_net); int check_consistency_logical_block_net_num(t_logical_block* lgk_blk, @@ -290,50 +194,6 @@ void find_drive_rr_nodes_switch_box(int switch_box_x, t_rr_node*** drive_rr_nodes, int* switch_index); -int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model, - int mux_size); - -int count_num_conf_bits_one_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type, - int mux_size); - -int count_num_reserved_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type); - -int count_num_reserved_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type, - int mux_size); - -int count_num_reserved_conf_bits_one_rram_sram_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type); - -int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model, - enum e_sram_orgz cur_sram_orgz_type, - int mux_size); - -int count_num_conf_bit_one_interc(t_interconnect* cur_interc, - enum e_sram_orgz cur_sram_orgz_type); - -int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc, - enum e_sram_orgz cur_sram_orgz_type); - -int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode, - enum e_sram_orgz cur_sram_orgz_type); - -int rec_count_num_conf_bits_pb_type_default_mode(t_pb_type* cur_pb_type, - t_sram_orgz_info* cur_sram_orgz_info); - -int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, - t_sram_orgz_info* cur_sram_orgz_info); - -int rec_count_num_conf_bits_pb(t_pb* cur_pb, - t_sram_orgz_info* cur_sram_orgz_info); - -void init_one_grid_num_conf_bits(int ix, int iy, - t_sram_orgz_info* cur_sram_orgz_info); - -void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info); - void zero_spice_models_cnt(int num_spice_models, t_spice_model* spice_model); void zero_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model); @@ -362,23 +222,6 @@ void update_spice_models_routing_index_low(int x, int y, t_rr_type chan_type, int num_spice_models, t_spice_model* spice_model); -void rec_count_num_iopads_pb_type_physical_mode(t_pb_type* cur_pb_type); - -void rec_count_num_iopads_pb_type_default_mode(t_pb_type* cur_pb_type); - -void rec_count_num_iopads_pb(t_pb* cur_pb); - -void init_one_grid_num_iopads(int ix, int iy); - -void init_grids_num_iopads(); - -void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type); - -void rec_count_num_mode_bits_pb(t_pb* cur_pb); - -void init_one_grid_num_mode_bits(int ix, int iy); - -void init_grids_num_mode_bits(); void check_sram_spice_model_ports(t_spice_model* cur_spice_model, boolean include_bl_wl); @@ -401,31 +244,6 @@ add_conf_bit_info_to_llist(t_llist* head, int index, t_conf_bit* sram_val, t_conf_bit* bl_val, t_conf_bit* wl_val, t_spice_model* parent_spice_model); -void -add_mux_scff_conf_bits_to_llist(int mux_size, - t_sram_orgz_info* cur_sram_orgz_info, - int num_mux_sram_bits, int* mux_sram_bits, - t_spice_model* mux_spice_model); - -void -add_mux_membank_conf_bits_to_llist(int mux_size, - t_sram_orgz_info* cur_sram_orgz_info, - int num_mux_sram_bits, int* mux_sram_bits, - t_spice_model* mux_spice_model); - -void -add_mux_conf_bits_to_llist(int mux_size, - t_sram_orgz_info* cur_sram_orgz_info, - int num_mux_sram_bits, int* mux_sram_bits, - t_spice_model* mux_spice_model); - -void add_sram_membank_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, - int num_bls, int num_wls, - int* bl_conf_bits, int* wl_conf_bits); - -void -add_sram_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, - int num_sram_bits, int* sram_bits); void find_bl_wl_ports_spice_model(t_spice_model* cur_spice_model, int* num_bl_ports, t_spice_model_port*** bl_ports, @@ -435,51 +253,7 @@ void find_blb_wlb_ports_spice_model(t_spice_model* cur_spice_model, int* num_blb_ports, t_spice_model_port*** blb_ports, int* num_wlb_ports, t_spice_model_port*** wlb_ports); -int* decode_mode_bits(char* mode_bits, int* num_sram_bits); -/* Useful functions for LUT decoding */ -void stats_lut_spice_mux(t_llist** muxes_head, - t_spice_model* spice_model); - -char* complete_truth_table_line(int lut_size, - char* input_truth_table_line); - -void configure_lut_sram_bits_per_line_rec(int** sram_bits, - int lut_size, - char* truth_table_line, - int start_point); - -int* generate_lut_sram_bits(int truth_table_len, - char** truth_table, - int lut_size, - int default_sram_bit_value); - -char** assign_lut_truth_table(t_logical_block* mapped_logical_block, - int* truth_table_length); - -void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_block, - int* num_lut_pin, int** lut_pin_net); - -void get_logical_block_output_vpack_net_num(t_logical_block* cur_logical_block, - int* num_lb_output_ports, int** num_lb_output_pins, - int*** lb_output_vpack_net_num); - -int get_pb_graph_node_wired_lut_logical_block_index(t_pb_graph_node* cur_pb_graph_node, - t_rr_node* op_pb_rr_graph); - -char** assign_post_routing_wired_lut_truth_table(t_logical_block* wired_lut_logical_block, - int lut_size, int* lut_pin_vpack_net_num, - int* truth_table_length); - -char** assign_post_routing_lut_truth_table(t_logical_block* mapped_logical_block, - int lut_size, int* lut_pin_vpack_net_num, - int* truth_table_length); - -int get_ff_output_init_val(t_logical_block* ff_logical_block); - -int get_lut_output_init_val(t_logical_block* lut_logical_block); - -int get_logical_block_output_init_val(t_logical_block* cur_logical_block); /* Functions to manipulate structs of SRAM orgz */ t_sram_orgz_info* alloc_one_sram_orgz_info(); @@ -534,9 +308,13 @@ void init_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, t_spice_model* cur_mem_model, int grid_nx, int grid_ny); +t_sram_orgz_info* snapshot_sram_orgz_info(t_sram_orgz_info* src_sram_orgz_info); + +t_sram_orgz_info* diff_sram_orgz_info(t_sram_orgz_info* des_sram_orgz_info, + t_sram_orgz_info* base_sram_orgz_info); + void free_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, - enum e_sram_orgz cur_sram_orgz_type, - int grid_nx, int grid_ny); + enum e_sram_orgz cur_sram_orgz_type); void update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info, int updated_reserved_bl, int updated_reserved_wl); @@ -555,6 +333,12 @@ void update_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info, void get_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info, t_spice_model** mem_model_ptr); +void update_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mem_model); + +void copy_sram_orgz_info(t_sram_orgz_info* des_sram_orgz_info, + t_sram_orgz_info* src_sram_orgz_info); + void init_reserved_syntax_char(t_reserved_syntax_char* cur_reserved_syntax_char, char cur_syntax_char, boolean cur_verilog_reserved, boolean cur_spice_reserved); @@ -562,48 +346,6 @@ void check_mem_model_blwl_inverted(t_spice_model* cur_mem_model, enum e_spice_model_port_type blwl_port_type, boolean* blwl_inverted); -void init_spice_mux_arch(t_spice_model* spice_model, - t_spice_mux_arch* spice_mux_arch, - int mux_size); - -int find_spice_mux_arch_special_basis_size(t_spice_mux_arch spice_mux_arch); - -t_llist* search_mux_linked_list(t_llist* mux_head, - int mux_size, - t_spice_model* spice_model); - -void check_and_add_mux_to_linked_list(t_llist** muxes_head, - int mux_size, - t_spice_model* spice_model); - -void free_muxes_llist(t_llist* muxes_head); - -void stats_spice_muxes_routing_arch(t_llist** muxes_head, - int num_switch, - t_switch_inf* switches, - t_spice* spice, - t_det_routing_arch* routing_arch); - -void stats_mux_spice_model_pb_type_rec(t_llist** muxes_head, - t_pb_type* cur_pb_type); - -void stats_mux_spice_model_pb_node_rec(t_llist** muxes_head, - t_pb_graph_node* cur_pb_node); - -t_llist* stats_spice_muxes(int num_switch, - t_switch_inf* switches, - t_spice* spice, - t_det_routing_arch* routing_arch); - -enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin); - -t_spice_model* find_pb_graph_pin_in_edges_interc_spice_model(t_pb_graph_pin pb_graph_pin); - -int find_path_id_between_pb_rr_nodes(t_rr_node* local_rr_graph, - int src_node, - int des_node); - -t_pb* get_child_pb_for_phy_pb_graph_node(t_pb* cur_pb, int ipb, int jpb); void config_spice_model_port_inv_spice_model(int num_spice_models, t_spice_model* spice_model); @@ -611,15 +353,6 @@ void config_spice_model_port_inv_spice_model(int num_spice_models, void config_spice_models_sram_port_spice_model(int num_spice_model, t_spice_model* spice_models, t_spice_model* default_sram_spice_model); -t_pb* get_lut_child_pb(t_pb* cur_lut_pb, - int mode_index); - -t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb, - int mode_index); - -int get_grid_pin_height(int grid_x, int grid_y, int pin_index); - -int get_grid_pin_side(int grid_x, int grid_y, int pin_index); void determine_sb_port_coordinator(t_sb cur_sb_info, int side, int* port_x, int* port_y); @@ -650,18 +383,29 @@ t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head, boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head, char* subckt_file_name); -void get_mapped_lut_pb_input_pin_vpack_net_num(t_pb_graph_node* lut_pb_graph_node, - t_rr_node* pb_rr_graph, - int* num_lut_pin, int** lut_pin_net); +boolean is_primitive_pb_type(t_pb_type* cur_pb_type); void rec_stats_spice_model_global_ports(t_spice_model* cur_spice_model, boolean recursive, t_llist** spice_model_head); -boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node, - t_pb_type* cur_pb_type, - t_rr_node* pb_rr_graph); +int* snapshot_spice_model_counter(int num_spice_models, + t_spice_model* spice_model); -boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node, - t_pb_type* cur_pb_type, - t_rr_node* pb_rr_graph); +void set_spice_model_counter(int num_spice_models, + t_spice_model* spice_model, + int* spice_model_counter); + +void get_logical_block_output_vpack_net_num(INP t_logical_block* cur_logical_block, + OUTP int* num_lb_output_ports, OUTP int** num_lb_output_pins, + OUTP int*** lb_output_vpack_net_num); + +int get_lut_logical_block_index_with_output_vpack_net_num(int target_vpack_net_num); + +void get_fpga_x2p_global_op_clock_ports(t_llist* head, + int* num_clock_ports, + t_spice_model_port*** clock_port); + +void get_fpga_x2p_global_all_clock_ports(t_llist* head, + int* num_clock_ports, + t_spice_model_port*** clock_port); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/quicksort.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/quicksort.c similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/quicksort.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/quicksort.c diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/quicksort.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/quicksort.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/quicksort.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/base/quicksort.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.c b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.c similarity index 69% rename from vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.c index cd9527249..505391f47 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/base/fpga_spice_bitstream.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.c @@ -24,14 +24,12 @@ /* Include FPGA-SPICE utils */ #include "read_xml_spice_util.h" #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "spice_api.h" -#include "fpga_spice_globals.h" - -/* Include SynVerilog headers */ -#include "verilog_global.h" -#include "verilog_utils.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream_pbtypes.h" +#include "fpga_bitstream_routing.h" /* Global variables only in file */ static int dumped_num_conf_bits = 0; @@ -228,7 +226,6 @@ void dump_conf_bits_to_bitstream_file(FILE* fp, bl_decoder_size = determine_decoder_size(num_bl); wl_decoder_size = determine_decoder_size(num_wl); - while (NULL != temp) { cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); /* We alraedy touch the tail, start dump */ @@ -286,3 +283,119 @@ void dump_conf_bits_to_bitstream_file(FILE* fp, return; } + +/* Top-level function*/ +void vpr_fpga_generate_bitstream(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name, + char* bitstream_file_path, + t_sram_orgz_info** cur_sram_orgz_info) { + /* Timer */ + clock_t t_start; + clock_t t_end; + float run_time_sec; + + char* chomped_parent_dir = NULL; + char* chomped_circuit_name = NULL; + + char* routing_bitstream_log_file_path = NULL; + char* lb_bitstream_log_file_path = NULL; + + /* Check if the routing architecture we support*/ + if (UNI_DIRECTIONAL != vpr_setup.RoutingArch.directionality) { + vpr_printf(TIO_MESSAGE_ERROR, "FPGA Bitstream Generator only support uni-directional routing architecture!\n"); + exit(1); + } + + /* We don't support mrFPGA */ +#ifdef MRFPGA_H + if (is_mrFPGA) { + vpr_printf(TIO_MESSAGE_ERROR, "FPGA Bitstream Generator do not support mrFPGA!\n"); + exit(1); + } +#endif + + assert (TRUE == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream); + + /* Format the directory paths */ + split_path_prog_name(circuit_name, '/', &chomped_parent_dir, &chomped_circuit_name); + + /* VerilogGenerator formally starts*/ + vpr_printf(TIO_MESSAGE_INFO, "\nFPGA Bitstream generator starts...\n"); + + /* Start time count */ + t_start = clock(); + + /* assign the global variable of SRAM model */ + assert(NULL != Arch.sram_inf.verilog_sram_inf_orgz); /* Check !*/ + /* initialize the SRAM organization information struct */ + (*cur_sram_orgz_info) = alloc_one_sram_orgz_info(); + init_sram_orgz_info(*cur_sram_orgz_info, Arch.sram_inf.verilog_sram_inf_orgz->type, + Arch.sram_inf.verilog_sram_inf_orgz->spice_model, nx + 2, ny + 2); + /* Check all the SRAM port is using the correct SRAM SPICE MODEL */ + config_spice_models_sram_port_spice_model(Arch.spice->num_spice_model, + Arch.spice->spice_models, + Arch.sram_inf.verilog_sram_inf_orgz->spice_model); + + /* zero the counter of each spice_model */ + zero_spice_models_cnt(Arch.spice->num_spice_model, Arch.spice->spice_models); + + /* Generate Bitstreams + * Bitstream generation must follow the sequence: CB => SB => Grid + * (To be consistent with Verilog Generator !!!) + */ + init_sram_orgz_info_reserved_blwl(*cur_sram_orgz_info, vpr_setup.RoutingArch.num_switch, + switch_inf, Arch.spice, &vpr_setup.RoutingArch); + + /* Routing: Connection Boxes and Switch Boxes */ + routing_bitstream_log_file_path = my_strcat(circuit_name, fpga_spice_bitstream_routing_log_file_postfix); + fpga_spice_generate_bitstream_routing_resources(routing_bitstream_log_file_path, + Arch, &vpr_setup.RoutingArch, *cur_sram_orgz_info, + num_rr_nodes, rr_node, rr_node_indices); + + + /* Logic blocks */ + lb_bitstream_log_file_path = my_strcat(circuit_name, fpga_spice_bitstream_logic_block_log_file_postfix); + fpga_spice_generate_bitstream_logic_block(lb_bitstream_log_file_path, + &Arch, *cur_sram_orgz_info); + + + /* Dump bitstream file */ + dump_fpga_spice_bitstream(bitstream_file_path, chomped_circuit_name, *cur_sram_orgz_info); + + /* End time count */ + t_end = clock(); + + run_time_sec = (float)(t_end - t_start) / CLOCKS_PER_SEC; + vpr_printf(TIO_MESSAGE_INFO, "Bitstream Generation took %g seconds\n", run_time_sec); + + /* Free */ + + return; + +} + +/* This is a shell for bitstream generation + * Prepare all the variables required by the core generator + */ +void vpr_fpga_bitstream_generator(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name, + t_sram_orgz_info** cur_sram_orgz_info) { + char* bitstream_file_path = NULL; + + if (NULL == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.bitstream_output_file) { + bitstream_file_path = my_strcat(circuit_name, fpga_spice_bitstream_output_file_postfix); + } else { + bitstream_file_path = my_strdup(vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.bitstream_output_file); + } + + /* Run bitstream generation and dump output file */ + vpr_fpga_generate_bitstream(vpr_setup, Arch, circuit_name, bitstream_file_path, cur_sram_orgz_info); + + /* Free */ + my_free(bitstream_file_path); + +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.h b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.h new file mode 100644 index 000000000..39213e9a1 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream.h @@ -0,0 +1,18 @@ + +void encode_decoder_addr(int input, + int decoder_size, char* addr); + +void dump_fpga_spice_bitstream(char* bitstream_file_name, + char* circuit_name, + t_sram_orgz_info* cur_sram_orgz_info); + +void vpr_fpga_generate_bitstream(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name, + char* bitstream_file_path, + t_sram_orgz_info** cur_sram_orgz_info); + +void vpr_fpga_bitstream_generator(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name, + t_sram_orgz_info** cur_sram_orgz_info); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c new file mode 100644 index 000000000..c752765a5 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.c @@ -0,0 +1,684 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_bitstream_primitives.h" + + +/***** Subroutines *****/ + +/* We check output_pins of cur_pb_graph_node and its the input_edges + * Built the interconnections between outputs of cur_pb_graph_node and outputs of child_pb_graph_node + * src_pb_graph_node.[in|out]_pins -----------------> des_pb_graph_node.[in|out]pins + * /|\ + * | + * input_pins, edges, output_pins + */ +void fpga_spice_generate_bitstream_pb_graph_pin_interc(FILE* fp, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, + t_pb_graph_pin* des_pb_graph_pin, + t_mode* cur_mode, + int select_edge, + t_sram_orgz_info* cur_sram_orgz_info) { + int iedge, ilevel; + int fan_in = 0; + t_interconnect* cur_interc = NULL; + enum e_interconnect verilog_interc_type = DIRECT_INTERC; + + int num_mux_sram_bits = 0; + int* mux_sram_bits = NULL; + int mux_level = 0; + int cur_bl, cur_wl; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* 1. identify pin interconnection type, + * 2. Identify the number of fan-in (Consider interconnection edges of only selected mode) + * 3. Select and print the SPICE netlist + */ + fan_in = 0; + cur_interc = NULL; + find_interc_fan_in_des_pb_graph_pin(des_pb_graph_pin, cur_mode, &cur_interc, &fan_in); + if ((NULL == cur_interc)||(0 == fan_in)) { + /* No interconnection matched */ + /* Connect this pin to GND for better convergence */ + /* TODO: find the correct pin name!!!*/ + return; + } + verilog_interc_type = determine_actual_pb_interc_type(cur_interc, fan_in); + /* This time, (2nd round), we print the subckt, according to interc type*/ + switch (verilog_interc_type) { + case DIRECT_INTERC: + /* Check : + * 1. Direct interc has only one fan-in! + */ + assert(1 == fan_in); + //assert(1 == des_pb_graph_pin->num_input_edges); + /* For more than one mode defined, the direct interc has more than one input_edge , + * We need to find which edge is connected the pin we want + */ + for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { + if (cur_interc == des_pb_graph_pin->input_edges[iedge]->interconnect) { + break; + } + } + assert(iedge < des_pb_graph_pin->num_input_edges); + /* 2. spice_model is a wire */ + assert(NULL != cur_interc->spice_model); + assert(SPICE_MODEL_WIRE == cur_interc->spice_model->type); + assert(NULL != cur_interc->spice_model->wire_param); + /* Call the subckt that has already been defined before */ + cur_interc->spice_model->cnt++; /* Stats the number of spice_model used*/ + break; + case COMPLETE_INTERC: + case MUX_INTERC: + /* Check : + * MUX should have at least 2 fan_in + */ + assert((2 == fan_in)||(2 < fan_in)); + /* 2. spice_model is a wire */ + assert(NULL != cur_interc->spice_model); + assert(SPICE_MODEL_MUX == cur_interc->spice_model->type); + /* Print SRAMs that configure this MUX */ + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + /* SRAMs */ + switch (cur_interc->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(cur_interc->spice_model, fan_in, select_edge, + &num_mux_sram_bits, &mux_sram_bits, &mux_level); + break; + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(cur_interc->spice_model, fan_in, select_edge, + &num_mux_sram_bits, &mux_sram_bits, &mux_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", + __FILE__, __LINE__, cur_interc->spice_model->name); + } + + /* Print the encoding in SPICE netlist for debugging */ + fprintf(fp, "***** SRAM bits for MUX[%d], mux_size=%d, level=%d, select_path_id=%d. *****\n", + cur_interc->spice_model->cnt, fan_in, mux_level, select_edge); + fprintf(fp, "*****"); + for (ilevel = 0; ilevel < num_mux_sram_bits; ilevel++) { + fprintf(fp, "%d", mux_sram_bits[ilevel]); + } + fprintf(fp, "*****\n\n"); + + /* Store the configuraion bit to linked-list */ + add_mux_conf_bits_to_llist(fan_in, cur_sram_orgz_info, + num_mux_sram_bits, mux_sram_bits, + cur_interc->spice_model); + /* Synchronize the sram_orgz_info with mem_bits */ + add_mux_conf_bits_to_sram_orgz_info(cur_sram_orgz_info, cur_interc->spice_model, fan_in); + /* update sram counter */ + cur_interc->spice_model->cnt++; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + + return; +} + +void fpga_spice_generate_bitstream_pb_graph_port_interc(FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb, + enum e_spice_pb_port_type pb_port_type, + t_mode* cur_mode, + t_sram_orgz_info* cur_sram_orgz_info) { + int iport, ipin; + int node_index = -1; + int prev_node = -1; + int path_id = -1; + t_rr_node* pb_rr_nodes = NULL; + + if (NULL != cur_pb) { + fprintf(fp, "***** Logic block:%s *****\n", + cur_pb->spice_name_tag); + fprintf(fp, "***** Pb_graph_node: %s[%d]*****\n", + cur_pb_graph_node->pb_type->name, cur_pb_graph_node->placement_index); + } + + switch (pb_port_type) { + case SPICE_PB_PORT_INPUT: + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + fprintf(fp, "***** Input Port: %s[%d]*****\n", + cur_pb_graph_node->input_pins[iport][ipin].port->name, + cur_pb_graph_node->input_pins[iport][ipin].pin_number); + /* If this is a idle block, we set 0 to the selected edge*/ + /* Get the selected edge of current pin*/ + if (NULL == cur_pb) { + path_id = DEFAULT_PATH_ID; + } else { + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->input_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + /* Path id for the sdc generation */ + pb_rr_nodes[node_index].id_path = path_id; + + if (OPEN != pb_rr_nodes[node_index].vpack_net_num) { + fprintf(fp, "***** Net name: %s *****\n", + vpack_net[pb_rr_nodes[node_index].vpack_net_num].name); + } + } + fpga_spice_generate_bitstream_pb_graph_pin_interc(fp, INPUT2INPUT_INTERC, + &(cur_pb_graph_node->input_pins[iport][ipin]), + cur_mode, + path_id, cur_sram_orgz_info); + } + } + break; + case SPICE_PB_PORT_OUTPUT: + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + fprintf(fp, "***** Output Port: %s[%d]*****\n", + cur_pb_graph_node->output_pins[iport][ipin].port->name, + cur_pb_graph_node->output_pins[iport][ipin].pin_number); + /* If this is a idle block, we set 0 to the selected edge*/ + /* Get the selected edge of current pin*/ + if (NULL == cur_pb) { + path_id = DEFAULT_PATH_ID; + } else { + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->output_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + // Path id for the sdc generation + pb_rr_nodes[node_index].id_path = path_id; + + if (OPEN != pb_rr_nodes[node_index].vpack_net_num) { + fprintf(fp, "***** Net name: %s *****\n", + vpack_net[pb_rr_nodes[node_index].vpack_net_num].name); + } + } + fpga_spice_generate_bitstream_pb_graph_pin_interc(fp, OUTPUT2OUTPUT_INTERC, + &(cur_pb_graph_node->output_pins[iport][ipin]), + cur_mode, + path_id, cur_sram_orgz_info); + } + } + break; + case SPICE_PB_PORT_CLOCK: + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + fprintf(fp, "***** Clock Port: %s[%d]*****\n", + cur_pb_graph_node->clock_pins[iport][ipin].port->name, + cur_pb_graph_node->clock_pins[iport][ipin].pin_number); + /* If this is a idle block, we set 0 to the selected edge*/ + /* Get the selected edge of current pin*/ + if (NULL == cur_pb) { + path_id = DEFAULT_PATH_ID; + } else { + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->clock_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + // Path id for the sdc generation + pb_rr_nodes[node_index].id_path = path_id; + + if (OPEN != pb_rr_nodes[node_index].vpack_net_num) { + fprintf(fp, "***** Net name: %s *****\n", + vpack_net[pb_rr_nodes[node_index].vpack_net_num].name); + } + } + fpga_spice_generate_bitstream_pb_graph_pin_interc(fp, INPUT2INPUT_INTERC, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + cur_mode, + path_id, cur_sram_orgz_info); + + } + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pb port type!\n", + __FILE__, __LINE__); + exit(1); + } + + + return; +} + +/* Print the SPICE interconnections according to pb_graph */ +void fpga_spice_generate_bitstream_pb_graph_interc(FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb, + int select_mode_index, + t_sram_orgz_info* cur_sram_orgz_info) { + int ipb, jpb; + t_mode* cur_mode = NULL; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + t_pb_graph_node* child_pb_graph_node = NULL; + t_phy_pb* child_pb = NULL; + + /* Check cur_pb_type*/ + if (NULL == cur_pb_graph_node) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Assign current mode */ + cur_mode = &(cur_pb_graph_node->pb_type->modes[select_mode_index]); + + /* We check output_pins of cur_pb_graph_node and its the input_edges + * Built the interconnections between outputs of cur_pb_graph_node and outputs of child_pb_graph_node + * child_pb_graph_node.output_pins -----------------> cur_pb_graph_node.outpins + * /|\ + * | + * input_pins, edges, output_pins + */ + fpga_spice_generate_bitstream_pb_graph_port_interc(fp, cur_pb_graph_node, + cur_pb, + SPICE_PB_PORT_OUTPUT, + cur_mode, + cur_sram_orgz_info); + + /* We check input_pins of child_pb_graph_node and its the input_edges + * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node + * cur_pb_graph_node.input_pins -----------------> child_pb_graph_node.input_pins + * /|\ + * | + * input_pins, edges, output_pins + */ + for (ipb = 0; ipb < cur_pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { + child_pb_graph_node = &(cur_pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]); + /* branch on empty pb */ + if (NULL == cur_pb) { + child_pb = NULL; + } else { + child_pb = &(cur_pb->child_pbs[ipb][jpb]); + } + /* For each child_pb_graph_node input pins*/ + fpga_spice_generate_bitstream_pb_graph_port_interc(fp, child_pb_graph_node, + child_pb, + SPICE_PB_PORT_INPUT, + cur_mode, + cur_sram_orgz_info); + /* TODO: for clock pins, we should do the same work */ + fpga_spice_generate_bitstream_pb_graph_port_interc(fp, child_pb_graph_node, + child_pb, + SPICE_PB_PORT_CLOCK, + cur_mode, + cur_sram_orgz_info); + } + } + + return; +} + +/* Print the subckt of a primitive pb */ +void fpga_spice_generate_bitstream_pb_primitive(FILE* fp, + t_phy_pb* prim_pb, + t_pb_type* prim_pb_type, + t_sram_orgz_info* cur_sram_orgz_info) { + /* Check cur_pb_graph_node*/ + if (NULL == prim_pb_type) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_type.\n", + __FILE__, __LINE__); + exit(1); + } + assert (TRUE == prim_pb_type->parent_mode->define_physical_mode); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* According to different type, we print netlist*/ + switch (prim_pb_type->spice_model->type) { + case SPICE_MODEL_LUT: + /* If this is a idle block we should set sram_bits to zero*/ + fpga_spice_generate_bitstream_pb_primitive_lut(fp, prim_pb, prim_pb_type, cur_sram_orgz_info); + break; + case SPICE_MODEL_FF: + assert(NULL != prim_pb_type->spice_model->model_netlist); + /* TODO : We should learn trigger type and initial value!!! and how to apply them!!! */ + fpga_spice_generate_bitstream_pb_generic_primitive(fp, prim_pb, prim_pb_type, cur_sram_orgz_info); + break; + case SPICE_MODEL_IOPAD: + assert(NULL != prim_pb_type->spice_model->model_netlist); + fpga_spice_generate_bitstream_pb_generic_primitive(fp, prim_pb, prim_pb_type, cur_sram_orgz_info); + break; + case SPICE_MODEL_HARDLOGIC: + assert(NULL != prim_pb_type->spice_model->model_netlist); + fpga_spice_generate_bitstream_pb_generic_primitive(fp, prim_pb, prim_pb_type, cur_sram_orgz_info); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of verilog_model(%s), should be [LUT|FF|HARD_LOGIC|IO]!\n", + __FILE__, __LINE__, prim_pb_type->spice_model->name); + exit(1); + } + + return; +} + +/* Print physical mode of pb_types and configure it to the idle pb_types recursively + * search the idle_mode until we reach the leaf node + */ +void fpga_spice_generate_bitstream_phy_pb_graph_node_rec(FILE* fp, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, + int pb_type_index, + t_sram_orgz_info* cur_sram_orgz_info) { + int mode_index, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + t_phy_pb* child_pb = NULL; + + /* Check cur_pb_graph_node*/ + if (NULL == cur_pb_graph_node) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + cur_pb_type = cur_pb_graph_node->pb_type; + + /* Recursively finish all the child pb_types*/ + if (NULL == cur_pb_type->spice_model) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + /* Find the child pb that is mapped, and the mapping info is not stored in the physical mode ! */ + if (NULL == cur_pb) { + child_pb = NULL; + } else { + assert (NULL != cur_pb); + child_pb = get_phy_child_pb_for_phy_pb_graph_node(cur_pb, ipb, jpb); + } + fpga_spice_generate_bitstream_phy_pb_graph_node_rec(fp, child_pb, + &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), jpb, + cur_sram_orgz_info); + } + } + } + + /* Check if this has defined a spice_model*/ + if (NULL != cur_pb_type->spice_model) { + switch (cur_pb_type->class_type) { + case LUT_CLASS: + /* Special care for LUT !!! + * Mapped logical block information is stored in child_pbs + */ + fpga_spice_generate_bitstream_pb_primitive( fp, cur_pb, + cur_pb_type, + cur_sram_orgz_info); + break; + case LATCH_CLASS: + assert(0 == cur_pb_type->num_modes); + /* Consider the num_pb, create all the subckts*/ + fpga_spice_generate_bitstream_pb_primitive( fp, cur_pb, + cur_pb_type, + cur_sram_orgz_info); + break; + case UNKNOWN_CLASS: + case MEMORY_CLASS: + /* Consider the num_pb, create all the subckts*/ + fpga_spice_generate_bitstream_pb_primitive( fp, cur_pb, + cur_pb_type, + cur_sram_orgz_info); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", + __FILE__, __LINE__, cur_pb_type->name); + exit(1); + } + /* Finish for primitive node, return */ + return; + } + + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + + /* Print interconnections, set is_idle as TRUE*/ + fpga_spice_generate_bitstream_pb_graph_interc(fp, cur_pb_graph_node, cur_pb, mode_index, cur_sram_orgz_info); + + return; +} + + +/* Print an physical logic block + * Find the physical_mode in arch files, + * And print the verilog netlist into file + */ +void fpga_spice_generate_bitstream_one_physical_block(FILE* fp, + int x, int y, int z, + t_type_ptr type_descriptor, + t_sram_orgz_info* cur_sram_orgz_info) { + t_pb_graph_node* top_pb_graph_node = NULL; + t_block* mapped_block = NULL; + t_phy_pb* top_pb = NULL; + + /* Ensure we have a valid type_descriptor*/ + assert(NULL != type_descriptor); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Go for the pb_types*/ + top_pb_graph_node = type_descriptor->pb_graph_head; + assert(NULL != top_pb_graph_node); + + /* Check in all the mapped blocks(clustered logic block), there is a match x,y,z*/ + mapped_block = search_mapped_block(x, y, z); + if (NULL != mapped_block) { + top_pb = (t_phy_pb*)mapped_block->phy_pb; + assert(NULL != top_pb); + } + + /* Recursively find all idle mode and print netlist*/ + fpga_spice_generate_bitstream_phy_pb_graph_node_rec(fp, top_pb, top_pb_graph_node, + z, cur_sram_orgz_info); + + return; +} + +/* Print the SPICE netlist for a I/O grid blocks */ +void fpga_spice_generate_bitstream_physical_grid_block(FILE* fp, + int ix, int iy, + t_arch* arch, + t_sram_orgz_info* cur_sram_orgz_info) { + int iz; + int capacity; + + /* Check */ + assert((!(0 > ix))&&(!(ix > (nx + 1)))); + assert((!(0 > iy))&&(!(iy > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* generate_grid_subckt, type_descriptor of each grid defines the capacity, + * for example, each grid may contains more than one top-level pb_types, such as I/O + */ + if ((NULL == grid[ix][iy].type) + ||(EMPTY_TYPE == grid[ix][iy].type) + ||(0 != grid[ix][iy].offset)) { + return; + } + + capacity= grid[ix][iy].type->capacity; + assert(0 < capacity); + + /* check capacity and if this has been mapped */ + for (iz = 0; iz < capacity; iz++) { + /* Print a NULL logic block...*/ + fpga_spice_generate_bitstream_one_physical_block(fp, ix, iy, iz, grid[ix][iy].type, cur_sram_orgz_info); + } + + return; +} + +/* Print all logic blocks SPICE models + * Each logic blocks in the grid that allocated for the FPGA + * will be printed. May have an additional option that only + * output the used logic blocks + */ +void fpga_spice_generate_bitstream_logic_block(char* lb_bitstream_log_file_path, + t_arch* arch, + t_sram_orgz_info* cur_sram_orgz_info) { + int ix, iy; + FILE* fp = NULL; + + /* Create a file handler */ + fp = fopen(lb_bitstream_log_file_path, "w"); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in creating log file %s", + __FILE__, __LINE__, lb_bitstream_log_file_path); + exit(1); + } + + /* Check the grid*/ + if ((0 == nx)||(0 == ny)) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid grid size (nx=%d, ny=%d)!\n", __FILE__, __LINE__, nx, ny); + return; + } + + assert(NULL != grid); + + /* Print the core logic block one by one + * Note ix=0 and ix = nx + 1 are IO pads. They surround the core logic blocks + */ + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for core grids...\n"); + for (ix = 1; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is not a io */ + assert(IO_TYPE != grid[ix][iy].type); + /* Ensure a valid usage */ + assert((0 == grid[ix][iy].usage)||(0 < grid[ix][iy].usage)); + fpga_spice_generate_bitstream_physical_grid_block(fp, ix, iy, arch, cur_sram_orgz_info); + } + } + + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for IO grids...\n"); + /* Print the IO pads */ + /* Top side : x = 1 .. nx + 1, y = nx + 1 */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + fpga_spice_generate_bitstream_physical_grid_block(fp, ix, iy, arch, cur_sram_orgz_info); + } + + /* Right side : x = nx + 1, y = 1 .. ny*/ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + fpga_spice_generate_bitstream_physical_grid_block(fp, ix, iy, arch, cur_sram_orgz_info); + } + /* Bottom side : x = 1 .. nx + 1, y = 0 */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + fpga_spice_generate_bitstream_physical_grid_block(fp, ix, iy, arch, cur_sram_orgz_info); + } + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + fpga_spice_generate_bitstream_physical_grid_block(fp, ix, iy, arch, cur_sram_orgz_info); + } + + /* Close log file */ + fclose(fp); + + /* Free */ + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.h b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.h new file mode 100644 index 000000000..af50df3d7 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_pbtypes.h @@ -0,0 +1,6 @@ + + + +void fpga_spice_generate_bitstream_logic_block(char* lb_bitstream_log_file_path, + t_arch* arch, + t_sram_orgz_info* cur_sram_orgz_info) ; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.c b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.c new file mode 100644 index 000000000..112cf5716 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.c @@ -0,0 +1,483 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "rr_graph_swseg.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_lut_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" + +/* Generate the bitstream of a generic primitive node: + * this node can be HARD LOGIC, IO, FF */ +void fpga_spice_generate_bitstream_pb_generic_primitive(FILE* fp, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + t_sram_orgz_info* cur_sram_orgz_info) { + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + t_spice_model* verilog_model = NULL; + + int i, mapped_logical_block_index; + int num_sram = 0; + int* sram_bits = NULL; + + /* For each SRAM, we could have multiple BLs/WLs */ + int num_bl_ports = 0; + t_spice_model_port** bl_port = NULL; + int num_wl_ports = 0; + t_spice_model_port** wl_port = NULL; + int num_bl_per_sram = 0; + int num_wl_per_sram = 0; + int expected_num_sram; + + int cur_num_sram = 0; + t_spice_model* mem_model = NULL; + + /* Ensure a valid physical pritimive pb */ + if (NULL == prim_pb_type) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Asserts */ + if (NULL != prim_phy_pb) { + assert (prim_phy_pb->pb_graph_node->pb_type->phy_pb_type == prim_pb_type); + } + assert (NULL != prim_pb_type->spice_model); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + verilog_model = prim_pb_type->spice_model; + + assert((SPICE_MODEL_IOPAD == verilog_model->type) + || (SPICE_MODEL_HARDLOGIC == verilog_model->type) + || (SPICE_MODEL_FF == verilog_model->type)); + + /* Find ports*/ + sram_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + + /* if there is no SRAM ports, we can return */ + if ( 0 == num_sram_port) { + /* Back-annotate to logical block */ + if (NULL != prim_phy_pb) { + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + mapped_logical_block_index = prim_phy_pb->logical_block[i]; + logical_block[mapped_logical_block_index].mapped_spice_model = verilog_model; + logical_block[mapped_logical_block_index].mapped_spice_model_index = verilog_model->cnt; + } + } + /* Update the verilog_model counter */ + verilog_model->cnt++; + return; + } + + /* Initialize */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + /* Local wires */ + /* Find the number of BLs/WLs of each SRAM */ + /* Detect the SRAM SPICE model linked to this SRAM port */ + assert(NULL != sram_ports[0]->spice_model); + assert(SPICE_MODEL_SRAM == sram_ports[0]->spice_model->type); + find_bl_wl_ports_spice_model(sram_ports[0]->spice_model, + &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); + assert(1 == num_bl_ports); + assert(1 == num_wl_ports); + num_bl_per_sram = bl_port[0]->size; + num_wl_per_sram = wl_port[0]->size; + break; + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + /* what is the SRAM bit of a mode? */ + /* If logical block is not NULL, we need to decode the sram bit */ + if (NULL != prim_phy_pb) { + sram_bits = decode_mode_bits(prim_phy_pb->mode_bits, &expected_num_sram); + } else { /* get default mode_bits */ + sram_bits = decode_mode_bits(prim_pb_type->mode_bits, &expected_num_sram); + } + assert(expected_num_sram == num_sram); + + /* SRAM_bit will be later reconfigured according to operating mode */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + for (i = 0; i < num_sram; i++) { + /* Decode the SRAM bits to BL/WL bits. + * first half part is BL, the other half part is WL + */ + decode_and_add_sram_membank_conf_bit_to_llist(cur_sram_orgz_info, cur_num_sram + i, + num_bl_per_sram, num_wl_per_sram, + sram_bits[i]); + } + break; + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + /* Store the configuraion bit to linked-list */ + add_mux_conf_bits_to_llist(0, cur_sram_orgz_info, + num_sram, sram_bits, + verilog_model); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Back-annotate to logical block */ + if (NULL != prim_phy_pb) { + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + mapped_logical_block_index = prim_phy_pb->logical_block[i]; + logical_block[mapped_logical_block_index].mapped_spice_model = verilog_model; + logical_block[mapped_logical_block_index].mapped_spice_model_index = verilog_model->cnt; + } + } + /* Synchronize the internal counters of sram_orgz_info with generated bitstreams*/ + add_sram_conf_bits_to_sram_orgz_info(cur_sram_orgz_info, verilog_model); + + /* Print the encoding in SPICE netlist for debugging */ + if (NULL != prim_phy_pb) { + fprintf(fp, "***** Logic Block %s *****\n", + prim_phy_pb->spice_name_tag); + } + fprintf(fp, "***** SRAM bits for %s[%d] *****\n", + verilog_model->name, verilog_model->cnt); + fprintf(fp, "*****"); + for (i = 0; i < num_sram; i++) { + fprintf(fp, "%d", sram_bits[i]); + } + fprintf(fp, "*****\n"); + + + /* Update the verilog_model counter */ + verilog_model->cnt++; + + /*Free*/ + my_free(sram_ports); + my_free(sram_bits); + my_free(bl_port); + my_free(wl_port); + + return; +} + +void fpga_spice_generate_bitstream_pb_primitive_lut(FILE* fp, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + t_sram_orgz_info* cur_sram_orgz_info) { + + int i, j; + int* lut_sram_bits = NULL; /* decoded SRAM bits */ + int* mode_sram_bits = NULL; /* decoded SRAM bits */ + int* sram_bits = NULL; /* decoded SRAM bits */ + int* truth_table_length = 0; + char*** truth_table = NULL; + int lut_size = 0; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + t_spice_model_port* lut_sram_port = NULL; + t_spice_model_port* mode_bit_port = NULL; + int num_lut_pin_nets; + int* lut_pin_net = NULL; + int mapped_logical_block_index; + + int cur_num_sram = 0; + int num_sram = 0; + int num_lut_sram = 0; + int num_mode_sram = 0; + /* For each SRAM, we could have multiple BLs/WLs */ + int num_bl_ports = 0; + t_spice_model_port** bl_port = NULL; + int num_wl_ports = 0; + t_spice_model_port** wl_port = NULL; + int num_bl_per_sram = 0; + int num_wl_per_sram = 0; + t_spice_model* mem_model = NULL; + int expected_num_sram = 0; + t_spice_model* verilog_model = NULL; + + /* Ensure a valid physical pritimive pb */ + if (NULL == prim_pb_type) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Asserts */ + if (NULL != prim_phy_pb) { + assert (prim_phy_pb->pb_graph_node->pb_type->phy_pb_type == prim_pb_type); + } + assert (NULL != prim_pb_type->spice_model); + + verilog_model = prim_pb_type->spice_model; + assert(SPICE_MODEL_LUT == verilog_model->type); + + /* Find the input ports for LUT size */ + input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + assert(1 == num_input_port); + lut_size = input_ports[0]->size; + + /* Find SRAM ports for truth tables and mode bits */ + sram_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + assert((1 == num_sram_port) || (2 == num_sram_port)); + for (i = 0; i < num_sram_port; i++) { + if (FALSE == sram_ports[i]->mode_select) { + lut_sram_port = sram_ports[i]; + num_lut_sram = sram_ports[i]->size; + assert (num_lut_sram == (int)pow(2.,(double)(lut_size))); + } else { + assert (TRUE == sram_ports[i]->mode_select); + mode_bit_port = sram_ports[i]; + num_mode_sram = sram_ports[i]->size; + } + } + /* Must have a lut_sram_port, while mode_bit_port is optional */ + assert (NULL != lut_sram_port); + + /* Count the number of configuration bits */ + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + /* Get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + /* Find the number of BLs/WLs of each SRAM */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + /* Detect the SRAM SPICE model linked to this SRAM port */ + assert(NULL != sram_ports[0]->spice_model); + assert(SPICE_MODEL_SRAM == sram_ports[0]->spice_model->type); + find_bl_wl_ports_spice_model(sram_ports[0]->spice_model, + &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); + assert(1 == num_bl_ports); + assert(1 == num_wl_ports); + num_bl_per_sram = bl_port[0]->size; + num_wl_per_sram = wl_port[0]->size; + /* Asserts */ + assert(num_bl_per_sram == num_wl_per_sram); + break; + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* If this is an idle LUT, we give an empty truth table */ + if ((NULL == prim_phy_pb) + || ((NULL != prim_phy_pb && (0 == prim_phy_pb->num_logical_blocks)))) { + lut_sram_bits = (int*) my_calloc ( num_lut_sram, sizeof(int)); + for (i = 0; i < num_lut_sram; i++) { + lut_sram_bits[i] = lut_sram_port->default_val; + } + } else { + assert (NULL != prim_phy_pb); + /* Allocate truth tables */ + truth_table_length = (int*) my_malloc (sizeof(int) * prim_phy_pb->num_logical_blocks); + truth_table = (char***) my_malloc (sizeof(char**) * prim_phy_pb->num_logical_blocks); + + /* Output log for debugging purpose */ + fprintf(fp, "***** Logic Block %s *****\n", + prim_phy_pb->spice_name_tag); + + /* Find truth tables and decode them one by one + * Fracturable LUT may have multiple truth tables, + * which should be grouped in a unique one + */ + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + mapped_logical_block_index = prim_phy_pb->logical_block[i]; + /* For wired LUT we provide a default truth table */ + if (TRUE == prim_phy_pb->is_wired_lut[i]) { + /* TODO: assign post-routing lut truth table!!!*/ + get_mapped_lut_phy_pb_input_pin_vpack_net_num(prim_phy_pb, &num_lut_pin_nets, &lut_pin_net); + truth_table[i] = assign_post_routing_wired_lut_truth_table(prim_phy_pb->rr_graph->rr_node[prim_phy_pb->lut_output_pb_graph_pin[i]->rr_node_index_physical_pb].vpack_net_num, + num_lut_pin_nets, lut_pin_net, &truth_table_length[i]); + } else { + assert (FALSE == prim_phy_pb->is_wired_lut[i]); + assert (VPACK_COMB == logical_block[mapped_logical_block_index].type); + /* Get the mapped vpack_net_num of this physical LUT pb */ + get_mapped_lut_phy_pb_input_pin_vpack_net_num(prim_phy_pb, &num_lut_pin_nets, &lut_pin_net); + /* consider LUT pin remapping when assign lut truth tables */ + /* Match truth table and post-routing results */ + truth_table[i] = assign_post_routing_lut_truth_table(&logical_block[mapped_logical_block_index], + num_lut_pin_nets, lut_pin_net, &truth_table_length[i]); + } + /* Adapt truth table for a fracturable LUT + * TODO: Determine fixed input bits for this truth table: + * 1. input bits within frac_level (all '-' if not specified) + * 2. input bits outside frac_level, decoded to its output mask (0 -> first part -> all '1') + */ + adapt_truth_table_for_frac_lut(prim_phy_pb->lut_output_pb_graph_pin[i], + truth_table_length[i], truth_table[i]); + /* Output log for debugging purpose */ + if (WIRED_LUT_LOGICAL_BLOCK_ID == mapped_logical_block_index) { + fprintf(fp, "***** Wired LUT: mapped to a buffer *****\n"); + } else { + fprintf(fp, "***** Mapped Logic Block[%d] %s *****\n", + i, logical_block[mapped_logical_block_index].name); + } + fprintf(fp, "***** Net map *****\n"); + for (j = 0; j < num_lut_pin_nets; j++) { + if (OPEN == lut_pin_net[j]) { + fprintf(fp, "OPEN, "); + } else { + assert (OPEN != lut_pin_net[j]); + fprintf(fp, "%s, ", vpack_net[lut_pin_net[j]].name); + } + } + fprintf(fp, "\n"); + fprintf(fp, "***** Truth Table *****\n"); + for (j = 0; j < truth_table_length[i]; j++) { + fprintf(fp, "%s\n", truth_table[i][j]); + } + } + /* Generate base sram bits*/ + lut_sram_bits = generate_frac_lut_sram_bits(prim_phy_pb, truth_table_length, truth_table, lut_sram_port->default_val); + } + + /* Add mode bits */ + if (NULL != mode_bit_port) { + if (NULL != prim_phy_pb) { + mode_sram_bits = decode_mode_bits(prim_phy_pb->mode_bits, &expected_num_sram); + } else { /* get default mode_bits */ + mode_sram_bits = decode_mode_bits(prim_pb_type->mode_bits, &expected_num_sram); + } + assert(expected_num_sram == num_mode_sram); + } + + /* Merge the SRAM bits from LUT SRAMs and Mode selection */ + assert ( num_sram == num_lut_sram + num_mode_sram ); + sram_bits = (int*)my_calloc(num_sram, sizeof(int)); + /* LUT SRAMs go first and then mode bits */ + memcpy(sram_bits, lut_sram_bits, num_lut_sram * sizeof(int)); + if (NULL != mode_bit_port) { + memcpy(sram_bits + num_lut_sram, mode_sram_bits, num_mode_sram * sizeof(int)); + } + + /* Decode the SRAM bits to BL/WL bits. */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + for (i = 0; i < num_sram; i++) { + /* TODO: should be more structural in coding !!! */ + /* Decode the SRAM bits to BL/WL bits. + * first half part is BL, the other half part is WL + */ + decode_and_add_sram_membank_conf_bit_to_llist(cur_sram_orgz_info, cur_num_sram + i, + num_bl_per_sram, num_wl_per_sram, + sram_bits[i]); + } + /* NUM_SRAM is set to be consistent with number of BL/WLs + * TODO: NUM_SRAM should be the as they are. + * Should use another variable i.e., num_bl + */ + break; + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + /* Store the configuraion bit to linked-list */ + add_mux_conf_bits_to_llist(0, cur_sram_orgz_info, + num_sram, sram_bits, + verilog_model); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Synchronize the internal counters of sram_orgz_info with generated bitstreams*/ + add_sram_conf_bits_to_sram_orgz_info(cur_sram_orgz_info, verilog_model); + + /* Back-annotate to logical block */ + if (NULL != prim_phy_pb) { + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + mapped_logical_block_index = prim_phy_pb->logical_block[i]; + logical_block[mapped_logical_block_index].mapped_spice_model = verilog_model; + logical_block[mapped_logical_block_index].mapped_spice_model_index = verilog_model->cnt; + } + } + + /* Print the encoding in SPICE netlist for debugging */ + fprintf(fp, "***** LUT SRAM bits for %s[%d] *****\n", + verilog_model->name, verilog_model->cnt); + fprintf(fp, "*****"); + for (i = 0; i < num_lut_sram; i++) { + fprintf(fp, "%d", lut_sram_bits[i]); + } + fprintf(fp, "*****\n"); + if (0 < num_mode_sram) { + fprintf(fp, "***** LUT Mode bits for %s[%d] *****\n", + verilog_model->name, verilog_model->cnt); + fprintf(fp, "*****"); + for (i = 0; i < num_mode_sram; i++) { + fprintf(fp, "%d", mode_sram_bits[i]); + } + fprintf(fp, "*****\n"); + } + + /* Update counter */ + verilog_model->cnt++; + + /*Free*/ + if (NULL != prim_phy_pb) { + my_free(lut_pin_net); + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + for (j = 0; j < truth_table_length[i]; j++) { + my_free(truth_table[i][j]); + } + my_free(truth_table[i]); + } + my_free(truth_table_length); + } + my_free(input_ports); + my_free(sram_ports); + my_free(sram_bits); + my_free(lut_sram_bits); + my_free(mode_sram_bits); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.h b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.h new file mode 100644 index 000000000..2caf5affa --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_primitives.h @@ -0,0 +1,11 @@ + + +void fpga_spice_generate_bitstream_pb_generic_primitive(FILE* fp, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + t_sram_orgz_info* cur_sram_orgz_info); + +void fpga_spice_generate_bitstream_pb_primitive_lut(FILE* fp, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + t_sram_orgz_info* cur_sram_orgz_info); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.c new file mode 100644 index 000000000..3bbe1f646 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.c @@ -0,0 +1,592 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_bitstream_utils.h" + +/* Include Verilog support headers*/ + + +static +void fpga_spice_generate_bitstream_routing_chan_subckt(int x, int y, + t_rr_type chan_type, + t_sram_orgz_info* cur_sram_orgz_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + int num_segment, t_segment_inf* segments) { + return; +} + +/* Print a short interconneciton in switch box + * There are two cases should be noticed. + * 1. The actual fan-in of cur_rr_node is 0. In this case, + the cur_rr_node need to be short connected to itself which is on the opposite side of this switch + * 2. The actual fan-in of cur_rr_node is 0. In this case, + * The cur_rr_node need to connected to the drive_rr_node + */ +static +void fpga_spice_generate_bitstream_switch_box_short_interc(t_sb* cur_sb_info, + t_sram_orgz_info* cur_sram_orgz_info, + int chan_side, + t_rr_node* cur_rr_node, + int actual_fan_in, + t_rr_node* drive_rr_node) { + + return; +} + +/* Print the SPICE netlist of multiplexer that drive this rr_node */ +static +void fpga_spice_generate_bitstream_switch_box_mux(FILE* fp, + t_sb* cur_sb_info, + t_sram_orgz_info* cur_sram_orgz_info, + int chan_side, + t_rr_node* cur_rr_node, + int mux_size, + t_rr_node** drive_rr_nodes, + int switch_index) { + int inode, ilevel; + t_spice_model* verilog_model = NULL; + int mux_level, path_id; + int num_mux_sram_bits = 0; + int* mux_sram_bits = NULL; + + /* Check */ + assert((!(0 > cur_sb_info->x))&&(!(cur_sb_info->x > (nx + 1)))); + assert((!(0 > cur_sb_info->y))&&(!(cur_sb_info->y > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check current rr_node is CHANX or CHANY*/ + assert((CHANX == cur_rr_node->type)||(CHANY == cur_rr_node->type)); + + /* Allocate drive_rr_nodes according to the fan-in*/ + assert((2 == mux_size)||(2 < mux_size)); + + /* Get verilog model*/ + verilog_model = switch_inf[switch_index].spice_model; + + /* Configuration bits for this MUX*/ + path_id = DEFAULT_PATH_ID; + for (inode = 0; inode < mux_size; inode++) { + if (drive_rr_nodes[inode] == &(rr_node[cur_rr_node->prev_node])) { + path_id = inode; + break; + } + } + + assert((DEFAULT_PATH_ID == path_id) || + ((DEFAULT_PATH_ID < path_id) &&(path_id < mux_size))); + + /* Depend on both technology and structure of this MUX*/ + switch (verilog_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); + break; + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", + __FILE__, __LINE__, verilog_model->name); + exit(1); + } + + /* Print the encoding in SPICE netlist for debugging */ + fprintf(fp, "***** Switch Block [%d][%d] *****\n", + cur_sb_info->x, cur_sb_info->y); + fprintf(fp, "***** SRAM bits for MUX[%d], level=%d, select_path_id=%d. *****\n", + verilog_model->cnt, mux_level, path_id); + fprintf(fp, "*****"); + for (ilevel = 0; ilevel < num_mux_sram_bits; ilevel++) { + fprintf(fp, "%d", mux_sram_bits[ilevel]); + } + fprintf(fp, "*****\n\n"); + + /* Store the configuraion bit to linked-list */ + add_mux_conf_bits_to_llist(mux_size, cur_sram_orgz_info, + num_mux_sram_bits, mux_sram_bits, + verilog_model); + + /* Synchronize the sram_orgz_info with mem_bits */ + add_mux_conf_bits_to_sram_orgz_info(cur_sram_orgz_info, verilog_model, mux_size); + + /* update sram counter */ + verilog_model->cnt++; + + /* Free */ + my_free(mux_sram_bits); + + return; +} + +static +void fpga_spice_generate_bitstream_switch_box_interc(FILE* fp, + t_sb* cur_sb_info, + t_sram_orgz_info* cur_sram_orgz_info, + int chan_side, + t_rr_node* cur_rr_node) { + int sb_x, sb_y; + int num_drive_rr_nodes = 0; + t_rr_node** drive_rr_nodes = NULL; + + sb_x = cur_sb_info->x; + sb_y = cur_sb_info->y; + + /* Check */ + assert((!(0 > sb_x))&&(!(sb_x > (nx + 1)))); + assert((!(0 > sb_y))&&(!(sb_y > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Determine if the interc lies inside a channel wire, that is interc between segments */ + /* Check each num_drive_rr_nodes, see if they appear in the cur_sb_info */ + if (TRUE == check_drive_rr_node_imply_short(*cur_sb_info, cur_rr_node, chan_side)) { + /* Double check if the interc lies inside a channel wire, that is interc between segments */ + assert(1 == is_rr_node_exist_opposite_side_in_sb_info(*cur_sb_info, cur_rr_node, chan_side)); + num_drive_rr_nodes = 0; + drive_rr_nodes = NULL; + } else { + num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes; + drive_rr_nodes = cur_rr_node->drive_rr_nodes; + } + + if (0 == num_drive_rr_nodes) { + /* Print a special direct connection*/ + fpga_spice_generate_bitstream_switch_box_short_interc(cur_sb_info, cur_sram_orgz_info, + chan_side, cur_rr_node, + num_drive_rr_nodes, cur_rr_node); + } else if (1 == num_drive_rr_nodes) { + /* Print a direct connection*/ + fpga_spice_generate_bitstream_switch_box_short_interc(cur_sb_info, cur_sram_orgz_info, + chan_side, cur_rr_node, + num_drive_rr_nodes, drive_rr_nodes[DEFAULT_SWITCH_ID]); + } else if (1 < num_drive_rr_nodes) { + /* Print the multiplexer, fan_in >= 2 */ + fpga_spice_generate_bitstream_switch_box_mux(fp, cur_sb_info, cur_sram_orgz_info, + chan_side, cur_rr_node, + num_drive_rr_nodes, drive_rr_nodes, + cur_rr_node->drive_switches[DEFAULT_SWITCH_ID]); + } /*Nothing should be done else*/ + + /* Free */ + + return; +} + +/* Task: Print the subckt of a Switch Box. + * A Switch Box subckt consists of following ports: + * 1. Channel Y [x][y] inputs + * 2. Channel X [x+1][y] inputs + * 3. Channel Y [x][y-1] outputs + * 4. Channel X [x][y] outputs + * 5. Grid[x][y+1] Right side outputs pins + * 6. Grid[x+1][y+1] Left side output pins + * 7. Grid[x+1][y+1] Bottom side output pins + * 8. Grid[x+1][y] Top side output pins + * 9. Grid[x+1][y] Left side output pins + * 10. Grid[x][y] Right side output pins + * 11. Grid[x][y] Top side output pins + * 12. Grid[x][y+1] Bottom side output pins + * + * -------------- -------------- + * | | | | + * | Grid | ChanY | Grid | + * | [x][y+1] | [x][y+1] | [x+1][y+1] | + * | | | | + * -------------- -------------- + * ---------- + * ChanX | Switch | ChanX + * [x][y] | Box | [x+1][y] + * | [x][y] | + * ---------- + * -------------- -------------- + * | | | | + * | Grid | ChanY | Grid | + * | [x][y] | [x][y] | [x+1][y] | + * | | | | + * -------------- -------------- + */ +static +void fpga_spice_generate_bitstream_routing_switch_box_subckt(FILE* fp, + t_sb* cur_sb_info, + t_sram_orgz_info* cur_sram_orgz_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int itrack, side; + + /* Check */ + assert((!(0 > cur_sb_info->x))&&(!(cur_sb_info->x > (nx + 1)))); + assert((!(0 > cur_sb_info->y))&&(!(cur_sb_info->y > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Put down all the multiplexers */ + for (side = 0; side < cur_sb_info->num_sides; side++) { + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + assert((CHANX == cur_sb_info->chan_rr_node[side][itrack]->type) + ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); + /* We care INC_DIRECTION tracks at this side*/ + if (OUT_PORT == cur_sb_info->chan_rr_node_direction[side][itrack]) { + fpga_spice_generate_bitstream_switch_box_interc(fp, cur_sb_info, cur_sram_orgz_info, + side, cur_sb_info->chan_rr_node[side][itrack]); + } + } + } + + /* Check */ + + /* Free chan_rr_nodes */ + + return; +} + +/* SRC rr_node is the IPIN of a grid.*/ +static +void fpga_spice_generate_bitstream_connection_box_short_interc(t_cb* cur_cb_info, + t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* src_rr_node) { + return; +} + +static +void fpga_spice_generate_bitstream_connection_box_mux(FILE* fp, + t_cb* cur_cb_info, + t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* src_rr_node) { + int mux_size = 0; + t_rr_node** drive_rr_nodes = NULL; + int inode, mux_level, path_id, switch_index; + t_spice_model* verilog_model = NULL; + int num_mux_sram_bits = 0; + int* mux_sram_bits = NULL; + int ilevel; + + /* Check */ + assert((!(0 > cur_cb_info->x))&&(!(cur_cb_info->x > (nx + 1)))); + assert((!(0 > cur_cb_info->y))&&(!(cur_cb_info->y > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Find drive_rr_nodes*/ + mux_size = src_rr_node->num_drive_rr_nodes; + drive_rr_nodes = src_rr_node->drive_rr_nodes; + + /* Configuration bits for MUX*/ + path_id = DEFAULT_PATH_ID; + for (inode = 0; inode < mux_size; inode++) { + if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { + path_id = inode; + break; + } + } + assert((DEFAULT_PATH_ID == path_id) || + ((DEFAULT_PATH_ID < path_id) &&(path_id < mux_size))); + + switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID]; + + verilog_model = switch_inf[switch_index].spice_model; + + switch (verilog_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); + break; + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", + __FILE__, __LINE__, verilog_model->name); + } + + /* Print the encoding in SPICE netlist for debugging */ + switch(cur_cb_info->type) { + case CHANX: + fprintf(fp, "***** Connection Block X-channel [%d][%d] *****\n", + cur_cb_info->x, cur_cb_info->y); + break; + case CHANY: + fprintf(fp, "***** Connection Block Y-channel [%d][%d] *****\n", + cur_cb_info->x, cur_cb_info->y); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "***** SRAM bits for MUX[%d], level=%d, select_path_id=%d. *****\n", + verilog_model->cnt, mux_level, path_id); + fprintf(fp, "*****"); + for (ilevel = 0; ilevel < num_mux_sram_bits; ilevel++) { + fprintf(fp, "%d", mux_sram_bits[ilevel]); + } + fprintf(fp, "*****\n\n"); + + /* Store the configuraion bit to linked-list */ + add_mux_conf_bits_to_llist(mux_size, cur_sram_orgz_info, + num_mux_sram_bits, mux_sram_bits, + verilog_model); + /* Synchronize the sram_orgz_info with mem_bits */ + add_mux_conf_bits_to_sram_orgz_info(cur_sram_orgz_info, verilog_model, mux_size); + + /* update sram counter */ + verilog_model->cnt++; + + /* Free */ + my_free(mux_sram_bits); + + return; +} + +static +void fpga_spice_generate_bitstream_connection_box_interc(FILE* fp, + t_cb* cur_cb_info, + t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* src_rr_node) { + /* Check */ + assert((!(0 > cur_cb_info->x))&&(!(cur_cb_info->x > (nx + 1)))); + assert((!(0 > cur_cb_info->y))&&(!(cur_cb_info->y > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + if (1 == src_rr_node->fan_in) { + /* Print a direct connection*/ + fpga_spice_generate_bitstream_connection_box_short_interc(cur_cb_info, cur_sram_orgz_info, + src_rr_node); + } else if (1 < src_rr_node->fan_in) { + /* Print the multiplexer, fan_in >= 2 */ + fpga_spice_generate_bitstream_connection_box_mux(fp, cur_cb_info, cur_sram_orgz_info, + src_rr_node); + } /*Nothing should be done else*/ + + return; +} + + +/* Print connection boxes + * Print the sub-circuit of a connection Box (Type: [CHANX|CHANY]) + * Actually it is very similiar to switch box but + * the difference is connection boxes connect Grid INPUT Pins to channels + * TODO: merge direct connections into CB + * -------------- -------------- + * | | | | + * | Grid | ChanY | Grid | + * | [x][y+1] | [x][y] | [x+1][y+1] | + * | | Connection | | + * -------------- Box_Y[x][y] -------------- + * ---------- + * ChanX | Switch | ChanX + * [x][y] | Box | [x+1][y] + * Connection | [x][y] | Connection + * Box_X[x][y] ---------- Box_X[x+1][y] + * -------------- -------------- + * | | | | + * | Grid | ChanY | Grid | + * | [x][y] | [x][y-1] | [x+1][y] | + * | | Connection | | + * --------------Box_Y[x][y-1]-------------- + */ +static +void fpga_spice_generate_bitstream_routing_connection_box_subckt(FILE* fp, + t_cb* cur_cb_info, + t_sram_orgz_info* cur_sram_orgz_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int inode, side; + int side_cnt = 0; + + /* Check */ + assert((!(0 > cur_cb_info->x))&&(!(cur_cb_info->x > (nx + 1)))); + assert((!(0 > cur_cb_info->y))&&(!(cur_cb_info->y > (ny + 1)))); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Print multiplexers or direct interconnect*/ + side_cnt = 0; + for (side = 0; side < cur_cb_info->num_sides; side++) { + /* Bypass side with zero IPINs*/ + if (0 == cur_cb_info->num_ipin_rr_nodes[side]) { + continue; + } + side_cnt++; + assert(0 < cur_cb_info->num_ipin_rr_nodes[side]); + assert(NULL != cur_cb_info->ipin_rr_node[side]); + for (inode = 0; inode < cur_cb_info->num_ipin_rr_nodes[side]; inode++) { + fpga_spice_generate_bitstream_connection_box_interc(fp, cur_cb_info, cur_sram_orgz_info, + cur_cb_info->ipin_rr_node[side][inode]); + } + } + + /* Check */ + + /* Free */ + + return; +} + +/* Top Function*/ +/* Build the routing resource SPICE sub-circuits*/ +void fpga_spice_generate_bitstream_routing_resources(char* routing_bitstream_log_file_path, + t_arch arch, + t_det_routing_arch* routing_arch, + t_sram_orgz_info* cur_sram_orgz_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int ix, iy; + FILE* fp = NULL; + + assert(UNI_DIRECTIONAL == routing_arch->directionality); + + /* Create a file handler */ + fp = fopen(routing_bitstream_log_file_path, "w"); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in creating log file %s", + __FILE__, __LINE__, routing_bitstream_log_file_path); + exit(1); + } + + /* Two major tasks: + * 1. Generate sub-circuits for Routing Channels + * 2. Generate sub-circuits for Switch Boxes + */ + /* Now: First task: Routing channels + * Sub-circuits are named as chanx[ix][iy] or chany[ix][iy] for horizontal or vertical channels + * each channels consist of a number of routing tracks. (Actually they are metal wires) + * We only support single-driver routing architecture. + * The direction is defined as INC_DIRECTION ------> and DEC_DIRECTION <-------- for chanx + * The direction is defined as INC_DIRECTION /|\ and DEC_DIRECTION | for chany + * | | + * | | + * | \|/ + * For INC_DIRECTION chanx, the inputs are at the left of channels, the outputs are at the right of channels + * For DEC_DIRECTION chanx, the inputs are at the right of channels, the outputs are at the left of channels + * For INC_DIRECTION chany, the inputs are at the bottom of channels, the outputs are at the top of channels + * For DEC_DIRECTION chany, the inputs are at the top of channels, the outputs are at the bottom of channels + */ + /* X - channels [1...nx][0..ny]*/ + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Routing Channels - X direction...\n"); + for (iy = 0; iy < (ny + 1); iy++) { + for (ix = 1; ix < (nx + 1); ix++) { + fpga_spice_generate_bitstream_routing_chan_subckt(ix, iy, CHANX, cur_sram_orgz_info, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + arch.num_segments, arch.Segments); + } + } + /* Y - channels [1...ny][0..nx]*/ + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Routing Channels - Y direction...\n"); + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + fpga_spice_generate_bitstream_routing_chan_subckt(ix, iy, CHANY, cur_sram_orgz_info, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + arch.num_segments, arch.Segments); + } + } + + /* Switch Boxes*/ + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Switch blocks...\n"); + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 0; iy < (ny + 1); iy++) { + /* vpr_printf(TIO_MESSAGE_INFO, "Writing Switch Boxes[%d][%d]...\n", ix, iy); */ + update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models); + fpga_spice_generate_bitstream_routing_switch_box_subckt(fp, + &(sb_info[ix][iy]), cur_sram_orgz_info, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models); + } + } + + /* Connection Boxes */ + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - X direction ...\n"); + /* X - channels [1...nx][0..ny]*/ + for (iy = 0; iy < (ny + 1); iy++) { + for (ix = 1; ix < (nx + 1); ix++) { + /* vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy); */ + update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models); + if ((TRUE == is_cb_exist(CHANX, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) { + fpga_spice_generate_bitstream_routing_connection_box_subckt(fp, + &(cbx_info[ix][iy]), cur_sram_orgz_info, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models); + } + } + /* Y - channels [1...ny][0..nx]*/ + vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - Y direction ...\n"); + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + /* vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy); */ + update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models); + if ((TRUE == is_cb_exist(CHANY, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) { + fpga_spice_generate_bitstream_routing_connection_box_subckt(fp, + &(cby_info[ix][iy]), cur_sram_orgz_info, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models); + } + } + + /* Close log file */ + fclose(fp); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.h new file mode 100644 index 000000000..cd28884e8 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/bitstream/fpga_bitstream_routing.h @@ -0,0 +1,8 @@ + + +void fpga_spice_generate_bitstream_routing_resources(char* routing_bitstream_log_file_path, + t_arch arch, + t_det_routing_arch* routing_arch, + t_sram_orgz_info* cur_sram_orgz_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) ; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/clb_pin_remap_util.c b/vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/clb_pin_remap_util.c similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/clb_pin_remap_util.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/clb_pin_remap_util.c diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/clb_pin_remap_util.h b/vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/clb_pin_remap_util.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/clb_pin_remap_util.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/clb_pin_remap_util.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/place_clb_pin_remap.c b/vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/place_clb_pin_remap.c similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/place_clb_pin_remap.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/place_clb_pin_remap.c diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/place_clb_pin_remap.h b/vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/place_clb_pin_remap.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/place_clb_pin_remap.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/place_clb_pin_remap.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/post_place_timing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/post_place_timing.c similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/post_place_timing.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/post_place_timing.c diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/post_place_timing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/post_place_timing.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/clb_pin_remap/post_place_timing.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/clb_pin_remap/post_place_timing.h diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/router/.fpga_x2p_router.c.swp b/vpr7_x2p/vpr/SRC/fpga_x2p/router/.fpga_x2p_router.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..0a269694ff8baefa696979678bb4f37b5824f3d3 GIT binary patch literal 49152 zcmeI53w&HxedhtQDZh!dL{TMh!pawW?F9A~(ixsoQ9X2i_M zvXf>h6!?_K(uFpZLc73j`D`hHWlJGhDB+ouR~Jg4C9oyXE!(BL;hhDV2KM{=pL6cq zJDM3uPO{5m=Hs7dbRXxQ^FROdKmXS`cXs=ciA$rWjy}1-=j=k^dp|yL`59l^{=&z+ z8p^Q`2M3xH@nDovh5o)sdtek2Gtw#m3ldJ+77(lE&DH<@!^L^?JOdUt`l#d&lOM z=i}nZ^OnczwUuU4Pya5uzeh_QD$qaFr@${X1s+;B|GXXBMS>@6IVXDLBW8Y~snKtI zp8|af^eND%K%WAA3iK(^r$CI7l`Zt$nz&EO?q2|Nev2D`vH;I4mB zD0~sT7rX~7fGyzD4=ofv1+E6$z?aV|6kZ7~0{;u6{Egt*;7$zqw}YeLA>jQO{KvuL z!Q;SPI0(J~J`X+wJ_ud}=D?3}E_@x_2L2s*Huxb9iMN6&@MD}8cY%KZH-nqNpMV80 z4;}?RiUVL7)W9Kd0k{Pl|8wA#U;^BMPv92t3GiX?A@DZvD)2J!QgA-_8nhHWU%h$f zK%~!5v{0)Zk5-nWrCL3SCJs#;Y(&jk)Lf`EqUni)&yEIG7b>NNh(A{s;%2m(M5}SN zIXD_c6LWUGm7}5x_G>7rC&|g>xLQui(Oj)gQ3;2Z;tEIVQEkqZT}_(jHX5l)0_E^@cFZqELSqQ$t;ELN5))uL5u zS5(n=D2r!4=}FPRVyzS}l3P-ougA*^BfI&ftB%^W$3~ZD-H9T_P?wdZBIH?KX%>_6 zeA0+^?TWS!4n|k|`bAM?E*jWOnbA4BqJuLB4h;GdbpJY4YMxq7^x%nuho|-w_a2y; zK0H2E9N%}zxGLhyiOXecN3mH;8&_ON;^nr|haFLdqwS-^(ZR{$p{emB6O%L3ZGTK2 z8b3H3>Hon%KO<1uOX8%H?i9?qm_!4ilhPKZl^Zf{QDtDVyZ0FybL|}xch-|wqoNtb z^KiCCL$%RN;_`5`n8YU%d#ZRMYS!aYG8>nUN6BKclvJD1fX3AzBVo>u8901zTs^lL z(bvXEZsgUfk?PH;XfEW*l{8DkQKM2V={XvdHQl|)00Mkgi;d8nvY) zT7V)ZX_9I@OBd1@gaqV?7ZETg66yu1Opr7xP@>|cZi*kH|}a=fuzW(+Df!Q z_elDvDMnK6KJ4hVvRFnmM2*GTDwM266OJ`f8K&D-7iv_@a=diOTwIR^l9Q#ym9j*N z6P0?by0bxlR#R4UT~?~m{VlPmBGsS6NZWGUbSzS;RTc~Wu9o!WWl5!8j!JPOp=AeZ&4$FQQFfGuCQ%7qtWrD_J*BcCz6ti# znr}bHlBMP5DXZl*aA+fmt`?V=I99mOzBNpuFR5XRwfRaZnnivbZ;Xb1 z4}#Up&b2~yeuMt3{A`CO5^GZZ4t=ix9t>ltlc7L>B|nMNArfw2^IL%!m3#`Q4kHOl;LP73@|sbNKP>W zF418Oi`5zo2FzQ0-yUK z(XD=rG#e?Bn5GZp7?74v%xQ4fJp-!czJ84bV{3Q)f`o9aN`=~J&}w{9p-#<=m~?s}xumYyCR1s&2`-@=iHKo) zrm7d{rzb7Z8mEC}OCLr)dV=a!)hDSoR$v%)m5J9@<l#! zkW&qfcTT;s5jP zr7c{x68KhkGTWE}O} z>L}*UAZaP5*4m)R1iJ82XmTJ{}(esP7*|`0AWU&|1Vp^?PUO3gLsI48&sn+?2 zUfirKC8GpihCHNeam7cMhRwVE>*2)8qK< zI5d~UjS9XUTPBAhnJP_d+=7RvW^|8fsh3nR+>&}7+iEFkG~#(VVv?$FGU}j29;k?w=fvwj9D-;jXbM=V*=&d95cpRIkm) zOH1Z^dWJbM(4+B$Z=FX0M)NK=F0XFE-NOBDnO{*F5S4s_%!xT3+;%G3wksN#Tdc*+ z!2#*%BTnrf9EbU_H?#{%3L{_quA_mN4&UHT3K3I z4Bn;s3Kj%D1G(W<-IR#tB2X=NVZh?S83@!LcNT^&7O|yj>f5e&&Yk7BxiDwG{G#(? zrQM23+Gwun+htZ_7UyCdmZrDXi?!uuW0Z>Opkowh=`W%_jb?f0&ZSCqARNQ3(!|~? z74gJ0FE$GA9(d*qeSBzgdgAcJk@4dG1Cx6WM`O{BL_@qpN&Ovfj))V}8Q& z&gf8EcWj7L)oCfST6^-myjh0bWD!~B6x(-UT2F{gF|O`e!@RzrUJUFaCXJO+3BeNV zP5&pIym5Jz5ps$G74&Qggsvk4??mU(kvBI-c00oqQ@(r@cTCaTpT~xy9Y`Y2Zh^nE z;U^oOt`faDYFcgg&SZ^ixqP-dN!MNzPGzb_MzyKT^1Qa;65oOWg0~h#&hi}Etxl@}5{VXRE zX3B$G^9~Lxq$oC%II9#Jct}f0Q9P9KR;&@uI&VCd(zVruR_%K{Z8Hy${r?;koWJ++ z|B(Ow6YTv@f=_@Cf)9W{2Umj&z>~p$#|Q9Qum^k_d;d+~AoyqO`a8jG;49#bU^w)ydfJ?xB@FQ&c>%bM@ z7?4dr0L}#u1pkPS<7V(@;N74Jt^mitv%mznlRSWTfGfZ;umd~@e1%+q8^G(pRp1m* zj=;0P7VtxI1O5uU6TAkz3Mgk_7;FP~krVLG;Jx4^cs?kCZ$a~K0@41XqW>m8;=lC6 z#I;uDrDyrk@q#t#!rc{$BORq;%F=Lcg+H7Kk_I%OKRLSnB0CXX+~(|aA$P86xC^#z zb902d*XH(U2dDJw;=E3<6rc2)K@=-Q1I#_GQn=KWQs}BqI0vQf%4if^j<{!V2HB?{ zN)_C=N3|+n3D6NIVmV&4m%W z$JacPrs-RoZHw1E)rvK>Yj5XyYp&?f%pI;y*=KZX<#`)yr7x0Z!UYZG=fs#jIQ6~Q z&o|WdC?UE~efpZf6>&Mj4zPft4vsP@cM^5z{&AClkI*gD>I8mCPC&g;D9;jY6kS1#U1)rU;1?ZW)$_D30R6&(T&d(cwJ@FWDLGtzi>IS;I)(CS8a?NHBXa zI50aMRn6c?tDzFz;EUY+$gnjw%XGf3v7j)cUnwsM8Uz2iiB>0P*>Hw9Z{$@^u4&D+ zW;s)5r*j-$Ac!ZEH;!gk=B+R7K_foWr=%=h;Sz*sLEBjZ{)((wY83ezC{xNhnN3PD z1b0ELx@8yX8QdO20#Xl3n2?y?%C4HVm?75^HuW-y+VDuI)~IlS@d_1I_qU>sx)%m8 z%RP1_@dV|Js1EdwV-2waLnW$Vw~{heI;EhMdOv*>m9mRe7g%72aiFfKakx&AH3D=g z{}W6^H#=7`$Gh_4#o&?S4K3onSs9on&DhjQMgEbpZe$&gcA&^^$Ror=;%-7_4S z_Nxn0?w_!Efz~g@SNTAsq;!mN7tDs}U@~9Bwp6;u-q!Gn7w2nrV$Ms$#{7YM;I3jP zB`~Y+wI-1E$d*lQYUq%7HK|vzXf^filNw2WcBIlJv49G`np>qd{{jyj15WID9DiZIY*kjoLwEP z>vq#6KUY?&b7_K|Y$%J3Y6gq8<%YGoN@F0Ep(P8{TikmohW+Sk(naKxLP$w*$4|6G z>Vz9eR%~27MOYs`aV#X^GchObmRq0{BVQ^_WCBT)WlPzr${3?4%YIU}jpinmG;9M8 zDZ9XaRTdm}_LjG{WM8zE8thq85pyBTG|SMd4!y`>Wo~1Tjii;u07)q#*`?2h9}rq& zt_IaNU#_2sU9q7_yEBizT78XR_k?4{?(*o+!Qo0*q)}+STewJ9J0;KOZkmQDiPKp{ z48lojB3Gpvo(X*&8CI9eOmrO{GJN*!IXr&%B$KG2PmoZKJ<1e%_?Z*a(bVM3;faIe z(Vpq)862S;9FHdV?wvWb=iuJwMo0D>nBm~W!Dwo#cyMwb*G-K_Gl!UKD6ybo$(_UL zYFvnSj$$WBa9kuM$GQ5*R|z91m}vb@TW_Qsg=+BAGvP^qd>sEp(cJmfu|B*H1{fzdR3Dk9I! z&*{1dxi#x@kI4kA$EqG5Utn6FpeeQdIJDi1USBy$HxrB2(%HoOr4#jlD^OFnrU9o_ zDD&A1377qn($CFfezZ$cTD#p{X}K%^Zq zGiK9r$(CDbuEyl6Dk!n2*_8ZTX|`ljN!80)gVo3vS!=Ey|%PQP1<<2txsTes>cRX^C7HB++DISa-Is=hMoQ0_8fCI+OG~X zx`@dH>*k2Y(MG*wO>~}c`?FF$dCaAp3e6->K( z5V)qTi&5Ypol*WA>;vnWN@f{la3@z}7pl02MVtMoK57beZz*bEMysFN4T9l&kTX?_Rt-ehVva?BhWQeGgy19^O*?09-waRw|7XfI?3Ahr zc`29gN(QDaU2>~?ema=RS%Dj8DaM4;(VMlVx3#?Vt0?B=RvzWoA6?`0ZF2biEy%59 zlYQHQ>}!cUUw(+FHJ6D3m{otZ4n&ayQBpzc*mOK#OMZ$^;{ z?r1W|^u%XuNXD3RzgpG<>mfV^{DmFlwy$}x#LOdg)F^taWnYQF+$;OaeqJoq+%0eO zhl0~RJ-+^<(o0>|iBd4qj!NeOJuYo0{L3(rb$F%L|QF zOxsVpF#p35%K1*yb&#`o9nBz_t(}Y-%Sov+S7Dk74!h#)tohXBtAml<1f&}1<5i+V zwnoEyS3I%Np2}CUyo||(8oC)ZvkZx9rWXcxoysd%xf}jZqQZGGgCdk;jngX4jAU=N zn9|W{GHcJ;t|nNFkh0#`oULLttW?S9uV~>_OI5L%3F_4=Nqa1%$6_8vwrjKNWECRv z`^8ngc%ui&gM>jd)XLV0=t`}`z>8Ln2GZp^r~Kj(OjgA_U>^->w|-3C$!P_q!y*vJ zIi~&W*NnA@<7onQ#&K70*HuqN%XrGAU~7o@97oU8@a7cAJvZBDLb}^1_MH@1B3xlUiD#TpNKROL3i* zEi}{G9BY-#36aG@DaNB(1sF3%aXe>;g`1}u2G#m>$*&8`6KA9=bzENkK>lVecFnGm z9TE$&^rtpYotSvW~NV&k5@e;@2~NXF*66mjEetb$`@Yd?f;D;WEzp|&7%12Od~hDP54aIKU%CFT0WSu}fO7u7hrRz@@JaA*z%^hM90tns zzX4ni=7Dni?*rrm_$Tlc@V7v5|7ma@_&&D2V*W1%JHa=w@Bb2f8oUTR7Tk$F{~aKk z{}tfH;6*_3{)dCJ!N;-huLakD70?7nz#%XR?!d->BRB#g@XO$r!1vF<2Lj#;{tUbu zyafCP*a|*}jsKfq5Db97fyScqOV`-^>WZI7gIz+zK7NuKlI3P=I-TRYe42JwD3)*2 znQiT7MdAvJ>27^m^Q!&AJRFYJ^)>KdhIg>8)WnU&dnj5uoSDM$ax)DJTe{Fl@W^`g z-g__Svkrx5AWdFm`f*0O(=1c@-adz#3T*3(^Hc7cv<1zlPK}>q^N9S#MW*by?G9Y) zD|M}I^h&m0m)o9?n))BR-R`2ZzL1`))4FS+Yr`tepH-Y&jOX3lw*IVOs@t*A%$*}6 zE}6s4$w4DTF?H*I=}P0i5CU_$A2B9Jm$uo{6Ia|CGEqYcqmJpbsXo;WG71O;_ZtFbXTR40+%_;?ZUWOQX zQ@4k@neRcdjVZ9zWVL7(gJUEd@3z{|XNvpB1=e;CZ(TuyHKH7gxRWwsv9M6u-N+(} zUR)$=r;P-|(UbBO>ZE{qmP!X_N;lVa&d}LSuFr)RG9h%(JO<@A+ph*$RETMPh48tDN)@r_&L$GMXN4 zUAgfmW|Z8NEkZdOD}mtYN#-L__+YZ?h6ZC>>J{Xcvf0wXn8!SqWoxTzLh-KXuEEi@ z5-Md1SAyRzVZ&|Bh^eq&f@6rDQYeV3&Jt+j@<&8dj$2h(QL_nAyTtZfVPZ^))cv@2Khk~e-f2?*uGOu3C%_+y-Wc5S zqy-IB;9O-+c8aI-JUL^eP&IHK@vw*t1THpDkQ*UPf7Ov4S}(6n4${3bB9b)}cXE?q zPf}3<%e?cNf@Ui-EoJnzroKr9Ae|An`p%U?#&m zj(awDIT*&~{<$HkD$@^8Y(kHP$olvK{aytG;YrmXlP^@z>-T1ot9b5Kz8-|EjxdDO z03;4Av50G?Ku&V)Va~K7t~`=U$u(rI;u+N1cBsM+EyF{=$%5|C9oYt;PK$w z*!o`uUjiQo?*acAyal`gC_mtr!S}KIuLu7Tyal`&Tmv2hzJ?Frt3W=16|e-96R;PY z4gL;)fcyhDgKL3&1XqKrK*$q#6u)o5C-A30YXpYDeZl+i1607J-~hM}cs)LVtHBGv zGB^`F7<>fV{|NXeZ2mWZ39to-#<#7p{d>gm?}1asi0%JvaZ{5-1RO0jY$q#@#r6LSeKNBBf~>HW zpHWVA&y_v5m~6W2TuWwccaSyDlH$36gHk!MIkV47HoFSlvQ}l$imhZY{mH36Zl6xCSDB{)1%uDeu%T%6?`|o|`0F$= z(oeFWG6vjHe(EZ2d>>(9`<@mxOAHg~5|K{rG+y5HvEd9BM?SIVb z!kp|<^8XKcoAXt~{k6aUw~6_G2HXUc2XGB|ICu}X{tUPu_*?9Ht?`$ge=D~9E5ViE z`Jf0M3$EiKTHAj+cKRQH6>vV#KK?HNPXPA?Kg9n2Hux5}9=s6zYcL7Mf!6aYu75Uo z7znX_<@0|7{7;}Y{=W|t@4pNTf`17f3jP~*`=`Op;A7xQa5nf9cKfy9cfmE_Qt$-u z8SMDCftv|+0_=w`m4&6ScG zr){Np0aIwzj$bynuQh*}C9*bSC@IV-=!h&mVeXA=Lz70MtJcWADbxo&(zzRO18BQT z{_dtu>ZJhrY1-V?5f+Dz^PI2X>nO(otR& zXFp)?omGA9dK6K&rIKB$_&fuRPkw^7z;i$8pd`nx)HHEInsng0J#c?J@Bb8-k>}m> zW+ZI0Hl+bBXBBYB227dX$D$PTcf5r_FzYZiPP?aONa;KtEb`7~ts_4y8%C<)V{0qd zA>Sg@=Jf2-(-|W+w6e($fonA6GN062)9yeB*R%^!pVPdaYd1_9p&0+Yxzf5#W}#4} ztfao>xs^p0(X&q$j^E-!g_Wy>zfP?QvG%Ti%l|sqr3L>FTC*#_ROM07MnY<`}`+4-G3bQ={o{m@n0&KYfH$lzd@MYGddmKbhs?thqs^ z`2U5dMSmrG75l&FZPwqx_LmRfh2Ruuf(9sqSrCKggB@T5+=5Tw72xIIY2Y953%m}D zgYV-PcsqC=cregj|L+CA4Yq>&fir+|0Nx5-1d3n_xC%`++axAGi*@96TTF2S36`@ILTcpaNoW6zl{e;9T$oum$`NdN&AhEj08pk$s<`TA z1*|P&M^dZZ?lybxSmuRyF6wOF@Qs<)zJ!7vmGg#c{h_SFjpd`|f(jI-dZe{BgSO~* z@^V%@(_3oHk?93NAKHB+SRVdD3lMH(|}H#0@QU@Q+UOS5+wu4fz}LV?$SN=F>KO*bB0- zncMT%W&~Mo6Cp$8vIc+IoB+V2QVp_(QQ(9ePf-~Df)xkO5@X4f! zhGLmCc&RN$N#>jzAbjZx*9|^&o{f27Xs->rwFHP0I-zIs)ikmM5z^|kc1KWFShX=` zTi7#4+tZiJovC1n#q|;-aN)Q>i%$J-*V@KZJ`FjI;I+|8JeCes;?M@5^OEIuX?HBps5-ach-G%Z=yVV)HgKwXRjFrFWR(iE}$-<5UWnw`>Y%?4(K9 z^NoAHd#E<^v%%&GU1uvgTYpbj=Vrecmq z0;jY!((?i}YDw^P_@WYY>ZdmMxu4@(N$KM!OUbgm9!@PbLBLb3it4zoHApANdx#^| zE0Ai!y)B@^o{x-Gj)gV!T_@*m>ldNYKsYxTEuAWAo77rqjeAKgY|p4?8(C^ln+pZ# zEeR5b^0RB%p;1xt8Si>7Jl;?9_M2f!k%hATH1BoOycuLa*9(ko)W8Z-E5cyzrXKa& zjK9bBIS3D=1>$2*c@v9u3lg(_d6g5W{Owh&Ac4I_kx?4xFZa1uec1>c+5eclg?VrP zYcD{3ZpNm+37h~=0}lu9!mj^aa2a?oct5uNesD3kKlmiJ{ae8dI0rlcybrs+3hu;~ z|7&mr90c0me;?Qbo(z5oJRaN^6u?ig=YI@t1TP1_1ug{th&}%X@cZCpKzaU;10SFf zvg_Xjego_Rj|Ptb$`kkz_WS$69C$u>BKQF|yz&7)3|2cg?bZXqch zPwGCpa?B@f2bFIFh1nV|ciXTg!49AHI`no>rjdnvrnpu}r%Ubb)o~EiwKY_6b8lhI zaUCcY_fH%cFBXUSb$|_C^{exhTL$*?ZmgZ;%^uZ-tg#qmqYvD0<>;_><7C;7QYWP2 z1fp{d+0nD|&TyY!nK6is(OlL3rbxPht=e&s+cW{{k8?J*T4Q`_YH})5)2vm1X+B$P z*o#rpCTD#^ej8OZUfUEYeK}7{?RD=6!+uUFfxNW5h1N^7ZF!vAd{!Hh;1|#oo42AIIwS}lYxpMZ~ zTI>_(YAn{mgkVz`HrI{VHQ!!UoR*u_pu0bT#)$Bq4pcLf8sQrhR_klGtX8!{JUh2b zkBaL0*7fwo>Fwj*x<`A-m0h-vn(NeW^@X!j^s7VG3rj{h)AptgU&*29GF}=dODwkO zQymZGTRY5qsz{lOZEIZPCEEettq!g%vQIagZ_}^x&WK1>Xu8R9iHoRG-Ib=2oFBGPeJ1i@vze1&y(r?BHcVUQ#47sxD*DxCH ziL#qT>jtb=R#c0SJSc~*(*b-kn=@u{`uaErDNbDmq5qNL`wFZXog zP@;$hrWF=2=yt8(^zBc#1&oQ-S?N6yXD-KN`(#)@|0R?VnhkZjIf z=)299LN}ZfGptN#ZLd9&cA@t%vW`=qp+dpFd;S;LAS0#2p-`+jgis4vcc=Q zy<~F6ui2Q&!5UD{%WdH^>H9h7hBj4qBPJ*};XBuwEr-}1fJMgT+KTq0G9Hgk z;n9embLjyem_SG};n|R9-MZe`!#KCMR#<dj@sPGa;5U=xZ$*tvcl2Z0RrfT6@{YU)&3cmFDI`+Qa z`}Z!O`2Sw;MDQqZJGTGJz~$gq!6zT;_5vK{`wndWZ-T!EUj`ome-3T{*Mrvs`3KGh zXMvyK8~8hL6ZjZ-5f}t#fv@8S&^rO-FE}535c|Ilwu0NS`QHWp82nrC3Lt;LOFW){~y21mgoZBvqx z^_3f-{9{>P_M{*KyWG1rQplR7{A+(U^q!mC#?5Obim&N!7iGP^3oLV^;CYCH9p~$n_Dw?F_Wsex7>d;8)W1=x zS7uRJJ&!sIhTWOi0QstRbEONf1uKS$llf4z3CjW8CO34Z-xx;5oR(Txck|YusLWP5 z+9V(IWr3IbG?a#c8tu2JX;E3_va6F!E-9&VJm;+?`p=njGUc>U&xGF5=03i_4xQqz>u^GqZ1-Zg z1u!ZyGvnz>E7)&nR?^B-=ZnP zlIGcVQSv(Rh`hw;pf1y4e9~+--O(w+>MmO=MxbKWtI=6}ti3JptPKgalJBy|Rp-I7 z+2Ym_1^2QKqKhz)GZzl-vQTQH@*s*jNrZiHxV40 zIJke3p6Qfa2AlMd3}Pbb0PZEE>6=3}zXx&TSy-fTepAPI?kxi0J?O1*l^Mi-T;Y`u e0>8}+>J|Cgw$16>zJ?Rk5-S? +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_lut_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_rr_graph_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_globals.h" + +/* Count the number of rr_graph nodes that should be allocated + * (a) INPUT pins at the top-level pb_graph_node should be a local_rr_node and plus a SOURCE + * (b) CLOCK pins at the top-level pb_graph_node should be a local_rr_node and plus a SOURCE + * (c) OUTPUT pins at the top-level pb_graph_node should be a local_rr_node and plus a SINK + * (e) INPUT pins at a primitive pb_graph_node should be a local_rr_node and plus a SINK + * (f) CLOCK pins at a primitive pb_graph_node should be a local_rr_node and plus a SINK + * (g) OUTPUT pins at a primitive pb_graph_node should be a local_rr_node and plus a SOURCE + * (h) all the other pins should be a local_rr_node + */ +int rec_count_rr_graph_nodes_for_phy_pb_graph_node(t_pb_graph_node* cur_pb_graph_node) { + boolean is_top_pb_graph_node = (boolean) (NULL == cur_pb_graph_node->parent_pb_graph_node); + boolean is_primitive_pb_graph_node = (boolean) (NULL != cur_pb_graph_node->pb_type->spice_model); + int phy_mode_idx = -1; + int cur_num_rr_nodes = 0; + int ichild, ipb; + + /* Count in INPUT/OUTPUT/CLOCK pins as regular rr_nodes */ + cur_num_rr_nodes = count_pin_number_one_pb_graph_node(cur_pb_graph_node); + + /* check if this is a top pb_graph_node or a primitive node */ + if ((TRUE == is_top_pb_graph_node)||(TRUE == is_primitive_pb_graph_node)) { + /* Count in INPUT/OUTPUT/CLOCK pins as SINK/SOURCE rr_nodes */ + cur_num_rr_nodes += cur_num_rr_nodes; + } + + /* Return when this is a primitive node */ + if (TRUE == is_primitive_pb_graph_node) { + return cur_num_rr_nodes; + } + + /* Go recursively to the lower levels */ + /* Find the physical mode in the next level! */ + phy_mode_idx = find_pb_type_physical_mode_index(*(cur_pb_graph_node->pb_type)); + for (ichild = 0; ichild < cur_pb_graph_node->pb_type->modes[phy_mode_idx].num_pb_type_children; ichild++) { + /* num_pb is the number of such pb_type in a physical mode*/ + for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[phy_mode_idx].pb_type_children[ichild].num_pb; ipb++) { + cur_num_rr_nodes += rec_count_rr_graph_nodes_for_phy_pb_graph_node(&cur_pb_graph_node->child_pb_graph_nodes[phy_mode_idx][ichild][ipb]); + } + } + + return cur_num_rr_nodes; +} + +void init_one_rr_node_pack_cost_for_phy_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + enum PORTS port_type) { + switch (port_type) { + case IN_PORT: + /* Routing costs : INPUT pins + * need to normalize better than 5 and 10, bias router to use earlier inputs pins + */ + local_rr_graph->rr_node[cur_rr_node_index].pack_intrinsic_cost = 1 + 1 * (float) local_rr_graph->rr_node[cur_rr_node_index].num_edges / 5 + + 1 * ((float)cur_pb_graph_pin->pin_number / (float)cur_pb_graph_pin->port->num_pins) / (float)10; + break; + case OUT_PORT: + /* Routing costs : OUTPUT pins + * need to normalize better than 5 + */ + local_rr_graph->rr_node[cur_rr_node_index].pack_intrinsic_cost = 1 + 1 * (float) local_rr_graph->rr_node[cur_rr_node_index].num_edges / 5; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid rr_node_type (%d)! \n", + __FILE__, __LINE__, port_type); + exit(1); + } +} + + +/* Override the fan-in and fan-out for a top/primitive pb_graph_node */ +void override_one_rr_node_for_top_primitive_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + boolean is_top_pb_graph_node, + boolean is_primitive_pb_graph_node) { + /* check : must be either a top_pb_graph_node or a primitive_pb_graph_node */ + if ((FALSE == is_top_pb_graph_node) && (FALSE == is_primitive_pb_graph_node)) { + return; + } + + /* depends on the port type */ + switch (cur_pb_graph_pin->port->type) { + case IN_PORT: + if (TRUE == is_top_pb_graph_node) { + /* Top-level IN_PORT should only has 1 fan-in */ + local_rr_graph->rr_node[cur_rr_node_index].fan_in = 1; + return; + } + if (TRUE == is_primitive_pb_graph_node) { + /* Primitive-level IN_PORT should only has 1 output edge */ + local_rr_graph->rr_node[cur_rr_node_index].num_edges = 1; + return; + } + break; + case OUT_PORT: + if (TRUE == is_top_pb_graph_node) { + /* Top-level OUT_PORT should only has 1 output edge */ + local_rr_graph->rr_node[cur_rr_node_index].num_edges = 1; + return; + } + if (TRUE == is_primitive_pb_graph_node) { + /* Primitive-level OUT_PORT should only has 1 fan-in */ + local_rr_graph->rr_node[cur_rr_node_index].fan_in = 1; + return; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid rr_node_type (%d)! \n", + __FILE__, __LINE__, cur_pb_graph_pin->port->type); + exit(1); + } + + return; +} + +/* initialize a rr_node in a rr_graph of phyical pb_graph_node */ +void init_one_rr_node_for_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + int fan_in_phy_mode_index, + int fan_out_phy_mode_index, + t_rr_type rr_node_type, + boolean is_top_pb_graph_node, + boolean is_primitive_pb_graph_node) { + + switch (rr_node_type) { + case INTRA_CLUSTER_EDGE: + /* Link the rr_node to the pb_graph_pin*/ + cur_pb_graph_pin->rr_node_index_physical_pb = cur_rr_node_index; + local_rr_graph->rr_node[cur_rr_node_index].pb_graph_pin = cur_pb_graph_pin; + /* Get the number of input edges that belong to physical mode only! */ + local_rr_graph->rr_node[cur_rr_node_index].fan_in = count_pb_graph_node_input_edge_in_phy_mode(cur_pb_graph_pin, fan_in_phy_mode_index); + /* Get the number of output edges that belong to physical mode only! */ + local_rr_graph->rr_node[cur_rr_node_index].num_edges = count_pb_graph_node_output_edge_in_phy_mode(cur_pb_graph_pin, fan_out_phy_mode_index); + /* Override for special rr_nodes : at top-level and primitive nodes */ + override_one_rr_node_for_top_primitive_phy_pb_graph_node(cur_pb_graph_pin, local_rr_graph, cur_rr_node_index, + is_top_pb_graph_node, is_primitive_pb_graph_node); + /* Routing costs */ + init_one_rr_node_pack_cost_for_phy_graph_node(cur_pb_graph_pin, local_rr_graph, cur_rr_node_index, cur_pb_graph_pin->port->type); + break; + case SOURCE: + /* SOURCE only has one output and zero inputs */ + local_rr_graph->rr_node[cur_rr_node_index].pb_graph_pin = cur_pb_graph_pin; + local_rr_graph->rr_node[cur_rr_node_index].fan_in = 0; + local_rr_graph->rr_node[cur_rr_node_index].num_edges = 1; + /* Routing costs : SOURCE */ + init_one_rr_node_pack_cost_for_phy_graph_node(cur_pb_graph_pin, local_rr_graph, cur_rr_node_index, OUT_PORT); + break; + case SINK: + /* SINK only has one input and zero outputs */ + local_rr_graph->rr_node[cur_rr_node_index].pb_graph_pin = cur_pb_graph_pin; + local_rr_graph->rr_node[cur_rr_node_index].fan_in = 1; + local_rr_graph->rr_node[cur_rr_node_index].num_edges = 0; + /* Routing costs : SINK */ + local_rr_graph->rr_node[cur_rr_node_index].pack_intrinsic_cost = 1; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid rr_node_type (%d)! \n", + __FILE__, __LINE__, rr_node_type); + exit(1); + } + + /* Routing connectivity */ + local_rr_graph->rr_node[cur_rr_node_index].edges = (int *) my_calloc(local_rr_graph->rr_node[cur_rr_node_index].num_edges, sizeof(int)); + local_rr_graph->rr_node[cur_rr_node_index].switches = (short *) my_calloc(local_rr_graph->rr_node[cur_rr_node_index].num_edges, sizeof(short)); + local_rr_graph->rr_node[cur_rr_node_index].net_num = OPEN; + local_rr_graph->rr_node[cur_rr_node_index].prev_node = OPEN; + local_rr_graph->rr_node[cur_rr_node_index].prev_edge = OPEN; + + local_rr_graph->rr_node[cur_rr_node_index].capacity = 1; + local_rr_graph->rr_node[cur_rr_node_index].type = rr_node_type; + + return; +} + +/* Connect a rr_node in a rr_graph of phyical pb_graph_node, + * Assign the edges and switches + */ +void connect_one_rr_node_for_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + int phy_mode_index, + t_rr_type rr_node_type) { + int iedge; + + /* Check: if type matches! */ + assert(rr_node_type == local_rr_graph->rr_node[cur_rr_node_index].type); + + switch (rr_node_type) { + case INTRA_CLUSTER_EDGE: + /* Check out all the output_edges belonging to the same physical mode */ + for (iedge = 0; iedge < cur_pb_graph_pin->num_output_edges; iedge++) { + check_pb_graph_edge(*(cur_pb_graph_pin->output_edges[iedge])); + if (phy_mode_index == cur_pb_graph_pin->output_edges[iedge]->interconnect->parent_mode_index) { + local_rr_graph->rr_node[cur_rr_node_index].edges[iedge] = cur_pb_graph_pin->output_edges[iedge]->output_pins[0]->rr_node_index_physical_pb; + local_rr_graph->rr_node[cur_rr_node_index].switches[iedge] = local_rr_graph->delayless_switch_index; + } + } + break; + case SOURCE: + /* Connect the SOURCE nodes to the rr_node of cur_pb_graph_pin */ + assert (0 == local_rr_graph->rr_node[cur_rr_node_index].fan_in); + assert (1 == local_rr_graph->rr_node[cur_rr_node_index].num_edges); + local_rr_graph->rr_node[cur_rr_node_index].edges[0] = cur_pb_graph_pin->rr_node_index_physical_pb; + local_rr_graph->rr_node[cur_rr_node_index].switches[0] = local_rr_graph->delayless_switch_index; + /* Fix the connection */ + local_rr_graph->rr_node[cur_pb_graph_pin->rr_node_index_physical_pb].prev_node = cur_rr_node_index; + local_rr_graph->rr_node[cur_pb_graph_pin->rr_node_index_physical_pb].prev_edge = 0; + break; + case SINK: + /* Connect the rr_node of cur_pb_graph_pin to the SINK */ + assert (1 == local_rr_graph->rr_node[cur_rr_node_index].fan_in); + assert (0 == local_rr_graph->rr_node[cur_rr_node_index].num_edges); + assert (1 == local_rr_graph->rr_node[cur_pb_graph_pin->rr_node_index_physical_pb].num_edges); + local_rr_graph->rr_node[cur_pb_graph_pin->rr_node_index_physical_pb].edges[0] = cur_rr_node_index; + local_rr_graph->rr_node[cur_pb_graph_pin->rr_node_index_physical_pb].switches[0] = local_rr_graph->delayless_switch_index; + /* Fix the connection */ + local_rr_graph->rr_node[cur_rr_node_index].prev_node = cur_pb_graph_pin->rr_node_index_physical_pb; + local_rr_graph->rr_node[cur_rr_node_index].prev_edge = 0; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid rr_node_type (%d)! \n", + __FILE__, __LINE__, rr_node_type); + exit(1); + } + + return; +} + + +/* Recursively configure all the rr_nodes in the rr_graph + * Initialize the routing cost, fan-in rr_nodes and fan-out rr_nodes, and switches + */ +void rec_init_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* cur_pb_graph_node, + INOUTP t_rr_graph* local_rr_graph, + int* cur_rr_node_index) { + boolean is_top_pb_graph_node = (boolean) (NULL == cur_pb_graph_node->parent_pb_graph_node); + boolean is_primitive_pb_graph_node = (boolean) (NULL != cur_pb_graph_node->pb_type->spice_model); + int phy_mode_idx = -1; + int parent_phy_mode_idx = -1; + int iport, ipin; + int ichild, ipb; + + /* Find the physical mode in the next level! */ + phy_mode_idx = find_pb_type_physical_mode_index(*(cur_pb_graph_node->pb_type)); + /* There is no parent mode index for top-level node */ + if (FALSE == is_top_pb_graph_node) { + parent_phy_mode_idx = find_pb_type_physical_mode_index(*(cur_pb_graph_node->parent_pb_graph_node->pb_type)); + } else { + parent_phy_mode_idx = phy_mode_idx; + } + + /* Configure rr_nodes with the information of pb_graph_pin */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->input_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, phy_mode_idx, INTRA_CLUSTER_EDGE, + is_top_pb_graph_node, is_primitive_pb_graph_node); + (*cur_rr_node_index)++; + } + } + + /* Importantly, the interconnection for output ports belong to the parent pb_graph_node */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->output_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, parent_phy_mode_idx, INTRA_CLUSTER_EDGE, + is_top_pb_graph_node, is_primitive_pb_graph_node); + (*cur_rr_node_index)++; + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->clock_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, phy_mode_idx, INTRA_CLUSTER_EDGE, + is_top_pb_graph_node, is_primitive_pb_graph_node); + (*cur_rr_node_index)++; + } + } + + /* check if this is a top pb_graph_node */ + if ((TRUE == is_top_pb_graph_node)) { + /* Configure SOURCE and SINK rr_node: + * input_pins should have a SOURCE node + */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->input_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, phy_mode_idx, SOURCE, + is_top_pb_graph_node, is_primitive_pb_graph_node); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * clock_pins should have a SOURCE node + */ + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->clock_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, phy_mode_idx, SOURCE, + is_top_pb_graph_node, is_primitive_pb_graph_node); + + (*cur_rr_node_index)++; + } + } + + /* Configure SOURCE and SINK rr_node: + * output_pins should have a SINK node + */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->output_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, phy_mode_idx, SINK, + is_top_pb_graph_node, is_primitive_pb_graph_node); + + (*cur_rr_node_index)++; + } + } + /* Finish adding SOURCE and SINKs */ + } + + /* Return when this is a primitive node */ + if (TRUE == is_primitive_pb_graph_node) { + /* Configure SOURCE and SINK rr_node: + * output_pins should have a SOURCE node + */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->output_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, parent_phy_mode_idx, SOURCE, + is_top_pb_graph_node, is_primitive_pb_graph_node); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * input_pins should have a SINK node + */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->input_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, phy_mode_idx, SINK, + is_top_pb_graph_node, is_primitive_pb_graph_node); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * clock_pins should have a SINK node + */ + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + init_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->clock_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, phy_mode_idx, SINK, + is_top_pb_graph_node, is_primitive_pb_graph_node); + + (*cur_rr_node_index)++; + } + } + /* Finish adding SOURCE and SINKs */ + + return; + } + + /* Go recursively to the lower levels */ + for (ichild = 0; ichild < cur_pb_graph_node->pb_type->modes[phy_mode_idx].num_pb_type_children; ichild++) { + /* num_pb is the number of such pb_type in a physical mode*/ + for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[phy_mode_idx].pb_type_children[ichild].num_pb; ipb++) { + rec_init_rr_graph_for_phy_pb_graph_node(&cur_pb_graph_node->child_pb_graph_nodes[phy_mode_idx][ichild][ipb], + local_rr_graph, cur_rr_node_index); + } + } + + return; +} + +/* Recursively connect all the rr_nodes in the rr_graph + * output_edges, output_switches + */ +void rec_connect_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* cur_pb_graph_node, + INOUTP t_rr_graph* local_rr_graph, + int* cur_rr_node_index) { + boolean is_top_pb_graph_node = (boolean) (NULL == cur_pb_graph_node->parent_pb_graph_node); + boolean is_primitive_pb_graph_node = (boolean) (NULL != cur_pb_graph_node->pb_type->spice_model); + int phy_mode_idx = -1; + int parent_phy_mode_idx = -1; + int iport, ipin; + int ichild, ipb; + + /* Find the physical mode in the next level! */ + phy_mode_idx = find_pb_type_physical_mode_index(*(cur_pb_graph_node->pb_type)); + /* There is no parent mode index for top-level node */ + if (FALSE == is_top_pb_graph_node) { + parent_phy_mode_idx = find_pb_type_physical_mode_index(*(cur_pb_graph_node->parent_pb_graph_node->pb_type)); + } else { + parent_phy_mode_idx = phy_mode_idx; + } + + /* Configure rr_nodes with the information of pb_graph_pin */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->input_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, INTRA_CLUSTER_EDGE); + (*cur_rr_node_index)++; + } + } + + /* Importantly, the interconnection for output ports belong to the parent pb_graph_node */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->output_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, INTRA_CLUSTER_EDGE); + (*cur_rr_node_index)++; + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->clock_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, INTRA_CLUSTER_EDGE); + (*cur_rr_node_index)++; + } + } + + /* check if this is a top pb_graph_node */ + if ((TRUE == is_top_pb_graph_node)) { + /* Configure SOURCE and SINK rr_node: + * input_pins should have a SOURCE node + */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->input_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, SOURCE); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * clock_pins should have a SOURCE node + */ + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->clock_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, SOURCE); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * output_pins should have a SINK node + */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->output_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, SINK); + + (*cur_rr_node_index)++; + } + } + /* Finish adding SOURCE and SINKs */ + } + + /* Return when this is a primitive node */ + if (TRUE == is_primitive_pb_graph_node) { + /* Configure SOURCE and SINK rr_node: + * output_pins should have a SOURCE node + */ + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->output_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, parent_phy_mode_idx, SOURCE); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * input_pins should have a SINK node + */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->input_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, SINK); + + (*cur_rr_node_index)++; + } + } + /* Configure SOURCE and SINK rr_node: + * clock_pins should have a SINK node + */ + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + connect_one_rr_node_for_phy_pb_graph_node(&cur_pb_graph_node->clock_pins[iport][ipin], local_rr_graph, + *cur_rr_node_index, phy_mode_idx, SINK); + + (*cur_rr_node_index)++; + } + } + /* Finish adding SOURCE and SINKs */ + + return; + } + + /* Go recursively to the lower levels */ + for (ichild = 0; ichild < cur_pb_graph_node->pb_type->modes[phy_mode_idx].num_pb_type_children; ichild++) { + /* num_pb is the number of such pb_type in a physical mode*/ + for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[phy_mode_idx].pb_type_children[ichild].num_pb; ipb++) { + rec_connect_rr_graph_for_phy_pb_graph_node(&cur_pb_graph_node->child_pb_graph_nodes[phy_mode_idx][ichild][ipb], + local_rr_graph, cur_rr_node_index); + } + } + + return; +} + +/* Allocate a rr_graph for a given pb_graph node + * This is function is a copy of alloc_and_load_rr_graph_for_pb_graph_node + * The major difference lies in removing the use of global variables + * This function does the following tasks: + * 1. Count all the pins in pb_graph_node (only those in physical modes) that can be a rr_node in the local rr_graph + * (a) INPUT pins at the top-level pb_graph_node should be a local_rr_node and plus a SOURCE + * (b) CLOCK pins at the top-level pb_graph_node should be a local_rr_node and plus a SOURCE + * (c) OUTPUT pins at the top-level pb_graph_node should be a local_rr_node and plus a SINK + * (e) INPUT pins at a primitive pb_graph_node should be a local_rr_node and plus a SINK + * (f) CLOCK pins at a primitive pb_graph_node should be a local_rr_node and plus a SINK + * (g) OUTPUT pins at a primitive pb_graph_node should be a local_rr_node and plus a SOURCE + * (h) all the other pins should be a local_rr_node + * 2. Allocate the rr_graph and initialize its properties according to the pb_graph_pin interconnections + * capacity, mapped net name, edges, switches, routing cost information + * 3. Synchronize mapped_net_name from a mapped pb: + * (a) give mapped_net_name to INPUT/OUTPUT/CLOCK pins of the top-level pb_graph_node + * (b) give mapped_net_name to INPUT/OUTPUT/CLOCK pins of the primitive pb_graph_nodes + */ +void alloc_and_load_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* top_pb_graph_node, + OUTP t_rr_graph* local_rr_graph) { + + int phy_pb_num_rr_nodes, check_point; + + /* Count the number of rr_nodes that are required */ + phy_pb_num_rr_nodes = rec_count_rr_graph_nodes_for_phy_pb_graph_node(top_pb_graph_node); + + /* Allocate rr_graph */ + alloc_and_load_rr_graph_rr_node(local_rr_graph, phy_pb_num_rr_nodes); + + /* Fill basic information for the rr_graph */ + check_point = 0; + rec_init_rr_graph_for_phy_pb_graph_node(top_pb_graph_node, local_rr_graph, &check_point); + assert (check_point == local_rr_graph->num_rr_nodes); + + /* Fill edges and switches for the rr_graph */ + check_point = 0; + rec_connect_rr_graph_for_phy_pb_graph_node(top_pb_graph_node, local_rr_graph, &check_point); + assert (check_point == local_rr_graph->num_rr_nodes); + + return; +} + +/* Check the vpack_net_num of a rr_node mapped to a pb_graph_pin and + * mark the used vpack_net_num in the list + */ +void mark_vpack_net_used_in_pb_pin(t_pb* cur_op_pb, t_pb_graph_pin* cur_pb_graph_pin, + int L_num_vpack_nets, boolean* vpack_net_used_in_pb) { + int inode; + + assert (NULL != cur_pb_graph_pin); + + inode = cur_pb_graph_pin->pin_count_in_cluster; + + /* bypass unmapped rr_node */ + if (OPEN == cur_op_pb->rr_graph[inode].vpack_net_num) { + return; + } + /* Reach here, it means this net is used in this pb */ + assert( (-1 < cur_op_pb->rr_graph[inode].vpack_net_num) + && ( cur_op_pb->rr_graph[inode].vpack_net_num < L_num_vpack_nets)); + vpack_net_used_in_pb[cur_op_pb->rr_graph[inode].vpack_net_num] = TRUE; + + return; +} + +/* Recursively visit all the child pbs and + * mark the used vpack_net_num in the list + */ +void mark_vpack_net_used_in_pb(t_pb* cur_op_pb, + int L_num_vpack_nets, boolean* vpack_net_used_in_pb) { + int mode_index, ipb, jpb; + int iport, ipin; + t_pb_type* cur_pb_type = NULL; + + cur_pb_type = cur_op_pb->pb_graph_node->pb_type; + mode_index = cur_op_pb->mode; + + /* Mark all the nets at this level */ + for (iport = 0; iport < cur_op_pb->pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_op_pb->pb_graph_node->num_input_pins[iport]; ipin++) { + mark_vpack_net_used_in_pb_pin(cur_op_pb, &(cur_op_pb->pb_graph_node->input_pins[iport][ipin]), + L_num_vpack_nets, vpack_net_used_in_pb); + } + } + + for (iport = 0; iport < cur_op_pb->pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_op_pb->pb_graph_node->num_output_pins[iport]; ipin++) { + mark_vpack_net_used_in_pb_pin(cur_op_pb, &(cur_op_pb->pb_graph_node->output_pins[iport][ipin]), + L_num_vpack_nets, vpack_net_used_in_pb); + } + } + + for (iport = 0; iport < cur_op_pb->pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_op_pb->pb_graph_node->num_clock_pins[iport]; ipin++) { + mark_vpack_net_used_in_pb_pin(cur_op_pb, &(cur_op_pb->pb_graph_node->clock_pins[iport][ipin]), + L_num_vpack_nets, vpack_net_used_in_pb); + } + } + + /* recursive for the child_pbs*/ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_op_pb->child_pbs[ipb])&&(NULL != cur_op_pb->child_pbs[ipb][jpb].name)) { + mark_vpack_net_used_in_pb(&(cur_op_pb->child_pbs[ipb][jpb]), + L_num_vpack_nets, vpack_net_used_in_pb); + } + } + } + } + + return; +} + +/* Find the vpack_nets used by this pb + * And allocate an array for those nets and load it to pb_rr_graph + */ +void alloc_and_load_phy_pb_rr_graph_nets(INP t_pb* cur_op_pb, + t_rr_graph* local_rr_graph, + int L_num_vpack_nets, t_net* L_vpack_net) { + /* Create an array labeling which vpack_net is used in this pb */ + int num_vpack_net_used_in_pb = 0; + boolean* vpack_net_used_in_pb = NULL; + int inet, net_index; + + /* Allocate */ + vpack_net_used_in_pb = (boolean*)my_malloc(sizeof(boolean) * L_num_vpack_nets); + /* Initial to FALSE */ + for (inet = 0; inet < L_num_vpack_nets; inet++) { + vpack_net_used_in_pb[inet] = FALSE; + } + + /* Build vpack_net_used_in_pb */ + mark_vpack_net_used_in_pb(cur_op_pb, L_num_vpack_nets, vpack_net_used_in_pb); + + /* Count the number of vpack_net used in this pb */ + num_vpack_net_used_in_pb = 0; + for (inet = 0; inet < L_num_vpack_nets; inet++) { + if (TRUE == vpack_net_used_in_pb[inet]) { + num_vpack_net_used_in_pb++; + } + } + + /* Allocate net for rr_graph */ + local_rr_graph->num_nets = num_vpack_net_used_in_pb; + local_rr_graph->net = (t_net**) my_malloc(sizeof(t_net*) * local_rr_graph->num_nets); + local_rr_graph->net_to_vpack_net_mapping = (int*) my_malloc(sizeof(int) * local_rr_graph->num_nets); + + /* Fill the net array and net_to_net_mapping */ + net_index = 0; + for (inet = 0; inet < L_num_vpack_nets; inet++) { + if (TRUE == vpack_net_used_in_pb[inet]) { + local_rr_graph->net[net_index] = &L_vpack_net[inet]; + local_rr_graph->net_to_vpack_net_mapping[net_index] = inet; + net_index++; + } + } + assert( net_index == local_rr_graph->num_nets ); + + return; +} + +/* Find the rr_node in the primitive node of a pb_rr_graph*/ +void sync_pb_graph_pin_vpack_net_num_to_phy_pb(t_rr_node* cur_op_pb_rr_graph, + t_pb_graph_pin* cur_pb_graph_pin, + t_rr_graph* local_rr_graph) { + int inode, jnode, iedge, next_node; + int rr_node_net_num; + + inode = cur_pb_graph_pin->pin_count_in_cluster; + /* bypass non-exist physical pb_graph_pins */ + if (NULL == cur_pb_graph_pin->physical_pb_graph_pin) { + return; + } + jnode = cur_pb_graph_pin->physical_pb_graph_pin->rr_node_index_physical_pb; + + /* If we have a valid vpack_net_num */ + if (OPEN == cur_op_pb_rr_graph[inode].vpack_net_num) { + /* Do not overwrite because this rr_node may have been updated! */ + /* + local_rr_graph->rr_node[jnode].net_num = OPEN; + local_rr_graph->rr_node[jnode].vpack_net_num = OPEN; + */ + return; + } + + /* Synchronize depending on the rr_node type */ + switch (local_rr_graph->rr_node[jnode].type) { + case SOURCE: + case SINK: + /* SOURCE or SINK: we are done, just synchronize the vpack_net_num and we can return*/ + rr_node_net_num = get_rr_graph_net_index_with_vpack_net(local_rr_graph, cur_op_pb_rr_graph[inode].vpack_net_num); + assert (( -1 < rr_node_net_num ) && (rr_node_net_num < local_rr_graph->num_nets)); + local_rr_graph->rr_node[jnode].net_num = rr_node_net_num; + local_rr_graph->rr_node[jnode].vpack_net_num = cur_op_pb_rr_graph[inode].vpack_net_num; + break; + case INTRA_CLUSTER_EDGE: + /* We need to find a SOURCE or a SINK nodes! */ + /* Check driving rr_nodes */ + for (iedge = 0; iedge < local_rr_graph->rr_node[jnode].num_drive_rr_nodes; iedge++) { + if (SOURCE != local_rr_graph->rr_node[jnode].drive_rr_nodes[iedge]->type) { + continue; + } + /* Give the vpack_net_num to the SOURCE nodes */ + rr_node_net_num = get_rr_graph_net_index_with_vpack_net(local_rr_graph, cur_op_pb_rr_graph[inode].vpack_net_num); + assert (( -1 < rr_node_net_num ) && (rr_node_net_num < local_rr_graph->num_nets)); + local_rr_graph->rr_node[jnode].drive_rr_nodes[iedge]->net_num = rr_node_net_num; + local_rr_graph->rr_node[jnode].drive_rr_nodes[iedge]->vpack_net_num = cur_op_pb_rr_graph[inode].vpack_net_num; + } + /* Check the output rr_nodes */ + for (iedge = 0; iedge < local_rr_graph->rr_node[jnode].num_edges; iedge++) { + next_node = local_rr_graph->rr_node[jnode].edges[iedge]; + if (SINK != local_rr_graph->rr_node[next_node].type) { + continue; + } + /* Give the vpack_net_num to the SOURCE nodes */ + rr_node_net_num = get_rr_graph_net_index_with_vpack_net(local_rr_graph, cur_op_pb_rr_graph[inode].vpack_net_num); + assert (( -1 < rr_node_net_num ) && (rr_node_net_num < local_rr_graph->num_nets)); + local_rr_graph->rr_node[next_node].net_num = rr_node_net_num; + local_rr_graph->rr_node[next_node].vpack_net_num = cur_op_pb_rr_graph[inode].vpack_net_num; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid rr_node_type (%d)! \n", + __FILE__, __LINE__, local_rr_graph->rr_node[jnode].type); + exit(1); + } + + return; +} + +void rec_sync_wired_pb_vpack_net_num_to_phy_pb_rr_graph(t_pb_graph_node* cur_pb_graph_node, + t_rr_node* op_pb_rr_graph, + t_rr_graph* local_rr_graph) { + int imode, ipb, jpb; + int ipin, iport; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + + /* Copy LUT information if this is a leaf node */ + if ((TRUE == is_primitive_pb_type(cur_pb_type)) + && (LUT_CLASS == cur_pb_type->class_type)) { + /* Mark all the nets at this level */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + sync_pb_graph_pin_vpack_net_num_to_phy_pb(op_pb_rr_graph, + &(cur_pb_graph_node->input_pins[iport][ipin]), + local_rr_graph); + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + sync_pb_graph_pin_vpack_net_num_to_phy_pb(op_pb_rr_graph, + &(cur_pb_graph_node->output_pins[iport][ipin]), + local_rr_graph); + } + } + + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + sync_pb_graph_pin_vpack_net_num_to_phy_pb(op_pb_rr_graph, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + local_rr_graph); + } + } + + /* Finish here */ + return; + } + + /* Go recursively */ + assert (FALSE == is_primitive_pb_type(cur_pb_type)); + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + /* We care only those have been used for wiring */ + if (FALSE == is_pb_used_for_wiring(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + &(cur_pb_type->modes[imode].pb_type_children[ipb]), + op_pb_rr_graph)) { + continue; + } + rec_sync_wired_pb_vpack_net_num_to_phy_pb_rr_graph(&(cur_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + op_pb_rr_graph, + local_rr_graph); + } + } + } + + return; +} + +/* Recursively visit all the child pbs and + * synchronize the vpack_net_num of the top-level/primitive pb_graph_pin + * to the physical pb rr_node nodes + */ +void rec_sync_pb_vpack_net_num_to_phy_pb_rr_graph(t_pb* cur_op_pb, + t_rr_graph* local_rr_graph) { + int mode_index, ipb, jpb; + int iport, ipin; + t_pb_type* cur_pb_type = NULL; + + cur_pb_type = cur_op_pb->pb_graph_node->pb_type; + mode_index = cur_op_pb->mode; + + /* Mark all the nets at this level */ + for (iport = 0; iport < cur_op_pb->pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_op_pb->pb_graph_node->num_input_pins[iport]; ipin++) { + sync_pb_graph_pin_vpack_net_num_to_phy_pb(cur_op_pb->rr_graph, + &(cur_op_pb->pb_graph_node->input_pins[iport][ipin]), + local_rr_graph); + } + } + + for (iport = 0; iport < cur_op_pb->pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_op_pb->pb_graph_node->num_output_pins[iport]; ipin++) { + sync_pb_graph_pin_vpack_net_num_to_phy_pb(cur_op_pb->rr_graph, + &(cur_op_pb->pb_graph_node->output_pins[iport][ipin]), + local_rr_graph); + } + } + + for (iport = 0; iport < cur_op_pb->pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_op_pb->pb_graph_node->num_clock_pins[iport]; ipin++) { + sync_pb_graph_pin_vpack_net_num_to_phy_pb(cur_op_pb->rr_graph, + &(cur_op_pb->pb_graph_node->clock_pins[iport][ipin]), + local_rr_graph); + } + } + + /* Return if we reach the primitive */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + return; + } + + /* recursive for the child_pbs*/ + assert (FALSE == is_primitive_pb_type(cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_op_pb->child_pbs[ipb])&&(NULL != cur_op_pb->child_pbs[ipb][jpb].name)) { + rec_sync_pb_vpack_net_num_to_phy_pb_rr_graph(&(cur_op_pb->child_pbs[ipb][jpb]), + local_rr_graph); + } else if (TRUE == is_pb_used_for_wiring(&(cur_op_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), + cur_op_pb->rr_graph)) { + /* Identify pbs and LUTs that are used for wiring purpose */ + rec_sync_wired_pb_vpack_net_num_to_phy_pb_rr_graph(&(cur_op_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + cur_op_pb->rr_graph, + local_rr_graph); + } + } + } + + return; +} + + +/* Load mapping information from an op_pb to the net_rr_terminals of a phy_pb rr_graph + * This function should do the following tasks: + * 1. Find mapped pb_graph_pin in the rr_graph of cur_op_pb + * 2. Locate the pin-to-pin annotation in the pb_graph_pin of cur_op_pb + * and find the corresponding pb_graph_pin in local_rr_graph (phy_pb) + * 3. Find the SOURCE and SINK rr_nodes related to the pb_graph_pin + * 4. Configure the net_rr_terminals with the SINK/SOURCE rr_nodes + */ +void alloc_and_load_phy_pb_rr_graph_net_rr_terminals(INP t_pb* cur_op_pb, + t_rr_graph* local_rr_graph) { + int inet, inode, rr_node_net_name; + int* net_cur_terminal = (int*) my_calloc(local_rr_graph->num_nets, sizeof(int)); + int* net_cur_source = (int*) my_calloc(local_rr_graph->num_nets, sizeof(int)); + int* net_cur_sink = (int*) my_calloc(local_rr_graph->num_nets, sizeof(int)); + + /* Initialize */ + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + /* SINK index starts from 1!!!*/ + net_cur_terminal[inet] = 1; + net_cur_source[inet] = 0; + net_cur_sink[inet] = 0; + } + + /* Check each net in the local_rr_graph, + * Find the routing resource node in the pb_rr_graph of the cur_op_pb + * and annotate in the local_rr_graph + * assign the net_rr_terminal with the node index in the local_rr_graph + * Two steps to go: + * 1. synchronize the vpack_net_num of pb_graph_pin (rr_node) in op_pb + * to the local rr_graph (SINK and SOURCE nodes!) + * 2. Annotate the net_rr_terminals by sweeping the rr_node in local_rr_graph + */ + rec_sync_pb_vpack_net_num_to_phy_pb_rr_graph(cur_op_pb, + local_rr_graph); + + /* Allocate net_rr_terminals */ + alloc_rr_graph_net_rr_terminals(local_rr_graph); + /* Some nets may have two sources nodes to route + * We store the sources node in the net_rr_sources list + * We keep a list for the sink nodes + * in the net_rr_sinks list + */ + alloc_rr_graph_net_rr_sources_and_sinks(local_rr_graph); + + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + /* We only care the SOURCE and SINK nodes */ + switch (local_rr_graph->rr_node[inode].type) { + case SOURCE: + /* SOURCE is easy: give the rr_node id to first terminal of the vpack_net */ + rr_node_net_name = local_rr_graph->rr_node[inode].net_num; + if (OPEN == rr_node_net_name) { + break; + } + local_rr_graph->net_rr_terminals[rr_node_net_name][0] = inode; + /* Store in the source and sink lists */ + local_rr_graph->net_rr_sources[rr_node_net_name][net_cur_source[rr_node_net_name]] = inode; + /* Update the counter */ + net_cur_source[rr_node_net_name]++; + break; + case SINK: + /* SINK: we need to record the sink we considered */ + rr_node_net_name = local_rr_graph->rr_node[inode].net_num; + if (OPEN == rr_node_net_name) { + break; + } + /* Make sure we do not overwrite on the source */ + assert ( 0 < net_cur_terminal[rr_node_net_name] ); + local_rr_graph->net_rr_terminals[rr_node_net_name][net_cur_terminal[rr_node_net_name]] = inode; + net_cur_terminal[rr_node_net_name]++; + /* Store in the source and sink lists */ + local_rr_graph->net_rr_sinks[rr_node_net_name][net_cur_sink[rr_node_net_name]] = inode; + /* Update the counter */ + net_cur_sink[rr_node_net_name]++; + break; + case INTRA_CLUSTER_EDGE: + /* Nothing to do */ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid rr_node_type (%d)! \n", + __FILE__, __LINE__, local_rr_graph->rr_node[inode].type); + exit(1); + } + } + /* Check */ + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + /* Count in the first node is SOURCE not the SINK */ + assert ( net_cur_terminal[inet] == local_rr_graph->net_num_sinks[inet] + 1); + assert ( net_cur_source[inet] == local_rr_graph->net_num_sources[inet]); + assert ( net_cur_sink[inet] == local_rr_graph->net_num_sinks[inet]); + } + + /* Free */ + my_free(net_cur_terminal); + my_free(net_cur_source); + my_free(net_cur_sink); + + return; +} + +void alloc_pb_rr_graph_rr_indexed_data(t_rr_graph* local_rr_graph) { + /* inside a cluster, I do not consider rr_indexed_data cost, set to 1 since other costs are multiplied by it */ + alloc_rr_graph_rr_indexed_data(local_rr_graph, 1); + local_rr_graph->rr_indexed_data[0].base_cost = 1; + + return; +} + +/* Reach here means that this LUT is in wired mode (a buffer) + * Add an output edge to the rr_node of the used input + * connect it to the rr_node of the used LUT output + */ +void add_rr_node_edge_to_one_wired_lut(t_pb_graph_node* cur_pb_graph_node, + t_pb_type* cur_pb_type, + t_rr_node* op_pb_rr_graph, + t_rr_graph* local_rr_graph) { + int iport, ipin; + int jport, jpin; + int iedge; + int lut_input_rr_node_index, lut_output_rr_node_index; + int num_used_lut_input_pins = 0; + int num_used_lut_output_pins = 0; + int temp_rr_node_index; + int wired_lut_net_num = OPEN; + boolean exist = FALSE; + int cnt = 0; + + num_used_lut_input_pins = 0; + lut_input_rr_node_index = OPEN; + + /* Find the used input pin of this LUT and rr_node in the graph */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + temp_rr_node_index = cur_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; + /* Force the vpack_net_num from net_name here */ + if ((OPEN != op_pb_rr_graph[temp_rr_node_index].net_num) + && (OPEN == op_pb_rr_graph[temp_rr_node_index].vpack_net_num)) { + op_pb_rr_graph[temp_rr_node_index].vpack_net_num = op_pb_rr_graph[temp_rr_node_index].net_num; + } + if (OPEN != op_pb_rr_graph[temp_rr_node_index].vpack_net_num) { + num_used_lut_input_pins++; + wired_lut_net_num = op_pb_rr_graph[temp_rr_node_index].vpack_net_num; + lut_input_rr_node_index = cur_pb_graph_node->input_pins[iport][ipin].physical_pb_graph_pin->rr_node_index_physical_pb; + } + /* If we did not find one, finish this round, otherwise set it to zero and edges */ + if (0 == num_used_lut_input_pins) { + continue; + } else { + assert (1 == num_used_lut_input_pins); + num_used_lut_input_pins = 0; + } + + /* Find the used output*/ + num_used_lut_output_pins = 0; + lut_output_rr_node_index = OPEN; + /* Find the used output pin of this LUT and rr_node in the graph */ + for (jport = 0; jport < cur_pb_graph_node->num_output_ports; jport++) { + for (jpin = 0; jpin < cur_pb_graph_node->num_output_pins[jport]; jpin++) { + temp_rr_node_index = cur_pb_graph_node->output_pins[jport][jpin].pin_count_in_cluster; + /* Force the vpack_net_num from net_name here */ + if ((OPEN != op_pb_rr_graph[temp_rr_node_index].net_num) + && (OPEN == op_pb_rr_graph[temp_rr_node_index].vpack_net_num)) { + op_pb_rr_graph[temp_rr_node_index].vpack_net_num = op_pb_rr_graph[temp_rr_node_index].net_num; + } + if (wired_lut_net_num == op_pb_rr_graph[temp_rr_node_index].vpack_net_num) { + num_used_lut_output_pins++; + lut_output_rr_node_index = cur_pb_graph_node->output_pins[jport][jpin].physical_pb_graph_pin->rr_node_index_physical_pb; + } + } + } + /* Make sure we only have 1 used output pin */ + assert ((1 == num_used_lut_output_pins) + && (OPEN != lut_output_rr_node_index)); + + /* Add a special edge between the two rr_nodes */ + /* Check if the lut_output_rr_node is already in the edge list */ + exist = FALSE; + for (iedge = 0; iedge < local_rr_graph->rr_node[lut_input_rr_node_index].num_edges; iedge++) { + if (lut_output_rr_node_index == local_rr_graph->rr_node[lut_input_rr_node_index].edges[iedge]) { + exist = TRUE; + break; + } + } + if (FALSE == exist) { + /* Modify the input(source) node */ + local_rr_graph->rr_node[lut_input_rr_node_index].num_edges++; + local_rr_graph->rr_node[lut_input_rr_node_index].edges = (int*) my_realloc(local_rr_graph->rr_node[lut_input_rr_node_index].edges, + local_rr_graph->rr_node[lut_input_rr_node_index].num_edges * sizeof(int)); + local_rr_graph->rr_node[lut_input_rr_node_index].edges[local_rr_graph->rr_node[lut_input_rr_node_index].num_edges -1] = lut_output_rr_node_index; + local_rr_graph->rr_node[lut_input_rr_node_index].switches = (short*) my_realloc(local_rr_graph->rr_node[lut_input_rr_node_index].switches, + local_rr_graph->rr_node[lut_input_rr_node_index].num_edges * sizeof(short)); + local_rr_graph->rr_node[lut_input_rr_node_index].switches[local_rr_graph->rr_node[lut_input_rr_node_index].num_edges -1] = DEFAULT_SWITCH_ID; + } + + /* Check if the lut_input_rr_node is already in the drive_rr_node list */ + exist = FALSE; + for (iedge = 0; iedge < local_rr_graph->rr_node[lut_output_rr_node_index].num_drive_rr_nodes; iedge++) { + if (&(local_rr_graph->rr_node[lut_input_rr_node_index]) == local_rr_graph->rr_node[lut_output_rr_node_index].drive_rr_nodes[iedge]) { + exist = TRUE; + break; + } + } + if (FALSE == exist) { + /* Modify the output(destination) node */ + local_rr_graph->rr_node[lut_output_rr_node_index].fan_in++; + local_rr_graph->rr_node[lut_output_rr_node_index].num_drive_rr_nodes++; + local_rr_graph->rr_node[lut_output_rr_node_index].drive_rr_nodes = (t_rr_node**) my_realloc(local_rr_graph->rr_node[lut_output_rr_node_index].drive_rr_nodes, + local_rr_graph->rr_node[lut_output_rr_node_index].num_drive_rr_nodes * sizeof(t_rr_node*)); + local_rr_graph->rr_node[lut_output_rr_node_index].drive_rr_nodes[local_rr_graph->rr_node[lut_output_rr_node_index].num_drive_rr_nodes - 1] = &(local_rr_graph->rr_node[lut_input_rr_node_index]); + + local_rr_graph->rr_node[lut_output_rr_node_index].drive_switches = (int*) my_realloc(local_rr_graph->rr_node[lut_output_rr_node_index].drive_switches, + local_rr_graph->rr_node[lut_output_rr_node_index].num_drive_rr_nodes * sizeof(int)); + local_rr_graph->rr_node[lut_output_rr_node_index].drive_switches[local_rr_graph->rr_node[lut_output_rr_node_index].num_drive_rr_nodes - 1] = DEFAULT_SWITCH_ID; + } + /* Update counter */ + cnt++; + } + } + + /* vpr_printf(TIO_MESSAGE_INFO, "Added %d rr_node edge for wired LUT\n", cnt); */ + + return; +} + +/* Add rr edges connecting from an input of a LUT to its output + * IMPORTANT: this is only applied to LUT which operates in wire mode (a buffer) + */ +void rec_add_unused_rr_graph_wired_lut_rr_edges(INP t_pb_graph_node* cur_op_pb_graph_node, + INP t_rr_node* cur_op_pb_rr_graph, + INOUTP t_rr_graph* local_rr_graph) { + int imode, ipb, jpb; + t_pb_type* cur_pb_type = NULL; + + cur_pb_type = cur_op_pb_graph_node->pb_type; + + /* Go recursively until we reach a primitive node which is a LUT */ + + /* Return if we reach the primitive */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + /* We only care the LUTs, that is in wired mode */ + if (TRUE == is_pb_wired_lut(cur_op_pb_graph_node, + cur_pb_type, + cur_op_pb_rr_graph)) { + + /* Reach here means that this LUT is in wired mode (a buffer) + * Add an output edge to the rr_node of the used input + * connect it to the rr_node of the used LUT output + */ + add_rr_node_edge_to_one_wired_lut(cur_op_pb_graph_node, + cur_pb_type, + cur_op_pb_rr_graph, + local_rr_graph); + } + return; + } + + /* recursive for the child_pbs*/ + assert (FALSE == is_primitive_pb_type(cur_pb_type)); + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + for (ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[imode].pb_type_children[ipb].num_pb; jpb++) { + /* We only care those used for wiring */ + if (FALSE == is_pb_used_for_wiring(&(cur_op_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + &(cur_pb_type->modes[imode].pb_type_children[ipb]), + cur_op_pb_rr_graph)) { + continue; + } + rec_add_unused_rr_graph_wired_lut_rr_edges(&(cur_op_pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + cur_op_pb_rr_graph, + local_rr_graph); + } + } + } + + return; +} + + +/* Add rr edges connecting from an input of a LUT to its output + * IMPORTANT: this is only applied to LUT which operates in wire mode (a buffer) + */ +void rec_add_rr_graph_wired_lut_rr_edges(INP t_pb* cur_op_pb, + INOUTP t_rr_graph* local_rr_graph) { + int mode_index, ipb, jpb, imode; + t_pb_type* cur_pb_type = NULL; + + cur_pb_type = cur_op_pb->pb_graph_node->pb_type; + mode_index = cur_op_pb->mode; + + /* Go recursively until we reach a primitive node which is a LUT */ + + /* Return if we reach the primitive */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + /* We only care the LUTs, that is in wired mode */ + if ((LUT_CLASS == cur_pb_type->class_type) + && (WIRED_LUT_MODE_INDEX == mode_index)) { + /* Reach here means that this LUT is in wired mode (a buffer) + * Add an output edge to the rr_node of the used input + * connect it to the rr_node of the used LUT output + */ + add_rr_node_edge_to_one_wired_lut(cur_op_pb->pb_graph_node, + cur_pb_type, + cur_op_pb->rr_graph, + local_rr_graph); + } + return; + } + + /* recursive for the child_pbs*/ + assert (FALSE == is_primitive_pb_type(cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Recursive*/ + /* Refer to pack/output_clustering.c [LINE 392] */ + if ((NULL != cur_op_pb->child_pbs[ipb])&&(NULL != cur_op_pb->child_pbs[ipb][jpb].name)) { + rec_add_rr_graph_wired_lut_rr_edges(&(cur_op_pb->child_pbs[ipb][jpb]), + local_rr_graph); + } else if (TRUE == is_pb_used_for_wiring(&(cur_op_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), + cur_op_pb->rr_graph)) { + /* We need to extend this part: + * Some open op_pb contains wired LUTs + * We need go further into the hierarchy and find out the wired LUTs + */ + for (imode = 0; imode < cur_pb_type->num_modes; imode++) { + rec_add_unused_rr_graph_wired_lut_rr_edges(&(cur_op_pb->pb_graph_node->child_pb_graph_nodes[imode][ipb][jpb]), + cur_op_pb->rr_graph, + local_rr_graph); + } + } + } + } + + return; +} + +/* To avoid a messy multi-source routing that may never converge, + * For each multiple-source net, I add a new source as the unique source in routing purpose + * As so, edges have to be added to the decendents of sources + */ +int add_virtual_sources_to_rr_graph_multi_sources(t_rr_graph* local_rr_graph) { + int inet, isrc, iedge, to_node; + int unique_src_node; + int cnt = 0; + + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + /* Bypass single-source nets */ + if (1 == local_rr_graph->net_num_sources[inet]) { + continue; + } + /* Add a new source */ + local_rr_graph->num_rr_nodes++; + local_rr_graph->rr_node = (t_rr_node*)my_realloc(local_rr_graph->rr_node, + local_rr_graph->num_rr_nodes * sizeof(t_rr_node)); + /* Configure the unique source node */ + unique_src_node = local_rr_graph->num_rr_nodes - 1; + local_rr_graph->rr_node[unique_src_node].type = SOURCE; + local_rr_graph->rr_node[unique_src_node].capacity = 1; + local_rr_graph->rr_node[unique_src_node].fan_in = 0; + local_rr_graph->rr_node[unique_src_node].num_drive_rr_nodes = 0; + local_rr_graph->rr_node[unique_src_node].drive_rr_nodes = NULL; + local_rr_graph->rr_node[unique_src_node].num_edges = local_rr_graph->net_num_sources[inet]; + local_rr_graph->rr_node[unique_src_node].edges = (int*) my_calloc(local_rr_graph->rr_node[unique_src_node].num_edges, sizeof(int)); + local_rr_graph->rr_node[unique_src_node].switches = (short*) my_calloc(local_rr_graph->rr_node[unique_src_node].num_edges, sizeof(short)); + /* Configure edges */ + for (isrc = 0; isrc < local_rr_graph->net_num_sources[inet]; isrc++) { + /* Connect edges to sources */ + local_rr_graph->rr_node[unique_src_node].edges[isrc] = local_rr_graph->net_rr_sources[inet][isrc]; + local_rr_graph->rr_node[unique_src_node].switches[isrc] = DEFAULT_SWITCH_ID; + /* Configure the original sources */ + to_node = local_rr_graph->net_rr_sources[inet][isrc]; + } + /* Replace the sources with the new source node */ + local_rr_graph->net_num_sources[inet] = 1; + local_rr_graph->net_rr_sources[inet] = (int*)my_realloc(local_rr_graph->net_rr_sources[inet], + local_rr_graph->net_num_sources[inet] * sizeof(int)); + local_rr_graph->net_rr_sources[inet][0] = unique_src_node; + /* Replace the sources in the net_rr_terminals */ + local_rr_graph->net_rr_terminals[inet][0] = unique_src_node; + /* Update counter */ + cnt++; + } + + vpr_printf(TIO_MESSAGE_INFO, + "Added %d virtual source nodes for routing.\n", + cnt); + + return cnt; +} + +/* Allocate and load a local rr_graph for a pb + * 1. Allocate the rr_graph nodes and configure with pb_graph_node connectivity + * 2. load all the routing statisitics required by the router + * 3. load the net to be routed into the rr_graph + */ +void alloc_and_load_rr_graph_for_phy_pb(INP t_pb* cur_op_pb, + INP t_phy_pb* cur_phy_pb, + int L_num_vpack_nets, t_net* L_vpack_net) { + + /* Allocate rr_graph*/ + cur_phy_pb->rr_graph = (t_rr_graph*) my_calloc(1, sizeof(t_rr_graph)); + + /* Create rr_graph */ + alloc_and_load_rr_graph_for_phy_pb_graph_node(cur_phy_pb->pb_graph_node, cur_phy_pb->rr_graph); + + /* Build prev nodes list for rr_nodes */ + alloc_and_load_prev_node_list_rr_graph_rr_nodes(cur_phy_pb->rr_graph); + + /* Allocate structs routing information */ + alloc_and_load_rr_graph_route_structs(cur_phy_pb->rr_graph); + + /* Find the nets inside the pb and initialize the rr_graph */ + alloc_and_load_phy_pb_rr_graph_nets(cur_op_pb, cur_phy_pb->rr_graph, + L_num_vpack_nets, L_vpack_net); + + /* Add edges to connected rr_nodes for a wired LUT */ + /* + rec_add_rr_graph_wired_lut_rr_edges(cur_op_pb, cur_phy_pb->rr_graph); + */ + + /* Allocate trace in rr_graph */ + alloc_rr_graph_route_static_structs(cur_phy_pb->rr_graph, nx * ny); /* TODO: nx * ny should be reduced for pb-only routing */ + + alloc_pb_rr_graph_rr_indexed_data(cur_phy_pb->rr_graph); + + /* Fill the net_rr_terminals with + * 1. pin-to-pin mapping in pb_graph_node in cur_op_pb + * 2. rr_graph in the cur_op_pb + */ + alloc_and_load_phy_pb_rr_graph_net_rr_terminals(cur_op_pb, cur_phy_pb->rr_graph); + + add_virtual_sources_to_rr_graph_multi_sources(cur_phy_pb->rr_graph); + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_pb_rr_graph.h b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_pb_rr_graph.h new file mode 100644 index 000000000..461cd08d4 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_pb_rr_graph.h @@ -0,0 +1,42 @@ + + +int rec_count_rr_graph_nodes_for_phy_pb_graph_node(t_pb_graph_node* cur_pb_graph_node); + +void init_one_rr_node_pack_cost_for_phy_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + enum PORTS port_type); + +void init_one_rr_node_for_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + int phy_mode_index, + t_rr_type rr_node_type); + +void connect_one_rr_node_for_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index, + int phy_mode_index, + t_rr_type rr_node_type); + +int rec_init_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* cur_pb_graph_node, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index); + +int rec_connect_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* cur_pb_graph_node, + INOUTP t_rr_graph* local_rr_graph, + int cur_rr_node_index); + +void alloc_and_load_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* top_pb_graph_node, + OUTP t_rr_graph* local_rr_graph); + +void alloc_and_load_phy_pb_rr_graph_nets(INP t_pb* cur_op_pb, + t_rr_graph* local_rr_graph, + int L_num_vpack_nets, t_net* L_vpack_net); + +void load_phy_pb_rr_graph_net_rr_terminals(INP t_pb* cur_op_pb, + t_rr_graph* local_rr_graph); + +void alloc_and_load_rr_graph_for_phy_pb(INP t_pb* cur_op_pb, + INP t_phy_pb* cur_phy_pb, + int L_num_vpack_nets, t_net* L_vpack_net); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c new file mode 100644 index 000000000..e2585a215 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.c @@ -0,0 +1,849 @@ +#include +#include +#include +#include + +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "route_common.h" + +#include "fpga_x2p_types.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_rr_graph_utils.h" +#include "fpga_x2p_pb_rr_graph.h" + +void breadth_first_expand_rr_graph_trace_segment(t_rr_graph* local_rr_graph, + t_trace *start_ptr, + int remaining_connections_to_sink) { + + /* Adds all the rr_nodes in the traceback segment starting at tptr (and * + * continuing to the end of the traceback) to the heap with a cost of zero. * + * This allows expansion to begin from the existing wiring. The * + * remaining_connections_to_sink value is 0 if the route segment ending * + * at this location is the last one to connect to the SINK ending the route * + * segment. This is the usual case. If it is not the last connection this * + * net must make to this SINK, I have a hack to ensure the next connection * + * to this SINK goes through a different IPIN. Without this hack, the * + * router would always put all the connections from this net to this SINK * + * through the same IPIN. With LUTs or cluster-based logic blocks, you * + * should never have a net connecting to two logically-equivalent pins on * + * the same logic block, so the hack will never execute. If your logic * + * block is an and-gate, however, nets might connect to two and-inputs on * + * the same logic block, and since the and-inputs are logically-equivalent, * + * this means two connections to the same SINK. */ + + t_trace *tptr, *next_ptr; + int inode, sink_node, last_ipin_node; + + tptr = start_ptr; + + if (remaining_connections_to_sink == 0) { /* Usual case. */ + while (tptr != NULL) { + add_node_to_rr_graph_heap(local_rr_graph, tptr->index, 0., NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); + tptr = tptr->next; + } + } else { /* This case never executes for most logic blocks. */ + /* Weird case. Lots of hacks. The cleanest way to do this would be to empty * + * the heap, update the congestion due to the partially-completed route, put * + * the whole route so far (excluding IPINs and SINKs) on the heap with cost * + * 0., and expand till you hit the next SINK. That would be slow, so I * + * do some hacks to enable incremental wavefront expansion instead. */ + + if (tptr == NULL) + return; /* No route yet */ + + next_ptr = tptr->next; + last_ipin_node = OPEN; /* Stops compiler from complaining. */ + + /* Can't put last SINK on heap with NO_PREVIOUS, etc, since that won't let * + * us reach it again. Instead, leave the last traceback element (SINK) off * + * the heap. */ + + while (next_ptr != NULL) { + inode = tptr->index; + add_node_to_rr_graph_heap(local_rr_graph, inode, 0., NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); + + if (local_rr_graph->rr_node[inode].type == INTRA_CLUSTER_EDGE) { + if ((local_rr_graph->rr_node[inode].pb_graph_pin != NULL) + && (local_rr_graph->rr_node[inode].pb_graph_pin->num_output_edges == 0)) { + last_ipin_node = inode; + } + } + + tptr = next_ptr; + next_ptr = tptr->next; + } + + /* This will stop the IPIN node used to get to this SINK from being * + * reexpanded for the remainder of this net's routing. This will make us * + * hook up more IPINs to this SINK (which is what we want). If IPIN * + * doglegs are allowed in the graph, we won't be able to use this IPIN to * + * do a dogleg, since it won't be re-expanded. Shouldn't be a big problem. */ + assert(last_ipin_node != OPEN); + local_rr_graph->rr_node_route_inf[last_ipin_node].path_cost = -HUGE_POSITIVE_FLOAT; + + /* Also need to mark the SINK as having high cost, so another connection can * + * be made to it. */ + + sink_node = tptr->index; + local_rr_graph->rr_node_route_inf[sink_node].path_cost = HUGE_POSITIVE_FLOAT; + + /* Finally, I need to remove any pending connections to this SINK via the * + * IPIN I just used (since they would result in congestion). Scan through * + * the heap to do this. */ + + invalidate_rr_graph_heap_entries(local_rr_graph, sink_node, last_ipin_node); + } + + return; +} + +void breadth_first_expand_rr_graph_neighbours(t_rr_graph* local_rr_graph, + int inode, float pcost, + int inet, boolean first_time) { + + /* Puts all the rr_nodes adjacent to inode on the heap. rr_nodes outside * + * the expanded bounding box specified in route_bb are not added to the * + * heap. pcost is the path_cost to get to inode. */ + + int iconn, to_node, num_edges; + float tot_cost; + + num_edges = local_rr_graph->rr_node[inode].num_edges; + for (iconn = 0; iconn < num_edges; iconn++) { + to_node = local_rr_graph->rr_node[inode].edges[iconn]; + /*if (first_time) { */ + tot_cost = pcost + get_rr_graph_rr_cong_cost(local_rr_graph, to_node) + * get_rr_graph_rr_node_pack_intrinsic_cost(local_rr_graph, to_node); + /* + } else { + tot_cost = pcost + get_rr_cong_cost(to_node); + }*/ + add_node_to_rr_graph_heap(local_rr_graph, to_node, tot_cost, inode, iconn, OPEN, OPEN); + } +} + +/* A copy of breath_first_add_source_to_heap_cluster + * I remove all the use of global variables + */ +void breadth_first_add_source_to_rr_graph_heap(t_rr_graph* local_rr_graph, + int src_net_index) { + + /* Adds the SOURCE of this net to the heap. Used to start a net's routing. */ + + int inode; + float cost; + + inode = local_rr_graph->net_rr_terminals[src_net_index][0]; /* SOURCE */ + cost = get_rr_graph_rr_cong_cost(local_rr_graph, inode); + + add_node_to_rr_graph_heap(local_rr_graph, inode, cost, NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); +} + +/* A copy of breath_first_add_source_to_heap_cluster + * I remove all the use of global variables + */ +void breadth_first_add_one_source_to_rr_graph_heap(t_rr_graph* local_rr_graph, + int src_net_index, + int src_idx) { + + /* Adds the SOURCE of this net to the heap. Used to start a net's routing. */ + int inode; + float cost; + + inode = local_rr_graph->net_rr_sources[src_net_index][src_idx]; /* SOURCE */ + cost = get_rr_graph_rr_cong_cost(local_rr_graph, inode); + + add_node_to_rr_graph_heap(local_rr_graph, inode, cost, NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN); + + return; +} + +/* A copy of breath_first_route_net_cluster + * I remove all the use of global variables + */ +boolean breadth_first_route_one_net_pb_rr_graph(t_rr_graph* local_rr_graph, + int inet) { + + /* Uses a maze routing (Dijkstra's) algorithm to route a net. The net * + * begins at the net output, and expands outward until it hits a target * + * pin. The algorithm is then restarted with the entire first wire segment * + * included as part of the source this time. For an n-pin net, the maze * + * router is invoked n-1 times to complete all the connections. Inet is * + * the index of the net to be routed. * + * If this routine finds that a net *cannot* be connected (due to a complete * + * lack of potential paths, rather than congestion), it returns FALSE, as * + * routing is impossible on this architecture. Otherwise it returns TRUE. */ + + int i, inode, prev_node, remaining_connections_to_sink; + float pcost, new_pcost; + struct s_heap *current; + struct s_trace *tptr; + boolean first_time; + + free_rr_graph_traceback(local_rr_graph, inet); + breadth_first_add_source_to_rr_graph_heap(local_rr_graph, inet); + mark_rr_graph_ends(local_rr_graph, inet); + + tptr = NULL; + remaining_connections_to_sink = 0; + + for (i = 1; i < local_rr_graph->net_num_sinks[inet] + 1; i++) { /* Need n-1 wires to connect n pins */ + + /* Do not connect open terminals */ + if (local_rr_graph->net_rr_terminals[inet][i] == OPEN) { + continue; + } + /* Expand and begin routing */ + breadth_first_expand_rr_graph_trace_segment(local_rr_graph, tptr, remaining_connections_to_sink); + current = get_rr_graph_heap_head(local_rr_graph); + + if (current == NULL) { /* Infeasible routing. No possible path for net. */ + reset_rr_graph_path_costs(local_rr_graph); /* Clean up before leaving. */ + return (FALSE); + } + + inode = current->index; + + while (local_rr_graph->rr_node_route_inf[inode].target_flag == 0) { + pcost = local_rr_graph->rr_node_route_inf[inode].path_cost; + new_pcost = current->cost; + if (pcost > new_pcost) { /* New path is lowest cost. */ + local_rr_graph->rr_node_route_inf[inode].path_cost = new_pcost; + prev_node = current->u.prev_node; + local_rr_graph->rr_node_route_inf[inode].prev_node = prev_node; + local_rr_graph->rr_node_route_inf[inode].prev_edge = current->prev_edge; + first_time = FALSE; + + if (pcost > 0.99 * HUGE_POSITIVE_FLOAT) /* First time touched. */{ + add_to_rr_graph_mod_list(local_rr_graph, &local_rr_graph->rr_node_route_inf[inode].path_cost); + first_time = TRUE; + } + + breadth_first_expand_rr_graph_neighbours(local_rr_graph, inode, new_pcost, inet, first_time); + } + + free_rr_graph_heap_data(local_rr_graph, current); + current = get_rr_graph_heap_head(local_rr_graph); + + if (current == NULL) { /* Impossible routing. No path for net. */ + reset_rr_graph_path_costs(local_rr_graph); + return (FALSE); + } + + inode = current->index; + } + + local_rr_graph->rr_node_route_inf[inode].target_flag--; /* Connected to this SINK. */ + remaining_connections_to_sink = local_rr_graph->rr_node_route_inf[inode].target_flag; + tptr = update_rr_graph_traceback(local_rr_graph, current, inet); + free_rr_graph_heap_data(local_rr_graph, current); + } + + empty_rr_graph_heap(local_rr_graph); + reset_rr_graph_path_costs(local_rr_graph); + return (TRUE); +} + +/* Adapt for the multi-source rr_graph routing + */ +boolean breadth_first_route_one_single_source_net_pb_rr_graph(t_rr_graph* local_rr_graph, + int inet, int isrc, + int start_isink, + boolean* net_sink_routed) { + + /* Uses a maze routing (Dijkstra's) algorithm to route a net. The net * + * begins at the net output, and expands outward until it hits a target * + * pin. The algorithm is then restarted with the entire first wire segment * + * included as part of the source this time. For an n-pin net, the maze * + * router is invoked n-1 times to complete all the connections. Inet is * + * the index of the net to be routed. * + * If this routine finds that a net *cannot* be connected (due to a complete * + * lack of potential paths, rather than congestion), it returns FALSE, as * + * routing is impossible on this architecture. Otherwise it returns TRUE. */ + + int isink, inode, jsink, prev_node, remaining_connections_to_sink; + float pcost, new_pcost; + struct s_heap *current; + struct s_trace *tptr; + boolean first_time; + + free_rr_graph_traceback(local_rr_graph, inet); + breadth_first_add_one_source_to_rr_graph_heap(local_rr_graph, inet, isrc); + mark_rr_graph_sinks(local_rr_graph, inet, start_isink, net_sink_routed); + + tptr = NULL; + remaining_connections_to_sink = 0; + +#ifdef VERBOSE + printf("Sink nodes for net=%s to try: ", + local_rr_graph->net[inet]->name); + for (isink = start_isink; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + if (OPEN == local_rr_graph->net_rr_sinks[inet][isink]) { + continue; + } + if (TRUE == net_sink_routed[isink]) { + continue; + } + printf("%d,", + isink); + } + printf("\n"); +#endif + + for (isink = start_isink; isink < local_rr_graph->net_num_sinks[inet]; isink++) { /* Need n-1 wires to connect n pins */ + /* Do not connect open terminals */ + if (OPEN == local_rr_graph->net_rr_sinks[inet][isink]) { + continue; + } + + /* Expand and begin routing */ + breadth_first_expand_rr_graph_trace_segment(local_rr_graph, tptr, remaining_connections_to_sink); + current = get_rr_graph_heap_head(local_rr_graph); + + /* Exit only when this is the last source node + * Infeasible routing. No possible path for net. + */ + if (NULL == current) { +#ifdef VERBOSE + printf("1. Fail Routing: net=%s, sink=%d\n", + local_rr_graph->net[inet]->name, + isink); +#endif + reset_rr_graph_path_costs(local_rr_graph); + return FALSE; + } + + inode = current->index; + + while (local_rr_graph->rr_node_route_inf[inode].target_flag == 0) { + pcost = local_rr_graph->rr_node_route_inf[inode].path_cost; + new_pcost = current->cost; + if (pcost > new_pcost) { /* New path is lowest cost. */ + local_rr_graph->rr_node_route_inf[inode].path_cost = new_pcost; + prev_node = current->u.prev_node; + local_rr_graph->rr_node_route_inf[inode].prev_node = prev_node; + local_rr_graph->rr_node_route_inf[inode].prev_edge = current->prev_edge; + first_time = FALSE; + + if (pcost > 0.99 * HUGE_POSITIVE_FLOAT) /* First time touched. */{ + add_to_rr_graph_mod_list(local_rr_graph, &local_rr_graph->rr_node_route_inf[inode].path_cost); + first_time = TRUE; + } + + breadth_first_expand_rr_graph_neighbours(local_rr_graph, inode, new_pcost, inet, first_time); + + if ( (0 == strcmp("_18363_", local_rr_graph->net[inet]->name)) + && (0 == strcmp("fle", local_rr_graph->rr_node[inode].pb_graph_pin->parent_node->pb_type->name)) + && (0 == strcmp("out", local_rr_graph->rr_node[inode].pb_graph_pin->port->name)) + && (2 == local_rr_graph->rr_node[inode].pb_graph_pin->parent_node->placement_index) + && (1 == local_rr_graph->rr_node[inode].pb_graph_pin->pin_number) ) { + vpr_printf(TIO_MESSAGE_INFO, + "Expanding to node: %s/%s[%d], cost=%.5g\n", + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node), + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + new_pcost); + } + + if ( (0 == strcmp("_18363_", local_rr_graph->net[inet]->name)) + && (0 == strcmp("fle", local_rr_graph->rr_node[inode].pb_graph_pin->parent_node->pb_type->name)) + && (0 == strcmp("out", local_rr_graph->rr_node[inode].pb_graph_pin->port->name)) + && (3 == local_rr_graph->rr_node[inode].pb_graph_pin->parent_node->placement_index) + && (0 == local_rr_graph->rr_node[inode].pb_graph_pin->pin_number) ) { + vpr_printf(TIO_MESSAGE_INFO, + "Expanding to node: %s/%s[%d], cost=%.5g\n", + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node), + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + new_pcost); + } + + if ( (0 == strcmp("_18363_", local_rr_graph->net[inet]->name)) + && (0 == strcmp("fle", local_rr_graph->rr_node[inode].pb_graph_pin->parent_node->pb_type->name)) + && (0 == strcmp("regout", local_rr_graph->rr_node[inode].pb_graph_pin->port->name)) + && (2 == local_rr_graph->rr_node[inode].pb_graph_pin->parent_node->placement_index) + && (0 == local_rr_graph->rr_node[inode].pb_graph_pin->pin_number) ) { + vpr_printf(TIO_MESSAGE_INFO, + "Expanding to node: %s/%s[%d], cost=%.5g\n", + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node), + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + new_pcost); + } + } + + free_rr_graph_heap_data(local_rr_graph, current); + current = get_rr_graph_heap_head(local_rr_graph); + + /* Impossible routing. No path for net. + */ + if (NULL == current) { + break; + } + + inode = current->index; + + + } + + /* Impossible routing, try another iteration */ + if (NULL == current) { +#ifdef VERBOSE + printf("2. Fail Routing: net=%s, sink=%d\n", + local_rr_graph->net[inet]->name, + isink); +#endif + reset_rr_graph_path_costs(local_rr_graph); + continue; + } + + local_rr_graph->rr_node_route_inf[inode].target_flag--; /* Connected to this SINK. */ + remaining_connections_to_sink = local_rr_graph->rr_node_route_inf[inode].target_flag; + tptr = update_rr_graph_traceback(local_rr_graph, current, inet); + free_rr_graph_heap_data(local_rr_graph, current); + + /* Update the flag + * BE CAREFUL: the inode is one of the sink + * it is not always the isink node!!! + * In each iteration, the routing algorithm will route a sink with lowest cost, + * This is out of the order of sinks + */ + for (jsink = start_isink; jsink < local_rr_graph->net_num_sinks[inet]; jsink++) { /* Need n-1 wires to connect n pins */ + if (inode != local_rr_graph->net_rr_sinks[inet][jsink]) { + continue; + } + net_sink_routed[jsink] = TRUE; +#ifdef VERBOSE + printf("Round %d, Success Routing: net=%s, sink=%d, port=%s[%d], pb_type=%s\n", + isink, local_rr_graph->net[inet]->name, + jsink, + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node)); +#endif + break; + } + } + + return TRUE; +} + + +/* Adapt for the multi-source rr_graph routing + */ +boolean breadth_first_route_one_multi_source_net_pb_rr_graph(t_rr_graph* local_rr_graph, + int inet) { + + /* Uses a maze routing (Dijkstra's) algorithm to route a net. The net * + * begins at the net output, and expands outward until it hits a target * + * pin. The algorithm is then restarted with the entire first wire segment * + * included as part of the source this time. For an n-pin net, the maze * + * router is invoked n-1 times to complete all the connections. Inet is * + * the index of the net to be routed. * + * If this routine finds that a net *cannot* be connected (due to a complete * + * lack of potential paths, rather than congestion), it returns FALSE, as * + * routing is impossible on this architecture. Otherwise it returns TRUE. */ + + int isrc, isink, inode, start_isink; + boolean* net_sink_routed = (boolean*) my_malloc(local_rr_graph->net_num_sinks[inet] * sizeof(boolean)); + boolean route_success = FALSE; + + /* Initialize */ + for (isink = 0; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + net_sink_routed[isink] = FALSE; + /* Exception for OPEN nets */ + if (OPEN == local_rr_graph->net_rr_sinks[inet][isink]) { + net_sink_routed[isink] = TRUE; + } + } + + start_isink = 0; + + /* try each sources */ + for (isrc = 0; isrc < local_rr_graph->net_num_sources[inet]; isrc++) { + /* Get the start sink index, + * when a sink is failed in routing, + * we update flags the net_sink_routed + * Next time, we will start from first sink is + */ +#ifdef VERBOSE + printf("\nnum_src=%d, isrc=%d\n", local_rr_graph->net_num_sources[inet], isrc); +#endif + for (isink = 0; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + if (TRUE == net_sink_routed[isink]) { + continue; + } + start_isink = isink; + break; + } + +#ifdef VERBOSE + printf("\nstart_sink=%d\n", start_isink); +#endif + /* Reset the target_flag for sinks to be routed */ + start_isink = 0; + for (isink = start_isink; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + inode = local_rr_graph->net_rr_sinks[inet][isink]; + if (OPEN != inode) { + local_rr_graph->rr_node_route_inf[inode].target_flag = 0; + } + } + breadth_first_route_one_single_source_net_pb_rr_graph(local_rr_graph, inet, isrc, + start_isink, + net_sink_routed); + /* Clean up routing data */ + empty_rr_graph_heap(local_rr_graph); + reset_rr_graph_path_costs(local_rr_graph); + /* See if we can early exit */ + /* Make sure every sink if routed */ + route_success = TRUE; + for (isink = 0; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + if ( (OPEN != local_rr_graph->net_rr_sinks[inet][isink]) + && (FALSE == net_sink_routed[isink])) { + route_success = FALSE; + } + } + if (TRUE == route_success) { + break; + } + } + + /* Provide more information for users when route fails */ + if (FALSE == route_success) { + for (isink = 0; isink < local_rr_graph->net_num_sinks[inet]; isink++) { + if ( (OPEN != local_rr_graph->net_rr_sinks[inet][isink]) + && (FALSE == net_sink_routed[isink])) { + /* Give informatioin about the starting pin */ + vpr_printf(TIO_MESSAGE_ERROR, "Fail Routing:\n"); + + for (isrc = 0; isrc < local_rr_graph->net_num_sources[inet]; isrc++) { + inode = local_rr_graph->net_rr_sources[inet][isrc]; + vpr_printf(TIO_MESSAGE_INFO, + "Starting points %d: net=%s, source_rr_node=%d, port=%s[%d], pb_type=%s\n", + isrc, + local_rr_graph->net[inet]->name, inode, + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node)); + } + /* Give informatioin about the starting pin */ + inode = local_rr_graph->net_rr_sinks[inet][isink]; + vpr_printf(TIO_MESSAGE_INFO, + "Ending points: net=%s, sink=%d, port=%s[%d], pb_type=%s\n", + local_rr_graph->net[inet]->name, + isink, + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node)); + vpr_printf(TIO_MESSAGE_INFO, + "Please double check your XML about if pins in operating modes are correctedly linked to physical mode!\n"); + } + } + } + + /* Free */ + free(net_sink_routed); + + return route_success; +} + + +boolean feasible_routing_rr_graph(t_rr_graph* local_rr_graph, + boolean verbose) { + + /* This routine checks to see if this is a resource-feasible routing. * + * That is, are all rr_node capacity limitations respected? It assumes * + * that the occupancy arrays are up to date when it is called. */ + + int inode, inet; + t_trace* tptr; + int* rr_node_net_checker = (int*) my_calloc (local_rr_graph->num_rr_nodes, sizeof(int)); + int* rr_node_occ_checker = (int*) my_calloc (local_rr_graph->num_rr_nodes, sizeof(int)); + boolean feasible = TRUE; + + /* Initialize the checker */ + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + rr_node_net_checker[inode] = OPEN; + } + + /* Check the trace: + * We may have the same nets sharing the part of the traces + * We will adapt the occupancy of rr_node to avoid errors in feasibility checking + */ + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + tptr = local_rr_graph->trace_head[inet]; + while (tptr != NULL) { + inode = tptr->index; + /* Update the checker for net num */ + if (OPEN == rr_node_net_checker[inode]) { + /* First visit, we assign a value */ + rr_node_net_checker[inode] = inet; + /* Initialize occ */ + rr_node_occ_checker[inode] = 1; + } else if (inet != rr_node_net_checker[inode]) { + /* This means two traces share the same node + * This is not a feasible routing, error out + */ + if (TRUE == verbose) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) Shared Trace Found for rr_node[%d] (pb pin:%s/%s[%d]) between net(%s) and net (%s)!\n", + __FILE__, __LINE__, + inode, + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node), + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + local_rr_graph->net[inet]->name, + local_rr_graph->net[rr_node_net_checker[inode]]->name); + } + /* Increase occ */ + rr_node_occ_checker[inode]++; + } else { + assert (inet == rr_node_net_checker[inode]); + /* Try to increase the capacity of rr_node */ + if (TRUE == verbose) { +#ifdef VERBOSE + vpr_printf(TIO_MESSAGE_INFO, + "(File:%s,[LINE%d]) Detect rr_node[%d] (pb pin:%s/%s[%d]) for shared net(%s)!\n", + __FILE__, __LINE__, + inode, + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node), + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + local_rr_graph->net[inet]->name); +#endif + } + } + tptr = tptr->next; + } + } + + /* Update occ of rr_graph */ + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + local_rr_graph->rr_node[inode].occ = rr_node_occ_checker[inode]; + } + /* Free */ + free(rr_node_occ_checker); + free(rr_node_net_checker); + + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + if (local_rr_graph->rr_node[inode].occ > local_rr_graph->rr_node[inode].capacity) { + if (TRUE == verbose) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) rr_node[%d] (pin:%s/%s[%d]) occupancy(%d) exceeds its capacity(%d)!\n", + __FILE__, __LINE__, + inode, + get_pb_graph_full_name_in_hierarchy(local_rr_graph->rr_node[inode].pb_graph_pin->parent_node), + local_rr_graph->rr_node[inode].pb_graph_pin->port->name, + local_rr_graph->rr_node[inode].pb_graph_pin->pin_number, + local_rr_graph->rr_node[inode].occ, + local_rr_graph->rr_node[inode].capacity); + } + feasible = FALSE; + } + } + + return feasible; +} + +void pathfinder_update_rr_graph_one_cost(t_rr_graph* local_rr_graph, + t_trace *route_segment_start, + int add_or_sub, float pres_fac) { + + /* This routine updates the occupancy and pres_cost of the rr_nodes that are * + * affected by the portion of the routing of one net that starts at * + * route_segment_start. If route_segment_start is trace_head[inet], the * + * cost of all the nodes in the routing of net inet are updated. If * + * add_or_sub is -1 the net (or net portion) is ripped up, if it is 1 the * + * net is added to the routing. The size of pres_fac determines how severly * + * oversubscribed rr_nodes are penalized. */ + + struct s_trace *tptr; + int inode, occ, capacity; + + tptr = route_segment_start; + if (tptr == NULL) /* No routing yet. */ + return; + + for (;;) { + inode = tptr->index; + + occ = local_rr_graph->rr_node[inode].occ + add_or_sub; + capacity = local_rr_graph->rr_node[inode].capacity; + + local_rr_graph->rr_node[inode].occ = occ; + + /* pres_cost is Pn in the Pathfinder paper. I set my pres_cost according to * + * the overuse that would result from having ONE MORE net use this routing * + * node. */ + + if (occ < capacity) { + local_rr_graph->rr_node_route_inf[inode].pres_cost = 1.; + } else { + local_rr_graph->rr_node_route_inf[inode].pres_cost = 1. + (occ + 1 - capacity) * pres_fac; + } + + if (local_rr_graph->rr_node[inode].type == SINK) { + tptr = tptr->next; /* Skip next segment. */ + if (tptr == NULL) + break; + } + + tptr = tptr->next; + + } /* End while loop -- did an entire traceback. */ + + return; +} + +void pathfinder_update_rr_graph_cost(t_rr_graph* local_rr_graph, + float pres_fac, float acc_fac) { + + /* This routine recomputes the pres_cost and acc_cost of each routing * + * resource for the pathfinder algorithm after all nets have been routed. * + * It updates the accumulated cost to by adding in the number of extra * + * signals sharing a resource right now (i.e. after each complete iteration) * + * times acc_fac. It also updates pres_cost, since pres_fac may have * + * changed. THIS ROUTINE ASSUMES THE OCCUPANCY VALUES IN RR_NODE ARE UP TO * + * DATE. */ + + int inode, occ, capacity; + + for (inode = 0; inode < local_rr_graph->num_rr_nodes; inode++) { + occ = local_rr_graph->rr_node[inode].occ; + capacity = local_rr_graph->rr_node[inode].capacity; + + if (occ > capacity) { + local_rr_graph->rr_node_route_inf[inode].acc_cost += (occ - capacity) * acc_fac; + local_rr_graph->rr_node_route_inf[inode].pres_cost = 1. + (occ + 1 - capacity) * pres_fac; + } else if (occ == capacity) { + /* If occ == capacity, we don't need to increase acc_cost, but a change * + * in pres_fac could have made it necessary to recompute the cost anyway. */ + local_rr_graph->rr_node_route_inf[inode].pres_cost = 1. + pres_fac; + } + } + + return; +} + + +/** + * A Copy of try_breadth_first_route_cluster + * I remove all the use of global variables + * internal_nets: index of nets to route [0..num_internal_nets - 1] + */ +boolean try_breadth_first_route_pb_rr_graph(t_rr_graph* local_rr_graph) { + + /* Iterated maze router ala Pathfinder Negotiated Congestion algorithm, * + * (FPGA 95 p. 111). Returns TRUE if it can route this FPGA, FALSE if * + * it can't. */ + + /* For different modes, when a mode is turned on, I set the max occupancy of all rr_nodes in the mode to 1 and all others to 0 */ + /* TODO: There is a bug for route-throughs where edges in route-throughs do not get turned off because the rr_edge is in a particular mode but the two rr_nodes are outside */ + + boolean success, is_routable; + int itry, inet, net_index; + struct s_router_opts router_opts; + float pres_fac; + + /* Xifan TANG: Count runtime for routing in packing stage */ + clock_t begin, end; + + begin = clock(); + + /* Usually the first iteration uses a very small (or 0) pres_fac to find * + * the shortest path and get a congestion map. For fast compiles, I set * + * pres_fac high even for the first iteration. */ + + /* sets up a fast breadth-first router */ + router_opts.first_iter_pres_fac = 10; + router_opts.max_router_iterations = 20; + router_opts.initial_pres_fac = 10; + router_opts.pres_fac_mult = 2; + router_opts.acc_fac = 1; + + /* Default breath-first router opts */ + /* + router_opts.first_iter_pres_fac = 0; + router_opts.max_router_iterations = 50; + router_opts.initial_pres_fac = 0.5; + router_opts.pres_fac_mult = 1.3; + router_opts.acc_fac = 0.2; + */ + + reset_rr_graph_rr_node_route_structs(local_rr_graph); /* Clear all prior rr_graph history */ + + pres_fac = router_opts.first_iter_pres_fac; + + for (itry = 1; itry <= router_opts.max_router_iterations; itry++) { + for (inet = 0; inet < local_rr_graph->num_nets; inet++) { + net_index = inet; + + pathfinder_update_rr_graph_one_cost(local_rr_graph, local_rr_graph->trace_head[net_index], -1, pres_fac); + + /* + is_routable = breadth_first_route_one_net_pb_rr_graph(local_rr_graph, net_index); + */ + is_routable = breadth_first_route_one_multi_source_net_pb_rr_graph(local_rr_graph, net_index); + + /* Impossible to route? (disconnected rr_graph) */ + + if (!is_routable) { + /* TODO: Inelegant, can be more intelligent */ + vpr_printf(TIO_MESSAGE_INFO, "Failed routing net %s\n", local_rr_graph->net[net_index]->name); + vpr_printf(TIO_MESSAGE_INFO, "Routing failed. Disconnected rr_graph.\n"); + return FALSE; + } else { + /* + vpr_printf(TIO_MESSAGE_INFO, "Succeed routing net %s\n", local_rr_graph->net[net_index]->name); + */ + } + + pathfinder_update_rr_graph_one_cost(local_rr_graph, local_rr_graph->trace_head[net_index], 1, pres_fac); + + } + + success = feasible_routing_rr_graph(local_rr_graph, FALSE); + if (success) { + /* End of packing routing */ + end = clock(); + /* accumulate the runtime for pack routing */ +#ifdef CLOCKS_PER_SEC + pack_route_time += (float)(end - begin)/ CLOCKS_PER_SEC; +#else + pack_route_time += (float)(end - begin)/ CLK_PER_SEC; +#endif + /* vpr_printf(TIO_MESSAGE_INFO, "Updated: Packing routing took %g seconds\n", pack_route_time); */ + return (TRUE); + } + + if (itry == 1) { + pres_fac = router_opts.initial_pres_fac; + } else { + pres_fac *= router_opts.pres_fac_mult; + } + + pres_fac = std::min(pres_fac, static_cast(HUGE_POSITIVE_FLOAT / 1e5)); + + pathfinder_update_rr_graph_cost(local_rr_graph, pres_fac, router_opts.acc_fac); + } + /* End of packing routing */ + end = clock(); + /* accumulate the runtime for pack routing */ +#ifdef CLOCKS_PER_SEC + pack_route_time += (float)(end - begin)/ CLOCKS_PER_SEC; +#else + pack_route_time += (float)(end - begin)/ CLK_PER_SEC; +#endif + vpr_printf(TIO_MESSAGE_INFO, "Packing/Routing Physical Progammable Blocks took %g seconds\n", pack_route_time); + + /* Give error message when routing is failed */ + feasible_routing_rr_graph(local_rr_graph, TRUE); + + return (FALSE); +} + + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.h b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.h new file mode 100644 index 000000000..7bb856dca --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/router/fpga_x2p_router.h @@ -0,0 +1,28 @@ + +void breadth_first_expand_rr_graph_trace_segment(t_rr_graph* local_rr_graph, + t_trace *start_ptr, + int remaining_connections_to_sink); + +void breadth_first_expand_rr_graph_neighbours(t_rr_graph* local_rr_graph, + int inode, float pcost, + int inet, boolean first_time); + +boolean breadth_first_route_one_net_rr_graph_cluster(t_rr_graph* local_rr_graph, + int inet); + +boolean feasible_routing_rr_graph(t_rr_graph* local_rr_graph); + +void pathfinder_update_rr_graph_one_cost(t_rr_graph* local_rr_graph, + t_trace *route_segment_start, + int add_or_sub, float pres_fac); + +void pathfinder_update_rr_graph_cost(t_rr_graph* local_rr_graph, + float pres_fac, float acc_fac); + +void breadth_first_add_source_to_rr_graph_heap(t_rr_graph* local_rr_graph, + int src_net_index); + +boolean breadth_first_route_one_net_pb_rr_graph(t_rr_graph* local_rr_graph, + int inet); + +boolean try_breadth_first_route_pb_rr_graph(t_rr_graph* local_rr_graph); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.c new file mode 100644 index 000000000..58504c49d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.c @@ -0,0 +1,21 @@ + +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "shell_types.h" + +void shell_execute_exit(t_shell_env* env, t_opt_info* opts) { + + char* vpr_shell_name = "VPR7-OpenFPGA"; + + vpr_printf(TIO_MESSAGE_INFO, + "Thank you for using %s!\n", + vpr_shell_name); + exit(1); +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.h new file mode 100644 index 000000000..5dc006d15 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_exit.h @@ -0,0 +1,8 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info exit_opts[] = { + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +void shell_execute_exit(t_shell_env* env, t_opt_info* opts); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.c new file mode 100644 index 000000000..db84a9655 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.c @@ -0,0 +1,47 @@ + +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "linkedlist.h" +#include "fpga_x2p_utils.h" +#include "fpga_bitstream.h" + +boolean shell_setup_fpga_bitstream(t_shell_env* env, t_opt_info* opts) { + /* Setup the PowerOpts */ + env->vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.bitstream_output_file = get_opt_val(opts, "output_file"); + + if (NULL == env->arch.spice) { + vpr_printf(TIO_MESSAGE_ERROR, + "FPGA X2P Information has not been initialized in architecture!\nPlease redo read_arch by enabling read_xml_fpga_x2p option!\n"); + return FALSE; + } + + return TRUE; +} + +void shell_execute_fpga_bitstream(t_shell_env* env, t_opt_info* opts) { + t_sram_orgz_info* sram_bitstream_orgz_info = NULL; + + if (FALSE == shell_setup_fpga_bitstream(env, opts)) { + return; + } + + vpr_fpga_bitstream_generator(env->vpr_setup, env->arch, + env->vpr_setup.FileNameOpts.CircuitName, + &sram_bitstream_orgz_info); + + free_sram_orgz_info(sram_bitstream_orgz_info, + sram_bitstream_orgz_info->type); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.h new file mode 100644 index 000000000..e69e59d67 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_bitstream.h @@ -0,0 +1,10 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info fpga_bitstream_opts[] = { + {"output_file", "--output_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the output file containing bitstream"}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_fpga_bitstream(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.c new file mode 100644 index 000000000..5a41f0593 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.c @@ -0,0 +1,79 @@ +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "spice_api.h" + +boolean shell_setup_fpga_spice(t_shell_env* env, t_opt_info* opts) { + /* Setup the PowerOpts */ + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_dir = get_opt_val(opts, "output_dir"); + + /* TODO: this could be more flexible*/ + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.include_dir = "include/"; + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.subckt_dir = "subckt/"; + + + if (NULL == env->arch.spice) { + vpr_printf(TIO_MESSAGE_ERROR, + "FPGA X2P Information has not been initialized in architecture!\nPlease redo read_arch by enabling read_xml_fpga_x2p option!\n"); + return FALSE; + } + + /* Configure FPGA X2P options*/ + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_testbench_load_extraction = is_opt_set(opts, "testbench_load_extraction", TRUE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation = is_opt_set(opts, "parasitic_net_estimation", TRUE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only = is_opt_set(opts, "leakage_only", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_top_testbench = is_opt_set(opts, "print_top_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_pb_mux_testbench = is_opt_set(opts, "print_pb_mux_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_mux_testbench = is_opt_set(opts, "print_cb_mux_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_mux_testbench = is_opt_set(opts, "print_sb_mux_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_testbench = is_opt_set(opts, "print_cb_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_testbench = is_opt_set(opts, "print_sb_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_lut_testbench = is_opt_set(opts, "print_lut_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_hardlogic_testbench = is_opt_set(opts, "print_hardlogic_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_io_testbench = is_opt_set(opts, "print_io_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_grid_testbench = is_opt_set(opts, "print_grid_testbench", FALSE); + + /* Set default options */ + if ((TRUE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_top_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_grid_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_pb_mux_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_mux_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_mux_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_lut_testbench) + &&(FALSE == env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_hardlogic_testbench)) { + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_pb_mux_testbench = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_mux_testbench = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_mux_testbench = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_lut_testbench = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_hardlogic_testbench = TRUE; + } + + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_sim_multi_thread_num = get_opt_int_val(opts, "sim_multi_thread_num", 8); + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.simulator_path = get_opt_val(opts, "simulator_path"); + + return TRUE; +} + +void shell_execute_fpga_spice(t_shell_env* env, t_opt_info* opts) { + if (FALSE == shell_setup_fpga_spice(env, opts)) { + return; + } + + vpr_fpga_spice(env->vpr_setup, env->arch, + env->vpr_setup.FileNameOpts.CircuitName); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.h new file mode 100644 index 000000000..648afb22e --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_spice.h @@ -0,0 +1,25 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info fpga_spice_opts[] = { + {"output_dir", "--output_dir", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the directory path of outputted SPICE netlists"}, + {"testbench_load_extraction", "-tle,--testbench_load_extraction", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable the load extraction when building SPICE testbenches"}, + {"parasitic_net_estimation", "-pne,--parasitic_net_estimation", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable the parasitic net estimation when building SPICE testbenches"}, + {"leakage_only", "--leakage_only", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Only measure leakage power when building SPICE testbenches"}, + {"print_top_testbench", "--print_top_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output top-level testbench for full FPGA fabrics"}, + {"print_pb_mux_testbench", "--print_pb_mux_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output multiplexer testbenches for Configurable Logic Blocks"}, + {"print_cb_mux_testbench", "--print_cb_mux_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output multiplexer testbenches for Connection Blocks"}, + {"print_sb_mux_testbench", "--print_sb_mux_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output multiplexer testbenches for Switch Blocks"}, + {"print_cb_testbench", "--print_cb_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output testbenches for Connection Blocks"}, + {"print_sb_testbench", "--print_sb_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output testbenches for Switch Blocks"}, + {"print_lut_testbench", "--print_lut_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output testbenches for Look-Up Tables"}, + {"print_hardlogic_testbench", "--print_hardlogic_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output testbenches for Hard Logics"}, + {"print_io_testbench", "--print_io_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output testbenches for IO pads"}, + {"print_grid_testbench", "--print_grid_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output testbenches for CLBs and Heterogeneous Blocks"}, + {"sim_multi_thread_num", "--sim_multi_thread_num", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, "Specify the number of threads used by simulator"}, + {"simulator_path", "--simulator_path", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the simulator path"}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_fpga_spice(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.c new file mode 100644 index 000000000..f030867b4 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.c @@ -0,0 +1,58 @@ + +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "linkedlist.h" +#include "fpga_x2p_utils.h" +#include "verilog_api.h" + +boolean shell_setup_fpga_verilog(t_shell_env* env, t_opt_info* opts) { + /* Setup the PowerOpts */ + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog = TRUE; + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.syn_verilog_dump_dir = get_opt_val(opts, "output_dir"); + + if (NULL == env->arch.spice) { + vpr_printf(TIO_MESSAGE_ERROR, + "FPGA X2P Information has not been initialized in architecture!\nPlease redo read_arch by enabling read_xml_fpga_x2p option!\n"); + return FALSE; + } + + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_testbench = is_opt_set(opts, "print_top_testbench", TRUE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_autocheck_top_testbench = is_opt_set(opts, "print_autocheck_top_testbench", TRUE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.reference_verilog_benchmark_file = get_opt_val(opts, "reference_verilog_benchmark_file"); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_input_blif_testbench = is_opt_set(opts, "print_input_blif_testbench", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_formal_verification_top_netlist = is_opt_set(opts, "print_formal_verification_top_netlist", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.include_timing = is_opt_set(opts, "include_timing", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.include_signal_init = is_opt_set(opts, "include_signal_init", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.include_icarus_simulator = is_opt_set(opts, "include_icarus_simulator", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_modelsim_autodeck = is_opt_set(opts, "print_modelsim_autodeck", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.modelsim_ini_path = get_opt_val(opts, "modelsim_ini_path"); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_user_defined_template = is_opt_set(opts, "print_user_defined_template", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_report_timing_tcl = is_opt_set(opts, "print_report_timing_tcl", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.report_timing_path = get_opt_val(opts, "report_timing_dir_path"); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_sdc_pnr = is_opt_set(opts, "print_sdc_pnr", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_sdc_analysis = is_opt_set(opts, "print_sdc_analysis", FALSE); + + return TRUE; +} + +void shell_execute_fpga_verilog(t_shell_env* env, t_opt_info* opts) { + + if (FALSE == shell_setup_fpga_verilog(env, opts)) { + return; + } + + vpr_fpga_verilog(env->vpr_setup, env->arch, + env->vpr_setup.FileNameOpts.CircuitName); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.h new file mode 100644 index 000000000..1fe5bebe6 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_verilog.h @@ -0,0 +1,25 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info fpga_verilog_opts[] = { + {"output_dir", "--output_dir", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the output directory containing Verilog netlists"}, + {"print_top_testbench", "--print_top_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the top-level testbench for full FPGA fabric"}, + {"print_autocheck_top_testbench", "--print_autodeck_top_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the top-level testbench for full FPGA fabric with autocheck features"}, + {"reference_verilog_benchmark_file", "--reference_verilog_benchmark_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the reference Verilog benchmark file used by the autocheck top-level testbench"}, + {"print_input_blif_testbench", "--print_input_blif_testbench", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the testbench for the input blif benchmark"}, + {"print_formal_verification_top_netlist", "--print_formal_verification_top_netlist", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the top-level Verilog netlist for full FPGA fabric adapted to formal verification"}, + {"include_timing", "--include_timing", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Include timing annotation in the outputted Verilog netlists"}, + {"include_signal_init", "--include_signal_init", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Include signal initialization in the outputted Verilog netlists"}, + {"print_modelsim_autodeck", "--print_modelsim_autodeck", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Output the script to launch Modelsim simulation for the autocheck testbench"}, + {"modelsim_ini_path", "--modelsim_ini_path", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the path of modelsim.ini file"}, + {"print_user_defined_template", "--print_user_defined_template", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the Verilog template for user-defined modules"}, + {"print_report_timing_tcl", "--print_report_timing_tcl", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the TCL script in report timing purpose"}, + {"report_timing_dir_path", "--report_timing_dir_path", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the directory path of report timing results"}, + {"print_sdc_pnr", "--print_sdc_pnr", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the SDC file in P&R purpose"}, + {"print_sdc_analysis", "--print_sdc_analysis", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable output the SDC file in Timing/Power analysis purpose"}, + {"include_icarus_simulator", "--include_icarus_simulator", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable Verilog preprocessing flags and features for Icarus simulator"}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_fpga_verilog(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.c new file mode 100644 index 000000000..fd55acb66 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.c @@ -0,0 +1,46 @@ +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "vpr_api.h" +#include "fpga_x2p_setup.h" + +boolean shell_setup_fpga_x2p_setup(t_shell_env* env, t_opt_info* opts) { + /* Setup the PowerOpts */ + env->vpr_setup.FPGA_SPICE_Opts.do_fpga_spice = TRUE; + + if (NULL == env->arch.spice) { + vpr_printf(TIO_MESSAGE_ERROR, + "FPGA X2P Information has not been initialized in architecture!\nPlease redo read_arch by enabling read_xml_fpga_x2p option!\n"); + return FALSE; + } + + /* Configure FPGA X2P options*/ + env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation = is_opt_set(opts, "parasitic_net_estimation", TRUE); + env->vpr_setup.FPGA_SPICE_Opts.read_act_file = env->vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_parasitic_net_estimation; + + + env->vpr_setup.FPGA_SPICE_Opts.rename_illegal_port = is_opt_set(opts, "rename_illegal_port", FALSE); + env->vpr_setup.FPGA_SPICE_Opts.signal_density_weight = get_opt_float_val(opts, "signal_density_weight", 1.); + env->vpr_setup.FPGA_SPICE_Opts.sim_window_size = get_opt_float_val(opts, "sim_window_size", 0.5); + + return TRUE; +} + +void shell_execute_fpga_x2p_setup(t_shell_env* env, t_opt_info* opts) { + if (FALSE == shell_setup_fpga_x2p_setup(env, opts)) { + return; + } + + fpga_x2p_setup(env->vpr_setup, &(env->arch)); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.h new file mode 100644 index 000000000..3d967900d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_fpga_x2p_setup.h @@ -0,0 +1,14 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info fpga_x2p_setup_opts[] = { + {"activity_file", "-a,--activity_file,",0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the activity file"}, + {"parasitic_net_estimation", "-pne,--parasitic_net_estimation", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Enable the parasitic net estimation when building SPICE testbenches"}, + {"rename_illegal_port", "-rip,--rename_illegal_port", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Rename illegal ports that violates Verilog syntax"}, + {"signal_density_weight", "-sdw,--signal_density_weight", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, "Specify the signal density weight when doing the average number"}, + {"sim_window_size", "-sws,--sim_window_size", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, "Specify the size of window when doing simulation"}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_fpga_x2p_setup(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.c new file mode 100644 index 000000000..0ff1f93bd --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.c @@ -0,0 +1,19 @@ + +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "shell_types.h" +#include "shell_utils.h" + +void shell_execute_help(t_shell_env* env, t_opt_info* opts) { + + shell_print_usage(env); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.h new file mode 100644 index 000000000..d5f15f879 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_help.h @@ -0,0 +1,8 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info help_opts[] = { + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + + +void shell_execute_help(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.c new file mode 100644 index 000000000..97466656e --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + + +#include "vpr_types.h" +#include "vpr_utils.h" +#include "globals.h" +#include "pack.h" +#include "vpr_api.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +void shell_execute_vpr_pack(t_shell_env* env, + t_opt_info* opts) { + char* temp = NULL; + + + vpr_printf(TIO_MESSAGE_INFO, + "Setup vpr_packer...\n"); + /* Packer File Names */ + /* Post packing netlist */ + temp = get_opt_val(opts, "net_file"); + if (NULL != temp) { + env->vpr_setup.FileNameOpts.NetFile = temp; + } + + /* SDC constraints */ + temp = get_opt_val(opts, "sdc_file"); + if (NULL != temp) { + env->vpr_setup.Timing.SDCFile = temp; + } + + /* Packer Options */ + if (env->arch.clb_grid.IsAuto) { + env->vpr_setup.PackerOpts.aspect = env->arch.clb_grid.Aspect; + } else { + env->vpr_setup.PackerOpts.aspect = (float) env->arch.clb_grid.H / (float) env->arch.clb_grid.W; + } + env->vpr_setup.PackerOpts.output_file = my_strdup(env->vpr_setup.FileNameOpts.NetFile); + + env->vpr_setup.PackerOpts.blif_file_name = my_strdup(env->vpr_setup.FileNameOpts.BlifFile); + + /* Call this program, it means that we need to do packing */ + env->vpr_setup.PackerOpts.doPacking = TRUE; + + env->vpr_setup.PackerOpts.global_clocks = is_opt_set(opts, "global_clocks", TRUE); + + env->vpr_setup.PackerOpts.hill_climbing_flag = is_opt_set(opts, "hill_climbing", FALSE); + + env->vpr_setup.PackerOpts.sweep_hanging_nets_and_inputs = is_opt_set(opts, "sweep_hanging_nets_and_inputs", TRUE); + + env->vpr_setup.PackerOpts.skip_clustering = is_opt_set(opts, "skip_clustering", FALSE); + + env->vpr_setup.PackerOpts.allow_unrelated_clustering = is_opt_set(opts, "allow_unrelated_clustering", TRUE); + + env->vpr_setup.PackerOpts.allow_early_exit = is_opt_set(opts, "allow_early_exit", FALSE); + + env->vpr_setup.PackerOpts.connection_driven = is_opt_set(opts, "connection_driven", TRUE); + + env->vpr_setup.PackerOpts.timing_driven = is_opt_set(opts, "timing_driven", TRUE); + + env->vpr_setup.PackerOpts.cluster_seed_type = ( + env->vpr_setup.PackerOpts.timing_driven ? VPACK_TIMING : VPACK_MAX_INPUTS); /* DEFAULT */ + /* Get the value if we have any */ + temp = get_opt_val(opts, "cluster_seed_type"); + if (NULL != temp) { + if (0 == strcmp(temp, "timing")) { + env->vpr_setup.PackerOpts.cluster_seed_type = VPACK_TIMING; + } else if (0 == strcmp(temp, "max_inputs")) { + env->vpr_setup.PackerOpts.cluster_seed_type = VPACK_MAX_INPUTS; + } + } + /* Free */ + my_free(temp); + + env->vpr_setup.PackerOpts.alpha = get_opt_float_val(opts, "alpha", 0.75); /* DEFAULT */ + + env->vpr_setup.PackerOpts.beta = get_opt_float_val(opts, "beta", 0.9); /* DEFAULT */ + + + /* never recomputer timing */ + env->vpr_setup.PackerOpts.recompute_timing_after = get_opt_int_val(opts, "recompute_timing_after", MAX_SHORT); /* DEFAULT */ + + vpr_printf(TIO_MESSAGE_INFO, + "Launch pack_algorithm...\n"); + + env->vpr_setup.PackerOpts.block_delay = get_opt_int_val(opts, "block_delay", 0) ; /* DEFAULT */ + + + env->vpr_setup.PackerOpts.intra_cluster_net_delay = get_opt_float_val(opts, "intra_cluster_net_delay", 0.); /* DEFAULT */ + + env->vpr_setup.PackerOpts.inter_cluster_net_delay = get_opt_float_val(opts, "inter_cluster_net_delay", 1.0); /* DEFAULT */ + + + + env->vpr_setup.PackerOpts.auto_compute_inter_cluster_net_delay = is_opt_set(opts, "auto_compute_inter_cluster_net_delay", TRUE); + + + env->vpr_setup.PackerOpts.packer_algorithm = PACK_GREEDY; /* DEFAULT */ + /* Get the value if we have any */ + temp = get_opt_val(opts, "algorithm"); + if (NULL != temp) { + if (0 == strcmp(temp, "greedy")) { + env->vpr_setup.PackerOpts.packer_algorithm = PACK_GREEDY; + } else if (0 == strcmp(temp, "brute_force")) { + env->vpr_setup.PackerOpts.packer_algorithm = PACK_BRUTE_FORCE; + } + } + /* Free */ + my_free(temp); + + /* Xifan TANG: PACK_CLB_PIN_REMAP */ + env->vpr_setup.PackerOpts.pack_clb_pin_remap = is_opt_set(opts, "clb_pin_remap", FALSE); /* DEFAULT */ + + /* TODO: check if we have done read_blif and read_arch !!! */ + + /* Run VPR packer */ + + vpr_printf(TIO_MESSAGE_INFO, + "Launch vpr_packer...\n"); + vpr_pack(env->vpr_setup, env->arch); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.h new file mode 100644 index 000000000..b08fcee8b --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_pack.h @@ -0,0 +1,32 @@ +/* Command-line options for Packer */ +t_opt_info vpr_pack_opts[] = { + /* Packer Options should be listed here */ + /* Packer File Options */ + {"sdc_file", "--sdc_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "File name of SDC constraints"}, + {"net_file", "--net_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "File name of post-packing netlist"}, + /* Packer Options */ + {"global_clocks", "--global_clocks", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"hill_climb", "--hill_climb", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"sweep_hanging_nets_and_inputs", "-s,--sweep", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"timing_driven", "--timing_driven", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"cluster_seed_type", "--seed_type", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"alpha", "--alpha", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"beta", "--beta", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"recompute_timing_after", "--recompute_timing_after", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"block_delay", "--block_delay", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"intra_cluster_net_delay", "--intra_cluster_net_delay", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"inter_cluster_net_delay", "--inter_cluster_net_delay", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"auto_compute_inter_cluster_net_delay", "--auto_compute_inter_cluster_net_delay", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"skip_clustering", "--skip_clustering", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"allow_unrelated_clustering", "--allow_unrelated_clustering", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"allow_early_exit", "--allow_early_exit", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"connection_driven", "--connnection_driven", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"aspect", "--aspect", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"algorithm", "--algorithm", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_vpr_pack(t_shell_env* env, + t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.c new file mode 100644 index 000000000..1639dc785 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.c @@ -0,0 +1,329 @@ +#include +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "vpr_api.h" + +void shell_init_vpr_placer(t_shell_env* env, t_opt_info* opts) { + char* temp = NULL; + + /* Placer File names */ + /* Post packing netlist */ + temp = get_opt_val(opts, "net_file"); + if (NULL != temp) { + env->vpr_setup.FileNameOpts.NetFile = temp; + } + + /* Post placement netlist */ + temp = get_opt_val(opts, "place_file"); + if (NULL != temp) { + env->vpr_setup.FileNameOpts.PlaceFile = temp; + } + + /* Placer Options */ + env->vpr_setup.TimingEnabled = is_opt_set(opts, "timing_driven", TRUE); /* DEFAULT */ + + /* Set seed for pseudo-random placement, default seed to 1 */ + env->vpr_setup.PlacerOpts.seed = get_opt_int_val(opts, "seed", 1); /* DEFAULT */ + my_srandom(env->vpr_setup.PlacerOpts.seed); + + env->vpr_setup.PlacerOpts.block_dist = get_opt_int_val(opts, "block_dist", 1); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.inner_loop_recompute_divider = get_opt_int_val(opts, "inner_loop_recompute_divider", 0); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.place_cost_exp = get_opt_float_val(opts, "place_cost_exp", 1.); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.td_place_exp_first = get_opt_float_val(opts, "place_exp_first", 1.); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.td_place_exp_last = get_opt_float_val(opts, "td_place_exp_last", 8.); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.place_algorithm = BOUNDING_BOX_PLACE; /* DEFAULT */ + if (TRUE == env->vpr_setup.TimingEnabled) { /* DEFAULT */ + env->vpr_setup.PlacerOpts.place_algorithm = PATH_TIMING_DRIVEN_PLACE; /* DEFAULT */ + } + temp = get_opt_val(opts, "placer_algorithm"); + if (NULL != temp) { + if (0 == strcmp(temp, "bounding_box")) { + env->vpr_setup.PlacerOpts.place_algorithm = BOUNDING_BOX_PLACE; + } else if (0 == strcmp(temp, "net_timing_driven")) { + env->vpr_setup.PlacerOpts.place_algorithm = NET_TIMING_DRIVEN_PLACE; + } else if (0 == strcmp(temp, "path_timing_driven")) { + env->vpr_setup.PlacerOpts.place_algorithm = PATH_TIMING_DRIVEN_PLACE;; + } + } + /* Free */ + my_free(temp); + + env->vpr_setup.PlacerOpts.pad_loc_file = get_opt_val(opts, "pad_loc_file"); + + env->vpr_setup.PlacerOpts.pad_loc_type = FREE; /* DEFAULT */ + temp = get_opt_val(opts, "pad_loc_type"); + if (NULL != temp) { + if (0 == strcmp(temp, "free")) { + env->vpr_setup.PlacerOpts.pad_loc_type = FREE; + } else if (0 == strcmp(temp, "user")) { + env->vpr_setup.PlacerOpts.pad_loc_type = USER; + } else if (0 == strcmp(temp, "random")) { + env->vpr_setup.PlacerOpts.pad_loc_type = RANDOM; + } + } + /* Free */ + my_free(temp); + + /* Check */ + if ( (USER == env->vpr_setup.PlacerOpts.pad_loc_type) + && (NULL == env->vpr_setup.PlacerOpts.pad_loc_file)) { + vpr_printf(TIO_MESSAGE_ERROR, + "VPR placer is configured to user-defined pad location while the location file is missing!\n"); + return; + } + + env->vpr_setup.PlacerOpts.place_chan_width = get_opt_int_val(opts, "place_chan_width", 100); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.recompute_crit_iter = get_opt_int_val(opts, "place_chan_width", 1); /* DEFAULT */ + + env->vpr_setup.PlacerOpts.timing_tradeoff = get_opt_float_val(opts, "timing_tradeoff", 0.5); /* DEFAULT */ + + /* Xifan TANG : PLACE_CLB_PIN_REMAP */ + env->vpr_setup.PlacerOpts.place_clb_pin_remap = is_opt_set(opts, "place_clb_pin_remap", FALSE); /* DEFAULT */ + /* END */ + + /* Depends on env->vpr_setup.PlacerOpts.place_algorithm */ + env->vpr_setup.PlacerOpts.enable_timing_computations = FALSE; /* DEFAULT */ + if ((env->vpr_setup.PlacerOpts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) + || (env->vpr_setup.PlacerOpts.place_algorithm == NET_TIMING_DRIVEN_PLACE)) { + env->vpr_setup.PlacerOpts.enable_timing_computations = TRUE; /* DEFAULT */ + } + + /* Annealing options */ + env->vpr_setup.AnnealSched.alpha_t = get_opt_float_val(opts, "alpha_t", 0.8); /* DEFAULT */ + if (env->vpr_setup.AnnealSched.alpha_t >= 1. || env->vpr_setup.AnnealSched.alpha_t <= 0.) { + vpr_printf(TIO_MESSAGE_ERROR, + "alpha_t(%.2g) must be between 0 and 1 exclusive.\n", + env->vpr_setup.AnnealSched.alpha_t); + return; + } + + env->vpr_setup.AnnealSched.exit_t = get_opt_float_val(opts, "exit_t", 0.01); /* DEFAULT */ + if (env->vpr_setup.AnnealSched.exit_t <= 0.) { + vpr_printf(TIO_MESSAGE_ERROR, "exit_t must be greater than 0.\n"); + return; + } + + env->vpr_setup.AnnealSched.init_t = get_opt_float_val(opts, "init_t", 100.0); /* DEFAULT */ + if (env->vpr_setup.AnnealSched.init_t <= 0.) { + vpr_printf(TIO_MESSAGE_ERROR, "init_t must be greater than 0.\n"); + return; + } + if (env->vpr_setup.AnnealSched.init_t < env->vpr_setup.AnnealSched.exit_t) { + vpr_printf(TIO_MESSAGE_ERROR, + "init_t must be greater or equal to than exit_t.\n"); + return; + } + + env->vpr_setup.AnnealSched.inner_num = get_opt_float_val(opts, "inner_num", 1.0); /* DEFAULT */ + if (env->vpr_setup.AnnealSched.inner_num <= 0) { + vpr_printf(TIO_MESSAGE_ERROR, "init_t must be greater than 0.\n"); + return; + } + + env->vpr_setup.AnnealSched.type = AUTO_SCHED; /* DEFAULT */ + if ( (TRUE == is_opt_set(opts, "alpha_t", FALSE)) + || (TRUE == is_opt_set(opts, "exit_it", FALSE)) + || (TRUE == is_opt_set(opts, "init_it", FALSE))) { + env->vpr_setup.AnnealSched.type = USER_SCHED; + } + + /* Enable Placer*/ + env->vpr_setup.PlacerOpts.doPlacement = TRUE; + + return; +} + +void shell_init_vpr_router(t_shell_env* env, t_opt_info* opts) { + char* temp = NULL; + + /* Router File names */ + /* Post packing netlist */ + temp = get_opt_val(opts, "net_file"); + if (NULL != temp) { + env->vpr_setup.FileNameOpts.NetFile = temp; + } + + /* Post placement netlist */ + temp = get_opt_val(opts, "place_file"); + if (NULL != temp) { + env->vpr_setup.FileNameOpts.PlaceFile = temp; + } + + /* Post placement netlist */ + temp = get_opt_val(opts, "route_file"); + if (NULL != temp) { + env->vpr_setup.FileNameOpts.RouteFile = temp; + } + + /* Router Options */ + env->vpr_setup.TimingEnabled = is_opt_set(opts, "timing_driven", TRUE); /* DEFAULT */ + + env->vpr_setup.RouterOpts.astar_fac = get_opt_float_val(opts, "astar_fac", 1.2); /* DEFAULT */ + + if (TRUE == is_opt_set(opts, "fast", FALSE)) { + env->vpr_setup.RouterOpts.bb_factor = get_opt_int_val(opts, "astar_fac", 0); /* DEFAULT */ + } else { + env->vpr_setup.RouterOpts.bb_factor = get_opt_int_val(opts, "astar_fac", 3); /* DEFAULT */ + } + + env->vpr_setup.RouterOpts.criticality_exp = get_opt_float_val(opts, "criticality_exp", 1.0); /* DEFAULT */ + + env->vpr_setup.RouterOpts.max_criticality = get_opt_float_val(opts, "max_criticality", 0.99); /* DEFAULT */ + + if (TRUE == is_opt_set(opts, "fast", FALSE)) { + env->vpr_setup.RouterOpts.max_router_iterations = get_opt_int_val(opts, "max_router_iterations", 10); /* DEFAULT */ + } else { + env->vpr_setup.RouterOpts.max_router_iterations = get_opt_int_val(opts, "max_router_iterations", 50); /* DEFAULT */ + } + + env->vpr_setup.RouterOpts.pres_fac_mult = get_opt_float_val(opts, "pres_fac_mult", 1.3); /* DEFAULT */ + + env->vpr_setup.RouterOpts.route_type = DETAILED; /* DEFAULT */ + temp = get_opt_val(opts, "router_type"); + if (NULL != temp) { + if ( 0 == strcmp(temp, "detailed") ) { + env->vpr_setup.RouterOpts.route_type = DETAILED; + } else if ( 0 == strcmp(temp, "global") ) { + env->vpr_setup.RouterOpts.route_type = GLOBAL; + } + } + /* Free */ + my_free(temp); + + env->vpr_setup.RouterOpts.full_stats = is_opt_set(opts, "full_stats", FALSE); /* DEFAULT */ + + env->vpr_setup.RouterOpts.verify_binary_search = is_opt_set(opts, "verify_binary_search", FALSE); /* DEFAULT */ + + /* Depends on RouteOpts->route_type */ + env->vpr_setup.RouterOpts.router_algorithm = NO_TIMING; /* DEFAULT */ + if (env->vpr_setup.TimingEnabled) { + env->vpr_setup.RouterOpts.router_algorithm = TIMING_DRIVEN; /* DEFAULT */ + } + if (GLOBAL == env->vpr_setup.RouterOpts.route_type) { + env->vpr_setup.RouterOpts.router_algorithm = NO_TIMING; /* DEFAULT */ + } + temp = get_opt_val(opts, "router_algorithm"); + if (NULL != temp) { + if ( 0 == strcmp(temp, "no_timing") ) { + env->vpr_setup.RouterOpts.router_algorithm = NO_TIMING; + } else if ( 0 == strcmp(temp, "timing_driven") ) { + env->vpr_setup.RouterOpts.router_algorithm = TIMING_DRIVEN; + } else if ( 0 == strcmp(temp, "breadth_first") ) { + env->vpr_setup.RouterOpts.router_algorithm = BREADTH_FIRST; + } + } + /* Free */ + my_free(temp); + + env->vpr_setup.RouterOpts.fixed_channel_width = NO_FIXED_CHANNEL_WIDTH; /* DEFAULT */ + temp = get_opt_val(opts, "route_chan_width"); + if (NULL != temp) { + env->vpr_setup.RouterOpts.fixed_channel_width = process_int_arg(temp); + } + /* Free */ + my_free(temp); + + /* mrFPGA: Xifan TANG */ + is_show_sram = is_opt_set(opts, "show_sram", FALSE); + is_show_pass_trans = is_opt_set(opts, "show_pass_trans", FALSE); + /* END */ + + /* Depends on env->vpr_setup.RouterOpts.router_algorithm */ + if (NO_TIMING == env->vpr_setup.RouterOpts.router_algorithm || is_opt_set(opts, "fast", FALSE)) { + env->vpr_setup.RouterOpts.initial_pres_fac = get_opt_int_val(opts, "initial_pres_fac", 10000.0); /* DEFAULT */ + } else { + env->vpr_setup.RouterOpts.initial_pres_fac = get_opt_int_val(opts, "initial_pres_fac", 0.5); /* DEFAULT */ + } + + /* Depends on env->vpr_setup.RouterOpts.router_algorithm */ + env->vpr_setup.RouterOpts.base_cost_type = DELAY_NORMALIZED; /* DEFAULT */ + if (BREADTH_FIRST == env->vpr_setup.RouterOpts.router_algorithm) { + env->vpr_setup.RouterOpts.base_cost_type = DEMAND_ONLY; /* DEFAULT */ + } + if (NO_TIMING == env->vpr_setup.RouterOpts.router_algorithm) { + env->vpr_setup.RouterOpts.base_cost_type = DEMAND_ONLY; /* DEFAULT */ + } + temp = get_opt_val(opts, "base_cost_type"); + if (NULL != temp) { + if ( 0 == strcmp(temp, "demand_only") ) { + env->vpr_setup.RouterOpts.base_cost_type = DEMAND_ONLY; + } else if ( 0 == strcmp(temp, "intrinsic_delay") ) { + env->vpr_setup.RouterOpts.base_cost_type = INTRINSIC_DELAY; + } else if ( 0 == strcmp(temp, "delay_normalized") ) { + env->vpr_setup.RouterOpts.base_cost_type = DELAY_NORMALIZED; + } + } + /* Free */ + my_free(temp); + + /* Depends on env->vpr_setup.RouterOpts.router_algorithm */ + if (BREADTH_FIRST == env->vpr_setup.RouterOpts.router_algorithm) { + env->vpr_setup.RouterOpts.first_iter_pres_fac = get_opt_float_val(opts, "first_iter_pres_fac", 0.0); /* DEFAULT */ + } else if ( (NO_TIMING == env->vpr_setup.RouterOpts.router_algorithm) + || (TRUE == is_opt_set(opts, "fast", FALSE)) ) { + env->vpr_setup.RouterOpts.first_iter_pres_fac = get_opt_float_val(opts, "first_iter_pres_fac", 10000.0); /* DEFAULT */ + } else { + env->vpr_setup.RouterOpts.first_iter_pres_fac = get_opt_float_val(opts, "first_iter_pres_fac", 0.5); /* DEFAULT */ + } + + /* Depends on env->vpr_setup.RouterOpts.router_algorithm */ + if (BREADTH_FIRST == env->vpr_setup.RouterOpts.router_algorithm) { + env->vpr_setup.RouterOpts.acc_fac = get_opt_float_val(opts, "acc_fac", 0.2); + } else { + env->vpr_setup.RouterOpts.acc_fac = get_opt_float_val(opts, "acc_fac", 1.0); + } + + /* Depends on env->vpr_setup.RouterOpts.route_type */ + if (GLOBAL == env->vpr_setup.RouterOpts.route_type) { + env->vpr_setup.RouterOpts.bend_cost = get_opt_float_val(opts, "bend_cost", 1.0); /* DEFAULT */ + } else { + env->vpr_setup.RouterOpts.bend_cost = get_opt_float_val(opts, "bend_cost", 0.0); /* DEFAULT */ + } + + /* Enable router */ + env->vpr_setup.RouterOpts.doRouting = TRUE; + + return; +} + +void shell_init_vpr_place_and_route(t_shell_env* env, t_opt_info* opts) { + + shell_init_vpr_placer(env, opts); + + shell_init_vpr_router(env, opts); + + env->vpr_setup.PlacerOpts.place_freq = PLACE_ONCE; /* DEFAULT */ + if ( (TRUE == is_opt_set(opts, "place_chan_width", FALSE)) + || (TRUE == is_opt_set(opts, "route_chan_width", FALSE)) ) { + env->vpr_setup.PlacerOpts.place_freq = PLACE_ONCE; + } + + return; +} + +void shell_execute_vpr_place_and_route(t_shell_env* env, t_opt_info* opts) { + + shell_init_vpr_place_and_route(env, opts); + + vpr_init_pre_place_and_route(env->vpr_setup, env->arch); + + vpr_place_and_route(env->vpr_setup, env->arch); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.h new file mode 100644 index 000000000..6ab163275 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_place_and_route.h @@ -0,0 +1,56 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info vpr_place_and_route_opts[] = { + /* File names */ + {"net_file", "--net_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the post-packing netlist"}, + /* General options */ + {"timing_driven", "--timing_driven", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify if algorithms are timing-driven"}, + /* Placer Options should be listed here */ + {"block_dist", "--block_dist", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"inner_loop_recompute_divider", "--inner_loop_recompute_divider", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"place_cost_exp", "--place_cost_exp", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"place_exp_first", "--place_exp_first", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"place_exp_last", "--place_exp_last", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"placer_algorithm", "--placer_algorithm", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Available algorithms of Placer: bounding_box|net_timing_driven|path_timing_driven"}, + {"pad_loc_type", "--pad_loc_type", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the location type of IO pads: free|user|random"}, + {"pad_loc_file", "--pad_loc_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the filename to constrain the location of IO pads"}, + {"place_chan_width", "--place_chan_width", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, "Specify the routing channel width used by placer"}, + {"recompute_crit_iter", "--recompute_crit_iter", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"timing_tradeoff", "--timing_tradeoff", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"seed", "--seed", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"place_clb_pin_remap", "--place_clb_pin_remap", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"place_freq", "--place_freq", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + /* For annealing */ + {"alpha_t", "--alpha_t", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"exit_t", "--exit_t", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"init_t", "--init_t", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"inner_num", "--inner_num", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + /* Router Options should be listed here */ + {"astar_fac", "--astar_fac", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"fast", "--fast", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"bb_factor", "--bb_factor", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"criticality_exp", "--criticality_exp", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"max_criticality", "--max_criticality", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"max_router_iterations", "--max_router_iterations", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"pres_fac_mult", "--pres_fac_mult", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"router_type", "--router_type", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"full_stats", "--full_stats", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"verify_binary_search", "--verify_binary_search", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"router_algorithm", "--router_algorithm", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"route_channel_width", "--route_chan_width", 0, OPT_WITHVAL, OPT_INT, OPT_OPT, OPT_NONDEF, ""}, + {"show_sram", "--show_sram", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"show_pass_trans", "--show_pass_trans", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"initial_pres_fac", "--initial_pres_fac", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"base_cost_type", "--base_cost_type", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, ""}, + {"first_iter_pres_fac", "--first_iter_pres_fac", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"acc_fac", "--acc_fac", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {"bend_cost", "--bend_cost", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, ""}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_vpr_place_and_route(t_shell_env* env, t_opt_info* opts); + + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.c new file mode 100644 index 000000000..d4cb8c395 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.c @@ -0,0 +1,37 @@ +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" +#include "vpr_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "vpr_api.h" + +boolean shell_setup_vpr_versa_power(t_shell_env* env, t_opt_info* opts) { + /* Setup the PowerOpts */ + env->vpr_setup.PowerOpts.do_power = TRUE; + + if ((NULL == env->arch.power) + || (NULL == env->arch.clocks) + || (NULL == g_clock_arch)) { + vpr_printf(TIO_MESSAGE_ERROR, + "Power Information has not been initialized in architecture!\nPlease redo read_arch by enabling versa_power option!\n"); + return FALSE; + } + + return TRUE; +} + +void shell_execute_vpr_versapower(t_shell_env* env, t_opt_info* opts) { + if (FALSE == shell_setup_vpr_versa_power(env, opts)) { + return; + } + + vpr_power_estimation(env->vpr_setup, env->arch); + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.h new file mode 100644 index 000000000..9753e57b9 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_power.h @@ -0,0 +1,11 @@ +/* Command-line options for VPR place_and_route */ +/* Add any option by following the format of t_opt_info */ +t_opt_info vpr_versapower_opts[] = { + {"activity_file", "--activity_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the activity file"}, + {"power_properties", "--power_properties", 0, OPT_WITHVAL, OPT_CHAR, OPT_REQ, OPT_NONDEF, "Specify the power property XML file"}, + {"power_report_file", "--power_report_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the output power report file name"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + +/* Function to execute the command */ +void shell_execute_vpr_versapower(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.c new file mode 100644 index 000000000..53d495192 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.c @@ -0,0 +1,280 @@ +#include +#include +/* Include vpr structs*/ +#include "util.h" +#include "arch_types.h" + +/* SPICE Support Headers */ +#include "read_xml_spice_util.h" + +#include "vpr_types.h" +#include "globals.h" +#include "read_xml_arch_file.h" +#include "ReadOptions.h" +#include "read_blif.h" +#include "SetupVPR.h" +#include "pb_type_graph.h" +#include "ReadOptions.h" +/* mrFPGA: Xifan TANG*/ +#include "mrfpga_api.h" +#include "mrfpga_globals.h" +/* END */ + +/* Xifan Tang: include for supporting Direct Parsing */ +#include "vpr_utils.h" + +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +#include "shell_file_postfix.h" + +char* shell_vpr_get_circuit_name(char* blif_name) { + int offset; + char* circuit_name = my_strdup(blif_name); + + /*if the user entered the circuit name with the .blif extension, remove it now*/ + offset = strlen(circuit_name) - 5; + if (offset > 0 && !strcmp(circuit_name + offset, BLIF_FILE_POSTFIX)) { + circuit_name[offset] = '\0'; + } + vpr_printf(TIO_MESSAGE_INFO, "Circuit name: %s%s\n", + circuit_name, BLIF_FILE_POSTFIX); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + + return circuit_name; +} + +char* shell_vpr_setup_gen_one_file_name(char* circuit_name, + char* cur_out_file_prefix, + char* postfix) { + int len; + char* file_name = NULL; + + len = strlen(circuit_name) + 1; /* circuit_name.net/0*/ + if (NULL != cur_out_file_prefix) { + len += strlen(cur_out_file_prefix); + } + if (NULL != postfix) { + len += strlen(postfix); + } + file_name = (char*) my_calloc(len, sizeof(char)); + if (NULL == cur_out_file_prefix ) { + if (NULL == postfix) { + sprintf(file_name, "%s", + circuit_name); + } else { + sprintf(file_name, "%s%s", + circuit_name, postfix); + } + } else { + if (NULL == postfix) { + sprintf(file_name, "%s%s", + cur_out_file_prefix, + circuit_name); + } else { + sprintf(file_name, "%s%s%s", + cur_out_file_prefix, + circuit_name, postfix); + } + } + + return file_name; +} + +void shell_vpr_setup_default_file_names(t_vpr_setup* vpr_setup, + t_opt_info* opts) { + char* circuit_name = shell_vpr_get_circuit_name(get_opt_val(opts, "blif_file")); + char* cur_out_file_prefix = get_opt_val(opts, "out_file_prefix"); + char* cur_default_output_name = NULL; + + vpr_setup->FileNameOpts.ArchFile = get_opt_val(opts, "arch_file"); + vpr_setup->FileNameOpts.CircuitName = circuit_name; + vpr_setup->FileNameOpts.out_file_prefix = cur_out_file_prefix; + vpr_setup->FileNameOpts.BlifFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + BLIF_FILE_POSTFIX); + vpr_setup->FileNameOpts.NetFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + NET_FILE_POSTFIX); + vpr_setup->FileNameOpts.PlaceFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + PLACE_FILE_POSTFIX); + vpr_setup->FileNameOpts.RouteFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + ROUTE_FILE_POSTFIX); + + vpr_setup->FileNameOpts.ActFile = get_opt_val(opts, "activity_file"); + if (NULL == vpr_setup->FileNameOpts.ActFile) { + vpr_setup->FileNameOpts.ActFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + ACTIVITY_FILE_POSTFIX); + } + + vpr_setup->FileNameOpts.PowerFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + POWER_FILE_POSTFIX); + + vpr_setup->FileNameOpts.CmosTechFile = shell_vpr_setup_gen_one_file_name(vpr_setup->FileNameOpts.ArchFile, + cur_out_file_prefix, + CMOS_TECH_FILE_POSTFIX); + + vpr_setup->FileNameOpts.SDCFile = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + SDC_FILE_POSTFIX); + + cur_default_output_name = shell_vpr_setup_gen_one_file_name(circuit_name, + cur_out_file_prefix, + NULL); + + alloc_and_load_output_file_names(cur_default_output_name); + + return; +} + +/* Setup the read_arch options, allocate data structures */ +void shell_setup_read_arch_opts(t_shell_env* env, t_opt_info* opts) { + /* Set read_xml_spice flag */ + env->arch.read_xml_spice = is_opt_set(opts, "read_xml_fpga_x2p", FALSE); + if (TRUE == env->arch.read_xml_spice) { + vpr_printf(TIO_MESSAGE_INFO, "Enable read_xml_fpga_x2p...\n"); + env->arch.spice = (t_spice*) my_calloc(1, sizeof(t_spice)); + } + + /* Set read_xml_power flag */ + if (TRUE == is_opt_set(opts, "read_xml_versa_power", FALSE)) { + env->arch.power = (t_power_arch*) my_calloc (1, sizeof(t_power_arch)); + env->arch.clocks = (t_clock_arch*) my_calloc (1, sizeof(t_clock_arch)); + g_clock_arch = env->arch.clocks; + } else { + env->arch.power = NULL; + env->arch.clocks = NULL; + g_clock_arch = NULL; + } + + return; +} + +void shell_setup_vpr_arch(t_shell_env* env, t_opt_info* opts) { + /* Setup ReadArch Options */ + shell_setup_read_arch_opts(env, opts); + + vpr_printf(TIO_MESSAGE_INFO, "Parsing XML file(%s)...\n", + env->vpr_setup.FileNameOpts.ArchFile); + XmlReadArch(env->vpr_setup.FileNameOpts.ArchFile, + env->vpr_setup.TimingEnabled, + &(env->arch), &type_descriptors, + &num_types); + + vpr_printf(TIO_MESSAGE_INFO, "Setup Architecture...\n"); + + VPRSetupArch(&(env->arch), &(env->vpr_setup.RoutingArch), + &(env->vpr_setup.Segments), &(env->vpr_setup.swseg_patterns), + &(env->vpr_setup.user_models), &(env->vpr_setup.library_models)); + + /* Build the complex block graph */ + vpr_printf(TIO_MESSAGE_INFO, "Building complex block graph.\n"); + alloc_and_load_all_pb_graphs(env->vpr_setup.PowerOpts.do_power); + + /* Xifan Tang: Initialize the clb to clb directs */ + alloc_and_init_globals_clb_to_clb_directs(env->arch.num_directs, env->arch.Directs); + + if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_PB_GRAPH)) { + echo_pb_graph(getEchoFileName(E_ECHO_PB_GRAPH)); + } + + if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_ARCH)) { + EchoArch(getEchoFileName(E_ECHO_ARCH), type_descriptors, num_types, + &(env->arch)); + } + + return; +} + +void shell_setup_vpr_timing(t_shell_env* env) { + /* Don't do anything if they don't want timing */ + if (FALSE == env->vpr_setup.TimingEnabled) { + memset(&(env->vpr_setup.Timing), 0, sizeof(t_timing_inf)); + env->vpr_setup.Timing.timing_analysis_enabled = FALSE; + return; + } + + env->vpr_setup.Timing.C_ipin_cblock = env->arch.C_ipin_cblock; + env->vpr_setup.Timing.T_ipin_cblock = env->arch.T_ipin_cblock; + env->vpr_setup.Timing.timing_analysis_enabled = env->vpr_setup.TimingEnabled; + + /* If the user specified an SDC filename on the command line, look for specified_name.sdc, otherwise look for circuit_name.sdc*/ + env->vpr_setup.Timing.SDCFile = env->vpr_setup.FileNameOpts.SDCFile; + + return; +} + +void shell_setup_graphics(t_shell_env* env, + t_opt_info* opts) { + env->vpr_setup.GraphPause = is_opt_set(opts, "auto", FALSE); +#ifdef NO_GRAPHICS + env->vpr_setup.ShowGraphics = FALSE; /* DEFAULT */ +#else /* NO_GRAPHICS */ + env->vpr_setup.ShowGraphics = !(is_opt_set(opts, "nodisp")); /* DEFAULT */ +#endif /* NO_GRAPHICS */ + + return; +} + +void shell_execute_vpr_setup(t_shell_env* env, + t_opt_info* opts) { + + /* Timing option priorities */ + vpr_printf(TIO_MESSAGE_INFO, "Setting up timing_analysis...\n"); + env->vpr_setup.TimingEnabled = is_opt_set(opts, "timing_analysis", TRUE); + + vpr_printf(TIO_MESSAGE_INFO, "Setting up echo file...\n"); + setEchoEnabled(is_opt_set(opts, "echo_file", FALSE)); + + vpr_printf(TIO_MESSAGE_INFO, "Setting up post-synthesis netlists...\n"); + SetPostSynthesisOption(is_opt_set(opts, "generate_postsynthesis_netlist", FALSE)); + + vpr_printf(TIO_MESSAGE_INFO, "Setting up constant net delay...\n"); + env->vpr_setup.constant_net_delay = get_opt_float_val(opts, "constant_net_delay", 0.); + + /* Set up default file names + * TODO: to be called with 'read_blif' + */ + vpr_printf(TIO_MESSAGE_INFO, "Setting up default file names...\n"); + shell_vpr_setup_default_file_names(&(env->vpr_setup), opts); + + /* TODO: to be called with 'read_arch' */ + vpr_printf(TIO_MESSAGE_INFO, "Reading Architecture...\n"); + shell_setup_vpr_arch(env, opts); + + /* VPR setup timing */ + vpr_printf(TIO_MESSAGE_INFO, "Setting up timing engine...\n"); + shell_setup_vpr_timing(env); + + /* init global variables */ + vpr_printf(TIO_MESSAGE_INFO, "Setting up some global variables...\n"); + out_file_prefix = env->vpr_setup.FileNameOpts.out_file_prefix; + grid_logic_tile_area = env->arch.grid_logic_tile_area; + ipin_mux_trans_size = env->arch.ipin_mux_trans_size; + + vpr_printf(TIO_MESSAGE_INFO, "Setting up Graphic engine...\n"); + shell_setup_graphics(env, opts); + + /* Read blif file and sweep unused components */ + vpr_printf(TIO_MESSAGE_INFO, "Reading blif...\n"); + if (TRUE == (boolean)(is_opt_set(opts, "read_xml_fpga_x2p", FALSE) || is_opt_set(opts, "read_xml_versa_power", FALSE))) { + vpr_printf(TIO_MESSAGE_INFO, "Reading activity...\n"); + } + read_and_process_blif(env->vpr_setup.FileNameOpts.BlifFile, + env->vpr_setup.PackerOpts.sweep_hanging_nets_and_inputs, + env->vpr_setup.user_models, env->vpr_setup.library_models, + /* Xifan TANG: we need activity in spice modeling */ + (boolean) (is_opt_set(opts, "read_xml_fpga_x2p", FALSE) || is_opt_set(opts, "read_xml_versa_power", FALSE)), + env->vpr_setup.FileNameOpts.ActFile); + fflush(stdout); + + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.h new file mode 100644 index 000000000..2ffed058a --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/cmd_vpr_setup.h @@ -0,0 +1,24 @@ +/* Command-line options for VPR setup */ +/* Add any option by following the format of t_opt_info */ +t_opt_info setup_vpr_opts[] = { + /* VPR Setup Options should be listed here */ + {"blif_file", "--blif_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_REQ, OPT_NONDEF, "Specify the blif for input benchmark"}, + {"arch_file", "--arch_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_REQ, OPT_NONDEF, "Specify the XML architecture description file for FPGA"}, + {"activity_file", "--activity_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the activity file for input benchmark in purpose of power estimation"}, + {"power_properties", "--power_properties", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the power property XML for power estimation"}, + {"timing_analysis", "--timing_analysis", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify if timing-driven and timing analysis should be enabled"}, + {"out_file_prefix", "--out_file_prefix", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the prefix of files to be "}, + {"net_file", "--net_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the netlist outputted by packers"}, + {"place_file", "--place_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the netlist outputted by placers"}, + {"route_file", "--route_file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify the netlist outputted by routers"}, + {"echo_file", "--echo_file", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify if echo files will be outputted"}, + {"generate_postsynthesis_netlist", "--generate_postsynthesis_netlist", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify if post synthesis netlists will be outputted"}, + {"constant_net_delay", "--constant_net_delay", 0, OPT_WITHVAL, OPT_FLOAT, OPT_OPT, OPT_NONDEF, "Specify if use constant net delay"}, + {"read_xml_fpga_x2p", "--read_xml_fpga_x2p", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify if read XML syntax for FPGA X2P"}, + {"read_xml_versa_power", "--read_xml_versa_power", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Specify if read XML syntax for VersaPower"}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch Help Desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch Help Desk"} +}; + +/* Function to execute the command */ +void shell_execute_vpr_setup(t_shell_env* env, t_opt_info* opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.c new file mode 100644 index 000000000..5b1d536c6 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" + + +/* Include SPICE support headers*/ +#include "quicksort.h" +#include "linkedlist.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +/* Include APIs */ +#include "vpr_api.h" +#include "fpga_x2p_api.h" +#include "cmd_vpr_setup.h" +#include "cmd_vpr_pack.h" +#include "cmd_vpr_place_and_route.h" +#include "cmd_vpr_power.h" +#include "cmd_fpga_x2p_setup.h" +#include "cmd_fpga_spice.h" +#include "cmd_fpga_verilog.h" +#include "cmd_fpga_bitstream.h" +#include "cmd_help.h" +#include "cmd_exit.h" +#include "shell_cmds.h" +#include "shell_utils.h" +#include "mini_shell.h" + +#include +#include + + +t_shell_env shell_env; + +char* vpr_shell_prefix = "VPR7-OpenFPGA> "; + + +void init_shell_env(t_shell_env* env) { + memset(&(env->vpr_setup), 0, sizeof(t_vpr_setup)); + memset(&(env->arch), 0, sizeof(t_arch)); + env->cmd = shell_cmd; + env->cmd_category = cmd_category; + + return; +} + +/* Start the interactive shell */ +void vpr_run_interactive_mode() { + + vpr_printf(TIO_MESSAGE_INFO, "Start interactive mode...\n"); + + vpr_print_title(); + + /* Initialize file handler */ + vpr_init_file_handler(); + + /* Initialize shell_env */ + init_shell_env(&shell_env); + + while (1) { + char * line = readline(vpr_shell_prefix); + process_shell_command(line, &shell_env); + /* Add to history */ + add_history(line); + free (line); + } + + return; +} + +void vpr_run_script_mode(char* script_file_name) { + FILE* fp = NULL; + char buffer[BUFSIZE]; + char str_end = '\0'; + int i; + + vpr_print_title(); + + /* Initialize file handler */ + vpr_init_file_handler(); + + /* Initialize shell_env */ + init_shell_env(&shell_env); + + vpr_printf(TIO_MESSAGE_INFO, "Reading script file %s!\n", script_file_name); + + /* Read the file */ + fp = fopen(script_file_name, "r"); + /* Error out if the File handle is empty */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "Fail to open the script file: %s.\n", + script_file_name); + exit(1); + } + + /* Read line by line */ + while (NULL != my_fgets(buffer, BUFSIZE, fp)) { + if ((0 == strlen(buffer)) + || (0 == my_strcmp(buffer, ""))) { + continue; + } + /* Chomp the \n of buffer */ + for (i = 0; i < strlen(buffer); i++) { + if ('\n' == buffer[i]) { + buffer[i] = str_end; + } + } + /* Treat each valid line as a command */ + process_shell_command(buffer, &shell_env); + } + + /* Close file */ + fclose(fp); + + return; +} + +void run_shell(int argc, char ** argv) { + + /* Parse the options and decide which interface to go */ + read_options(argc, argv, shell_opts); + + /* Interface 1: run through -i, --interactive + * Or with 0 arguments, we start the interactive shell + */ + if ( (1 == argc) + || (TRUE == is_opt_set(shell_opts, "i", FALSE)) ) { + vpr_run_interactive_mode(); + } else if (TRUE == is_opt_set(shell_opts, "f", FALSE)) { + /* Interface 2: run through -f, --file */ + char* script_file_name = get_opt_val(shell_opts, "f"); + vpr_run_script_mode(script_file_name); + } else { + vpr_printf(TIO_MESSAGE_ERROR, "Invalid command! Launch Help desk:\n"); + print_opt_info_help_desk(shell_opts); + } + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.h new file mode 100644 index 000000000..0b965e3a4 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/mini_shell.h @@ -0,0 +1,8 @@ + +t_opt_info shell_opts[] = { + {"f", "-f,--file", 0, OPT_WITHVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch program with a script file"}, + {"i", "-i,--interactive", 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch program in an interactive mode"}, + {HELP_OPT_TAG, HELP_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"}, + {LAST_OPT_TAG, LAST_OPT_NAME, 0, OPT_NONVAL, OPT_CHAR, OPT_OPT, OPT_NONDEF, "Launch help desk"} +}; + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.c new file mode 100644 index 000000000..386331e90 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.c @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include "util.h" +#include "read_opt_types.h" +#include "read_opt.h" + +/* External function */ +void my_free(void* ptr); +char** fpga_spice_strtok(char* str, + char* delims, + int* len); +int my_strcmp(char* str1, char* str2); + + +/** + * Read the integer in option list + * Do simple check and convert it from char to + * integer + */ +int process_int_arg(INP char* arg) { + /*Check if the pointor of arg is NULL */ + if (NULL == arg) { + vpr_printf(TIO_MESSAGE_ERROR, + "Error: Arg is NULL when processing integer!\n"); + exit(1); + } + + return atoi(arg); +} + +/** + * Read the float in option list + * Do simple check and convert it from char to + * float + */ +float process_float_arg(INP char* arg) { + /*Check if the pointor of arg is NULL */ + if (NULL == arg) { + vpr_printf(TIO_MESSAGE_ERROR, + "Error: Arg is NULL when processing float!\n"); + exit(1); + } + + return atof(arg); +} + +/** + * Process the argument by comparing + * Store the options in struct + */ +boolean process_arg_opt(INP char** argv, + INOUTP int* iarg, + INP char* curarg, + t_opt_info* cur) { + int itok = 0; + int num_tokens = 0; + char** token = NULL; + + while (0 != my_strcmp(LAST_OPT_TAG, cur->tag)) { + /* Tokenize the opt_name*/ + token = fpga_spice_strtok(cur->name, ",", &num_tokens); + /*Process Match Arguments*/ + for (itok = 0; itok < num_tokens; itok++) { + if (0 == my_strcmp(curarg, token[itok])) { + /* Check the defined flag if yes, return with error! */ + if (OPT_DEF == cur->opt_def) { + vpr_printf(TIO_MESSAGE_ERROR, + "Intend to redefine the option(%s) with (%s)!\n", + cur->name, token[itok]); + return FALSE; + } + cur->opt_def = OPT_DEF; + /*A value is stored in next argument*/ + if (OPT_WITHVAL == cur->with_val) { + *(iarg) += 1; + cur->val = my_strdup((argv[*iarg])); + return TRUE; + } else if (OPT_NONVAL == cur->with_val) { + /*Do not need next argument, return*/ + return TRUE; + } else { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, [LINE%d]) Unknown type of Option with_Val! Abort.\n", + __FILE__, __LINE__); + return FALSE; + } + } + } + cur++; + /* Free */ + for (itok = 0; itok < num_tokens; itok++) { + my_free(token[itok]); + } + my_free(token); + } + + return FALSE; +} + +char* convert_option_mandatory_to_str(enum opt_manda cur) { + switch (cur) { + case OPT_REQ: + return "Required"; + case OPT_OPT: + return "Optional"; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, [LINE%d]) Unknown type of Option Mandatory! Abort.\n", + __FILE__, __LINE__); + return NULL; + } +} + +void print_opt_info_help_desk(t_opt_info* cur_opt_info) { + int max_str_len = -1; + int offset; + t_opt_info* cur = cur_opt_info; + char* str_fixed_len = NULL; + char* name_tag = "Option Names"; + char str_end = '\0'; + + /* Get the maximum string length of options + * We can align to the longest string when outputing the help desk + */ + while (0 != my_strcmp(LAST_OPT_TAG, cur->tag)) { + if ( (-1 == max_str_len) + || (max_str_len < strlen(cur->name)) ) { + max_str_len = strlen(cur->name) + 1; + } + cur++; + } + /* Minimum size is 5 */ + if (max_str_len < strlen(name_tag) + 1) { + max_str_len = strlen(name_tag) + 1; + } + /* Malloc */ + str_fixed_len = (char*)my_calloc(max_str_len, sizeof(char)); + + vpr_printf(TIO_MESSAGE_INFO, "Help Desk:\n"); + memset(str_fixed_len, ' ', max_str_len); + strcpy(str_fixed_len, name_tag); + str_fixed_len[strlen(name_tag)] = ' '; + str_fixed_len[max_str_len] = str_end; + vpr_printf(TIO_MESSAGE_INFO, "%s Status Description\n", str_fixed_len); + cur = cur_opt_info; + while (0 != my_strcmp(LAST_OPT_TAG, cur->tag)) { + memset(str_fixed_len, ' ', max_str_len); + strcpy(str_fixed_len, cur->name); + str_fixed_len[strlen(cur->name)] = ' '; + str_fixed_len[max_str_len] = str_end; + vpr_printf(TIO_MESSAGE_INFO, "%s ", str_fixed_len); + vpr_printf(TIO_MESSAGE_INFO, "%s ", convert_option_mandatory_to_str(cur->mandatory)); + vpr_printf(TIO_MESSAGE_INFO, "%s", cur->description); + vpr_printf(TIO_MESSAGE_INFO, "\n"); + cur++; + } + vpr_printf(TIO_MESSAGE_INFO, "\n"); + + /* Free */ + my_free(str_fixed_len); + + return; +} + + +boolean read_options(INP int argc, + INP char **argv, + INOUTP t_opt_info* cur_opt_info) { + int iarg; + char* curarg = NULL; + boolean arg_processed = FALSE; + t_opt_info* cur = cur_opt_info; + + + vpr_printf(TIO_MESSAGE_INFO, + "Processing Options...\n"); + + /*Start from argv[1], the 1st argv is programme name*/ + for (iarg = 1; iarg < argc;) { + curarg = argv[iarg]; + /*Process the option start with hyphone*/ + if (0 == strncmp("-", curarg, 1)) { + arg_processed = process_arg_opt(argv, &iarg, curarg, cur_opt_info); + if (FALSE == arg_processed) { + vpr_printf(TIO_MESSAGE_WARNING, + "Warning: Unknown Option(%s) detected!\n", + curarg); + print_opt_info_help_desk(cur_opt_info); + return FALSE; + } + iarg += 1; /*Move on to the next argument*/ + } else { + iarg++; + } + } + + /* Search the command help */ + if (TRUE == is_opt_set(cur_opt_info, LAST_OPT_TAG, FALSE)) { + print_opt_info_help_desk(cur_opt_info); + return FALSE; + } + + /* Check if REQUIRED options are processed */ + while (0 != my_strcmp(LAST_OPT_TAG, cur->tag)) { + if ( (NULL == cur->val) + && (OPT_REQ == cur->mandatory)) { + vpr_printf(TIO_MESSAGE_WARNING, + "Warning: Required Option(%s) is missing!\n", + cur->name); + print_opt_info_help_desk(cur_opt_info); + return FALSE; + } + cur++; + } + + /* Confirm options */ + /* + show_opt_list(cur_opt_info); + */ + + return TRUE; +} + + +/** + * Show the options in opt_list after process. + * Only for debug use + */ +int show_opt_list(t_opt_info* cur) { + + vpr_printf(TIO_MESSAGE_INFO, + "List Options:\n"); + while (0 != my_strcmp(LAST_OPT_TAG, cur->tag)) { + vpr_printf(TIO_MESSAGE_INFO, + "Name=%s, Value=%s.\n", + cur->name, cur->val); + cur++; + } + + return 1; +} + +boolean is_opt_set(t_opt_info* opts, char* opt_name, boolean default_val) { + while (0 != my_strcmp(LAST_OPT_TAG, opts->tag)) { + if ( 0 != my_strcmp(opts->tag, opt_name)) { + opts++; + continue; + } + if (OPT_DEF == opts->opt_def) { + return TRUE; + } else { + return default_val; + } + opts++; + } + + return default_val; +} + +char* get_opt_val(t_opt_info* opts, char* opt_name) { + while (0 != my_strcmp(LAST_OPT_TAG, opts->tag)) { + if ( 0 != my_strcmp(opts->tag, opt_name)) { + opts++; + continue; + } + if (OPT_WITHVAL != opts->with_val) { + vpr_printf(TIO_MESSAGE_INFO, + "Try to get the val of an option(%s) which is defined to be without_val!\n", + opt_name); + } + if (NULL == opts->val) { + return NULL; + } else { + return my_strdup(opts->val); + } + opts++; + } + + return NULL; +} + +int get_opt_int_val(t_opt_info* opts, char* opt_name, int default_val) { + char* temp = get_opt_val(opts, opt_name); + int ret = default_val; + + if (NULL != temp) { + ret = process_int_arg(temp); + } + /* Free */ + my_free(temp); + + return ret; +} + +float get_opt_float_val(t_opt_info* opts, char* opt_name, float default_val) { + char* temp = get_opt_val(opts, opt_name); + float ret = default_val; + + if (NULL != temp) { + ret = process_float_arg(temp); + } + /* Free */ + my_free(temp); + + return ret; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.h new file mode 100644 index 000000000..97a33e918 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt.h @@ -0,0 +1,25 @@ +/*Subroutines in read_opts.c*/ +boolean read_options(INP int argc, + INP char ** argv, + t_opt_info* cur); + +void print_opt_info_help_desk(t_opt_info* cur_opt_info); + +boolean process_arg_opt(INP char** argv, + INOUTP int* iarg, + INP char* curarg, + t_opt_info* cur); + +int show_opt_list(t_opt_info* cur); + +int process_int_arg(INP char* arg); + +float process_float_arg(INP char* arg); + +boolean is_opt_set(t_opt_info* opts, char* opt_name, boolean default_val); + +char* get_opt_val(t_opt_info* opts, char* opt_name); + +int get_opt_int_val(t_opt_info* opts, char* opt_name, int default_val); + +float get_opt_float_val(t_opt_info* opts, char* opt_name, float default_val); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt_types.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt_types.h new file mode 100644 index 000000000..2909ff43d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/read_opt_types.h @@ -0,0 +1,63 @@ +/** + * Filename : Options.h + * Author : Xifan TANG, EPFL + * Description : Header file contains structs and enumeration + * types for option reading purpose. + */ + +/*Determine whether it is a mandatory option*/ +enum opt_manda { + OPT_REQ, + OPT_OPT +}; + +/*The option has been appeared in the command line */ +enum opt_default { + OPT_DEF, + OPT_NONDEF +}; + +/*Determine whether the option contains a value*/ +enum opt_with_val { + OPT_NONVAL, + OPT_WITHVAL +}; + +/*Determine the date type of value*/ +enum opt_val_type { + OPT_INT, + OPT_FLOAT, + OPT_CHAR, + OPT_DOUBLE +}; + +/*Basic struct stores option information*/ +typedef struct s_opt_info t_opt_info; +struct s_opt_info { + char* tag; /* tag of option */ + char* name; /*The name of option*/ + char* val; /*The value*/ + enum opt_with_val with_val; + enum opt_val_type val_type; + enum opt_manda mandatory; + enum opt_default opt_def; + char* description; +}; + +typedef struct s_cmd_info t_cmd_info; +struct s_cmd_info { + char* name; + t_opt_info opts[]; +}; + +#define HELP_OPT_TAG "help" +#define HELP_OPT_NAME "-h,--help" + +#define LAST_OPT_TAG NULL +#define LAST_OPT_NAME NULL + +/* Return flag */ +#define SHELL_SUCCESS 0 +#define SHELL_FAIL 1 +#define SHELL_ERROR 2 + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_api.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_api.h new file mode 100644 index 000000000..70c659083 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_api.h @@ -0,0 +1,2 @@ + +void run_shell(int argc, char ** argv); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_cmds.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_cmds.h new file mode 100644 index 000000000..f8d483b6c --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_cmds.h @@ -0,0 +1,27 @@ +/* Commands available in the shell */ +t_shell_cmd shell_cmd[] = { + {"vpr_setup", SETUP_CMD, setup_vpr_opts, &shell_execute_vpr_setup }, + {"vpr_pack", PACK_CMD, vpr_pack_opts, &shell_execute_vpr_pack }, + {"vpr_place_and_route", PLACE_CMD, vpr_place_and_route_opts, &shell_execute_vpr_place_and_route }, + {"vpr_versapower", ANALYSIS_CMD, vpr_versapower_opts, &shell_execute_vpr_versapower }, + {"fpga_x2p_setup", SETUP_CMD, fpga_x2p_setup_opts, &shell_execute_fpga_x2p_setup }, + {"fpga_spice", PRODUCTION_CMD, fpga_spice_opts, &shell_execute_fpga_spice }, + {"fpga_verilog", PRODUCTION_CMD, fpga_verilog_opts, &shell_execute_fpga_verilog }, + {"fpga_bitstream", PRODUCTION_CMD, fpga_bitstream_opts, &shell_execute_fpga_bitstream }, + {"help", BASIC_CMD, help_opts, &shell_execute_help }, + {"exit", BASIC_CMD, exit_opts, &shell_execute_exit }, + {"quit", BASIC_CMD, NULL, &shell_execute_exit }, + {LAST_CMD_NAME, BASIC_CMD, NULL, NULL} +}; + +/* Command category */ +t_cmd_category cmd_category[] = { + {BASIC_CMD, "Basic Commands"}, + {SETUP_CMD, "Commands to Setup Engines"}, + {PACK_CMD, "Packing Engines"}, + {PLACE_CMD, "Placement Engines"}, + {ROUTE_CMD, "Routing Engines"}, + {ANALYSIS_CMD, "Analysis Commands"}, + {PRODUCTION_CMD, "Production Commmands"}, + {LAST_CMD_CATEGORY, "END"} +}; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_file_postfix.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_file_postfix.h new file mode 100644 index 000000000..ef41348f1 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_file_postfix.h @@ -0,0 +1,9 @@ +#define BLIF_FILE_POSTFIX ".blif" +#define NET_FILE_POSTFIX ".net" +#define PLACE_FILE_POSTFIX ".place" +#define ROUTE_FILE_POSTFIX ".route" +#define ACTIVITY_FILE_POSTFIX ".act" +#define POWER_FILE_POSTFIX ".power" +#define CMOS_TECH_FILE_POSTFIX ".xml" +#define SDC_FILE_POSTFIX ".sdc" + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_types.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_types.h new file mode 100644 index 000000000..db7fd771c --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_types.h @@ -0,0 +1,39 @@ + +typedef struct s_cmd_category t_cmd_category; +typedef struct s_shell_cmd t_shell_cmd; +typedef struct s_shell_env t_shell_env; + +enum e_cmd_category { + BASIC_CMD, + SETUP_CMD, + PACK_CMD, + PLACE_CMD, + ROUTE_CMD, + ANALYSIS_CMD, + PRODUCTION_CMD, + LAST_CMD_CATEGORY +}; + +struct s_cmd_category { + e_cmd_category name; + char* label; +}; + + +struct s_shell_cmd { + char* name; + e_cmd_category category; + t_opt_info* opts; + void (*execute)(t_shell_env*, t_opt_info*); +}; + +struct s_shell_env { + t_arch arch; + t_vpr_setup vpr_setup; + t_shell_cmd* cmd; + t_cmd_category* cmd_category; +}; + +#define LAST_CMD_NAME NULL + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.c new file mode 100644 index 000000000..c1dfe566e --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" + + +/* Include SPICE support headers*/ +#include "quicksort.h" +#include "linkedlist.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "read_opt_types.h" +#include "read_opt.h" +#include "shell_types.h" + +/* Include APIs */ + +#include +#include + +int my_strcmp(char* str1, char* str2) { + if ((NULL == str1) && (NULL == str2)) { + return 0; + } else if ((NULL == str1) || (NULL == str2)) { + return 1; + } else { + return strcmp(str1, str2); + } +} + +void shell_print_usage(t_shell_env* env) { + t_cmd_category* cur_category = env->cmd_category; + + /* Output usage by command categories */ + while (LAST_CMD_CATEGORY != cur_category->name) { + vpr_printf(TIO_MESSAGE_INFO, + "%s:\n", cur_category->label); + t_shell_cmd* cur_cmd = env->cmd; + int cnt = 0; + while (0 != my_strcmp(LAST_CMD_NAME, cur_cmd->name)) { + if (cur_category->name != cur_cmd->category) { + /* Go to next command*/ + cur_cmd++; + continue; + } + /* Print command name */ + vpr_printf(TIO_MESSAGE_INFO, + "%s", + cur_cmd->name); + cnt++; + if (4 == cnt) { + vpr_printf(TIO_MESSAGE_INFO, "\n"); + cnt = 0; + } else { + vpr_printf(TIO_MESSAGE_INFO, "\t"); + } + /* Go to next command*/ + cur_cmd++; + } + vpr_printf(TIO_MESSAGE_INFO, "\n\n"); + /* Go to next */ + cur_category++; + } + + return; +} + +/* Identify the command to launch */ +void process_shell_command(char* line, t_shell_env* env) { + int itok; + int num_tokens = 0; + char** token = NULL; + t_shell_cmd* cur_cmd = env->cmd; + + /* Tokenize the line */ + token = fpga_spice_strtok(line, " ", &num_tokens); + + /* Search the shell command list and execute */ + while (0 != my_strcmp(LAST_CMD_NAME, cur_cmd->name)) { + if (0 == my_strcmp(cur_cmd->name, token[0])) { + /* Read options of read_blif */ + if (FALSE == read_options(num_tokens, token, cur_cmd->opts)) { + return; + } + /* Execute setup_vpr engine*/ + cur_cmd->execute(env, cur_cmd->opts); + /* Return here */ + return; + } + /* Go to next command*/ + cur_cmd++; + } + + /* Invalid command */ + vpr_printf(TIO_MESSAGE_INFO, + "Invalid command!\n"); + shell_print_usage(env); + + /* Free */ + for (itok = 0; itok < num_tokens; itok++) { + my_free(token[itok]); + } + my_free(token); + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.h new file mode 100644 index 000000000..fbc00c57f --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/shell/shell_utils.h @@ -0,0 +1,6 @@ + +int my_strcmp(char* str1, char* str2); + +void shell_print_usage(t_shell_env* env); + +void process_shell_command(char* line, t_shell_env* env); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.c similarity index 77% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.c index 296a34823..93ed199ec 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_api.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.c @@ -20,14 +20,17 @@ #include "vpr_utils.h" #include "path_delay.h" #include "stats.h" +#include "route_common.h" /* Include spice support headers*/ #include "read_xml_spice_util.h" #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "fpga_spice_globals.h" -#include "fpga_spice_bitstream.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" /* Include SPICE generator headers */ @@ -39,9 +42,8 @@ #include "spice_top_netlist.h" #include "spice_mux_testbench.h" #include "spice_grid_testbench.h" -#include "spice_lut_testbench.h" #include "spice_routing_testbench.h" -#include "spice_hardlogic_testbench.h" +#include "spice_primitive_testbench.h" #include "spice_run_scripts.h" /* For mrFPGA */ @@ -60,6 +62,7 @@ static char* spice_cb_tb_dir_name = "cb_tb/"; static char* spice_sb_tb_dir_name = "sb_tb/"; static char* spice_lut_tb_dir_name = "lut_tb/"; static char* spice_hardlogic_tb_dir_name = "hardlogic_tb/"; +static char* spice_io_tb_dir_name = "io_tb/"; /***** Subroutines Declarations *****/ static @@ -159,9 +162,9 @@ void free_spice_tb_llist() { } /***** Main Function *****/ -void vpr_print_spice_netlists(t_vpr_setup vpr_setup, - t_arch Arch, - char* circuit_name) { +void vpr_fpga_spice(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name) { clock_t t_start; clock_t t_end; float run_time_sec; @@ -186,6 +189,7 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup, char* grid_testbench_dir_path = NULL; char* lut_testbench_dir_path = NULL; char* hardlogic_testbench_dir_path = NULL; + char* io_testbench_dir_path = NULL; char* top_testbench_file = NULL; char* bitstream_file_name = NULL; char* bitstream_file_path = NULL; @@ -246,7 +250,7 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup, /* Update the global variable : * the number of mutli-thread used in SPICE simulator */ - spice_sim_multi_thread_num = vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_sim_multi_thread_num; + spice_sim_multi_thread_num = vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_sim_multi_thread_num; /* FPGA-SPICE formally starts*/ vpr_printf(TIO_MESSAGE_INFO, "\nFPGA-SPICE starts...\n"); @@ -280,7 +284,7 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup, generate_spice_subckts(subckt_dir_path, &Arch ,&vpr_setup.RoutingArch); /* Print MUX testbench if needed */ - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_pb_mux_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_pb_mux_testbench) { pb_mux_testbench_dir_path = my_strcat(spice_dir_formatted, spice_pb_mux_tb_dir_name); create_dir_path(pb_mux_testbench_dir_path); spice_print_mux_testbench(pb_mux_testbench_dir_path, chomped_circuit_name, @@ -288,74 +292,108 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup, rr_node_indices, num_clocks, Arch, SPICE_PB_MUX_TB, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(pb_mux_testbench_dir_path); } - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_cb_mux_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_mux_testbench) { cb_mux_testbench_dir_path = my_strcat(spice_dir_formatted, spice_cb_mux_tb_dir_name); create_dir_path(cb_mux_testbench_dir_path); spice_print_mux_testbench(cb_mux_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, rr_node_indices, num_clocks, Arch, SPICE_CB_MUX_TB, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(cb_mux_testbench_dir_path); } - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_sb_mux_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_mux_testbench) { sb_mux_testbench_dir_path = my_strcat(spice_dir_formatted, spice_sb_mux_tb_dir_name); create_dir_path(sb_mux_testbench_dir_path); spice_print_mux_testbench(sb_mux_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, rr_node_indices, num_clocks, Arch, SPICE_SB_MUX_TB, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(sb_mux_testbench_dir_path); } - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_cb_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_cb_testbench) { cb_testbench_dir_path = my_strcat(spice_dir_formatted, spice_cb_tb_dir_name); create_dir_path(cb_testbench_dir_path); spice_print_cb_testbench(cb_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(cb_testbench_dir_path); } - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_sb_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_sb_testbench) { sb_testbench_dir_path = my_strcat(spice_dir_formatted, spice_sb_tb_dir_name); create_dir_path(sb_testbench_dir_path); spice_print_sb_testbench(sb_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(sb_testbench_dir_path); } - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_lut_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_lut_testbench) { lut_testbench_dir_path = my_strcat(spice_dir_formatted, spice_lut_tb_dir_name); create_dir_path(lut_testbench_dir_path); - spice_print_lut_testbench(lut_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, - rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + spice_print_primitive_testbench(lut_testbench_dir_path, + chomped_circuit_name, include_dir_path, subckt_dir_path, + rr_node_indices, num_clocks, Arch, + SPICE_LUT_TB, + vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(lut_testbench_dir_path); } /* Print hardlogic testbench file if needed */ - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_hardlogic_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_hardlogic_testbench) { hardlogic_testbench_dir_path = my_strcat(spice_dir_formatted, spice_hardlogic_tb_dir_name); create_dir_path(hardlogic_testbench_dir_path); - spice_print_hardlogic_testbench(hardlogic_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, - rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + spice_print_primitive_testbench(hardlogic_testbench_dir_path, + chomped_circuit_name, include_dir_path, subckt_dir_path, + rr_node_indices, num_clocks, Arch, + SPICE_HARDLOGIC_TB, + vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(hardlogic_testbench_dir_path); } + /* Print IO testbench file if needed */ + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_io_testbench) { + io_testbench_dir_path = my_strcat(spice_dir_formatted, spice_io_tb_dir_name); + create_dir_path(io_testbench_dir_path); + spice_print_primitive_testbench(io_testbench_dir_path, + chomped_circuit_name, include_dir_path, subckt_dir_path, + rr_node_indices, num_clocks, Arch, + SPICE_IO_TB, + vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(io_testbench_dir_path); + } + + /* Print Grid testbench if needed */ - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_grid_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_grid_testbench) { grid_testbench_dir_path = my_strcat(spice_dir_formatted, spice_grid_tb_dir_name); create_dir_path(grid_testbench_dir_path); spice_print_grid_testbench(grid_testbench_dir_path, chomped_circuit_name, include_dir_path, subckt_dir_path, rr_node_indices, num_clocks, Arch, vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); + /* Free */ + my_free(grid_testbench_dir_path); } /* Print Netlists of the given FPGA*/ - if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.spice_print_top_testbench) { + if (vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_print_top_testbench) { top_testbench_file = my_strcat(chomped_circuit_name, spice_top_testbench_postfix); - bitstream_file_name = my_strcat(chomped_circuit_name, bitstream_spice_file_postfix); - bitstream_file_path = my_strcat(spice_dir_formatted, bitstream_file_name); /* Process top_netlist_path */ top_testbench_dir_path = my_strcat(spice_dir_formatted, spice_top_tb_dir_name); create_dir_path(top_testbench_dir_path); @@ -364,13 +402,29 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup, include_dir_path, subckt_dir_path, num_rr_nodes, rr_node, rr_node_indices, num_clocks, *(Arch.spice), vpr_setup.FPGA_SPICE_Opts.SpiceOpts.fpga_spice_leakage_only); - /* Dump bitstream file */ - dump_fpga_spice_bitstream(bitstream_file_path, chomped_circuit_name, sram_spice_orgz_info); + /* Free */ + my_free(top_testbench_dir_path); + my_free(top_testbench_file); + my_free(top_netlist_path); } + if (vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream) { + if (NULL == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.bitstream_output_file) { + bitstream_file_name = my_strcat(chomped_circuit_name, fpga_spice_bitstream_output_file_postfix); + bitstream_file_path = my_strcat(spice_dir_formatted, bitstream_file_name); + } else { + bitstream_file_path = my_strdup(vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.bitstream_output_file); + } + /* Dump bitstream file */ + dump_fpga_spice_bitstream(bitstream_file_path, chomped_circuit_name, sram_spice_orgz_info); + /* Free */ + my_free(bitstream_file_name); + my_free(bitstream_file_path); + } /* Generate a shell script for running HSPICE simulations */ - fprint_run_hspice_shell_script(*(Arch.spice), spice_dir_formatted, subckt_dir_path); + fprint_run_hspice_shell_script(*(Arch.spice), vpr_setup.FPGA_SPICE_Opts.SpiceOpts.simulator_path, + spice_dir_formatted, subckt_dir_path); /* END Clocking*/ t_end = clock(); @@ -380,8 +434,7 @@ void vpr_print_spice_netlists(t_vpr_setup vpr_setup, /* Free sram_orgz_info */ free_sram_orgz_info(sram_spice_orgz_info, - sram_spice_orgz_info->type, - nx + 2, ny + 2); + sram_spice_orgz_info->type); /* Free tb_llist */ free_spice_tb_llist(); /* Free */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.h new file mode 100644 index 000000000..13a29bf57 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_api.h @@ -0,0 +1,3 @@ +void vpr_fpga_spice(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_globals.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_globals.c similarity index 97% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_globals.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_globals.c index ec7efab14..48a9b2ce1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_globals.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_globals.c @@ -6,7 +6,7 @@ #include #include "spice_types.h" #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" #include "spice_globals.h" /* Threshold of max transistor width for each transistor */ @@ -67,7 +67,6 @@ char* spice_lut_testbench_postfix = "_lut_testbench.sp"; char* spice_dff_testbench_postfix = "_dff_testbench.sp"; char* spice_hardlogic_testbench_postfix = "_hardlogic_testbench.sp"; char* spice_io_testbench_postfix = "_io_testbench.sp"; -char* bitstream_spice_file_postfix = ".bitstream"; /* SRAM SPICE MODEL should be set as global*/ t_spice_model* sram_spice_model = NULL; @@ -86,7 +85,6 @@ int num_used_sb_tb = 0; int num_used_cb_mux_tb = 0; int num_used_sb_mux_tb = 0; int num_used_lut_tb = 0; -int num_used_dff_tb = 0; int num_used_hardlogic_tb = 0; int num_used_io_tb = 0; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_globals.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_globals.h similarity index 98% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_globals.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_globals.h index 9484eb554..2b303e7fb 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_globals.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_globals.h @@ -56,7 +56,6 @@ extern char* spice_lut_testbench_postfix; extern char* spice_dff_testbench_postfix; extern char* spice_hardlogic_testbench_postfix; extern char* spice_io_testbench_postfix; -extern char* bitstream_spice_file_postfix; /* RUN HSPICE Shell Script Name */ /* extern char* run_hspice_shell_script_name; @@ -85,7 +84,6 @@ extern int num_used_grid_tb; extern int num_used_cb_tb; extern int num_used_sb_tb; extern int num_used_lut_tb; -extern int num_used_dff_tb; extern int num_used_hardlogic_tb; extern int num_used_io_tb; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_grid_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_grid_testbench.c similarity index 99% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_grid_testbench.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_grid_testbench.c index f8c15d2dc..4061d633d 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_grid_testbench.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_grid_testbench.c @@ -20,12 +20,14 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_types.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" #include "spice_utils.h" #include "spice_pbtypes.h" #include "spice_subckt.h" @@ -422,6 +424,7 @@ int fprint_spice_one_grid_testbench(char* formatted_spice_dir, char* temp_include_file_path = NULL; char* title = my_strcat("FPGA Grid Testbench for Design: ", circuit_name); char* grid_testbench_file_path = my_strcat(formatted_spice_dir, grid_test_bench_name); + t_llist* temp = NULL; int used = 0; /* Check if the path exists*/ diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_grid_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_grid_testbench.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_grid_testbench.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_grid_testbench.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_heads.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_heads.c similarity index 98% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_heads.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_heads.c index ec242f978..c6301f85b 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_heads.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_heads.c @@ -17,12 +17,14 @@ #include "globals.h" #include "rr_graph.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_types.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" #include "spice_utils.h" #include "spice_mux.h" #include "spice_pbtypes.h" diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_heads.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_heads.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_heads.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_heads.h diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.c new file mode 100644 index 000000000..8b61248ec --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.c @@ -0,0 +1,673 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "rr_graph_swseg.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_lut_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "spice_utils.h" +#include "spice_mux.h" +#include "spice_pbtypes.h" +#include "spice_lut.h" + + +/***** Subroutines *****/ + +void fprint_spice_lut_subckt(FILE* fp, + t_spice_model* spice_model) { + int num_input_port = 0; + t_spice_model_port** input_port = NULL; + int num_output_port = 0; + t_spice_model_port** output_port = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_port = NULL; + + int iport, ipin; + int sram_port_index = OPEN; + int mode_port_index = OPEN; + int mode_lsb = 0; + int num_dumped_port = 0; + char* mode_inport_postfix = "_mode"; + + int jport, jpin, pin_cnt; + int modegate_num_input_port = 0; + int modegate_num_input_pins = 0; + int modegate_num_output_port = 0; + t_spice_model_port** modegate_input_port = NULL; + t_spice_model_port** modegate_output_port = NULL; + char* required_gate_type = NULL; + enum e_spice_model_gate_type required_gate_model_type; + + float total_width; + int width_cnt; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", + __FILE__, __LINE__); + } + + /* Find input ports, output ports and sram ports*/ + input_port = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_port = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + sram_port = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + + /* Check */ + if (FALSE == spice_model->design_tech_info.lut_info->frac_lut) { + /* when fracturable LUT is considered + * More than 1 output is allowed + * Only two SRAM ports are allowed + */ + assert(1 == num_input_port); + assert(1 == num_output_port); + assert(1 == num_sram_port); + } else { + assert (TRUE == spice_model->design_tech_info.lut_info->frac_lut); + /* when fracturable LUT is considered + * More than 1 output is allowed + * Only two SRAM ports are allowed + */ + assert(1 == num_input_port); + for (iport = 0; iport < num_output_port; iport++) { + assert(0 < output_port[iport]->size); + } + assert(2 == num_sram_port); + } + + fprintf(fp, "***** Auto-generated LUT info: spice_model_name = %s, size = %d *****\n", + spice_model->name, input_port[0]->size); + /* Define the subckt*/ + fprintf(fp, ".subckt %s ", spice_model->name); /* Subckt name*/ + /* Input ports*/ + for (iport = 0; iport < num_input_port; iport++) { + for (ipin = 0; ipin < input_port[iport]->size; ipin++) { + fprintf(fp, "%s%d ", input_port[iport]->prefix, ipin); + } + } + /* output ports*/ + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + fprintf(fp, "%s%d ", output_port[iport]->prefix, ipin); + } + } + /* sram ports */ + /* Print configuration ports*/ + num_dumped_port = 0; + for (iport = 0; iport < num_sram_port; iport++) { + /* By pass mode select ports */ + if (TRUE == sram_port[iport]->mode_select) { + continue; + } + assert(FALSE == sram_port[iport]->mode_select); + for (ipin = 0; ipin < sram_port[iport]->size; ipin++) { + fprintf(fp, "%s%d ", sram_port[iport]->prefix, ipin); + } + sram_port_index = iport; + num_dumped_port++; + } + /* Print mode configuration ports*/ + num_dumped_port = 0; + for (iport = 0; iport < num_sram_port; iport++) { + /* By pass mode select ports */ + if (FALSE == sram_port[iport]->mode_select) { + continue; + } + assert(TRUE == sram_port[iport]->mode_select); + for (ipin = 0; ipin < sram_port[iport]->size; ipin++) { + fprintf(fp, "%s_out%d ", sram_port[iport]->prefix, ipin); + } + mode_port_index = iport; + num_dumped_port++; + } + /* Check if all required SRAMs ports*/ + if (TRUE == spice_model->design_tech_info.lut_info->frac_lut) { + if (1 != num_dumped_port) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d]) Fracturable LUT (spice_model_name=%s) must have 1 mode port!\n", + __FILE__, __LINE__, spice_model->name); + exit(1); + } + } + + /* local vdd and gnd*/ + fprintf(fp, "svdd sgnd\n"); + + /* Input buffers */ + assert (1 == num_input_port); + assert (NULL != input_port); + + /* If this is a regular LUT, we give a default tri_state_map */ + if (FALSE == spice_model->design_tech_info.lut_info->frac_lut) { + for (iport = 0; iport < num_input_port; iport++) { + if (NULL == input_port[iport]->tri_state_map) { + input_port[iport]->tri_state_map = (char*)my_calloc(input_port[iport]->size, sizeof(char)); + } else { + vpr_printf(TIO_MESSAGE_WARNING, + "(File:%s, [LINE%d])Overwrite the tri-state map for the LUT inputs (name=%s)!\n", + __FILE__, __LINE__, spice_model->name); + } + for (ipin = 0; ipin < input_port[iport]->size; ipin++) { + input_port[iport]->tri_state_map[ipin] = '-'; + } + } + } + + /* Add AND/OR gates if this is a fracturable LUT */ + for (iport = 0; iport < num_input_port; iport++) { + /* Initialize lsb */ + mode_lsb = 0; + for (ipin = 0; ipin < input_port[iport]->size; ipin++) { + if ('0' == input_port[iport]->tri_state_map[ipin]) { + required_gate_type = "AND"; + required_gate_model_type = SPICE_MODEL_GATE_AND; + } + if ('1' == input_port[iport]->tri_state_map[ipin]) { + required_gate_type = "OR"; + required_gate_model_type = SPICE_MODEL_GATE_OR; + } + /* First check if we have the required gates*/ + switch (input_port[iport]->tri_state_map[ipin]) { + case '-': + break; + case '0': + case '1': + /* Check: we must have an AND2/OR2 gate */ + if (NULL == input_port[iport]->spice_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) is not defined!\n", + __FILE__, __LINE__, required_gate_type, + input_port[iport]->prefix, spice_model->name); + exit(1); + } + if ((SPICE_MODEL_GATE != input_port[iport]->spice_model->type) + || (required_gate_model_type != input_port[iport]->spice_model->design_tech_info.gate_info->type)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) is not defined as a AND logic gate!\n", + __FILE__, __LINE__, required_gate_type, + input_port[iport]->prefix, spice_model->name); + exit(1); + } + /* Check input ports */ + modegate_input_port = find_spice_model_ports(input_port[iport]->spice_model, SPICE_MODEL_PORT_INPUT, &modegate_num_input_port, TRUE); + modegate_num_input_pins = 0; + for (jport = 0; jport < modegate_num_input_port; jport++) { + modegate_num_input_pins += modegate_input_port[jport]->size; + } + if (2 != modegate_num_input_pins) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) should have only 2 input pins!\n", + __FILE__, __LINE__, required_gate_type, + input_port[iport]->prefix, spice_model->name); + exit(1); + } + /* Check output ports */ + modegate_output_port = find_spice_model_ports(input_port[iport]->spice_model, SPICE_MODEL_PORT_OUTPUT, &modegate_num_output_port, TRUE); + if ( (1 != modegate_num_output_port) + || (1 != modegate_output_port[0]->size)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) should have only 1 output!\n", + __FILE__, __LINE__, required_gate_type, + input_port[iport]->prefix, spice_model->name); + exit(1); + } + /* Instance the AND2/OR2 gate */ + fprintf(fp, "X%s_%s%d ", + input_port[iport]->spice_model->prefix, + input_port[iport]->prefix, ipin); + pin_cnt = 0; + for (jport = 0; jport < modegate_num_input_port; jport++) { + for (jpin = 0; jpin < modegate_input_port[jport]->size; jpin++) { + if (0 == pin_cnt) { + fprintf(fp, "%s%d", + input_port[iport]->prefix, ipin); + } else if (1 == pin_cnt) { + fprintf(fp, " %s_out%d", + sram_port[mode_port_index]->prefix, mode_lsb); + } + pin_cnt++; + } + } + assert(2 == pin_cnt); + fprintf(fp, " %s%s%d", + input_port[0]->prefix, mode_inport_postfix, ipin); + mode_lsb++; + /* local vdd and gnd*/ + fprintf(fp, " svdd sgnd"); + /* Call subckt name */ + fprintf(fp, " %s\n", input_port[iport]->spice_model->name); + /* Free ports */ + my_free(modegate_input_port); + my_free(modegate_output_port); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(file:%s,line[%d]) invalid LUT tri_state_map = %s ", + __FILE__, __LINE__, input_port[iport]->tri_state_map); + exit(1); + } + } + /* Check if we have dumped all the SRAM ports for mode selection */ + if ((OPEN != mode_port_index) + &&(mode_lsb != sram_port[mode_port_index]->size)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d]) SPICE model LUT (name=%s) has a unmatched tri-state map (%s) implied by mode_port size(%d)!\n", + __FILE__, __LINE__, + spice_model->name, input_port[iport]->tri_state_map[ipin], input_port[iport]->size); + exit(1); + } + + /* Create inverters between input port and its inversion */ + for (ipin = 0; ipin < input_port[iport]->size; ipin++) { + switch (input_port[iport]->tri_state_map[ipin]) { + case '-': + /* For negative input of LUT MUX*/ + /* Output inverter with maximum size allowed + * until the rest of width is smaller than threshold */ + total_width = spice_model->lut_input_buffer->size * spice_model->lut_input_buffer->f_per_stage; + width_cnt = 0; + while (total_width > max_width_per_trans) { + fprintf(fp, "Xinv0_in%d_no%d %s%d lut_mux_in%d_inv svdd sgnd inv size=\'%g\'", + ipin, width_cnt, + input_port[iport]->prefix, ipin, + ipin, max_width_per_trans); + fprintf(fp, "\n"); + /* Update */ + total_width = total_width - max_width_per_trans; + width_cnt++; + } + /* Print if we still have to */ + if (total_width > 0) { + fprintf(fp, "Xinv0_in%d_no%d %s%d lut_mux_in%d_inv svdd sgnd inv size=\'%g\'", + ipin, width_cnt, + input_port[iport]->prefix, ipin, + ipin, total_width); + fprintf(fp, "\n"); + } + /* For postive input of LUT MUX, we use the tapered_buffer subckt directly */ + assert(1 == spice_model->lut_input_buffer->tapered_buf); + fprintf(fp, "X%s_in%d %s%d lut_mux_in%d svdd sgnd tapbuf_level%d_f%d\n", + spice_model->lut_input_buffer->spice_model->prefix, ipin, + input_port[iport]->prefix, ipin, ipin, + spice_model->lut_input_buffer->tap_buf_level, + spice_model->lut_input_buffer->f_per_stage); + fprintf(fp, "\n"); + break; + case '0': + case '1': + /* For negative input of LUT MUX*/ + /* Output inverter with maximum size allowed + * until the rest of width is smaller than threshold */ + total_width = spice_model->lut_input_buffer->size * spice_model->lut_input_buffer->f_per_stage; + width_cnt = 0; + while (total_width > max_width_per_trans) { + fprintf(fp, "Xinv0_in%d_no%d %s%s%d lut_mux_in%d_inv svdd sgnd inv size=\'%g\'", + ipin, width_cnt, + input_port[iport]->prefix, mode_inport_postfix, ipin, + ipin, max_width_per_trans); + fprintf(fp, "\n"); + /* Update */ + total_width = total_width - max_width_per_trans; + width_cnt++; + } + /* Print if we still have to */ + if (total_width > 0) { + fprintf(fp, "Xinv0_in%d_no%d %s%s%d lut_mux_in%d_inv svdd sgnd inv size=\'%g\'", + ipin, width_cnt, + input_port[iport]->prefix, mode_inport_postfix, ipin, + ipin, total_width); + fprintf(fp, "\n"); + } + /* For postive input of LUT MUX, we use the tapered_buffer subckt directly */ + assert(1 == spice_model->lut_input_buffer->tapered_buf); + fprintf(fp, "X%s_in%d %s%s%d lut_mux_in%d svdd sgnd tapbuf_level%d_f%d\n", + spice_model->lut_input_buffer->spice_model->prefix, ipin, + input_port[iport]->prefix, mode_inport_postfix, ipin, ipin, + spice_model->lut_input_buffer->tap_buf_level, + spice_model->lut_input_buffer->f_per_stage); + fprintf(fp, "\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(file:%s,line[%d]) invalid LUT tri_state_map = %s ", + __FILE__, __LINE__, input_port[iport]->tri_state_map); + exit(1); + } + } + } + + + /* Output buffers already included in LUT MUX */ + /* LUT MUX*/ + assert(sram_port[sram_port_index]->size == (int)pow(2.,(double)(input_port[0]->size))); + fprintf(fp, "Xlut_mux "); + /* SRAM ports of LUT, they are inputs of lut_muxes*/ + for (ipin = 0; ipin < sram_port[sram_port_index]->size; ipin++) { + assert(FALSE == sram_port[sram_port_index]->mode_select); + fprintf(fp, "%s%d ", sram_port[sram_port_index]->prefix, ipin); + } + /* Output port, LUT output is LUT MUX output*/ + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + fprintf(fp, "%s%d ", output_port[iport]->prefix, ipin); + } + } + /* Connect MUX configuration port to LUT inputs */ + /* input port, LUT input is LUT MUX sram*/ + for (iport = 0; iport < num_input_port; iport++) { + for (ipin = 0; ipin < input_port[iport]->size; ipin++) { + fprintf(fp, "lut_mux_in%d lut_mux_in%d_inv ", ipin, ipin); + } + } + + /* Local vdd and gnd*/ + fprintf(fp, "svdd sgnd %s_mux_size%d\n", + spice_model->name, sram_port[sram_port_index]->size); + + /* End of LUT subckt*/ + fprintf(fp, ".eom\n"); + + /* Free */ + my_free(input_port); + my_free(output_port); + my_free(sram_port); + + return; +} + +/* Print LUT subckts into a SPICE file*/ +void generate_spice_luts(char* subckt_dir, + int num_spice_model, + t_spice_model* spice_models) { + FILE* fp = NULL; + char* sp_name = my_strcat(subckt_dir, luts_spice_file_name); + int imodel = 0; + + /* Create FILE*/ + fp = fopen(sp_name, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create SPICE netlist %s",__FILE__, __LINE__, wires_spice_file_name); + exit(1); + } + fprint_spice_head(fp,"LUTs"); + + for (imodel = 0; imodel < num_spice_model; imodel++) { + if ((SPICE_MODEL_LUT == spice_models[imodel].type) + &&(NULL == spice_models[imodel].model_netlist)) { + fprint_spice_lut_subckt(fp, &(spice_models[imodel])); + } + } + + /* Close*/ + fclose(fp); + + return; +} + +void fprint_pb_primitive_lut(FILE* fp, + char* subckt_prefix, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + int index, + t_spice_model* spice_model) { + int i, j; + int* lut_sram_bits = NULL; /* decoded SRAM bits */ + int* mode_sram_bits = NULL; /* decoded SRAM bits */ + int* sram_bits = NULL; /* decoded SRAM bits */ + int* truth_table_length = 0; + char*** truth_table = NULL; + + int lut_size = 0; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_output_port = 0; + t_spice_model_port** output_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + t_spice_model_port* lut_sram_port = NULL; + t_spice_model_port* mode_bit_port = NULL; + int num_lut_pin_nets; + int* lut_pin_net = NULL; + int mapped_logical_block_index; + + char* formatted_subckt_prefix = format_spice_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ + t_pb_type* cur_pb_type = prim_pb_type; + char* port_prefix = NULL; + + int cur_num_sram = 0; + int num_sram = 0; + int num_lut_sram = 0; + int num_mode_sram = 0; + int expected_num_sram = 0; + char* sram_vdd_port_name = NULL; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Asserts */ + assert(SPICE_MODEL_LUT == spice_model->type); + + /* Determine size of LUT*/ + input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + sram_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + assert(1 == num_input_port); + lut_size = input_ports[0]->size; + num_sram = (int)pow(2.,(double)(lut_size)); + /* Find SRAM ports for truth tables and mode bits */ + sram_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + assert((1 == num_sram_port) || (2 == num_sram_port)); + for (i = 0; i < num_sram_port; i++) { + if (FALSE == sram_ports[i]->mode_select) { + lut_sram_port = sram_ports[i]; + num_lut_sram = sram_ports[i]->size; + assert (num_lut_sram == (int)pow(2.,(double)(lut_size))); + } else { + assert (TRUE == sram_ports[i]->mode_select); + mode_bit_port = sram_ports[i]; + num_mode_sram = sram_ports[i]->size; + } + } + /* Must have a lut_sram_port, while mode_bit_port is optional */ + assert (NULL != lut_sram_port); + + /* Count the number of configuration bits */ + num_sram = count_num_sram_bits_one_spice_model(spice_model, -1); + + /* Get current counter of mem_bits, bl and wl */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); + + /* If this is an idle LUT, we give an empty truth table */ + if ((NULL == prim_phy_pb) + || ((NULL != prim_phy_pb && (0 == prim_phy_pb->num_logical_blocks)))) { + lut_sram_bits = (int*) my_calloc ( num_lut_sram, sizeof(int)); + for (i = 0; i < num_lut_sram; i++) { + lut_sram_bits[i] = lut_sram_port->default_val; + } + } else { + assert (NULL != prim_phy_pb); + /* Allocate truth tables */ + truth_table_length = (int*) my_malloc (sizeof(int) * prim_phy_pb->num_logical_blocks); + truth_table = (char***) my_malloc (sizeof(char**) * prim_phy_pb->num_logical_blocks); + + /* Output log for debugging purpose */ + fprintf(fp, "***** Logic Block %s *****\n", + prim_phy_pb->spice_name_tag); + + /* Find truth tables and decode them one by one + * Fracturable LUT may have multiple truth tables, + * which should be grouped in a unique one + */ + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + mapped_logical_block_index = prim_phy_pb->logical_block[i]; + /* For wired LUT we provide a default truth table */ + if (TRUE == prim_phy_pb->is_wired_lut[i]) { + /* TODO: assign post-routing lut truth table!!!*/ + get_mapped_lut_phy_pb_input_pin_vpack_net_num(prim_phy_pb, &num_lut_pin_nets, &lut_pin_net); + truth_table[i] = assign_post_routing_wired_lut_truth_table(prim_phy_pb->rr_graph->rr_node[prim_phy_pb->lut_output_pb_graph_pin[i]->rr_node_index_physical_pb].vpack_net_num, + num_lut_pin_nets, lut_pin_net, &truth_table_length[i]); + } else { + assert (FALSE == prim_phy_pb->is_wired_lut[i]); + assert (VPACK_COMB == logical_block[mapped_logical_block_index].type); + /* Get the mapped vpack_net_num of this physical LUT pb */ + get_mapped_lut_phy_pb_input_pin_vpack_net_num(prim_phy_pb, &num_lut_pin_nets, &lut_pin_net); + /* consider LUT pin remapping when assign lut truth tables */ + /* Match truth table and post-routing results */ + truth_table[i] = assign_post_routing_lut_truth_table(&logical_block[mapped_logical_block_index], + num_lut_pin_nets, lut_pin_net, &truth_table_length[i]); + } + /* Adapt truth table for a fracturable LUT + * TODO: Determine fixed input bits for this truth table: + * 1. input bits within frac_level (all '-' if not specified) + * 2. input bits outside frac_level, decoded to its output mask (0 -> first part -> all '1') + */ + adapt_truth_table_for_frac_lut(prim_phy_pb->lut_output_pb_graph_pin[i], + truth_table_length[i], truth_table[i]); + /* Output log for debugging purpose */ + if (WIRED_LUT_LOGICAL_BLOCK_ID == mapped_logical_block_index) { + fprintf(fp, "***** Wired LUT: mapped to a buffer *****\n"); + } else { + fprintf(fp, "***** Mapped Logic Block[%d] %s *****\n", + i, logical_block[mapped_logical_block_index].name); + } + fprintf(fp, "***** Net map *****\n*"); + for (j = 0; j < num_lut_pin_nets; j++) { + if (OPEN == lut_pin_net[j]) { + fprintf(fp, " OPEN, "); + } else { + assert (OPEN != lut_pin_net[j]); + fprintf(fp, " %s, ", vpack_net[lut_pin_net[j]].name); + } + } + fprintf(fp, "\n"); + fprintf(fp, "***** Truth Table *****\n"); + for (j = 0; j < truth_table_length[i]; j++) { + fprintf(fp, "*%s\n", truth_table[i][j]); + } + } + /* Generate base sram bits*/ + lut_sram_bits = generate_frac_lut_sram_bits(prim_phy_pb, truth_table_length, truth_table, lut_sram_port->default_val); + } + + /* Add mode bits */ + if (NULL != mode_bit_port) { + if (NULL != prim_phy_pb) { + mode_sram_bits = decode_mode_bits(prim_phy_pb->mode_bits, &expected_num_sram); + } else { /* get default mode_bits */ + mode_sram_bits = decode_mode_bits(prim_pb_type->mode_bits, &expected_num_sram); + } + assert(expected_num_sram == num_mode_sram); + } + + /* Merge the SRAM bits from LUT SRAMs and Mode selection */ + assert ( num_sram == num_lut_sram + num_mode_sram ); + sram_bits = (int*)my_calloc(num_sram, sizeof(int)); + /* LUT SRAMs go first and then mode bits */ + memcpy(sram_bits, lut_sram_bits, num_lut_sram * sizeof(int)); + if (NULL != mode_bit_port) { + memcpy(sram_bits + num_lut_sram, mode_sram_bits, num_mode_sram * sizeof(int)); + } + + /* Subckt definition*/ + fprintf(fp, ".subckt %s%s[%d] ", formatted_subckt_prefix, cur_pb_type->name, index); + /* Print inputs, outputs, inouts, clocks, NO SRAMs*/ + /* + port_prefix = (char*)my_malloc(sizeof(char)* + (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 + + strlen(my_itoa(index)) + 1 + 1)); + sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, cur_pb_type->name, index); + */ + /* Simplify the prefix, make the SPICE netlist readable*/ + port_prefix = (char*)my_malloc(sizeof(char)* + (strlen(cur_pb_type->name) + 1 + + strlen(my_itoa(index)) + 1 + 1)); + sprintf(port_prefix, "%s[%d]", cur_pb_type->name, index); + + /* Only dump the global ports belonging to a spice_model + * Do not go recursive, we can freely define global ports anywhere in SPICE netlist + */ + rec_fprint_spice_model_global_ports(fp, spice_model, FALSE); + + fprint_pb_type_ports(fp, port_prefix, 0, cur_pb_type); + /* SRAM bits are fixed in this subckt, no need to define them here*/ + /* Local Vdd and gnd*/ + fprintf(fp, "svdd sgnd\n"); + /* Definition ends*/ + + /* Call SRAM subckts*/ + /* Give the VDD port name for SRAMs */ + sram_vdd_port_name = (char*)my_malloc(sizeof(char)* + (strlen(spice_tb_global_vdd_lut_sram_port_name) + + 1 )); + sprintf(sram_vdd_port_name, "%s", + spice_tb_global_vdd_lut_sram_port_name); + /* Now Print SRAMs one by one */ + for (i = 0; i < num_sram; i++) { + fprint_spice_one_sram_subckt(fp, sram_spice_orgz_info, spice_model, sram_vdd_port_name); + } + + /* Call LUT subckt*/ + fprintf(fp, "X%s[%d] ", spice_model->prefix, spice_model->cnt); + /* Connect inputs*/ + /* Connect outputs*/ + fprint_pb_type_ports(fp, port_prefix, 0, cur_pb_type); + /* Connect srams*/ + for (i = 0; i < num_sram; i++) { + assert( (0 == sram_bits[i]) || (1 == sram_bits[i]) ); + fprint_spice_sram_one_outport(fp, sram_spice_orgz_info, cur_num_sram + i, sram_bits[i]); + } + + /* vdd should be connected to special global wire gvdd_lut and gnd, + * Every LUT has a special VDD for statistics + */ + fprintf(fp, "gvdd_%s[%d] sgnd %s\n", spice_model->prefix, spice_model->cnt, spice_model->name); + /* TODO: Add a nodeset for convergence */ + + /* End of subckt*/ + fprintf(fp, ".eom\n"); + + /* Store the configuraion bit to linked-list */ + add_sram_conf_bits_to_llist(sram_spice_orgz_info, cur_num_sram, + num_sram, sram_bits); + + spice_model->cnt++; + + /*Free*/ + my_free(formatted_subckt_prefix); + my_free(input_ports); + my_free(output_ports); + my_free(sram_ports); + my_free(sram_bits); + my_free(port_prefix); + my_free(sram_vdd_port_name); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.h new file mode 100644 index 000000000..ff8636184 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_lut.h @@ -0,0 +1,17 @@ + + + +void fprint_spice_lut_subckt(FILE* fp, + t_spice_model* spice_model); + +void generate_spice_luts(char* subckt_dir, + int num_spice_model, + t_spice_model* spice_models); + + +void fprint_pb_primitive_lut(FILE* fp, + char* subckt_prefix, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + int index, + t_spice_model* spice_model); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.c similarity index 82% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.c index daac233b4..ef6acef6a 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.c @@ -19,12 +19,18 @@ #include "rr_graph.h" #include "rr_graph_swseg.h" #include "vpr_utils.h" +#include "route_common.h" + +/* Include fpga_spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_bitstream_utils.h" /* Include spice support headers*/ -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" #include "spice_utils.h" #include "spice_lut.h" #include "spice_pbtypes.h" @@ -149,10 +155,10 @@ void fprint_spice_mux_model_basis_rram_subckt(FILE* fp, char* subckt_name, } /* assert(SPICE_MODEL_PASS_GATE_TRANSMISSION == spice_model.pass_gate_logic->type); */ - assert(0. < spice_model.design_tech_info.wprog_set_pmos); - assert(0. < spice_model.design_tech_info.wprog_reset_pmos); - assert(0. < spice_model.design_tech_info.wprog_set_nmos); - assert(0. < spice_model.design_tech_info.wprog_reset_nmos); + assert(0. < spice_model.design_tech_info.rram_info->wprog_set_pmos); + assert(0. < spice_model.design_tech_info.rram_info->wprog_reset_pmos); + assert(0. < spice_model.design_tech_info.rram_info->wprog_set_nmos); + assert(0. < spice_model.design_tech_info.rram_info->wprog_reset_nmos); /* Ensure we have a CMOS MUX*/ /* Exception: LUT require an auto-generation of netlist can run as well*/ @@ -171,7 +177,7 @@ void fprint_spice_mux_model_basis_rram_subckt(FILE* fp, char* subckt_name, * Advanced design employ normal logic transistors * Basic design employ IO transistors */ - if (TRUE == spice_model.design_tech_info.advanced_rram_design) { + if (TRUE == spice_model.design_tech_info.mux_info->advanced_rram_design) { prog_pmos_subckt_name = pmos_subckt_name; prog_nmos_subckt_name = nmos_subckt_name; prog_wp = "wp"; @@ -361,12 +367,30 @@ void fprint_spice_cmos_mux_tree_structure(FILE* fp, char* mux_basis_subckt_name, int nextj, out_idx; int mux_basis_cnt = 0; + boolean* inter_buf_loc = NULL; + /* Make sure we have a valid file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); exit(1); } + /* Intermediate buffer location map */ + inter_buf_loc = (boolean*)my_calloc(spice_mux_arch.num_level + 1, sizeof(boolean)); + for (i = 0; i < spice_mux_arch.num_level + 1; i++) { + inter_buf_loc[i] = FALSE; + } + printf("location_map: %s", spice_model.lut_intermediate_buffer->location_map); + if (NULL != spice_model.lut_intermediate_buffer->location_map) { + assert (spice_mux_arch.num_level - 1 == strlen(spice_model.lut_intermediate_buffer->location_map)); + /* For intermediate buffers */ + for (i = 0; i < spice_mux_arch.num_level - 1; i++) { + if ('1' == spice_model.lut_intermediate_buffer->location_map[i]) { + inter_buf_loc[spice_mux_arch.num_level - i - 1] = TRUE; + } + } + } + mux_basis_cnt = 0; for (i = 0; i < spice_mux_arch.num_level; i++) { level = spice_mux_arch.num_level - i; @@ -379,11 +403,25 @@ void fprint_spice_cmos_mux_tree_structure(FILE* fp, char* mux_basis_subckt_name, out_idx = j/2; /* Each basis mux2to1: svdd sgnd */ fprintf(fp, "Xmux_basis_no%d ", mux_basis_cnt); /* given_name */ - fprintf(fp, "mux2_l%d_in%d mux2_l%d_in%d ", level, j, level, nextj); /* input0 input1 */ + /* For intermediate buffers */ + if (TRUE == inter_buf_loc[level]) { + fprintf(fp, "mux2_l%d_in%d_buf mux2_l%d_in%d_buf ", level, j, level, nextj); /* input0 input1 */ + } else { + fprintf(fp, "mux2_l%d_in%d mux2_l%d_in%d ", level, j, level, nextj); /* input0 input1 */ + } fprintf(fp, "mux2_l%d_in%d ", nextlevel, out_idx); /* output */ /* fprintf(fp, "%s%d %s_inv%d ", sram_port[0]->prefix, nextlevel, sram_port[0]->prefix, nextlevel);*/ /* sram sram_inv */ fprintf(fp, "%s%d %s_inv%d ", sram_port[0]->prefix, i, sram_port[0]->prefix, i); /* sram sram_inv */ fprintf(fp, "svdd sgnd %s\n", mux_basis_subckt_name); /* subckt_name */ + /* For intermediate buffers */ + if (TRUE == inter_buf_loc[nextlevel]) { + fprintf(fp, "X%s_%d_%d ", + spice_model.lut_intermediate_buffer->spice_model->name, + nextlevel, out_idx); /* Given name*/ + fprintf(fp, "mux2_l%d_in%d ", nextlevel, out_idx); /* output */ + fprintf(fp, "mux2_l%d_in%d_buf ", nextlevel, out_idx); /* input0 input1 */ + fprintf(fp, "svdd sgnd %s\n", spice_model.lut_intermediate_buffer->spice_model->name); /* subckt_name */ + } /* Update the counter */ j = nextj; mux_basis_cnt++; @@ -394,6 +432,9 @@ void fprint_spice_cmos_mux_tree_structure(FILE* fp, char* mux_basis_subckt_name, assert(0 == out_idx); assert(mux_basis_cnt == spice_mux_arch.num_input - 1); + /* Free */ + my_free(inter_buf_loc); + return; } @@ -482,7 +523,6 @@ void fprint_spice_cmos_mux_onelevel_structure(FILE* fp, char* mux_basis_subckt_n int num_sram_port, t_spice_model_port** sram_port) { int k, mux_basis_cnt; int level, nextlevel, out_idx; - int num_sram_bits = 0; /* Make sure we have a valid file handler*/ if (NULL == fp) { @@ -505,9 +545,7 @@ void fprint_spice_cmos_mux_onelevel_structure(FILE* fp, char* mux_basis_subckt_n } fprintf(fp, "mux2_l%d_in%d ", nextlevel, out_idx); /* output */ /* Print number of sram bits for this basis */ - num_sram_bits = count_num_sram_bits_one_spice_model(&spice_model, - spice_mux_arch.num_input); - for (k = 0; k < num_sram_bits; k++) { + for (k = 0; k < spice_mux_arch.num_input; k++) { fprintf(fp, "%s%d %s_inv%d ", sram_port[0]->prefix, k, sram_port[0]->prefix, k); /* sram sram_inv */ } fprintf(fp, "svdd sgnd %s\n", mux_basis_subckt_name); /* subckt_name */ @@ -692,14 +730,15 @@ void fprint_spice_mux_model_cmos_subckt(FILE* fp, int mux_size, t_spice_model spice_model, t_spice_mux_arch spice_mux_arch) { - int i; + int iport, ipin; int num_input_port = 0; int num_output_port = 0; int num_sram_port = 0; t_spice_model_port** input_port = NULL; t_spice_model_port** output_port = NULL; t_spice_model_port** sram_port = NULL; - int num_sram_bits = 0; + int num_mode_bits = 0; + int num_conf_bits = 0; enum e_spice_model_structure cur_mux_structure; @@ -738,65 +777,97 @@ void fprint_spice_mux_model_cmos_subckt(FILE* fp, sram_port = find_spice_model_ports(&spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); /* Asserts*/ - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - assert(1 == output_port[0]->size); + if ((SPICE_MODEL_MUX == spice_model.type) + || ((SPICE_MODEL_LUT == spice_model.type) + && (FALSE == spice_model.design_tech_info.lut_info->frac_lut))) { + assert(1 == num_input_port); + assert(1 == num_output_port); + assert(1 == num_sram_port); + assert(1 == output_port[0]->size); + } else { + assert((SPICE_MODEL_LUT == spice_model.type) + && (TRUE == spice_model.design_tech_info.lut_info->frac_lut)); + assert(1 == num_input_port); + assert(2 == num_sram_port); + for (iport = 0; iport < num_output_port; iport++) { + assert(0 < output_port[iport]->size); + } + } + + /* Setup a reasonable frac_out level for the output port*/ + for (iport = 0; iport < num_output_port; iport++) { + /* We always initialize the lut_frac_level when there is only 1 output! + * It should be pointed the last level! + */ + if ((OPEN == output_port[iport]->lut_frac_level) + || (1 == num_output_port)) { + output_port[iport]->lut_frac_level = spice_mux_arch.num_level; + } + } + + /* Add Fracturable LUT outputs */ /* We have two types of naming rules in terms of the usage of MUXes: * 1. MUXes, the naming rule is __size * 2. LUTs, the naming rule is _mux_size */ - num_sram_bits = count_num_sram_bits_one_spice_model(&spice_model, - /* sram_verilog_orgz_info->type, */ + num_conf_bits = count_num_sram_bits_one_spice_model(&spice_model, mux_size); + num_mode_bits = count_num_mode_bits_one_spice_model(&spice_model); + /* Knock out the SRAM bits for the mode selection, they are separated dealed */ + num_conf_bits = num_conf_bits - num_mode_bits; if (SPICE_MODEL_LUT == spice_model.type) { /* Special for LUT MUX*/ - fprintf(fp, "***** CMOS MUX info: spice_model_name= %s_MUX, size=%d *****\n", spice_model.name, mux_size); + fprintf(fp, "***** CMOS MUX info: spice_model_name= %s_MUX, size=%d *****\n", + spice_model.name, mux_size); fprintf(fp, ".subckt %s_mux_size%d ", spice_model.name, mux_size); /* Global ports */ if (0 < rec_fprint_spice_model_global_ports(fp, &spice_model, FALSE)) { fprintf(fp, "+ "); } /* Print input ports*/ - assert(mux_size == num_sram_bits); - for (i = 0; i < num_sram_bits; i++) { - fprintf(fp, "%s%d ", input_port[0]->prefix, i); + assert(mux_size == num_conf_bits); + for (ipin = 0; ipin < num_conf_bits; ipin++) { + fprintf(fp, "%s%d ", input_port[0]->prefix, ipin); } /* Print output ports*/ - fprintf(fp, "%s ", output_port[0]->prefix); + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + fprintf(fp, "%s%d ", output_port[iport]->prefix, ipin); + } + } /* Print sram ports*/ - for (i = 0; i < input_port[0]->size; i++) { - fprintf(fp, "%s%d ", sram_port[0]->prefix, i); - fprintf(fp, "%s_inv%d ", sram_port[0]->prefix, i); + for (ipin = 0; ipin < input_port[0]->size; ipin++) { + fprintf(fp, "%s%d ", sram_port[0]->prefix, ipin); + fprintf(fp, "%s_inv%d ", sram_port[0]->prefix, ipin); } } else { fprintf(fp, "***** CMOS MUX info: spice_model_name=%s, size=%d, structure: %s *****\n", - spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.structure)); + spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.mux_info->structure)); fprintf(fp, ".subckt %s_size%d ", spice_model.name, mux_size); /* Global ports */ if (0 < rec_fprint_spice_model_global_ports(fp, &spice_model, FALSE)) { fprintf(fp, "+ "); } /* Print input ports*/ - for (i = 0; i < mux_size; i++) { - fprintf(fp, "%s%d ", input_port[0]->prefix, i); + for (ipin = 0; ipin < mux_size; ipin++) { + fprintf(fp, "%s%d ", input_port[0]->prefix, ipin); } /* Print output ports*/ fprintf(fp, "%s ", output_port[0]->prefix); /* Print sram ports*/ - for (i = 0; i < num_sram_bits; i++) { - fprintf(fp, "%s%d ", sram_port[0]->prefix, i); - fprintf(fp, "%s_inv%d ", sram_port[0]->prefix, i); + for (ipin = 0; ipin < num_conf_bits; ipin++) { + fprintf(fp, "%s%d ", sram_port[0]->prefix, ipin); + fprintf(fp, "%s_inv%d ", sram_port[0]->prefix, ipin); } } /* Print local vdd and gnd*/ fprintf(fp, "svdd sgnd"); fprintf(fp, "\n"); - /* Handle the corner case: input size = 2 */ - cur_mux_structure = spice_model.design_tech_info.structure; + /* Handle the corner case: input size = 2 */ + cur_mux_structure = spice_model.design_tech_info.mux_info->structure; if (2 == spice_mux_arch.num_input) { cur_mux_structure = SPICE_MODEL_STRUCTURE_ONELEVEL; } @@ -822,23 +893,31 @@ void fprint_spice_mux_model_cmos_subckt(FILE* fp, } /* To connect the input ports*/ - for (i = 0; i < mux_size; i++) { + for (ipin = 0; ipin < mux_size; ipin++) { if (1 == spice_model.input_buffer->exist) { switch (spice_model.input_buffer->type) { case SPICE_MODEL_BUF_INV: /* Each inv: svdd sgnd size=param*/ - fprintf(fp, "Xinv%d ", i); /* Given name*/ - fprintf(fp, "%s%d ", input_port[0]->prefix, i); /* input port */ - fprintf(fp, "mux2_l%d_in%d ", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ + fprintf(fp, "Xinv%d ", ipin); /* Given name*/ + /* Global ports */ + if (0 < rec_fprint_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE)) { + fprintf(fp, "+ "); + } + fprintf(fp, "%s%d ", input_port[0]->prefix, ipin); /* input port */ + fprintf(fp, "mux2_l%d_in%d ", spice_mux_arch.input_level[ipin], spice_mux_arch.input_offset[ipin]); /* output port*/ fprintf(fp, "svdd sgnd inv size=\'%s%s\'", spice_model.name, design_param_postfix_input_buf_size); /* subckt name */ fprintf(fp, "\n"); break; case SPICE_MODEL_BUF_BUF: /* TODO: what about tapered buffer, can we support? */ /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "Xbuf%d ", i); /* Given name*/ - fprintf(fp, "%s%d ", input_port[0]->prefix, i); /* input port */ - fprintf(fp, "mux2_l%d_in%d ", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ + fprintf(fp, "Xbuf%d ", ipin); /* Given name*/ + /* Global ports */ + if (0 < rec_fprint_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE)) { + fprintf(fp, "+ "); + } + fprintf(fp, "%s%d ", input_port[0]->prefix, ipin); /* input port */ + fprintf(fp, "mux2_l%d_in%d ", spice_mux_arch.input_level[ipin], spice_mux_arch.input_offset[ipin]); /* output port*/ fprintf(fp, "svdd sgnd buf size=\'%s%s\'", spice_model.name, design_param_postfix_input_buf_size); /* subckt name */ fprintf(fp, "\n"); break; @@ -851,55 +930,96 @@ void fprint_spice_mux_model_cmos_subckt(FILE* fp, /* There is no buffer, I create a zero resisitance between*/ /* Resistance R 0*/ fprintf(fp, "Rin%d %s%d mux2_l%d_in%d 0\n", - i, input_port[0]->prefix, i, spice_mux_arch.input_level[i], - spice_mux_arch.input_offset[i]); + ipin, input_port[0]->prefix, ipin, spice_mux_arch.input_level[ipin], + spice_mux_arch.input_offset[ipin]); } } + /* Special: for the last inputs, we connect to VDD|GND + * TODO: create an option to select the connection VDD or GND + */ + if ((SPICE_MODEL_MUX == spice_model.type) + && (TRUE == spice_model.design_tech_info.mux_info->add_const_input)) { + assert ( (0 == spice_model.design_tech_info.mux_info->const_input_val) + || (1 == spice_model.design_tech_info.mux_info->const_input_val) ); + fprintf(fp, "Rin%d mux2_l%d_in%d %s 0\n", + spice_mux_arch.num_input - 1, + spice_mux_arch.input_level[spice_mux_arch.num_input - 1], + spice_mux_arch.input_offset[spice_mux_arch.num_input - 1], + convert_const_input_value_to_str(spice_model.design_tech_info.mux_info->const_input_val)); + } /* Output buffer*/ - if (1 == spice_model.output_buffer->exist) { - switch (spice_model.output_buffer->type) { - case SPICE_MODEL_BUF_INV: - if (TRUE == spice_model.output_buffer->tapered_buf) { - break; + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + if (1 == spice_model.output_buffer->exist) { + /* Tapered buffer support */ + if (TRUE == spice_model.output_buffer->tapered_buf) { + /* Each buf: svdd sgnd size=param*/ + fprintf(fp, "Xbuf_out_%d_%d ", + iport, ipin); /* Given name*/ + /* Global ports */ + if (0 < rec_fprint_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE)) { + fprintf(fp, "+ "); + } + fprintf(fp, "mux2_l%d_in%d ", + spice_mux_arch.num_level - output_port[iport]->lut_frac_level, + output_port[iport]->lut_output_mask[ipin]); /* input port */ + fprintf(fp, "%s%d ", output_port[iport]->prefix, ipin); /* Output port*/ + fprintf(fp, "svdd sgnd tapbuf_level%d_f%d", + spice_model.output_buffer->tap_buf_level, spice_model.output_buffer->f_per_stage); /* subckt name */ + fprintf(fp, "\n"); + continue; + } + switch (spice_model.output_buffer->type) { + case SPICE_MODEL_BUF_INV: + if (TRUE == spice_model.output_buffer->tapered_buf) { + break; + } + /* Each inv: svdd sgnd size=param*/ + fprintf(fp, "Xinv_out_%d_%d ", iport, ipin); /* Given name*/ + /* Global ports */ + if (0 < rec_fprint_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE)) { + fprintf(fp, "+ "); + } + fprintf(fp, "mux2_l%d_in%d ", + spice_mux_arch.num_level - output_port[iport]->lut_frac_level, + output_port[iport]->lut_output_mask[ipin]); /* input port */ + fprintf(fp, "%s%d ", + output_port[iport]->prefix, ipin); /* Output port*/ + fprintf(fp, "svdd sgnd inv size=\'%s%s\'", spice_model.name, design_param_postfix_output_buf_size); /* subckt name */ + fprintf(fp, "\n"); + break; + case SPICE_MODEL_BUF_BUF: + if (TRUE == spice_model.output_buffer->tapered_buf) { + break; + } + /* Each buf: svdd sgnd size=param*/ + fprintf(fp, "Xbuf_out_%d_%d ", iport, ipin); /* Given name*/ + /* Global ports */ + if (0 < rec_fprint_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE)) { + fprintf(fp, "+ "); + } + fprintf(fp, "mux2_l%d_in%d ", + spice_mux_arch.num_level - output_port[iport]->lut_frac_level, + output_port[iport]->lut_output_mask[ipin]); /* input port */ + fprintf(fp, "%s%d ", output_port[iport]->prefix, ipin); /* Output port*/ + fprintf(fp, "svdd sgnd buf size=\'%s%s\'", spice_model.name, design_param_postfix_output_buf_size); /* subckt name */ + fprintf(fp, "\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type for spice_model_buffer.\n", + __FILE__, __LINE__); + exit(1); + } + } else { + /* There is no buffer, I create a zero resisitance between*/ + /* Resistance R 0*/ + fprintf(fp, "Rout mux2_l%d_in%d %s%d 0\n", + spice_mux_arch.num_level - output_port[iport]->lut_frac_level, + output_port[iport]->lut_output_mask[ipin], + output_port[0]->prefix, ipin); } - /* Each inv: svdd sgnd size=param*/ - fprintf(fp, "Xinv_out "); /* Given name*/ - fprintf(fp, "mux2_l%d_in%d ", 0, 0); /* input port */ - fprintf(fp, "%s ", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "svdd sgnd inv size=\'%s%s\'", spice_model.name, design_param_postfix_output_buf_size); /* subckt name */ - fprintf(fp, "\n"); - break; - case SPICE_MODEL_BUF_BUF: - if (TRUE == spice_model.output_buffer->tapered_buf) { - break; - } - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "Xbuf_out "); /* Given name*/ - fprintf(fp, "mux2_l%d_in%d ", 0, 0); /* input port */ - fprintf(fp, "%s ", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "svdd sgnd buf size=\'%s%s\'", spice_model.name, design_param_postfix_output_buf_size); /* subckt name */ - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type for spice_model_buffer.\n", - __FILE__, __LINE__); - exit(1); } - /* Tapered buffer support */ - if (TRUE == spice_model.output_buffer->tapered_buf) { - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "Xbuf_out "); /* Given name*/ - fprintf(fp, "mux2_l%d_in%d ", 0, 0); /* input port */ - fprintf(fp, "%s ", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "svdd sgnd tapbuf_level%d_f%d", - spice_model.output_buffer->tap_buf_level, spice_model.output_buffer->f_per_stage); /* subckt name */ - fprintf(fp, "\n"); - } - } else { - /* There is no buffer, I create a zero resisitance between*/ - /* Resistance R 0*/ - fprintf(fp, "Rout mux2_l0_in0 %s 0\n",output_port[0]->prefix); } fprintf(fp, ".eom\n"); @@ -995,7 +1115,7 @@ void fprint_spice_mux_model_rram_subckt(FILE* fp, */ } else { fprintf(fp, "***** RRAM MUX info: spice_model_name=%s, size=%d, structure: %s *****\n", - spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.structure)); + spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.mux_info->structure)); fprintf(fp, ".subckt %s_size%d ", spice_model.name, mux_size); } @@ -1027,7 +1147,7 @@ void fprint_spice_mux_model_rram_subckt(FILE* fp, if (2 == mux_size) { cur_mux_structure = SPICE_MODEL_STRUCTURE_ONELEVEL; } else { - cur_mux_structure = spice_model.design_tech_info.structure; + cur_mux_structure = spice_model.design_tech_info.mux_info->structure; } /* RRAM MUX is optimal in terms of area, delay and power for one-level structure. * Hence, we do not support the multi-level or tree-like RRAM MUX. @@ -1187,11 +1307,13 @@ void fprint_spice_mux_model_subckt(FILE* fp, switch (spice_mux_model->spice_model->design_tech) { case SPICE_MODEL_DESIGN_CMOS: fprint_spice_mux_model_cmos_subckt(fp, spice_mux_model->size, - *(spice_mux_model->spice_model), *(spice_mux_model->spice_mux_arch)); + *(spice_mux_model->spice_model), + *(spice_mux_model->spice_mux_arch)); break; case SPICE_MODEL_DESIGN_RRAM: fprint_spice_mux_model_rram_subckt(fp, spice_mux_model->size, - *(spice_mux_model->spice_model), *(spice_mux_model->spice_mux_arch)); + *(spice_mux_model->spice_model), + *(spice_mux_model->spice_mux_arch)); break; default: vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", @@ -1256,11 +1378,12 @@ void generate_spice_muxes(char* subckt_dir, } /* Check the SRAM port size */ num_input_basis = determine_num_input_basis_multilevel_mux(cur_spice_mux_model->size, - cur_spice_mux_model->spice_model->design_tech_info.mux_num_level); - if ((num_input_basis * cur_spice_mux_model->spice_model->design_tech_info.mux_num_level) != sram_ports[0]->size) { + cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level); + if ((num_input_basis * cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level) != sram_ports[0]->size) { vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])User-defined MUX SPICE MODEL(%s) SRAM size(%d) unmatch with the num of level(%d)!\n", - __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, sram_ports[0]->size, cur_spice_mux_model->spice_model->design_tech_info.mux_num_level*num_input_basis); + __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, sram_ports[0]->size, + cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level * num_input_basis); exit(1); } /* Move on to the next*/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.h new file mode 100644 index 000000000..1a4a431b3 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux.h @@ -0,0 +1,10 @@ + + + +void generate_spice_muxes(char* subckt_dir, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch); + + diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c similarity index 83% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux_testbench.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c index 6240af6ec..88333dbd5 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux_testbench.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.c @@ -20,13 +20,17 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" #include "spice_utils.h" #include "spice_routing.h" #include "spice_subckt.h" @@ -233,43 +237,17 @@ void fprint_spice_mux_testbench_one_mux(FILE* fp, * we should have a global SRAM vdd, AND it should be connected to a real sram subckt !!! */ /* Configuration bits for MUX*/ - assert((-1 != path_id)&&(path_id < mux_size)); - - /* 1. Get the mux level*/ - switch (mux_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - mux_level = determine_tree_mux_level(mux_size); - num_mux_sram_bits = mux_level; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, mux_level, path_id); + switch (mux_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(mux_spice_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - mux_level = 1; - /* Special for 2-input MUX */ - if (2 == mux_size) { - num_mux_sram_bits = 1; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, mux_level, path_id); - } else { - num_mux_sram_bits = mux_size; - mux_sram_bits = decode_onelevel_mux_sram_bits(mux_size, mux_level, path_id); - } - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - /* Special for 2-input MUX */ - if (2 == mux_size) { - mux_level = 1; - num_mux_sram_bits = 1; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, 1, path_id); - } else { - mux_level = mux_spice_model->design_tech_info.mux_num_level; - num_mux_sram_bits = determine_num_input_basis_multilevel_mux(mux_size, mux_level) * mux_level; - mux_sram_bits = decode_multilevel_mux_sram_bits(mux_size, mux_level, path_id); - } + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(mux_spice_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for spice model (%s)!\n", __FILE__, __LINE__, mux_spice_model->name); - exit(1); - } + } /* Print SRAMs that configure this MUX */ /* Get current counter of mem_bits, bl and wl */ @@ -566,7 +544,7 @@ void fprint_spice_mux_testbench_pb_graph_node_pin_mux(FILE* fp, static void fprint_spice_mux_testbench_pb_pin_mux(FILE* fp, t_rr_node* pb_rr_graph, - t_pb* des_pb, + t_phy_pb* des_pb, t_mode* cur_mode, t_pb_graph_pin* des_pb_graph_pin, t_interconnect* cur_interc, @@ -663,7 +641,7 @@ void fprint_spice_mux_testbench_pb_pin_mux(FILE* fp, static void fprint_spice_mux_testbench_pb_graph_node_pin_interc(FILE* fp, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, int select_path_id, @@ -755,8 +733,8 @@ void fprint_spice_mux_testbench_pb_graph_node_pin_interc(FILE* fp, static void fprint_spice_mux_testbench_pb_pin_interc(FILE* fp, t_rr_node* pb_rr_graph, - t_pb* des_pb, - enum e_pin2pin_interc_type pin2pin_interc_type, + t_phy_pb* des_pb, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, int select_path_id, @@ -845,161 +823,176 @@ void fprint_spice_mux_testbench_pb_pin_interc(FILE* fp, return; } -/* For each pb, we search the input pins and output pins for local interconnections */ +/* Print the SPICE interconnections of a port defined in pb_graph */ static -void fprint_spice_mux_testbench_pb_graph_node_interc(FILE* fp, - t_pb_graph_node* cur_pb_graph_node, - int grid_x, int grid_y, - t_ivec*** LL_rr_node_indices) { +void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb, + enum e_spice_pb_port_type pb_port_type, + t_mode* cur_mode, + int is_idle, + int grid_x, int grid_y, + t_ivec*** LL_rr_node_indices) { int iport, ipin; - int ipb, jpb; - t_pb_type* cur_pb_type = NULL; - t_mode* cur_mode = NULL; - t_pb_graph_node* child_pb_graph_node = NULL; - int select_mode_index = -1; - - int path_id = -1; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - assert(NULL != cur_pb_graph_node); - cur_pb_type = cur_pb_graph_node->pb_type; - assert(NULL != cur_pb_type); - select_mode_index = find_pb_type_idle_mode_index(*(cur_pb_type)); - cur_mode = &(cur_pb_type->modes[select_mode_index]); - assert(NULL != cur_mode); - - /* We check output_pins of cur_pb_graph_node and its the input_edges - * Built the interconnections between outputs of cur_pb_graph_node and outputs of child_pb_graph_node - * child_pb_graph_node.output_pins -----------------> cur_pb_graph_node.outpins - * /|\ - * | - * input_pins, edges, output_pins - */ - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - path_id = 0; - fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, - OUTPUT2OUTPUT_INTERC, - &(cur_pb_graph_node->output_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } - - /* We check input_pins of child_pb_graph_node and its the input_edges - * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node - * cur_pb_graph_node.input_pins -----------------> child_pb_graph_node.input_pins - * /|\ - * | - * input_pins, edges, output_pins - */ - for (ipb = 0; ipb < cur_pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { - child_pb_graph_node = &(cur_pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]); - /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - path_id = 0; - /* Write the interconnection*/ - fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } - /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - path_id = 0; - /* Write the interconnection*/ - fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } - } - } - - return; -} - -void fprint_spice_mux_testbench_idle_pb_graph_node_muxes_rec(FILE* fp, - t_pb_graph_node* cur_pb_graph_node, - int grid_x, int grid_y, - t_ivec*** LL_rr_node_indices) { - int ipb, jpb; - int mode_index; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - /* Check */ - assert(NULL != cur_pb_graph_node); - - /* If we touch the leaf, there is no need print interc*/ - if (NULL == cur_pb_graph_node->pb_type->spice_model) { - /* Print MUX interc at current-level pb*/ - fprint_spice_mux_testbench_pb_graph_node_interc(fp, cur_pb_graph_node, - grid_x, grid_y, - LL_rr_node_indices); - } else { - return; - } - - /* Go recursively ... */ - mode_index = find_pb_type_idle_mode_index(*(cur_pb_graph_node->pb_type)); - for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Print idle muxes */ - fprint_spice_mux_testbench_idle_pb_graph_node_muxes_rec(fp, - &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - grid_x, grid_y, - LL_rr_node_indices); - } - } - - return; -} - -/* For each pb, we search the input pins and output pins for local interconnections */ -static -void fprint_spice_mux_testbench_pb_interc(FILE* fp, - t_pb* cur_pb, - int grid_x, int grid_y, - t_ivec*** LL_rr_node_indices) { - int iport, ipin; - int ipb, jpb; - t_pb_graph_node* cur_pb_graph_node = NULL; - t_pb_type* cur_pb_type = NULL; - t_mode* cur_mode = NULL; - t_pb_graph_node* child_pb_graph_node = NULL; - t_pb* child_pb = NULL; - int select_mode_index = -1; - int node_index = -1; int prev_node = -1; - int prev_edge = -1; + /* int prev_edge = -1; */ int path_id = -1; t_rr_node* pb_rr_nodes = NULL; + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + switch (pb_port_type) { + case SPICE_PB_PORT_INPUT: + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + if (is_idle) { + assert(NULL == cur_pb); + path_id = DEFAULT_PATH_ID; + fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->input_pins[iport][ipin]), + cur_mode, + path_id, + grid_x, grid_y, + LL_rr_node_indices); + } else { + /* Get the selected edge of current pin*/ + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->input_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; // + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/ + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->input_pins[iport][ipin]), + cur_mode, + path_id, + grid_x, grid_y, + LL_rr_node_indices); + } + } + } + break; + case SPICE_PB_PORT_OUTPUT: + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + if (is_idle) { + assert(NULL == cur_pb); + path_id = DEFAULT_PATH_ID; + fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, + OUTPUT2OUTPUT_INTERC, + &(cur_pb_graph_node->output_pins[iport][ipin]), + cur_mode, + path_id, + grid_x, grid_y, + LL_rr_node_indices); + } else { + /* Get the selected edge of current pin*/ + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->output_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; // + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/ + OUTPUT2OUTPUT_INTERC, + &(cur_pb_graph_node->output_pins[iport][ipin]), + cur_mode, + path_id, + grid_x, grid_y, + LL_rr_node_indices); + } + } + } + break; + case SPICE_PB_PORT_CLOCK: + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + if (is_idle) { + assert(NULL == cur_pb); + path_id = DEFAULT_PATH_ID; + fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + cur_mode, + path_id, + grid_x, grid_y, + LL_rr_node_indices); + } else { + /* Get the selected edge of current pin*/ + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->clock_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; // + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, cur_pb, /* TODO: find out the child_pb*/ + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + cur_mode, + path_id, + grid_x, grid_y, + LL_rr_node_indices); + } + } + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pb port type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* For each pb, we search the input pins and output pins for local interconnections */ +static +void fprint_spice_mux_testbench_pb_interc(FILE* fp, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, + int grid_x, int grid_y, + t_ivec*** LL_rr_node_indices) { + int ipb, jpb; + t_pb_type* cur_pb_type = NULL; + t_mode* cur_mode = NULL; + t_pb_graph_node* child_pb_graph_node = NULL; + t_phy_pb* child_pb = NULL; + int select_mode_index = -1; + int is_child_pb_idle = -1; + int is_idle = 0; + /* Check the file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", @@ -1007,12 +1000,18 @@ void fprint_spice_mux_testbench_pb_interc(FILE* fp, exit(1); } - assert(NULL != cur_pb); - cur_pb_graph_node = cur_pb->pb_graph_node; - assert(NULL != cur_pb_graph_node); + /* Check */ + if (NULL == cur_pb) { + assert(NULL != cur_pb_graph_node); + select_mode_index = find_pb_type_physical_mode_index(*(cur_pb_graph_node->pb_type)); + is_idle = 1; + } else { + assert (cur_pb_graph_node == cur_pb->pb_graph_node); + select_mode_index = cur_pb->mode; + is_idle = 0; + } cur_pb_type = cur_pb_graph_node->pb_type; assert(NULL != cur_pb_type); - select_mode_index = cur_pb->mode; cur_mode = &(cur_pb_type->modes[select_mode_index]); assert(NULL != cur_mode); @@ -1023,39 +1022,15 @@ void fprint_spice_mux_testbench_pb_interc(FILE* fp, * | * input_pins, edges, output_pins */ - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - /* Get the selected edge of current pin*/ - assert(NULL != cur_pb); - pb_rr_nodes = cur_pb->rr_graph; - node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; - /* Bypass unmapped interc */ - /* - if (OPEN == pb_rr_nodes[node_index].net_num) { - continue; - } - */ - prev_node = pb_rr_nodes[node_index].prev_node; - /* prev_edge is the index of edge of prev_node !!! */ - prev_edge = pb_rr_nodes[node_index].prev_edge; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; - /* Determine the child_pb */ - } else { - /* Find the path_id */ - path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes ,cur_pb, /* TODO: find out the child_pb*/ - OUTPUT2OUTPUT_INTERC, - &(cur_pb_graph_node->output_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } + fprintf_spice_mux_testbench_pb_graph_port_interc(fp, + cur_pb_graph_node, + cur_pb, + SPICE_PB_PORT_OUTPUT, + cur_mode, + is_idle, + grid_x, grid_y, + LL_rr_node_indices); + /* We check input_pins of child_pb_graph_node and its the input_edges * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node @@ -1067,106 +1042,36 @@ void fprint_spice_mux_testbench_pb_interc(FILE* fp, for (ipb = 0; ipb < cur_pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { for (jpb = 0; jpb < cur_pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { child_pb_graph_node = &(cur_pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]); - child_pb = &(cur_pb->child_pbs[ipb][jpb]); - /* Check if child_pb is empty */ - if (NULL == child_pb->name) { - //continue; /* by pass*/ - /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - path_id = 0; - /* Write the interconnection*/ - fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } + if (NULL == cur_pb) { + child_pb = NULL; + } else { + child_pb = &(cur_pb->child_pbs[ipb][jpb]); + /* Check if child_pb is empty */ + if (NULL == child_pb->name) { + is_child_pb_idle = 1; + child_pb = NULL; + } else { + is_child_pb_idle = 0; } - /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - path_id = 0; - /* Write the interconnection*/ - fprint_spice_mux_testbench_pb_graph_node_pin_interc(fp, - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } - continue; } - /* Get pb_rr_graph of current pb*/ - pb_rr_nodes = child_pb->rr_graph; /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - /* Get the index of the edge that are selected to pass signal*/ - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - prev_edge = pb_rr_nodes[node_index].prev_edge; - /* Bypass unmapped interc */ - /* - if (OPEN == pb_rr_nodes[node_index].net_num) { - continue; - } - */ - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; - //break; /* TODO: if there exist parasitic input waveforms, we should print the interc */ - } else { - /* Find the path_id */ - path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - /* Write the interconnection*/ - fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, child_pb, - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } + fprintf_spice_mux_testbench_pb_graph_port_interc(fp, + child_pb_graph_node, + child_pb, + SPICE_PB_PORT_INPUT, + cur_mode, + is_child_pb_idle, + grid_x, grid_y, + LL_rr_node_indices); /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - /* Get the index of the edge that are selected to pass signal*/ - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - prev_edge = pb_rr_nodes[node_index].prev_edge; - /* Bypass unmapped interc */ - /* - if (OPEN == pb_rr_nodes[node_index].net_num) { - continue; - } - */ - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; - //break; /* TODO: if there exist parasitic input waveforms, we should print the interc */ - } else { - /* Find the path_id */ - path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - /* Write the interconnection*/ - fprint_spice_mux_testbench_pb_pin_interc(fp, pb_rr_nodes, child_pb, - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - path_id, - grid_x, grid_y, - LL_rr_node_indices); - } - } + fprintf_spice_mux_testbench_pb_graph_port_interc(fp, + child_pb_graph_node, + child_pb, + SPICE_PB_PORT_CLOCK, + cur_mode, + is_child_pb_idle, + grid_x, grid_y, + LL_rr_node_indices); } } @@ -1175,7 +1080,8 @@ void fprint_spice_mux_testbench_pb_interc(FILE* fp, static void fprint_spice_mux_testbench_pb_muxes_rec(FILE* fp, - t_pb* cur_pb, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, int grid_x, int grid_y, t_ivec*** LL_rr_node_indices) { int ipb, jpb; @@ -1187,13 +1093,21 @@ void fprint_spice_mux_testbench_pb_muxes_rec(FILE* fp, __FILE__, __LINE__); exit(1); } + /* Check */ - assert(NULL != cur_pb); + if (NULL == cur_pb) { + assert(NULL != cur_pb_graph_node); + } else { + assert (cur_pb_graph_node == cur_pb->pb_graph_node); + } + /* If we touch the leaf, there is no need print interc*/ - if (OPEN == cur_pb->logical_block) { + if (FALSE == is_primitive_pb_type(cur_pb_graph_node->pb_type)) { /* Print MUX interc at current-level pb*/ - fprint_spice_mux_testbench_pb_interc(fp, cur_pb, + fprint_spice_mux_testbench_pb_interc(fp, + cur_pb, + cur_pb_graph_node, grid_x, grid_y, LL_rr_node_indices); } else { @@ -1201,18 +1115,29 @@ void fprint_spice_mux_testbench_pb_muxes_rec(FILE* fp, } /* Go recursively ... */ - mode_index = cur_pb->mode; - for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - fprint_spice_mux_testbench_pb_muxes_rec(fp, &(cur_pb->child_pbs[ipb][jpb]), grid_x, grid_y, LL_rr_node_indices); - } else { + if (NULL == cur_pb) { + mode_index = find_pb_type_physical_mode_index(*(cur_pb_graph_node->pb_type)); + } else { + mode_index = cur_pb->mode; + } + for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + if (((NULL == cur_pb) + || ((NULL == cur_pb->child_pbs[ipb])||(NULL == cur_pb->child_pbs[ipb][jpb].name)))) { /* Print idle muxes */ - fprint_spice_mux_testbench_idle_pb_graph_node_muxes_rec(fp, - cur_pb->child_pbs[ipb][jpb].pb_graph_node, - grid_x, grid_y, - LL_rr_node_indices); + fprint_spice_mux_testbench_pb_muxes_rec(fp, + NULL, + &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + grid_x, grid_y, + LL_rr_node_indices); + } else { + /* Refer to pack/output_clustering.c [LINE 392] */ + assert ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)); + fprint_spice_mux_testbench_pb_muxes_rec(fp, + &(cur_pb->child_pbs[ipb][jpb]), + cur_pb->child_pbs[ipb][jpb].pb_graph_node, + grid_x, grid_y, + LL_rr_node_indices); } } } @@ -1259,16 +1184,15 @@ void fprint_spice_mux_testbench_cb_one_mux(FILE* fp, drive_rr_nodes = src_rr_node->drive_rr_nodes; /* Find path_id */ - path_id = -1; + path_id = DEFAULT_PATH_ID; for (inode = 0; inode < mux_size; inode++) { if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { path_id = inode; break; } } - assert((-1 != path_id)&&(path_id < mux_size)); - switch_index = src_rr_node->drive_switches[path_id]; + switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID]; mux_spice_model = switch_inf[switch_index].spice_model; @@ -1433,7 +1357,7 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp, int num_drive_rr_nodes = 0; t_rr_node** drive_rr_nodes = NULL; char* outport_name = NULL; - char* rr_node_outport_name = NULL; + char* rr_node_outport_name = NULL; int used = 0; float average_sb_mux_input_density = 0.; @@ -1467,7 +1391,7 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp, } else { num_drive_rr_nodes = src_rr_node->num_drive_rr_nodes; drive_rr_nodes = src_rr_node->drive_rr_nodes; - switch_index = src_rr_node->drive_switches[0]; + switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID]; } /* Print MUX only when fan-in >= 2 */ @@ -1503,14 +1427,13 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp, total_sb_mux_input_density += average_sb_mux_input_density; /* Find path_id */ - path_id = -1; + path_id = DEFAULT_PATH_ID; for (inode = 0; inode < mux_size; inode++) { if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { path_id = inode; break; } } - assert((-1 != path_id)&&(path_id < mux_size)); /* Build meas_tag: sb_mux[sb_x][sb_y]_rrnode[node]*/ meas_tag = (char*)my_malloc(sizeof(char)*(7 + strlen(my_itoa(switch_box_x)) + 2 @@ -1550,6 +1473,7 @@ int fprint_spice_mux_testbench_sb_one_mux(FILE* fp, my_free(input_init_value); my_free(input_density); my_free(input_probability); + my_free(rr_node_outport_name); return 1; } @@ -1623,11 +1547,12 @@ int fprint_spice_mux_testbench_call_one_grid_pb_muxes(FILE* fp, int ix, int iy, /* Used blocks */ for (iblk = 0; iblk < grid[ix][iy].usage; iblk++) { /* Only for mapped block */ - assert(NULL != block[grid[ix][iy].blocks[iblk]].pb); + assert(NULL != block[grid[ix][iy].blocks[iblk]].phy_pb); /* Mark the temporary net_num for the type pins*/ - mark_one_pb_parasitic_nets(block[grid[ix][iy].blocks[iblk]].pb); + mark_one_pb_parasitic_nets((t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb); fprint_spice_mux_testbench_pb_muxes_rec(fp, - block[grid[ix][iy].blocks[iblk]].pb, + (t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb, + grid[ix][iy].type->pb_graph_head, ix, iy, LL_rr_node_indices); used = 1; @@ -1636,10 +1561,11 @@ int fprint_spice_mux_testbench_call_one_grid_pb_muxes(FILE* fp, int ix, int iy, for (iblk = grid[ix][iy].usage; iblk < grid[ix][iy].type->capacity; iblk++) { /* Mark the temporary net_num for the type pins*/ mark_grid_type_pb_graph_node_pins_temp_net_num(ix, iy); - fprint_spice_mux_testbench_idle_pb_graph_node_muxes_rec(fp, - grid[ix][iy].type->pb_graph_head, - ix, iy, - LL_rr_node_indices); + fprint_spice_mux_testbench_pb_muxes_rec(fp, + NULL, + grid[ix][iy].type->pb_graph_head, + ix, iy, + LL_rr_node_indices); } return used; @@ -1684,7 +1610,7 @@ void fprint_spice_mux_testbench_stimulations(FILE* fp, static void fprint_spice_mux_testbench_measurements(FILE* fp, - enum e_spice_mux_tb_type mux_tb_type, + enum e_spice_tb_type mux_tb_type, t_spice spice) { int num_clock_cycle = max_sim_num_clock_cycles; @@ -1755,7 +1681,7 @@ int fprint_spice_one_mux_testbench(char* formatted_spice_dir, int num_clocks, t_arch arch, int grid_x, int grid_y, t_rr_type cb_type, - enum e_spice_mux_tb_type mux_tb_type, + enum e_spice_tb_type mux_tb_type, boolean leakage_only) { FILE* fp = NULL; char* formatted_subckt_dir_path = format_dir_path(subckt_dir_path); @@ -1926,7 +1852,7 @@ void spice_print_mux_testbench(char* formatted_spice_dir, t_ivec*** LL_rr_node_indices, int num_clocks, t_arch arch, - enum e_spice_mux_tb_type mux_tb_type, + enum e_spice_tb_type mux_tb_type, boolean leakage_only) { char* mux_testbench_name = NULL; int ix, iy; diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.h similarity index 87% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux_testbench.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.h index 4e6740ae8..25dacaec2 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_mux_testbench.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_mux_testbench.h @@ -1,8 +1,4 @@ -enum e_spice_mux_tb_type { - SPICE_CB_MUX_TB, SPICE_SB_MUX_TB, SPICE_PB_MUX_TB -}; - void spice_print_mux_testbench(char* formatted_spice_dir, char* circuit_name, char* include_dir_path, @@ -10,7 +6,7 @@ void spice_print_mux_testbench(char* formatted_spice_dir, t_ivec*** LL_rr_node_indices, int num_clock, t_arch arch, - enum e_spice_mux_tb_type mux_tb_type, + enum e_spice_tb_type mux_tb_type, boolean leakage_only); /* useful subroutines */ diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_pbtypes.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_pbtypes.c similarity index 83% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_pbtypes.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_pbtypes.c index 8cba980f0..fa1c180f9 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_pbtypes.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_pbtypes.c @@ -18,16 +18,22 @@ #include "globals.h" #include "rr_graph.h" #include "vpr_utils.h" +#include "route_common.h" /* Include SPICE support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" + #include "spice_utils.h" #include "spice_mux.h" #include "spice_lut.h" -#include "spice_primitives.h" +#include "spice_primitive.h" #include "spice_pbtypes.h" /***** Subroutines *****/ @@ -118,7 +124,7 @@ void fprint_pb_type_ports(FILE* fp, void fprint_spice_dangling_des_pb_graph_pin_interc(FILE* fp, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, char* parent_pin_prefix) { t_pb_graph_node* des_pb_graph_node = NULL; t_pb_type* des_pb_type = NULL; @@ -233,9 +239,9 @@ void fprint_spice_dangling_des_pb_graph_pin_interc(FILE* fp, return; } -void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_node, - t_pb_graph_node* des_pb_graph_node, - enum e_pin2pin_interc_type pin2pin_interc_type, +void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_pin* src_pb_graph_pin, + t_pb_graph_pin* des_pb_graph_pin, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_interconnect* pin2pin_interc, char* parent_pin_prefix, char** src_pin_prefix, @@ -246,19 +252,19 @@ void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_no t_pb_type* des_pb_type = NULL; int des_pb_type_index = -1; - //char* formatted_parent_pin_prefix = format_spice_node_prefix(parent_pin_prefix); /* Complete a "_" at the end if needed*/ - //char* chomped_parent_pin_prefix = chomp_spice_node_prefix(parent_pin_prefix); /* Remove a "_" at the end if needed*/ + /* char* formatted_parent_pin_prefix = format_spice_node_prefix(parent_pin_prefix);*/ /* Complete a "_" at the end if needed*/ + /* char* chomped_parent_pin_prefix = chomp_spice_node_prefix(parent_pin_prefix);*/ /* Remove a "_" at the end if needed*/ - t_mode* pin2pin_interc_parent_mode = NULL; + /* t_mode* pin2pin_interc_parent_mode = NULL; */ /* Check the pb_graph_nodes*/ - if (NULL == src_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: src_pb_graph_node.\n", + if (NULL == src_pb_graph_pin) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: src_pb_graph_pin.\n", __FILE__, __LINE__); exit(1); } - if (NULL == des_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: des_pb_graph_node.\n", + if (NULL == des_pb_graph_pin) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: des_pb_graph_pin.\n", __FILE__, __LINE__); exit(1); } @@ -269,12 +275,12 @@ void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_no } /* Initialize */ - src_pb_type = src_pb_graph_node->pb_type; - src_pb_type_index = src_pb_graph_node->placement_index; - des_pb_type = des_pb_graph_node->pb_type; - des_pb_type_index = des_pb_graph_node->placement_index; + src_pb_type = src_pb_graph_pin->parent_node->pb_type; + src_pb_type_index = src_pb_graph_pin->parent_node->placement_index; + des_pb_type = des_pb_graph_pin->parent_node->pb_type; + des_pb_type_index = des_pb_graph_pin->parent_node->placement_index; - pin2pin_interc_parent_mode = pin2pin_interc->parent_mode; + /* pin2pin_interc_parent_mode = pin2pin_interc->parent_mode;*/ assert(NULL == (*src_pin_prefix)); assert(NULL == (*des_pin_prefix)); @@ -319,7 +325,6 @@ void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_no sprintf((*des_pin_prefix), "%smode[%s]_%s[%d]", formatted_parent_pin_prefix, pin2pin_interc_parent_mode->name, des_pb_type->name, des_pb_type_index); */ - /*Simplify the prefix, make the SPICE netlist readable*/ (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* (strlen(des_pb_type->name) + 1 + strlen(my_itoa(des_pb_type_index)) + 1 + 1)); sprintf((*des_pin_prefix), "%s[%d]", @@ -340,32 +345,27 @@ void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_no formatted_parent_pin_prefix, pin2pin_interc_parent_mode->name, src_pb_type->name, src_pb_type_index); */ /*Simplify the prefix, make the SPICE netlist readable*/ - (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* - (strlen(src_pb_type->name) + 1 + strlen(my_itoa(src_pb_type_index)) + 1 + 1)); - sprintf((*src_pin_prefix), "%s[%d]", - src_pb_type->name, src_pb_type_index); - if (des_pb_type == src_pb_type->parent_mode->parent_pb_type) { /* Interconnection from parent pb_type*/ + if (des_pb_type == src_pb_type) { /* src pin is an input of the parent pb_type*/ /* - (*des_pin_prefix) = my_strdup(chomped_parent_pin_prefix); + (*src_pin_prefix) = my_strdup(chomped_parent_pin_prefix); */ /*Simplify the prefix, make the SPICE netlist readable*/ - (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* - (5 + strlen(src_pb_type->parent_mode->name) + 2)); - sprintf((*des_pin_prefix), "mode[%s]", src_pb_type->parent_mode->name); + (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* + (5 + strlen(pin2pin_interc->parent_mode->name) + 2)); + sprintf((*src_pin_prefix), "mode[%s]", pin2pin_interc->parent_mode->name); } else { - /* - (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* - (strlen(formatted_parent_pin_prefix) + 5 + strlen(pin2pin_interc_parent_mode->name) - + 2 + strlen(des_pb_type->name) + 1 + strlen(my_itoa(des_pb_type_index)) + 1 + 1)); - sprintf((*des_pin_prefix), "%smode[%s]_%s[%d]", - formatted_parent_pin_prefix, pin2pin_interc_parent_mode->name, des_pb_type->name, des_pb_type_index); - */ - /*Simplify the prefix, make the SPICE netlist readable*/ - (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* - (strlen(des_pb_type->name) + 1 + strlen(my_itoa(des_pb_type_index)) + 1 + 1)); - sprintf((*des_pin_prefix), "%s[%d]", - des_pb_type->name, des_pb_type_index); + (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* + (strlen(src_pb_type->name) + 1 + strlen(my_itoa(src_pb_type_index)) + 1 + 1)); + sprintf((*src_pin_prefix), "%s[%d]", + src_pb_type->name, src_pb_type_index); } + /* + (*des_pin_prefix) = my_strdup(chomped_parent_pin_prefix); + */ + /*Simplify the prefix, make the SPICE netlist readable*/ + (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* + (5 + strlen(pin2pin_interc->parent_mode->name) + 2)); + sprintf((*des_pin_prefix), "mode[%s]", pin2pin_interc->parent_mode->name); break; default: vpr_printf(TIO_MESSAGE_ERROR,"(File:%s [LINE%d])Invalid pin to pin interconnection type!\n", @@ -375,35 +375,6 @@ void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_no return; } -void find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, - t_mode* cur_mode, - t_interconnect** cur_interc, - int* fan_in) { - int iedge; - - (*cur_interc) = NULL; - (*fan_in) = 0; - - /* Search the input edges only, stats on the size of MUX we may need (fan-in) */ - for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { - /* 1. First, we should make sure this interconnect is in the selected mode!!!*/ - if (cur_mode == des_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode) { - /* Check this edge*/ - check_pb_graph_edge(*(des_pb_graph_pin->input_edges[iedge])); - /* Record the interconnection*/ - if (NULL == (*cur_interc)) { - (*cur_interc) = des_pb_graph_pin->input_edges[iedge]->interconnect; - } else { /* Make sure the interconnections for this pin is the same!*/ - assert((*cur_interc) == des_pb_graph_pin->input_edges[iedge]->interconnect); - } - /* Search the input_pins of input_edges only*/ - (*fan_in) += des_pb_graph_pin->input_edges[iedge]->num_input_pins; - } - } - - return; -} - /* We check output_pins of cur_pb_graph_node and its the input_edges * Built the interconnections between outputs of cur_pb_graph_node and outputs of child_pb_graph_node * src_pb_graph_node.[in|out]_pins -----------------> des_pb_graph_node.[in|out]pins @@ -413,7 +384,7 @@ void find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, */ void fprintf_spice_pb_graph_pin_interc(FILE* fp, char* parent_pin_prefix, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, int select_edge) { @@ -425,11 +396,11 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, t_pb_graph_pin* src_pb_graph_pin = NULL; t_pb_graph_node* src_pb_graph_node = NULL; t_pb_type* src_pb_type = NULL; - int src_pb_type_index = -1; + /* int src_pb_type_index = -1; */ t_pb_graph_node* des_pb_graph_node = NULL; - t_pb_type* des_pb_type = NULL; - int des_pb_type_index = -1; + /* t_pb_type* des_pb_type = NULL; */ + /* int des_pb_type_index = -1; */ char* formatted_parent_pin_prefix = chomp_spice_node_prefix(parent_pin_prefix); /* Complete a "_" at the end if needed*/ char* src_pin_prefix = NULL; @@ -438,6 +409,7 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, int num_sram_bits = 0; int* sram_bits = NULL; + /* int num_sram = 0; */ int cur_sram = 0; int mux_level = 0; @@ -464,28 +436,7 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, return; } /* Initialize the interconnection type that will be implemented in SPICE netlist*/ - switch (cur_interc->type) { - case DIRECT_INTERC: - assert(1 == fan_in); - spice_interc_type = DIRECT_INTERC; - break; - case COMPLETE_INTERC: - if (1 == fan_in) { - spice_interc_type = DIRECT_INTERC; - } else { - assert((2 == fan_in)||(2 < fan_in)); - spice_interc_type = MUX_INTERC; - } - break; - case MUX_INTERC: - assert((2 == fan_in)||(2 < fan_in)); - spice_interc_type = MUX_INTERC; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", - __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); - exit(1); - } + spice_interc_type = determine_actual_pb_interc_type(cur_interc, fan_in); /* This time, (2nd round), we print the subckt, according to interc type*/ switch (spice_interc_type) { case DIRECT_INTERC: @@ -512,13 +463,13 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, src_pb_graph_pin = des_pb_graph_pin->input_edges[iedge]->input_pins[0]; src_pb_graph_node = src_pb_graph_pin->parent_node; src_pb_type = src_pb_graph_node->pb_type; - src_pb_type_index = src_pb_graph_node->placement_index; + /* src_pb_type_index = src_pb_graph_node->placement_index; */ /* Des pin, node, pb_type */ des_pb_graph_node = des_pb_graph_pin->parent_node; - des_pb_type = des_pb_graph_node->pb_type; - des_pb_type_index = des_pb_graph_node->placement_index; + /* des_pb_type = des_pb_graph_node->pb_type; */ + /* des_pb_type_index = des_pb_graph_node->placement_index; */ /* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/ - generate_spice_src_des_pb_graph_pin_prefix(src_pb_graph_node, des_pb_graph_node, pin2pin_interc_type, + generate_spice_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type, cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); /* Call the subckt that has already been defined before */ fprintf(fp, "X%s[%d] ", cur_interc->spice_model->prefix, cur_interc->spice_model->cnt); @@ -574,13 +525,13 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, src_pb_graph_pin = des_pb_graph_pin->input_edges[iedge]->input_pins[0]; src_pb_graph_node = src_pb_graph_pin->parent_node; src_pb_type = src_pb_graph_node->pb_type; - src_pb_type_index = src_pb_graph_node->placement_index; + /* src_pb_type_index = src_pb_graph_node->placement_index; */ /* Des pin, node, pb_type */ des_pb_graph_node = des_pb_graph_pin->parent_node; - des_pb_type = des_pb_graph_node->pb_type; - des_pb_type_index = des_pb_graph_node->placement_index; + /* des_pb_type = des_pb_graph_node->pb_type; */ + /* des_pb_type_index = des_pb_graph_node->placement_index; */ /* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/ - generate_spice_src_des_pb_graph_pin_prefix(src_pb_graph_node, des_pb_graph_node, pin2pin_interc_type, + generate_spice_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type, cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); /* We need to find out if the des_pb_graph_pin is in the mode we want !*/ /* Print */ @@ -593,7 +544,7 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, des_pin_prefix = NULL; } /* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/ - generate_spice_src_des_pb_graph_pin_prefix(src_pb_graph_node, des_pb_graph_node, pin2pin_interc_type, + generate_spice_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type, cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); /* Outputs */ fprintf(fp, "%s->%s[%d] ", @@ -601,39 +552,20 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, assert(select_edge < fan_in); /* SRAMs */ - switch (cur_interc->spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - /* 1. Get the mux level*/ - mux_level = determine_tree_mux_level(fan_in); - /* Get the SRAM configurations*/ - /* Decode the selected_edge_index */ - num_sram_bits = mux_level; - sram_bits = decode_tree_mux_sram_bits(fan_in, mux_level, select_edge); - /* Print SRAM configurations, - * we should have a global SRAM vdd, AND it should be connected to a real sram subckt !!! - */ + switch (cur_interc->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(cur_interc->spice_model, fan_in, select_edge, + &num_sram_bits, &sram_bits, &mux_level); break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - mux_level = 1; - /* Special for 2-input MUX */ - if (2 == fan_in) { - num_sram_bits = 1; - sram_bits = decode_tree_mux_sram_bits(fan_in, mux_level, select_edge); - } else { - num_sram_bits = fan_in; - sram_bits = decode_onelevel_mux_sram_bits(fan_in, mux_level, select_edge); - } - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - mux_level = cur_interc->spice_model->design_tech_info.mux_num_level; - num_sram_bits = determine_num_input_basis_multilevel_mux(fan_in, mux_level) *mux_level; - sram_bits = decode_multilevel_mux_sram_bits(fan_in, mux_level, select_edge); + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(cur_interc->spice_model, fan_in, select_edge, + &num_sram_bits, &sram_bits, &mux_level); break; default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", __FILE__, __LINE__, cur_interc->spice_model->name); - exit(1); - } + } + cur_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); /* Create wires to sram outputs*/ for (ilevel = 0; ilevel < num_sram_bits; ilevel++) { @@ -686,29 +618,150 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, return; } +/* Print the SPICE interconnections of a port defined in pb_graph */ +void fprintf_spice_pb_graph_port_interc(FILE* fp, + char* formatted_pin_prefix, + t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb, + enum e_spice_pb_port_type pb_port_type, + t_mode* cur_mode, + int is_idle) { + int iport, ipin; + int node_index = -1; + int prev_node = -1; + /* int prev_edge = -1; */ + int path_id = -1; + t_rr_node* pb_rr_nodes = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + switch (pb_port_type) { + case SPICE_PB_PORT_INPUT: + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + if (is_idle) { + assert(NULL == cur_pb); + path_id = DEFAULT_PATH_ID; + } else { + /* Get the selected edge of current pin*/ + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->input_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; // + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + } + fprintf_spice_pb_graph_pin_interc(fp, + formatted_pin_prefix, /* parent_pin_prefix */ + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->input_pins[iport][ipin]), + cur_mode, + path_id); + } + } + break; + case SPICE_PB_PORT_OUTPUT: + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + if (is_idle) { + assert(NULL == cur_pb); + path_id = DEFAULT_PATH_ID; + } else { + /* Get the selected edge of current pin*/ + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->output_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; // + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + } + fprintf_spice_pb_graph_pin_interc(fp, + formatted_pin_prefix, /* parent_pin_prefix */ + OUTPUT2OUTPUT_INTERC, + &(cur_pb_graph_node->output_pins[iport][ipin]), + cur_mode, + path_id); + } + } + break; + case SPICE_PB_PORT_CLOCK: + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + if (is_idle) { + assert(NULL == cur_pb); + path_id = DEFAULT_PATH_ID; + } else { + /* Get the selected edge of current pin*/ + assert(NULL != cur_pb); + pb_rr_nodes = cur_pb->rr_graph->rr_node; + node_index = cur_pb_graph_node->clock_pins[iport][ipin].rr_node_index_physical_pb; + prev_node = pb_rr_nodes[node_index].prev_node; + /* prev_edge = pb_rr_nodes[node_index].prev_edge; */ + /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ + if (OPEN == prev_node) { + path_id = DEFAULT_PATH_ID; // + } else { + /* Find the path_id */ + path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); + assert(DEFAULT_PATH_ID != path_id); + } + } + fprintf_spice_pb_graph_pin_interc(fp, + formatted_pin_prefix, /* parent_pin_prefix */ + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + cur_mode, + path_id); + } + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pb port type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} /* Print the SPICE interconnections according to pb_graph */ void fprint_spice_pb_graph_interc(FILE* fp, char* pin_prefix, t_pb_graph_node* cur_pb_graph_node, - t_pb* cur_pb, + t_phy_pb* cur_pb, int select_mode_index, int is_idle) { - int iport, ipin; int ipb, jpb; t_mode* cur_mode = NULL; t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; t_pb_graph_node* child_pb_graph_node = NULL; - t_pb* child_pb = NULL; + t_phy_pb* child_pb = NULL; int is_child_pb_idle = 0; char* formatted_pin_prefix = format_spice_node_prefix(pin_prefix); /* Complete a "_" at the end if needed*/ - int node_index = -1; - int prev_node = -1; - int prev_edge = -1; - int path_id = -1; - t_rr_node* pb_rr_nodes = NULL; /* Check the file handler*/ if (NULL == fp) { @@ -733,41 +786,10 @@ void fprint_spice_pb_graph_interc(FILE* fp, * | * input_pins, edges, output_pins */ - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - /* If this is a idle block, we set 0 to the selected edge*/ - if (is_idle) { - assert(NULL == cur_pb); - fprintf_spice_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - OUTPUT2OUTPUT_INTERC, - &(cur_pb_graph_node->output_pins[iport][ipin]), - cur_mode, - 0); - } else { - /* Get the selected edge of current pin*/ - assert(NULL != cur_pb); - pb_rr_nodes = cur_pb->rr_graph; - node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - prev_edge = pb_rr_nodes[node_index].prev_edge; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; // - } else { - /* Find the path_id */ - path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - fprintf_spice_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - OUTPUT2OUTPUT_INTERC, - &(cur_pb_graph_node->output_pins[iport][ipin]), - cur_mode, - path_id); - } - } - } + fprintf_spice_pb_graph_port_interc(fp, formatted_pin_prefix, + cur_pb_graph_node, cur_pb, + SPICE_PB_PORT_OUTPUT, + cur_mode, is_idle); /* We check input_pins of child_pb_graph_node and its the input_edges * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node @@ -782,96 +804,29 @@ void fprint_spice_pb_graph_interc(FILE* fp, /* If this is a idle block, we set 0 to the selected edge*/ if (is_idle) { assert(NULL == cur_pb); - /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - fprintf_spice_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - 0); - } - } - /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - fprintf_spice_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - 0); - } - } - continue; - } - assert(NULL != cur_pb); - child_pb = &(cur_pb->child_pbs[ipb][jpb]); - /* Check if child_pb is empty */ - if (NULL != child_pb->name) { - is_child_pb_idle = 0; + child_pb = NULL; + is_child_pb_idle = is_idle; } else { - is_child_pb_idle = 1; + assert(NULL != cur_pb); + child_pb = &(cur_pb->child_pbs[ipb][jpb]); + /* Check if child_pb is empty */ + if (NULL != child_pb->name) { + is_child_pb_idle = 0; + } else { + is_child_pb_idle = 1; + child_pb = NULL; + } } - /* Get pb_rr_graph of current pb*/ - pb_rr_nodes = child_pb->rr_graph; /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - if (is_child_pb_idle) { - prev_edge = 0; - } else { - /* Get the index of the edge that are selected to pass signal*/ - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - prev_edge = pb_rr_nodes[node_index].prev_edge; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; // - } else { - /* Find the path_id */ - path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - } - /* Write the interconnection*/ - fprintf_spice_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - path_id); - } - } + fprintf_spice_pb_graph_port_interc(fp, formatted_pin_prefix, + child_pb_graph_node, child_pb, + SPICE_PB_PORT_INPUT, + cur_mode, is_child_pb_idle); /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - if (is_child_pb_idle) { - prev_edge = 0; - } else { - /* Get the index of the edge that are selected to pass signal*/ - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - prev_edge = pb_rr_nodes[node_index].prev_edge; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; // - } else { - /* Find the path_id */ - path_id = find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - } - /* Write the interconnection*/ - fprintf_spice_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - path_id); - } - } + fprintf_spice_pb_graph_port_interc(fp, formatted_pin_prefix, + child_pb_graph_node, child_pb, + SPICE_PB_PORT_CLOCK, + cur_mode, is_child_pb_idle); } } @@ -966,14 +921,12 @@ void fprint_spice_pb_graph_primitive_node(FILE* fp, /* Print the subckt of a primitive pb */ void fprint_pb_primitive_spice_model(FILE* fp, char* subckt_prefix, - t_pb* prim_pb, + t_phy_pb* prim_phy_pb, t_pb_graph_node* prim_pb_graph_node, int pb_index, t_spice_model* spice_model, - int is_idle, - t_rr_node* pb_rr_graph) { + int is_idle) { t_pb_type* prim_pb_type = NULL; - t_logical_block* mapped_logical_block = NULL; /* Check the file handler*/ if (NULL == fp) { @@ -988,73 +941,25 @@ void fprint_pb_primitive_spice_model(FILE* fp, exit(1); } - /* Initialize */ prim_pb_type = prim_pb_graph_node->pb_type; - - switch (is_idle) { - case PRIMITIVE_WIRED_LUT: - mapped_logical_block = NULL; - break; - case PRIMITIVE_IDLE: - mapped_logical_block = NULL; - break; - case PRIMITIVE_NORMAL: - mapped_logical_block = &logical_block[prim_pb->logical_block]; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n", - __FILE__, __LINE__, is_idle); - exit(1); - } /* Asserts*/ assert(pb_index == prim_pb_graph_node->placement_index); assert(0 == strcmp(spice_model->name, prim_pb_type->spice_model->name)); - switch (is_idle) { - case PRIMITIVE_WIRED_LUT: - assert(NULL == prim_pb); - break; - case PRIMITIVE_IDLE: - assert(NULL == prim_pb); - break; - case PRIMITIVE_NORMAL: - if (NULL == prim_pb) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb.\n", - __FILE__, __LINE__); - exit(1); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n", - __FILE__, __LINE__, is_idle); - exit(1); - } - /* According to different type, we print netlist*/ switch (spice_model->type) { case SPICE_MODEL_LUT: /* If this is a idle block we should set sram_bits to zero*/ - fprint_pb_primitive_lut(fp, subckt_prefix, prim_pb, mapped_logical_block, prim_pb_graph_node, - pb_index, spice_model, is_idle, pb_rr_graph); + fprint_pb_primitive_lut(fp, subckt_prefix, prim_phy_pb, prim_pb_type, + pb_index, spice_model); break; case SPICE_MODEL_FF: - assert(NULL != spice_model->model_netlist); - /* TODO : We should learn trigger type and initial value!!! and how to apply them!!! */ - fprint_pb_primitive_ff(fp, subckt_prefix, mapped_logical_block, prim_pb_graph_node, - pb_index, spice_model); - break; case SPICE_MODEL_IOPAD: - assert(NULL != spice_model->model_netlist); - fprint_pb_primitive_io(fp, subckt_prefix, mapped_logical_block, prim_pb_graph_node, - pb_index, spice_model); - break; case SPICE_MODEL_HARDLOGIC: assert(NULL != spice_model->model_netlist); - fprint_pb_primitive_hardlogic(fp, subckt_prefix, mapped_logical_block, prim_pb_graph_node, - pb_index, spice_model); + fprint_pb_primitive_generic(fp, subckt_prefix, prim_phy_pb, prim_pb_type, + pb_index, spice_model); break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of spice_model(%s), should be [LUT|FF|HARD_LOGIC|IO]!\n", @@ -1122,7 +1027,7 @@ void fprint_spice_idle_pb_graph_node_rec(FILE* fp, if (NULL != cur_pb_type->spice_model) { fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, NULL, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 1, NULL); + pb_type_index, cur_pb_type->spice_model, 1); /* Finish the primitive node, we return */ return; } @@ -1234,8 +1139,7 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, char* subckt_prefix, t_pb* cur_pb, t_pb_graph_node* cur_pb_graph_node, - int pb_type_index, - t_rr_node* pb_rr_graph) { + int pb_type_index) { int mode_index, ipb, jpb, child_mode_index; t_pb_type* cur_pb_type = NULL; char* subckt_name = NULL; @@ -1259,17 +1163,6 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, exit(1); } cur_pb_type = cur_pb_graph_node->pb_type; - - /* For wired LUTs only */ - if (NULL == cur_pb) { - assert(NULL != cur_pb_type->spice_model); - assert (LUT_CLASS == cur_pb_type->class_type); - fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, PRIMITIVE_WIRED_LUT, pb_rr_graph); - return; - } - mode_index = cur_pb->mode; /* Recursively finish all the child pb_types*/ @@ -1289,21 +1182,11 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, /* Refer to pack/output_clustering.c [LINE 392] */ if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { fprint_spice_pb_graph_node_rec(fp, pass_on_prefix, &(cur_pb->child_pbs[ipb][jpb]), - cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb, cur_pb->rr_graph); - /* For wired LUT */ - } else if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - &(cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb]), - cur_pb->rr_graph)) { - /* Reach here means that this LUT is in wired mode (a buffer) - * Print the Verilog of wired LUTs - */ - fprint_spice_pb_graph_node_rec(fp, pass_on_prefix, NULL, - &(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - jpb, cur_pb->rr_graph); + cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb); } else { /* Check if this pb has no children, no children mean idle*/ fprint_spice_idle_pb_graph_node_rec(fp, pass_on_prefix, - cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb); + cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb); } /* Free */ my_free(pass_on_prefix); @@ -1319,29 +1202,37 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, * Mapped logical block information is stored in child_pbs */ child_pb = get_lut_child_pb(cur_pb, mode_index); + /* fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, child_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, child_pb->rr_graph); + pb_type_index, cur_pb_type->spice_model, 0); + */ break; case LATCH_CLASS: assert(0 == cur_pb_type->num_modes); /* Consider the num_pb, create all the subckts*/ + /* fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, cur_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, cur_pb->rr_graph); + pb_type_index, cur_pb_type->spice_model, 0); + */ break; case MEMORY_CLASS: child_pb = get_hardlogic_child_pb(cur_pb, mode_index); /* Consider the num_pb, create all the subckts*/ + /* fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, child_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, child_pb->rr_graph); + pb_type_index, cur_pb_type->spice_model, 0); + */ break; case UNKNOWN_CLASS: /* Consider the num_pb, create all the subckts*/ + /* fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, cur_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, cur_pb->rr_graph); + pb_type_index, cur_pb_type->spice_model, 0); + */ break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", @@ -1426,7 +1317,9 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, } } /* Print interconnections, set is_idle as TRUE*/ + /* fprint_spice_pb_graph_interc(fp, subckt_name, cur_pb_graph_node, cur_pb, mode_index, 0); + */ /* Check each pins of pb_graph_node */ /* End the subckt */ fprintf(fp, ".eom\n"); @@ -1440,7 +1333,7 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, * at physical-level implementation */ void fprint_spice_phy_pb_graph_node_rec(FILE* fp, char* subckt_prefix, - t_pb* cur_pb, + t_phy_pb* cur_pb, t_pb_graph_node* cur_pb_graph_node, int pb_type_index) { int mode_index, ipb, jpb, child_mode_index, is_idle; @@ -1451,8 +1344,7 @@ void fprint_spice_phy_pb_graph_node_rec(FILE* fp, char* child_pb_type_prefix = NULL; char* subckt_port_prefix = NULL; - t_pb* child_pb = NULL; - t_rr_node* pb_rr_graph = NULL; + t_phy_pb* child_pb = NULL; /* Check the file handler*/ if (NULL == fp) { @@ -1468,16 +1360,14 @@ void fprint_spice_phy_pb_graph_node_rec(FILE* fp, } cur_pb_type = cur_pb_graph_node->pb_type; - is_idle = 1; - if (NULL != cur_pb) { - is_idle = 0; - pb_rr_graph = cur_pb->rr_graph; - } else { - pb_rr_graph = NULL; + /* Identify if this is an idle block */ + is_idle = 0; + if (NULL == cur_pb) { + is_idle = 1; } /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { + if (FALSE == is_primitive_pb_type(cur_pb_type)) { /* Find the mode that define_idle_mode*/ mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); /* recursive for the child_pbs*/ @@ -1494,7 +1384,12 @@ void fprint_spice_phy_pb_graph_node_rec(FILE* fp, /* Recursive*/ /* Refer to pack/output_clustering.c [LINE 392] */ /* Find the child pb that is mapped, and the mapping info is not stored in the physical mode ! */ - child_pb = get_child_pb_for_phy_pb_graph_node(cur_pb, ipb, jpb); + if (NULL == cur_pb) { + child_pb = NULL; + } else { + assert (NULL != cur_pb); + child_pb = get_phy_child_pb_for_phy_pb_graph_node(cur_pb, ipb, jpb); + } fprint_spice_phy_pb_graph_node_rec(fp, pass_on_prefix, child_pb, &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), jpb); /* Free */ @@ -1504,36 +1399,26 @@ void fprint_spice_phy_pb_graph_node_rec(FILE* fp, } /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { + if (TRUE == is_primitive_pb_type(cur_pb_type)) { switch (cur_pb_type->class_type) { case LUT_CLASS: - if (1 == is_idle) { - fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, is_idle, NULL); - } else { - child_pb = get_lut_child_pb(cur_pb, mode_index); - /* Special care for LUT !!! - * Mapped logical block information is stored in child_pbs - */ - fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, - child_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, is_idle, child_pb->rr_graph); - } + fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, + cur_pb, cur_pb_graph_node, + pb_type_index, cur_pb_type->spice_model, is_idle); break; case LATCH_CLASS: assert(0 == cur_pb_type->num_modes); /* Consider the num_pb, create all the subckts*/ fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, cur_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, is_idle, pb_rr_graph); + pb_type_index, cur_pb_type->spice_model, is_idle); break; case UNKNOWN_CLASS: case MEMORY_CLASS: /* Consider the num_pb, create all the subckts*/ fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix, cur_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, is_idle, pb_rr_graph); + pb_type_index, cur_pb_type->spice_model, is_idle); break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", @@ -1594,7 +1479,7 @@ void fprint_spice_phy_pb_graph_node_rec(FILE* fp, * else we can use the mode to name it */ if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model) { /* Not a leaf node*/ - child_mode_index = find_pb_type_idle_mode_index(cur_pb_type->modes[mode_index].pb_type_children[ipb]); + child_mode_index = find_pb_type_physical_mode_index(cur_pb_type->modes[mode_index].pb_type_children[ipb]); fprintf(fp, "%s_%s[%d]_mode[%s]\n", subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb, cur_pb_type->modes[mode_index].pb_type_children[ipb].modes[child_mode_index].name); @@ -1653,7 +1538,7 @@ void fprint_spice_block(FILE* fp, * Inside the type_descripor, there is a top_pb_graph_node(pb_graph_head), describe the top pb_type defined. * The index of such top pb_type is always 0. */ - fprint_spice_pb_graph_node_rec(fp, subckt_name, top_pb, top_pb_graph_node, z, top_pb->rr_graph); + fprint_spice_pb_graph_node_rec(fp, subckt_name, top_pb, top_pb_graph_node, z); return; } @@ -1698,7 +1583,7 @@ void fprint_spice_physical_block(FILE* fp, int y, int z, t_type_ptr type_descriptor) { - t_pb* top_pb = NULL; + t_phy_pb* top_pb = NULL; t_pb_graph_node* top_pb_graph_node = NULL; t_block* mapped_block = NULL; @@ -1719,7 +1604,7 @@ void fprint_spice_physical_block(FILE* fp, mapped_block = search_mapped_block(x, y, z); /* Go for the pb_types*/ if (NULL != mapped_block) { - top_pb = mapped_block->pb; + top_pb = (t_phy_pb*)mapped_block->phy_pb; assert(NULL != top_pb); } @@ -2425,15 +2310,17 @@ void generate_spice_logic_blocks(char* subckt_dir, assert(IO_TYPE != grid[ix][iy].type); /* Ensure a valid usage */ assert((0 == grid[ix][iy].usage)||(0 < grid[ix][iy].usage)); - fprint_grid_blocks(subckt_dir, ix, iy, arch); + /* I comment the previous version here in case we want to compare */ + /* fprint_grid_blocks(subckt_dir, ix, iy, arch); */ + fprint_grid_physical_blocks(subckt_dir, ix, iy, arch); } } vpr_printf(TIO_MESSAGE_INFO,"Generating IO grids...\n"); /* Print the IO pads */ - /* Left side: x = 0, y = 1 .. ny*/ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { + /* Top side : x = 1 .. nx + 1, y = nx + 1 */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { /* Ensure this is a io */ assert(IO_TYPE == grid[ix][iy].type); /* TODO: replace with physical block generator */ @@ -2455,9 +2342,9 @@ void generate_spice_logic_blocks(char* subckt_dir, /* TODO: replace with physical block generator */ fprint_grid_physical_blocks(subckt_dir, ix, iy, arch); } - /* Top side : x = 1 .. nx + 1, y = nx + 1 */ - iy = ny + 1; - for (ix = 1; ix < (nx + 1); ix++) { + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { /* Ensure this is a io */ assert(IO_TYPE == grid[ix][iy].type); /* TODO: replace with physical block generator */ diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_pbtypes.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_pbtypes.h similarity index 85% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_pbtypes.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_pbtypes.h index df1d1e04d..73890c89c 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_pbtypes.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_pbtypes.h @@ -7,12 +7,12 @@ void fprint_pb_type_ports(FILE* fp, void fprint_spice_dangling_des_pb_graph_pin_interc(FILE* fp, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, char* parent_pin_prefix); -void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_node, - t_pb_graph_node* des_pb_graph_node, - enum e_pin2pin_interc_type pin2pin_interc_type, +void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_pin* src_pb_graph_pin, + t_pb_graph_pin* des_pb_graph_pin, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_interconnect* pin2pin_interc, char* parent_pin_prefix, char** src_pin_prefix, @@ -25,7 +25,7 @@ void find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, void fprintf_spice_pb_graph_pin_interc(FILE* fp, char* parent_pin_prefix, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, int is_idle); @@ -33,6 +33,7 @@ void fprintf_spice_pb_graph_pin_interc(FILE* fp, void fprint_spice_pb_graph_interc(FILE* fp, char* pin_prefix, t_pb_graph_node* cur_pb_graph_node, + t_phy_pb* cur_pb, int select_mode_index, int is_idle); @@ -44,12 +45,11 @@ void fprint_spice_pb_graph_primitive_node(FILE* fp, void fprint_pb_primitive_spice_model(FILE* fp, char* subckt_prefix, - t_pb* prim_pb, + t_phy_pb* prim_pb, t_pb_graph_node* prim_pb_graph_node, int pb_index, t_spice_model* spice_model, - int is_idle, - t_rr_node* pb_rr_graph); + int is_idle); void fprint_spice_idle_pb_graph_node_rec(FILE* fp, char* subckt_prefix, @@ -60,8 +60,7 @@ void fprint_spice_pb_graph_node_rec(FILE* fp, char* subckt_prefix, t_pb* cur_pb, t_pb_graph_node* cur_pb_graph_node, - int pb_type_index, - t_rr_node* pb_rr_graph); + int pb_type_index); void fprint_spice_block(FILE* fp, diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.c new file mode 100644 index 000000000..a439e03c0 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.c @@ -0,0 +1,207 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "rr_graph_swseg.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "spice_utils.h" +#include "spice_pbtypes.h" +#include "spice_primitive.h" + +void fprint_pb_primitive_generic(FILE* fp, + char* subckt_prefix, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + int index, + t_spice_model* spice_model) { + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_output_port = 0; + t_spice_model_port** output_ports = NULL; + int num_clock_port = 0; + t_spice_model_port** clock_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + t_spice_model_port* regular_sram_port = NULL; + t_spice_model_port* mode_bit_port = NULL; + + int i; + int num_sram = 0; + int expected_num_sram = 0; + int* sram_bits = NULL; + int cur_num_sram = 0; + t_spice_model* mem_model = NULL; + int mapped_logical_block_index = OPEN; + + char* formatted_subckt_prefix = format_spice_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ + char* port_prefix = NULL; + char* sram_vdd_port_name = NULL; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Asserts */ + assert((SPICE_MODEL_FF == spice_model->type) + ||(SPICE_MODEL_HARDLOGIC == spice_model->type) + ||(SPICE_MODEL_IOPAD == spice_model->type)); + + /* Find ports*/ + input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + clock_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, TRUE); + sram_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + + /* Find mapped logical block */ + if (NULL != prim_phy_pb) { + for (i = 0; i < prim_phy_pb->num_logical_blocks; i++) { + mapped_logical_block_index = prim_phy_pb->logical_block[i]; + /* Back-annotate to logical block */ + logical_block[mapped_logical_block_index].mapped_spice_model = spice_model; + logical_block[mapped_logical_block_index].mapped_spice_model_index = spice_model->cnt; + fprintf(fp, "***** Logical block mapped to this primitive node: %s *****\n", + logical_block[mapped_logical_block_index].name); + } + } + + /* Generate Subckt for pb_type*/ + /* + port_prefix = (char*)my_malloc(sizeof(char)* + (strlen(formatted_subckt_prefix) + strlen(prim_pb_type->name) + 1 + + strlen(my_itoa(index)) + 1 + 1)); + sprintf(port_prefix, "%s%s[%d]", formatted_subckt_prefix, prim_pb_type->name, index); + */ + /* Simplify the port prefix, make SPICE netlist readable */ + port_prefix = (char*)my_malloc(sizeof(char)* + (strlen(prim_pb_type->name) + 1 + + strlen(my_itoa(index)) + 1 + 1)); + sprintf(port_prefix, "%s[%d]", prim_pb_type->name, index); + + /* Decode SRAM bits */ + num_sram = count_num_sram_bits_one_spice_model(spice_model, -1); + /* what is the SRAM bit of a mode? */ + /* If logical block is not NULL, we need to decode the sram bit */ + if ( 0 < num_sram_port) { + assert (1 == num_sram_port); + if (NULL != prim_phy_pb) { + sram_bits = decode_mode_bits(prim_phy_pb->mode_bits, &expected_num_sram); + } else { /* get default mode_bits */ + sram_bits = decode_mode_bits(prim_pb_type->mode_bits, &expected_num_sram); + } + assert(expected_num_sram == num_sram); + } + + /* Get current counter of mem_bits, bl and wl */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); + + /* Definition line */ + fprintf(fp, ".subckt %s%s ", formatted_subckt_prefix, port_prefix); + /* print ports*/ + fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); + /* Local vdd and gnd*/ + fprintf(fp, "svdd sgnd\n"); + /* Definition ends*/ + + /* Call the iopad subckt*/ + fprintf(fp, "X%s[%d] ", spice_model->prefix, spice_model->cnt); + /* Only dump the global ports belonging to a spice_model + * Do not go recursive, we can freely define global ports anywhere in SPICE netlist + */ + if (0 < rec_fprint_spice_model_global_ports(fp, spice_model, FALSE)) { + fprintf(fp, "+ "); + } + /* print regular ports*/ + fprint_pb_type_ports(fp, port_prefix, 0, prim_pb_type); + /* Print inout port */ + if (SPICE_MODEL_IOPAD == spice_model->type) { + fprintf(fp, " %s%s[%d] ", + gio_inout_prefix, + spice_model->prefix, + spice_model->cnt); + } + /* Print SRAM ports */ + for (i = 0; i < num_sram; i++) { + fprint_spice_sram_one_outport(fp, sram_spice_orgz_info, cur_num_sram + i, sram_bits[i]); + /* We need the invertered signal for better convergency */ + fprint_spice_sram_one_outport(fp, sram_spice_orgz_info, cur_num_sram + i, 1 - sram_bits[i]); + } + + /* Local vdd and gnd, spice_model name, + * TODO: Global vdd for i/o pad to split? + */ + fprintf(fp, "%s_%s[%d] sgnd %s\n", + spice_tb_global_vdd_port_name, + spice_model->prefix, + spice_model->cnt, + spice_model->name); + + + /* Print the encoding in SPICE netlist for debugging */ + fprintf(fp, "***** SRAM bits for %s[%d] *****\n", + spice_model->prefix, + spice_model->cnt); + fprintf(fp, "*****"); + for (i = 0; i < num_sram; i++) { + fprintf(fp, "%d", sram_bits[i]); + } + fprintf(fp, "*****\n"); + + /* Call SRAM subckts*/ + /* Give the VDD port name for SRAMs */ + sram_vdd_port_name = (char*)my_malloc(sizeof(char)* + (strlen(spice_tb_global_vdd_io_sram_port_name) + + 1 )); + sprintf(sram_vdd_port_name, "%s", + spice_tb_global_vdd_io_sram_port_name); + /* Now Print SRAMs one by one */ + for (i = 0; i < num_sram; i++) { + fprint_spice_one_sram_subckt(fp, sram_spice_orgz_info, spice_model, sram_vdd_port_name); + } + + /* Store the configuraion bit to linked-list */ + add_sram_conf_bits_to_llist(sram_spice_orgz_info, cur_num_sram, + num_sram, sram_bits); + + /* End */ + fprintf(fp, ".eom\n"); + + /* Update the spice_model counter */ + spice_model->cnt++; + + /*Free*/ + my_free(formatted_subckt_prefix); + my_free(port_prefix); + my_free(sram_vdd_port_name); + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.h new file mode 100644 index 000000000..77dd4ee21 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive.h @@ -0,0 +1,8 @@ + + +void fprint_pb_primitive_generic(FILE* fp, + char* subckt_prefix, + t_phy_pb* prim_phy_pb, + t_pb_type* prim_pb_type, + int index, + t_spice_model* spice_model); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.c new file mode 100644 index 000000000..e3dfa4f19 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.c @@ -0,0 +1,1107 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "spice_utils.h" +#include "spice_mux.h" +#include "spice_pbtypes.h" +#include "spice_subckt.h" + +/* local global variables */ +static int tb_num_primitive = 0; +static int testbench_load_cnt = 0; +static int upbound_sim_num_clock_cycles = 2; +static int max_sim_num_clock_cycles = 2; +static int auto_select_max_sim_num_clock_cycles = TRUE; + +/* Subroutines in this source file*/ +/* Initialize the global parameters in this source file */ +static +void init_spice_primitive_testbench_globals(t_spice spice) { + tb_num_primitive = 0; + auto_select_max_sim_num_clock_cycles = spice.spice_params.meas_params.auto_select_sim_num_clk_cycle; + upbound_sim_num_clock_cycles = spice.spice_params.meas_params.sim_num_clock_cycle + 1; + if (FALSE == auto_select_max_sim_num_clock_cycles) { + max_sim_num_clock_cycles = spice.spice_params.meas_params.sim_num_clock_cycle + 1; + } else { + max_sim_num_clock_cycles = 2; + } +} + +/* Print Common global ports in the testbench */ +static +void fprint_spice_primitive_testbench_global_ports(FILE* fp, int grid_x, int grid_y, + int num_clock, + enum e_spice_tb_type primitive_tb_type, + t_spice spice) { + /* int i; */ + /* A valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__); + exit(1); + } + + /* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */ + /* Print generic global ports*/ + fprint_spice_generic_testbench_global_ports(fp, + sram_spice_orgz_info, + global_ports_head); + /* VDD Load port name */ + fprintf(fp, ".global %s\n", + spice_tb_global_vdd_load_port_name); + + /*Global Vdds for PRIMITIVEs */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, spice); + break; + case SPICE_HARDLOGIC_TB: + fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, spice); + fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, spice); + break; + case SPICE_IO_TB: + fprint_grid_global_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_IOPAD, spice); + /* Global VDDs for SRAMs of IOPADs */ + fprintf(fp, ".global %s\n\n", + spice_tb_global_vdd_io_sram_port_name); + + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Dump the subckt of a hardlogic and also the input stimuli */ +void fprint_spice_primitive_testbench_call_one_primitive(FILE* fp, + char* subckt_name, + char* primitive_type, + t_spice_model* primitive_spice_model) { + int iport, ipin; + + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_output_port = 0; + t_spice_model_port** output_ports = NULL; + int num_inout_port = 0; + t_spice_model_port** inout_ports = NULL; + int num_clk_port = 0; + t_spice_model_port** clk_ports = NULL; + + /* A valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File Handler!\n",__FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert(NULL != primitive_spice_model); + + /* identify the type of spice model */ + /* Call defined subckt */ + fprintf(fp, "X%s_%s[%d] \n+ ", + primitive_type, + primitive_spice_model->prefix, + primitive_spice_model->tb_cnt); + + /* Sequence in dumping ports: + * 1. Global ports - INCLUDED IN THE MODULE, SO WE SKIP THIS + * 2. Input ports + * 3. Output ports + * 4. Inout ports + * 5. Configuration ports + * 6. VDD and GND ports + */ + + /* 2. Input ports (TODO: check the number of inputs matches the spice model definition) */ + /* Find pb_type input ports */ + input_ports = find_spice_model_ports(primitive_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + for (iport = 0; iport < num_input_port; iport++) { + for (ipin = 0; ipin < input_ports[iport]->size; ipin++) { + fprintf(fp, "%s_%s[%d]->%s[%d] ", + primitive_type, + primitive_spice_model->prefix, + primitive_spice_model->tb_cnt, + input_ports[iport]->prefix, ipin); + } + } + if (NULL != input_ports) { + fprintf(fp, "\n"); + fprintf(fp, "+ "); + } + + /* 3. Output ports */ + /* Find pb_type output ports */ + output_ports = find_spice_model_ports(primitive_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_ports[iport]->size; ipin++) { + fprintf(fp, "%s_%s[%d]->%s[%d] ", + primitive_type, + primitive_spice_model->prefix, + primitive_spice_model->tb_cnt, + output_ports[iport]->prefix, ipin); + } + } + if (NULL != output_ports) { + fprintf(fp, "\n"); + fprintf(fp, "+ "); + } + + /* 4. Inout ports: INOUTs are currently global ports, so we do not put it here. */ + /* INOUT ports */ + /* Find pb_type inout ports */ + /* + inout_ports = find_spice_model_ports(primitive_spice_model, SPICE_MODEL_PORT_INOUT, &num_inout_port, TRUE); + for (iport = 0; iport < num_inout_port; iport++) { + for (ipin = 0; ipin < inout_ports[iport]->size; ipin++) { + fprintf(fp, "%s_%s[%d]->%s[%d] ", + primitive_type, + primitive_spice_model->prefix, + primitive_spice_model->tb_cnt, + inout_ports[iport]->prefix, ipin); + } + } + if (NULL != inout_ports) { + fprintf(fp, "\n"); + fprintf(fp, "+ "); + } + */ + + /* Clocks */ + /* Identify if the clock port is a global signal */ + /* Find pb_type clock ports */ + clk_ports = find_spice_model_ports(primitive_spice_model, SPICE_MODEL_PORT_CLOCK, &num_clk_port, TRUE); + for (iport = 0; iport < num_clk_port; iport++) { + for (ipin = 0; ipin < clk_ports[iport]->size; ipin++) { + fprintf(fp, "%s_%s[%d]->%s[%d] ", + primitive_type, + primitive_spice_model->prefix, + primitive_spice_model->tb_cnt, + clk_ports[iport]->prefix, ipin); + } + } + if (NULL != clk_ports) { + fprintf(fp, "\n"); + fprintf(fp, "+ "); + } + + /* 5. Configuration ports */ + /* Generate SRAMs? */ + + /* 6. VDD and GND ports */ + fprintf(fp, "%s_%s[%d] %s ", + spice_tb_global_vdd_port_name, + primitive_spice_model->prefix, + primitive_spice_model->tb_cnt, + spice_tb_global_gnd_port_name); + fprintf(fp, "\n"); + fprintf(fp, "+ "); + + /* Call the name of subckt */ + fprintf(fp, "%s\n", subckt_name); + + /* Free */ + my_free(input_ports); + my_free(output_ports); + my_free(inout_ports); + my_free(clk_ports); + + return; +} + +void fprint_spice_primitive_testbench_one_primitive_input_stimuli(FILE* fp, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, + char* prefix, + int x, int y, + char* primitive_type, + t_ivec*** LL_rr_node_indices) { + int iport, ipin; + t_spice_model* pb_spice_model = cur_pb_graph_node->pb_type->spice_model; + t_rr_node* local_rr_graph = NULL; + + /* For pb_spice_model */ + int num_input_port; + t_spice_model_port** input_ports; + + /* Two-dimension arrays, corresponding to the port map [port_id][pin_id] */ + float** input_density = NULL; + float** input_probability = NULL; + int** input_init_value = NULL; + int** input_net_num = NULL; + + float average_density = 0.; + int avg_density_cnt = 0; + int num_sim_clock_cycles = 0; + + /* Malloc */ + /* First dimension */ + input_density = (float**)my_malloc(sizeof(float*) * cur_pb_graph_node->num_input_ports); + input_probability = (float**)my_malloc(sizeof(float*) * cur_pb_graph_node->num_input_ports); + input_init_value = (int**)my_malloc(sizeof(int*) * cur_pb_graph_node->num_input_ports); + input_net_num = (int**)my_malloc(sizeof(int*) * cur_pb_graph_node->num_input_ports); + /* Second dimension */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + input_density[iport] = (float*)my_malloc(sizeof(float) * cur_pb_graph_node->num_input_pins[iport]); + input_probability[iport] = (float*)my_malloc(sizeof(float) * cur_pb_graph_node->num_input_pins[iport]); + input_init_value[iport] = (int*)my_malloc(sizeof(int) * cur_pb_graph_node->num_input_pins[iport]); + input_net_num[iport] = (int*)my_malloc(sizeof(int) * cur_pb_graph_node->num_input_pins[iport]); + } + + /* Get activity information */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + /* if we find a mapped logic block */ + if (NULL != cur_pb) { + local_rr_graph = cur_pb->rr_graph->rr_node; + } else { + local_rr_graph = NULL; + } + input_net_num[iport][ipin] = pb_pin_net_num(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); + input_density[iport][ipin] = pb_pin_density(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); + input_probability[iport][ipin] = pb_pin_probability(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); + input_init_value[iport][ipin] = pb_pin_init_value(local_rr_graph, &(cur_pb_graph_node->input_pins[iport][ipin])); + } + } + + /* Add Input stimulates */ + /* Get the input port list of spice model */ + input_ports = find_spice_model_ports(pb_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + /* Check if the port map of current pb_graph_node matches that of the spice model !!!*/ + assert(num_input_port == cur_pb_graph_node->num_input_ports); + for (iport = 0; iport < num_input_port; iport++) { + assert(input_ports[iport]->size == cur_pb_graph_node->num_input_pins[iport]); + for (ipin = 0; ipin < input_ports[iport]->size; ipin++) { + /* Check the port size should match!*/ + fprintf(fp, "V%s_%s[%d]->%s[%d] %s_%s[%d]->%s[%d] 0 \n", + primitive_type, + pb_spice_model->prefix, + pb_spice_model->tb_cnt, + cur_pb_graph_node->input_pins[iport]->port->name, + ipin, + primitive_type, + pb_spice_model->prefix, + pb_spice_model->tb_cnt, + input_ports[iport]->prefix, + ipin); + fprint_voltage_pulse_params(fp, input_init_value[iport][ipin], input_density[iport][ipin], input_probability[iport][ipin]); + } + } + + /* Calculate average density of this hardlogic */ + average_density = 0.; + avg_density_cnt = 0; + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + assert(!(0 > input_density[iport][ipin])); + if (0. < input_density[iport][ipin]) { + average_density += input_density[iport][ipin]; + avg_density_cnt++; + } + } + } + /* Calculate the num_sim_clock_cycle for this MUX, update global max_sim_clock_cycle in this testbench */ + if (0 < avg_density_cnt) { + average_density = average_density/avg_density_cnt; + } else { + assert(0 == avg_density_cnt); + average_density = 0.; + } + if (0. == average_density) { + num_sim_clock_cycles = 2; + } else { + assert(0. < average_density); + num_sim_clock_cycles = (int)(1/average_density) + 1; + } + if (TRUE == auto_select_max_sim_num_clock_cycles) { + /* for idle blocks, 2 clock cycle is well enough... */ + if (2 < num_sim_clock_cycles) { + num_sim_clock_cycles = upbound_sim_num_clock_cycles; + } else { + num_sim_clock_cycles = 2; + } + if (max_sim_num_clock_cycles < num_sim_clock_cycles) { + max_sim_num_clock_cycles = num_sim_clock_cycles; + } + } else { + num_sim_clock_cycles = max_sim_num_clock_cycles; + } + + /* Free */ + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + my_free(input_net_num[iport]); + my_free(input_init_value[iport]); + my_free(input_density[iport]); + my_free(input_probability[iport]); + } + my_free(input_net_num); + my_free(input_init_value); + my_free(input_density); + my_free(input_probability); + my_free(input_ports); + + return; +} + +void fprint_spice_primitive_testbench_one_primitive_output_loads(FILE* fp, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, + char* prefix, + int x, int y, + char* primitive_type, + t_ivec*** LL_rr_node_indices) { + int iport, ipin; + int num_output_port = 0; + t_spice_model_port** output_ports = NULL; + t_spice_model* pb_spice_model = cur_pb_graph_node->pb_type->spice_model; + char* outport_name = NULL; + + /* Add loads: Recursively */ + /* Get the output port list of spice model */ + output_ports = find_spice_model_ports(pb_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_ports[iport]->size; ipin++) { + outport_name = (char*)my_malloc(sizeof(char)*( strlen(primitive_type) + 1 + + strlen(pb_spice_model->prefix) + 1 + + strlen(my_itoa(pb_spice_model->tb_cnt)) + + 3 + strlen(output_ports[iport]->prefix) + 1 + + strlen(my_itoa(ipin)) + 2 )); + sprintf(outport_name, "%s_%s[%d]->%s[%d]", + primitive_type, + pb_spice_model->prefix, + pb_spice_model->tb_cnt, + output_ports[iport]->prefix, + ipin); + if (TRUE == run_testbench_load_extraction) { /* Additional switch, default on! */ + if (NULL != cur_pb) { + fprint_spice_testbench_pb_graph_pin_inv_loads_rec(fp, &testbench_load_cnt, + x, y, + &(cur_pb_graph_node->output_pins[0][0]), + cur_pb, + outport_name, + FALSE, + LL_rr_node_indices); + } else { + fprint_spice_testbench_pb_graph_pin_inv_loads_rec(fp, &testbench_load_cnt, + x, y, + &(cur_pb_graph_node->output_pins[0][0]), + NULL, + outport_name, + FALSE, + LL_rr_node_indices); + } + } + /* Free outport_name in each iteration */ + my_free(outport_name); + } + } + + /* Free */ + my_free(output_ports); + + return; +} + +/** Core function: print the main body of this testbench + * 1. Print the primitive subckt + * 2. Add input stimuli + * 3. Add loads + */ +void fprint_spice_primitive_testbench_one_pb_primitive(FILE* fp, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, + char* prefix, + int x, int y, + enum e_spice_tb_type primitive_tb_type, + t_ivec*** LL_rr_node_indices) { + t_spice_model* pb_spice_model = NULL; + char* primitive_type = NULL; + + assert(NULL != cur_pb_graph_node); + assert(NULL != prefix); + + pb_spice_model = cur_pb_graph_node->pb_type->spice_model; + + /* Name the primitive subckt */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + primitive_type = "lut"; + /* If the spice model is not the type we want, return here */ + if (SPICE_MODEL_LUT != pb_spice_model->type) { + return; + } + break; + case SPICE_HARDLOGIC_TB: + primitive_type = "hardlogic"; + /* If the spice model is not the type we want, return here */ + if ((SPICE_MODEL_FF != pb_spice_model->type) + && (SPICE_MODEL_HARDLOGIC != pb_spice_model->type)) { + return; + } + break; + case SPICE_IO_TB: + primitive_type = "io"; + /* If the spice model is not the type we want, return here */ + if (SPICE_MODEL_IOPAD != pb_spice_model->type) { + return; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Now, we print the SPICE subckt of a hard logic */ + fprint_spice_primitive_testbench_call_one_primitive(fp, + prefix, + primitive_type, + pb_spice_model); + + /* Add input stimuli */ + fprint_spice_primitive_testbench_one_primitive_input_stimuli(fp, + cur_pb, + cur_pb_graph_node, + prefix, + x, y, + primitive_type, + LL_rr_node_indices); + + /* Add loads */ + fprint_spice_primitive_testbench_one_primitive_output_loads(fp, + cur_pb, + cur_pb_graph_node, + prefix, + x, y, + primitive_type, + LL_rr_node_indices); + + /* Increment the counter of the hardlogic spice model */ + pb_spice_model->tb_cnt++; + tb_num_primitive++; + + return; +} + +void fprint_spice_primitive_testbench_rec_pb_primitives(FILE* fp, + t_phy_pb* cur_pb, + t_pb_graph_node* cur_pb_graph_node, + char* prefix, + int x, int y, + enum e_spice_tb_type primitive_tb_type, + t_ivec*** LL_rr_node_indices) { + char* formatted_prefix = format_spice_node_prefix(prefix); + int ipb, jpb; + int mode_index; + char* rec_prefix = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + if (NULL == cur_pb) { + assert(NULL != cur_pb_graph_node); + } else { + assert (cur_pb_graph_node == cur_pb->pb_graph_node); + } + + /* If we touch the leaf, there is no need print interc*/ + if (TRUE == is_primitive_pb_type(cur_pb_graph_node->pb_type)) { + /* Generate rec_prefix */ + rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) + + strlen(cur_pb_graph_node->pb_type->name) + 1 + + strlen(my_itoa(cur_pb_graph_node->placement_index)) + + 1 + 1)); + sprintf(rec_prefix, "%s%s[%d]", + formatted_prefix, + cur_pb_graph_node->pb_type->name, + cur_pb_graph_node->placement_index); + /* Print a lut tb: call spice_model, stimulates */ + fprint_spice_primitive_testbench_one_pb_primitive(fp, + cur_pb, + cur_pb_graph_node, + rec_prefix, x, y, + primitive_tb_type, + LL_rr_node_indices); + my_free(rec_prefix); + return; + } + + /* Go recursively ... */ + if (NULL == cur_pb) { + mode_index = find_pb_type_physical_mode_index(*(cur_pb_graph_node->pb_type)); + } else { + mode_index = cur_pb->mode; + } + + if (!(0 < cur_pb_graph_node->pb_type->num_modes)) { + return; + } + for (ipb = 0; ipb < cur_pb_graph_node->pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + /* Generate rec_prefix */ + rec_prefix = (char*)my_malloc(sizeof(char) * (strlen(formatted_prefix) + + strlen(cur_pb_graph_node->pb_type->name) + 1 + + strlen(my_itoa(cur_pb_graph_node->placement_index)) + 7 + + strlen(cur_pb_graph_node->pb_type->modes[mode_index].name) + 1 + 1)); + sprintf(rec_prefix, "%s%s[%d]_mode[%s]", + formatted_prefix, cur_pb_graph_node->pb_type->name, + cur_pb_graph_node->placement_index, + cur_pb_graph_node->pb_type->modes[mode_index].name); + if (((NULL == cur_pb) + || ((NULL == cur_pb->child_pbs[ipb])||(NULL == cur_pb->child_pbs[ipb][jpb].name)))) { + /* Then we go on */ + fprint_spice_primitive_testbench_rec_pb_primitives(fp, + NULL, + &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), + rec_prefix, x, y, + primitive_tb_type, + LL_rr_node_indices); + } else { + assert ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)); + /* Refer to pack/output_clustering.c [LINE 392] */ + fprint_spice_primitive_testbench_rec_pb_primitives(fp, + &(cur_pb->child_pbs[ipb][jpb]), + cur_pb->child_pbs[ipb][jpb].pb_graph_node, + rec_prefix, x, y, + primitive_tb_type, + LL_rr_node_indices); + } + } + } + + return; +} + +void fprint_spice_primitive_testbench_call_one_grid_defined_primitives(FILE* fp, + int ix, int iy, + enum e_spice_tb_type primitive_tb_type, + t_ivec*** LL_rr_node_indices) { + int iblk; + char* prefix = NULL; + + if ((NULL == grid[ix][iy].type) + ||(EMPTY_TYPE == grid[ix][iy].type) + ||(0 != grid[ix][iy].offset)) { + return; + } + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d])Invalid File Handler!\n", + __FILE__, __LINE__); + exit(1); + } + + for (iblk = 0; iblk < grid[ix][iy].usage; iblk++) { + prefix = (char*)my_malloc(sizeof(char)* (5 + + strlen(my_itoa(ix)) + + 2 + strlen(my_itoa(iy)) + + 3 )); + sprintf(prefix, "grid[%d][%d]_", + ix, + iy); + /* Only for mapped block */ + assert(NULL != block[grid[ix][iy].blocks[iblk]].phy_pb); + /* It is weird that some used block has an invalid ID */ + if (OPEN == grid[ix][iy].blocks[iblk]) { + /* Mark the temporary net_num for the type pins*/ + mark_grid_type_pb_graph_node_pins_temp_net_num(ix, iy); + /* Go into the hierachy and dump hardlogics */ + fprint_spice_primitive_testbench_rec_pb_primitives(fp, + NULL, + grid[ix][iy].type->pb_graph_head, + prefix, ix, iy, + primitive_tb_type, + LL_rr_node_indices); + continue; + } + /* Mark the temporary net_num for the type pins*/ + mark_one_pb_parasitic_nets((t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb); + /* Go into the hierachy and dump hardlogics */ + fprint_spice_primitive_testbench_rec_pb_primitives(fp, + (t_phy_pb*)block[grid[ix][iy].blocks[iblk]].phy_pb, + grid[ix][iy].type->pb_graph_head, + prefix, ix, iy, + primitive_tb_type, + LL_rr_node_indices); + /* Free */ + my_free(prefix); + } + /* Bypass unused blocks */ + for (iblk = grid[ix][iy].usage; iblk < grid[ix][iy].type->capacity; iblk++) { + prefix = (char*)my_malloc(sizeof(char)* (5 + strlen(my_itoa(ix)) + + 2 + strlen(my_itoa(iy)) + 3 )); + sprintf(prefix, "grid[%d][%d]_", ix, iy); + assert(NULL != grid[ix][iy].type->pb_graph_head); + /* Mark the temporary net_num for the type pins*/ + mark_grid_type_pb_graph_node_pins_temp_net_num(ix, iy); + /* Go into the hierachy and dump hardlogics */ + fprint_spice_primitive_testbench_rec_pb_primitives(fp, + NULL, + grid[ix][iy].type->pb_graph_head, + prefix, ix, iy, + primitive_tb_type, + LL_rr_node_indices); + /* Free */ + my_free(prefix); + } + + return; +} + +static +void fprint_spice_primitive_testbench_stimulations(FILE* fp, int grid_x, int grid_y, + int num_clocks, + t_spice spice, + enum e_spice_tb_type primitive_tb_type, + t_ivec*** LL_rr_node_indices) { + /* Print generic stimuli */ + fprint_spice_testbench_generic_global_ports_stimuli(fp, num_clocks); + + /* Generate global ports stimuli */ + fprint_spice_testbench_global_ports_stimuli(fp, global_ports_head); + + /* SRAM ports */ + fprintf(fp, "***** Global Inputs for SRAMs *****\n"); + fprint_spice_testbench_global_sram_inport_stimuli(fp, sram_spice_orgz_info); + + fprintf(fp, "***** Global VDD for SRAMs *****\n"); + fprint_spice_testbench_global_vdd_port_stimuli(fp, + spice_tb_global_vdd_sram_port_name, + "vsp"); + + fprintf(fp, "***** Global VDD for load inverters *****\n"); + fprint_spice_testbench_global_vdd_port_stimuli(fp, + spice_tb_global_vdd_load_port_name, + "vsp"); + + switch (primitive_tb_type) { + case SPICE_LUT_TB: + /* Every LUT use an independent Voltage source */ + fprintf(fp, "***** Global VDD for LUTs *****\n"); + fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, spice); + break; + case SPICE_HARDLOGIC_TB: + /* Every Hardlogic use an independent Voltage source */ + fprintf(fp, "***** Global VDD for FFs *****\n"); + fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, spice); + fprintf(fp, "***** Global VDD for Hardlogics *****\n"); + fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, spice); + break; + case SPICE_IO_TB: + /* Every IO use an independent Voltage source */ + fprintf(fp, "***** Global VDD for IOs *****\n"); + fprint_grid_splited_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_IOPAD, spice); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +void fprint_spice_primitive_testbench_measurements(FILE* fp, int grid_x, int grid_y, + t_spice spice, + enum e_spice_tb_type primitive_tb_type, + boolean leakage_only) { + + /* int i; */ + /* First cycle reserved for measuring leakage */ + int num_clock_cycle = max_sim_num_clock_cycles; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + fprint_spice_netlist_transient_setting(fp, spice, num_clock_cycle, leakage_only); + fprint_spice_netlist_generic_measurements(fp, spice.spice_params.mc_params, spice.num_spice_model, spice.spice_models); + + /* TODO: Measure the delay of each mapped net and logical block */ + + /* Measure the power */ + /* Leakage ( the first cycle is reserved for leakage measurement) */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + /* Leakage power of LUTs*/ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); + break; + case SPICE_HARDLOGIC_TB: + /* Leakage power of FFs*/ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); + /* Leakage power of Hardlogic */ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); + break; + case SPICE_IO_TB: + /* Leakage power of LUTs*/ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_IOPAD, SPICE_MEASURE_LEAKAGE_POWER, num_clock_cycle, spice, leakage_only); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + if (TRUE == leakage_only) { + return; + } + + /* Dynamic power */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + /* Dynamic power of FFs */ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_LUT, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); + break; + case SPICE_HARDLOGIC_TB: + /* Dynamic power of FFs */ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_FF, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); + /* Dynamic power of Hardlogics */ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_HARDLOGIC, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); + break; + case SPICE_IO_TB: + /* Dynamic power of FFs */ + fprint_measure_grid_vdds_spice_model(fp, grid_x, grid_y, SPICE_MODEL_IOPAD, SPICE_MEASURE_DYNAMIC_POWER, num_clock_cycle, spice, leakage_only); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Top-level function in this source file */ +int fprint_spice_one_primitive_testbench(char* formatted_spice_dir, + char* circuit_name, + char* primitive_testbench_name, + char* include_dir_path, + char* subckt_dir_path, + t_ivec*** LL_rr_node_indices, + int num_clock, + t_arch arch, + int grid_x, int grid_y, + enum e_spice_tb_type primitive_tb_type, + boolean leakage_only) { + FILE* fp = NULL; + char* formatted_subckt_dir_path = format_dir_path(subckt_dir_path); + char* temp_include_file_path = NULL; + char* title = NULL; + char* primitive_testbench_file_path = NULL; + int used; + + /* Name the testbench */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + title = my_strcat("FPGA LUT Testbench for Design: ", circuit_name); + /* vpr_printf(TIO_MESSAGE_INFO, "Writing LUT Testbench for %s...\n", circuit_name); */ + break; + case SPICE_HARDLOGIC_TB: + title = my_strcat("FPGA Hard Logic Testbench for Design: ", circuit_name); + /* vpr_printf(TIO_MESSAGE_INFO, "Writing Hard Logic Testbench for %s...\n", circuit_name); */ + break; + case SPICE_IO_TB: + title = my_strcat("FPGA IO Testbench for Design: ", circuit_name); + /* vpr_printf(TIO_MESSAGE_INFO, "Writing IO Testbench for %s...\n", circuit_name); */ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + primitive_testbench_file_path = my_strcat(formatted_spice_dir, primitive_testbench_name); + + /* Check if the path exists*/ + fp = fopen(primitive_testbench_file_path,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create Primitive Testbench SPICE netlist %s!", + __FILE__, __LINE__, + primitive_testbench_file_path); + exit(1); + } + + /* Reset tb_cnt for all the spice models */ + init_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y); + + testbench_load_cnt = 0; + + /* Print the title */ + fprint_spice_head(fp, title); + my_free(title); + + /* print technology library and design parameters*/ + /* fprint_tech_lib(fp, arch.spice->tech_lib);*/ + + /* Include parameter header files */ + fprint_spice_include_param_headers(fp, include_dir_path); + + /* Include Key subckts */ + fprint_spice_include_key_subckts(fp, subckt_dir_path); + + /* Include user-defined sub-circuit netlist */ + init_include_user_defined_netlists(*(arch.spice)); + fprint_include_user_defined_netlists(fp, *(arch.spice)); + + fprintf(fp, "****** Include subckt netlists: LUTs *****\n"); + temp_include_file_path = my_strcat(formatted_subckt_dir_path, luts_spice_file_name); + fprintf(fp, ".include \'%s\'\n", temp_include_file_path); + my_free(temp_include_file_path); + + /* Generate filename */ + fprintf(fp, "****** Include subckt netlists: Grid[%d][%d] *****\n", + grid_x, grid_y); + temp_include_file_path = fpga_spice_create_one_subckt_filename(grid_spice_file_name_prefix, grid_x, grid_y, spice_netlist_file_postfix); + /* Check if we include an existing file! */ + if (FALSE == check_subckt_file_exist_in_llist(grid_spice_subckt_file_path_head, + my_strcat(formatted_subckt_dir_path, temp_include_file_path))) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Intend to include a non-existed SPICE netlist %s!\n", + __FILE__, __LINE__, temp_include_file_path); + exit(1); + } + spice_print_one_include_subckt_line(fp, formatted_subckt_dir_path, temp_include_file_path); + + + /* Print simulation temperature and other options for SPICE */ + fprint_spice_options(fp, arch.spice->spice_params); + + /* Global nodes: Vdd for SRAMs, Logic Blocks(Include IO), Switch Boxes, Connection Boxes */ + fprint_spice_primitive_testbench_global_ports(fp, + grid_x, grid_y, num_clock, + primitive_tb_type, + (*arch.spice)); + + /* Initialize global variables in this testbench */ + init_spice_primitive_testbench_globals(*(arch.spice)); + + /* Quote defined Logic blocks subckts (Grids) */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, + arch.spice->spice_models, + SPICE_MODEL_LUT); + break; + case SPICE_HARDLOGIC_TB: + init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, + arch.spice->spice_models, + SPICE_MODEL_FF); + init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, + arch.spice->spice_models, + SPICE_MODEL_HARDLOGIC); + break; + case SPICE_IO_TB: + init_logical_block_spice_model_type_temp_used(arch.spice->num_spice_model, + arch.spice->spice_models, + SPICE_MODEL_IOPAD); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Now start our job formally: dump hard logic circuit one by one */ + fprint_spice_primitive_testbench_call_one_grid_defined_primitives(fp, + grid_x, grid_y, + primitive_tb_type, + LL_rr_node_indices); + + /* Back-anotate activity information to each routing resource node + * (We should have activity of each Grid port) + */ + + /* Check if the all hardlogic located in this grid have been printed */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_LUT); + break; + case SPICE_HARDLOGIC_TB: + check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_FF); + check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_HARDLOGIC); + break; + case SPICE_IO_TB: + check_spice_models_grid_tb_cnt(arch.spice->num_spice_model, arch.spice->spice_models, grid_x, grid_y, SPICE_MODEL_IOPAD); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Add stimulations */ + fprint_spice_primitive_testbench_stimulations(fp, grid_x, grid_y, num_clock, (*arch.spice), primitive_tb_type, LL_rr_node_indices); + + /* Add measurements */ + fprint_spice_primitive_testbench_measurements(fp, grid_x, grid_y, (*arch.spice), primitive_tb_type, leakage_only); + + /* SPICE ends*/ + fprintf(fp, ".end\n"); + + /* Close the file*/ + fclose(fp); + + if (0 < tb_num_primitive) { + /* + vpr_printf(TIO_MESSAGE_INFO, "Writing Grid[%d][%d] SPICE Hard Logic Testbench for %s...\n", + grid_x, grid_y, circuit_name); + */ + /* Push the testbench to the linked list */ + tb_head = add_one_spice_tb_info_to_llist(tb_head, primitive_testbench_file_path, + max_sim_num_clock_cycles); + used = 1; + } else { + /* Remove the file generated */ + my_remove_file(primitive_testbench_file_path); + used = 0; + } + + return used; +} + +/* Top-level function in this source file */ +void spice_print_primitive_testbench(char* formatted_spice_dir, + char* circuit_name, + char* include_dir_path, + char* subckt_dir_path, + t_ivec*** LL_rr_node_indices, + int num_clock, + t_arch arch, + enum e_spice_tb_type primitive_tb_type, + boolean leakage_only) { + char* primitive_testbench_name = NULL; + char* primitive_testbench_postfix = NULL; + int ix, iy; + int cnt = 0; + int used = 0; + + + /* Other testbenches consider the core logic only */ + for (ix = 0; ix < (nx + 2); ix++) { + for (iy = 0; iy < (ny + 2); iy++) { + /* Bypass EMPTY GRIDs */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + /* If this is a block on perimeter, + * bypass the grid unless IO_testbench is required + */ + if ( ( (nx + 1 == ix) || (0 == ix) + || (ny + 1 == iy) || (0 == iy) ) + && (SPICE_IO_TB != primitive_tb_type)) { + continue; + } + /* Name the testbench */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + primitive_testbench_postfix = spice_lut_testbench_postfix; + break; + case SPICE_HARDLOGIC_TB: + primitive_testbench_postfix = spice_hardlogic_testbench_postfix; + break; + case SPICE_IO_TB: + primitive_testbench_postfix = spice_io_testbench_postfix; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + primitive_testbench_name = (char*)my_malloc(sizeof(char)*( strlen(circuit_name) + + 6 + strlen(my_itoa(ix)) + 1 + + strlen(my_itoa(iy)) + 1 + + strlen(primitive_testbench_postfix) + 1 )); + sprintf(primitive_testbench_name, "%s_grid%d_%d%s", + circuit_name, ix, iy, primitive_testbench_postfix); + /* Start building one testbench */ + used = fprint_spice_one_primitive_testbench(formatted_spice_dir, + circuit_name, primitive_testbench_name, + include_dir_path, subckt_dir_path, LL_rr_node_indices, + num_clock, arch, ix, iy, + primitive_tb_type, + leakage_only); + if (1 == used) { + cnt += used; + } + /* free */ + my_free(primitive_testbench_name); + } + } + /* Update the global counter */ + switch (primitive_tb_type) { + case SPICE_LUT_TB: + num_used_lut_tb = cnt; + vpr_printf(TIO_MESSAGE_INFO, + "No. of generated LUT testbench = %d\n", + num_used_lut_tb); + break; + case SPICE_HARDLOGIC_TB: + num_used_hardlogic_tb = cnt; + vpr_printf(TIO_MESSAGE_INFO, + "No. of generated hardlogic testbench = %d\n", + num_used_hardlogic_tb); + break; + case SPICE_IO_TB: + num_used_io_tb = cnt; + vpr_printf(TIO_MESSAGE_INFO, + "No. of generated IO testbench = %d\n", + num_used_io_tb); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid primitive_tb_type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.h new file mode 100644 index 000000000..09d46c206 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_primitive_testbench.h @@ -0,0 +1,10 @@ + +void spice_print_primitive_testbench(char* formatted_spice_dir, + char* circuit_name, + char* include_dir_path, + char* subckt_dir_path, + t_ivec*** LL_rr_node_indices, + int num_clock, + t_arch arch, + enum e_spice_tb_type primitive_tb_type, + boolean leakage_only); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c similarity index 94% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c index 3165964d0..3157fc9de 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.c @@ -20,17 +20,23 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "vpr_utils.h" +#include "route_common.h" + +/* Include FPGA-SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" /* Include SPICE support headers*/ -#include "linkedlist.h" -#include "fpga_spice_globals.h" -#include "spice_globals.h" -#include "fpga_spice_utils.h" #include "spice_utils.h" #include "spice_mux.h" #include "spice_lut.h" -#include "spice_primitives.h" -#include "fpga_spice_backannotate_utils.h" +#include "fpga_x2p_backannotate_utils.h" #include "spice_routing.h" @@ -458,52 +464,27 @@ void fprint_switch_box_mux(FILE* fp, fprint_switch_box_chan_port(fp, cur_sb_info, chan_side, cur_rr_node, OUT_PORT); /* Configuration bits for this MUX*/ - path_id = -1; + path_id = DEFAULT_PATH_ID; for (inode = 0; inode < mux_size; inode++) { if (drive_rr_nodes[inode] == &(rr_node[cur_rr_node->prev_node])) { path_id = inode; break; } } - - if (!((-1 != path_id)&&(path_id < mux_size))) { - assert((-1 != path_id)&&(path_id < mux_size)); - } - - switch (spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - mux_level = determine_tree_mux_level(mux_size); - num_mux_sram_bits = mux_level; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, mux_level, path_id); + /* Depend on both technology and structure of this MUX*/ + switch (spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(spice_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - mux_level = 1; - /* Special for 2-input MUX */ - if (2 == mux_size) { - num_mux_sram_bits = 1; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, mux_level, path_id); - } else { - num_mux_sram_bits = mux_size; - mux_sram_bits = decode_onelevel_mux_sram_bits(mux_size, mux_level, path_id); - } - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - /* Take care of corner case: MUX size = 2 */ - if (2 == mux_size) { - mux_level = 1; - num_mux_sram_bits = 1; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, 1, path_id); - } else { - mux_level = spice_model->design_tech_info.mux_num_level; - num_mux_sram_bits = determine_num_input_basis_multilevel_mux(mux_size, mux_level) * mux_level; - mux_sram_bits = decode_multilevel_mux_sram_bits(mux_size, mux_level, path_id); - } + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(spice_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for spice model (%s)!\n", __FILE__, __LINE__, spice_model->name); exit(1); - } + } + /* Print SRAMs that configure this MUX */ /* Get current counter of mem_bits, bl and wl */ cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); @@ -594,12 +575,12 @@ void fprint_switch_box_interc(FILE* fp, } else if (1 == num_drive_rr_nodes) { /* Print a direct connection*/ fprint_switch_box_short_interc(fp, cur_sb_info, chan_side, cur_rr_node, - num_drive_rr_nodes, drive_rr_nodes[0]); + num_drive_rr_nodes, drive_rr_nodes[DEFAULT_SWITCH_ID]); } else if (1 < num_drive_rr_nodes) { /* Print the multiplexer, fan_in >= 2 */ fprint_switch_box_mux(fp, cur_sb_info, chan_side, cur_rr_node, num_drive_rr_nodes, drive_rr_nodes, - cur_rr_node->drive_switches[0]); + cur_rr_node->drive_switches[DEFAULT_SWITCH_ID]); } /*Nothing should be done else*/ /* Free */ @@ -854,16 +835,15 @@ void fprint_connection_box_mux(FILE* fp, drive_rr_nodes = src_rr_node->drive_rr_nodes; /* Configuration bits for MUX*/ - path_id = -1; + path_id = DEFAULT_PATH_ID; for (inode = 0; inode < mux_size; inode++) { if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { path_id = inode; break; } } - assert((-1 != path_id)&&(path_id < mux_size)); - switch_index = src_rr_node->drive_switches[path_id]; + switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID]; mux_spice_model = switch_inf[switch_index].spice_model; @@ -905,40 +885,18 @@ void fprint_connection_box_mux(FILE* fp, cur_cb_info.ipin_rr_node_grid_side[side][index], xlow, ylow); - switch (mux_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_TREE: - mux_level = determine_tree_mux_level(mux_size); - num_mux_sram_bits = mux_level; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, mux_level, path_id); + switch (mux_spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + decode_cmos_mux_sram_bits(mux_spice_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; - case SPICE_MODEL_STRUCTURE_ONELEVEL: - mux_level = 1; - /* Special for 2-input MUX */ - if (2 == mux_size) { - num_mux_sram_bits = 1; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, mux_level, path_id); - } else { - num_mux_sram_bits = mux_size; - mux_sram_bits = decode_onelevel_mux_sram_bits(mux_size, mux_level, path_id); - } - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - /* Take care of corner case: MUX size = 2 */ - if (2 == mux_size) { - num_mux_sram_bits = 1; - mux_sram_bits = decode_tree_mux_sram_bits(mux_size, 1, path_id); - } else { - mux_level = mux_spice_model->design_tech_info.mux_num_level; - num_mux_sram_bits = determine_num_input_basis_multilevel_mux(mux_size, mux_level) * mux_level; - mux_sram_bits = decode_multilevel_mux_sram_bits(mux_size, mux_level, path_id); - } + case SPICE_MODEL_DESIGN_RRAM: + decode_rram_mux(mux_spice_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for spice model (%s)!\n", + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for spice model (%s)!\n", __FILE__, __LINE__, mux_spice_model->name); - exit(1); - } - + } + /* Print SRAMs that configure this MUX */ /* Get current counter of mem_bits, bl and wl */ cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_spice_orgz_info); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing_testbench.c similarity index 99% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing_testbench.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing_testbench.c index ea1be2060..00a5bcd15 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing_testbench.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing_testbench.c @@ -20,12 +20,15 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" #include "spice_utils.h" #include "spice_routing.h" #include "spice_subckt.h" diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing_testbench.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_routing_testbench.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_routing_testbench.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_run_scripts.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_run_scripts.c similarity index 66% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_run_scripts.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_run_scripts.c index d39d37334..fcdb07c61 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_run_scripts.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_run_scripts.c @@ -24,24 +24,15 @@ /* Include spice support headers*/ #include "read_xml_spice_util.h" #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" -#include "spice_subckt.h" -#include "spice_pbtypes.h" -#include "spice_heads.h" -#include "spice_lut.h" -#include "spice_top_netlist.h" -#include "spice_mux_testbench.h" -#include "spice_grid_testbench.h" -#include "spice_lut_testbench.h" -#include "spice_hardlogic_testbench.h" -#include "spice_routing_testbench.h" +#include "fpga_x2p_utils.h" static char* run_hspice_shell_script_name = "run_hspice_sim.sh"; static char* sim_results_dir_name = "results/"; void fprint_run_hspice_shell_script(t_spice spice, + char* spice_simulator_path, char* spice_dir_path, char* subckt_dir_path) { FILE* fp = NULL; @@ -63,7 +54,9 @@ void fprint_run_hspice_shell_script(t_spice spice, /* Check if the path exists*/ fp = fopen(shell_script_path,"w"); if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create Shell Script for running HSPICE %s!",__FILE__, __LINE__, shell_script_path); + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create Shell Script for running HSPICE %s!", + __FILE__, __LINE__, shell_script_path); exit(1); } @@ -72,7 +65,13 @@ void fprint_run_hspice_shell_script(t_spice spice, /* For VerilogA initilization */ if (1 == rram_design_tech) { fprintf(fp, "cd %s\n", subckt_dir_path); - fprintf(fp, "source /uusoc/facility/cad_common/Synopsys/hspice_vM-2017.03/hspice/bin/cshrc.meta\n"); + /* Error out when there is no specified simulator path */ + if (NULL == spice_simulator_path) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])SPICE simulator path must be specified when RRAM tech is used!", + __FILE__, __LINE__); + exit(1); + } + fprintf(fp, "source %s/cshrc.meta\n", spice_simulator_path); } total_num_sim = 0; @@ -90,24 +89,32 @@ void fprint_run_hspice_shell_script(t_spice spice, num_sim_clock_cycle = ((t_spicetb_info*)(temp->dptr))->num_sim_clock_cycles; chomped_testbench_file = chomp_file_name_postfix(testbench_file); split_path_prog_name(chomped_testbench_file,'/',&chomped_testbench_path ,&chomped_testbench_name); - fprintf(fp, "echo Number of clock cycles in simulation: %d\n", num_sim_clock_cycle); - fprintf(fp, "echo Simulation progress: %d Finish, %d to go, total %d\n", - progress_cnt, total_num_sim-progress_cnt, total_num_sim); + fprintf(fp, "echo \"Number of clock cycles in simulation: %d\"\n", num_sim_clock_cycle); + fprintf(fp, "echo \"Simulation progress: %d Finish, %d to go, total %d\"\n", + progress_cnt, total_num_sim - progress_cnt, total_num_sim); progress_cnt++; + if (NULL != spice_simulator_path) { + fprintf(fp, "%s", spice_simulator_path); + } fprintf(fp, "hspice64 -mt %d -i %s -o %s%s.lis ", spice_sim_multi_thread_num, testbench_file, sim_results_dir_path, chomped_testbench_name); temp = temp->next; if (1 == rram_design_tech) { - fprintf(fp, "-hdlpath /uusoc/facility/cad_common/Synopsys/hspice_vM-2017.03/hspice/include\n"); + if (NULL == spice_simulator_path) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])SPICE simulator path must be specified when RRAM tech is used!", + __FILE__, __LINE__); + exit(1); + } + fprintf(fp, "-hdlpath %s/include\n", spice_simulator_path); } else { fprintf(fp, "\n"); } } - fprintf(fp, "echo Simulation progress: %d Finish, %d to go, total %d\n", - progress_cnt, total_num_sim-progress_cnt, total_num_sim); + fprintf(fp, "echo \"Simulation progress: %d Finish, %d to go, total %d\"\n", + progress_cnt, total_num_sim - progress_cnt, total_num_sim); if (1 == rram_design_tech) { fprintf(fp, "cd %s\n", spice_dir_path); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_run_scripts.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_run_scripts.h similarity index 72% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_run_scripts.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_run_scripts.h index 4b19ce9af..188cdde9d 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_run_scripts.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_run_scripts.h @@ -1,4 +1,5 @@ void fprint_run_hspice_shell_script(t_spice spice, + char* spice_simulator_path, char* spice_dir_path, char* subckt_dir_path); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_subckt.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c similarity index 99% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_subckt.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c index 1c9a4d929..ba2d77839 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_subckt.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.c @@ -18,12 +18,14 @@ #include "globals.h" #include "rr_graph.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_types.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" #include "spice_utils.h" #include "spice_mux.h" #include "spice_lut.h" @@ -727,18 +729,19 @@ void generate_spice_subckts(char* subckt_dir, generate_spice_wires(subckt_dir, arch->num_segments, arch->Segments, arch->spice->num_spice_model, arch->spice->spice_models); - /*5. Generate LUTs */ + /* 5. Generate LUTs */ vpr_printf(TIO_MESSAGE_INFO,"Writing SPICE LUTs...\n"); generate_spice_luts(subckt_dir, arch->spice->num_spice_model, arch->spice->spice_models); - - /* 6. Generate Logic Blocks */ - vpr_printf(TIO_MESSAGE_INFO,"Writing Logic Blocks...\n"); - generate_spice_logic_blocks(subckt_dir, arch); - /* 7. Generate Routing architecture*/ + /* 6. Generate Routing architecture*/ vpr_printf(TIO_MESSAGE_INFO, "Writing Routing Resources....\n"); generate_spice_routing_resources(subckt_dir, (*arch), routing_arch, num_rr_nodes, rr_node, rr_node_indices); + + /* 7. Generate Logic Blocks */ + vpr_printf(TIO_MESSAGE_INFO,"Writing Logic Blocks...\n"); + generate_spice_logic_blocks(subckt_dir, arch); + return; } diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_subckt.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_subckt.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_subckt.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_top_netlist.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_top_netlist.c similarity index 99% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_top_netlist.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_top_netlist.c index effe583b1..0fc6a42db 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_top_netlist.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_top_netlist.c @@ -18,12 +18,14 @@ #include "globals.h" #include "rr_graph.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_types.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" #include "spice_mux.h" #include "spice_pbtypes.h" #include "spice_routing.h" diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_top_netlist.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_top_netlist.h similarity index 100% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_top_netlist.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_top_netlist.h diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c similarity index 96% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_utils.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c index f31aa0443..e195d994b 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.c @@ -20,16 +20,19 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "vpr_utils.h" +#include "route_common.h" /* Include spice support headers*/ #include "linkedlist.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" #include "spice_globals.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" #include "spice_mux.h" #include "spice_pbtypes.h" #include "spice_routing.h" -#include "fpga_spice_backannotate_utils.h" +#include "fpga_x2p_backannotate_utils.h" #include "spice_utils.h" /***** Subroutines *****/ @@ -696,6 +699,7 @@ void fprint_global_pad_ports_spice_model(FILE* fp, case SPICE_MODEL_SCFF: case SPICE_MODEL_INVBUF: case SPICE_MODEL_PASSGATE: + case SPICE_MODEL_GATE: break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Unknown type for spice model!\n", @@ -779,71 +783,83 @@ void fprint_measure_vdds_spice_model(FILE* fp, } for (imodel = 0; imodel < spice.num_spice_model; imodel++) { - if (spice_model_type == spice.spice_models[imodel].type) { - for (i = 0; i < spice.spice_models[imodel].cnt; i++) { - switch (meas_type) { - case SPICE_MEASURE_LEAKAGE_POWER: - if (TRUE == leakage_only) { - fprintf(fp, ".measure tran leakage_power_%s[%d] find p(Vgvdd_%s[%d]) at=0\n", - spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i); - } else { - fprintf(fp, ".measure tran leakage_power_%s[%d] avg p(Vgvdd_%s[%d]) from=0 to='clock_period'\n", - spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i); - } - break; - case SPICE_MEASURE_DYNAMIC_POWER: - fprintf(fp, ".measure tran dynamic_power_%s[%d] avg p(Vgvdd_%s[%d]) from='clock_period' to='%d*clock_period'\n", - spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i, num_cycle); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid meas_type!\n", __FILE__, __LINE__); - exit(1); + /* Only care the matched SPICE model type */ + if (spice_model_type != spice.spice_models[imodel].type) { + continue; + } + /* Skip if no such spice_model is used in the netlists */ + if (0 == spice.spice_models[imodel].cnt) { + continue; + } + for (i = 0; i < spice.spice_models[imodel].cnt; i++) { + switch (meas_type) { + case SPICE_MEASURE_LEAKAGE_POWER: + if (TRUE == leakage_only) { + fprintf(fp, ".measure tran leakage_power_%s[%d] find p(Vgvdd_%s[%d]) at=0\n", + spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i); + } else { + fprintf(fp, ".measure tran leakage_power_%s[%d] avg p(Vgvdd_%s[%d]) from=0 to='clock_period'\n", + spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i); } + break; + case SPICE_MEASURE_DYNAMIC_POWER: + fprintf(fp, ".measure tran dynamic_power_%s[%d] avg p(Vgvdd_%s[%d]) from='clock_period' to='%d*clock_period'\n", + spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i, num_cycle); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid meas_type!\n", __FILE__, __LINE__); + exit(1); } } } /* Measure the total power of this kind of spice model */ for (imodel = 0; imodel < spice.num_spice_model; imodel++) { - if (spice_model_type == spice.spice_models[imodel].type) { - switch (meas_type) { - case SPICE_MEASURE_LEAKAGE_POWER: - for (i = 0; i < spice.spice_models[imodel].cnt; i++) { - fprintf(fp, ".measure tran leakage_power_%s[0to%d] \n", spice.spice_models[imodel].prefix, i); - if (0 == i) { - fprintf(fp, "+ param = 'leakage_power_%s[%d]'\n", spice.spice_models[imodel].prefix, i); - } else { - fprintf(fp, "+ param = 'leakage_power_%s[%d]+leakage_power_%s[0to%d]'\n", - spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i-1); - } + /* Only care the matched SPICE model type */ + if (spice_model_type != spice.spice_models[imodel].type) { + continue; + } + /* Skip if no such spice_model is used in the netlists */ + if (0 == spice.spice_models[imodel].cnt) { + continue; + } + switch (meas_type) { + case SPICE_MEASURE_LEAKAGE_POWER: + for (i = 0; i < spice.spice_models[imodel].cnt; i++) { + fprintf(fp, ".measure tran leakage_power_%s[0to%d] \n", spice.spice_models[imodel].prefix, i); + if (0 == i) { + fprintf(fp, "+ param = 'leakage_power_%s[%d]'\n", spice.spice_models[imodel].prefix, i); + } else { + fprintf(fp, "+ param = 'leakage_power_%s[%d]+leakage_power_%s[0to%d]'\n", + spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i-1); } - /* Spot the total leakage power of this spice model */ - fprintf(fp, ".measure tran total_leakage_power_%s \n", spice.spice_models[imodel].prefix); - fprintf(fp, "+ param = 'leakage_power_%s[0to%d]'\n", - spice.spice_models[imodel].prefix, spice.spice_models[imodel].cnt-1); - break; - case SPICE_MEASURE_DYNAMIC_POWER: - for (i = 0; i < spice.spice_models[imodel].cnt; i++) { - fprintf(fp, ".measure tran dynamic_power_%s[0to%d] \n", spice.spice_models[imodel].prefix, i); - if (0 == i) { - fprintf(fp, "+ param = 'dynamic_power_%s[%d]'\n", spice.spice_models[imodel].prefix, i); - } else { - fprintf(fp, "+ param = 'dynamic_power_%s[%d]+dynamic_power_%s[0to%d]'\n", - spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i-1); - } - } - /* Spot the total dynamic power of this spice model */ - fprintf(fp, ".measure tran total_dynamic_power_%s \n", spice.spice_models[imodel].prefix); - fprintf(fp, "+ param = 'dynamic_power_%s[0to%d]'\n", - spice.spice_models[imodel].prefix, spice.spice_models[imodel].cnt-1); - fprintf(fp, ".measure tran total_energy_per_cycle_%s \n", spice.spice_models[imodel].prefix); - fprintf(fp, "+ param = 'dynamic_power_%s[0to%d]*clock_period'\n", - spice.spice_models[imodel].prefix, spice.spice_models[imodel].cnt-1); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid meas_type!\n", __FILE__, __LINE__); - exit(1); } + /* Spot the total leakage power of this spice model */ + fprintf(fp, ".measure tran total_leakage_power_%s \n", spice.spice_models[imodel].prefix); + fprintf(fp, "+ param = 'leakage_power_%s[0to%d]'\n", + spice.spice_models[imodel].prefix, spice.spice_models[imodel].cnt-1); + break; + case SPICE_MEASURE_DYNAMIC_POWER: + for (i = 0; i < spice.spice_models[imodel].cnt; i++) { + fprintf(fp, ".measure tran dynamic_power_%s[0to%d] \n", spice.spice_models[imodel].prefix, i); + if (0 == i) { + fprintf(fp, "+ param = 'dynamic_power_%s[%d]'\n", spice.spice_models[imodel].prefix, i); + } else { + fprintf(fp, "+ param = 'dynamic_power_%s[%d]+dynamic_power_%s[0to%d]'\n", + spice.spice_models[imodel].prefix, i, spice.spice_models[imodel].prefix, i-1); + } + } + /* Spot the total dynamic power of this spice model */ + fprintf(fp, ".measure tran total_dynamic_power_%s \n", spice.spice_models[imodel].prefix); + fprintf(fp, "+ param = 'dynamic_power_%s[0to%d]'\n", + spice.spice_models[imodel].prefix, spice.spice_models[imodel].cnt-1); + fprintf(fp, ".measure tran total_energy_per_cycle_%s \n", spice.spice_models[imodel].prefix); + fprintf(fp, "+ param = 'dynamic_power_%s[0to%d]*clock_period'\n", + spice.spice_models[imodel].prefix, spice.spice_models[imodel].cnt-1); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid meas_type!\n", __FILE__, __LINE__); + exit(1); } } @@ -1003,9 +1019,10 @@ void fprint_call_defined_grids(FILE* fp) { } /* IO Grids */ - /* LEFT side */ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { + + /* TOP side */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { /* Bypass EMPTY grid */ if (EMPTY_TYPE == grid[ix][iy].type) { continue; @@ -1017,7 +1034,7 @@ void fprint_call_defined_grids(FILE* fp) { fprintf(fp, "+ "); /* Connect to a speical vdd port for statistics power */ fprintf(fp, "gvdd_io 0 grid[%d][%d]\n", ix, iy); /* Call the name of subckt */ - } + } /* RIGHT side */ ix = nx + 1; @@ -1051,9 +1068,9 @@ void fprint_call_defined_grids(FILE* fp) { fprintf(fp, "gvdd_io 0 grid[%d][%d]\n", ix, iy); /* Call the name of subckt */ } - /* TOP side */ - iy = ny + 1; - for (ix = 1; ix < (nx + 1); ix++) { + /* LEFT side */ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { /* Bypass EMPTY grid */ if (EMPTY_TYPE == grid[ix][iy].type) { continue; @@ -1065,7 +1082,7 @@ void fprint_call_defined_grids(FILE* fp) { fprintf(fp, "+ "); /* Connect to a speical vdd port for statistics power */ fprintf(fp, "gvdd_io 0 grid[%d][%d]\n", ix, iy); /* Call the name of subckt */ - } + } return; } @@ -1888,32 +1905,32 @@ void fprint_spice_circuit_param(FILE* fp, /* Print Ron */ fprint_one_design_param_w_wo_variation(fp, my_strcat(spice_model[imodel].name, design_param_postfix_rram_ron), - spice_model[imodel].design_tech_info.ron, + spice_model[imodel].design_tech_info.rram_info->ron, mc_params.rram_variation); /* Print Roff */ fprint_one_design_param_w_wo_variation(fp, my_strcat(spice_model[imodel].name, design_param_postfix_rram_roff), - spice_model[imodel].design_tech_info.roff, + spice_model[imodel].design_tech_info.rram_info->roff, mc_params.rram_variation); /* Print Wprog_set_nmos */ fprint_one_design_param_w_wo_variation(fp, my_strcat(spice_model[imodel].name, design_param_postfix_rram_wprog_set_nmos), - spice_model[imodel].design_tech_info.wprog_set_nmos, + spice_model[imodel].design_tech_info.rram_info->wprog_set_nmos, mc_params.cmos_variation); /* Print Wprog_set_pmos */ fprint_one_design_param_w_wo_variation(fp, my_strcat(spice_model[imodel].name, design_param_postfix_rram_wprog_set_pmos), - spice_model[imodel].design_tech_info.wprog_set_pmos, + spice_model[imodel].design_tech_info.rram_info->wprog_set_pmos, mc_params.cmos_variation); /* Print Wprog_reset_nmos */ fprint_one_design_param_w_wo_variation(fp, my_strcat(spice_model[imodel].name, design_param_postfix_rram_wprog_reset_nmos), - spice_model[imodel].design_tech_info.wprog_reset_nmos, + spice_model[imodel].design_tech_info.rram_info->wprog_reset_nmos, mc_params.cmos_variation); /* Print Wprog_reset_pmos */ fprint_one_design_param_w_wo_variation(fp, my_strcat(spice_model[imodel].name, design_param_postfix_rram_wprog_reset_pmos), - spice_model[imodel].design_tech_info.wprog_reset_pmos, + spice_model[imodel].design_tech_info.rram_info->wprog_reset_pmos, mc_params.cmos_variation); } } @@ -2957,14 +2974,14 @@ float find_spice_testbench_rr_mux_load_inv_size(t_rr_node* load_rr_node, void fprint_spice_testbench_pb_graph_pin_inv_loads_rec(FILE* fp, int* testbench_load_cnt, int grid_x, int grid_y, t_pb_graph_pin* src_pb_graph_pin, - t_pb* src_pb, + t_phy_pb* src_pb, char* outport_name, boolean consider_parent_node, t_ivec*** LL_rr_node_indices) { int iedge, mode_index, ipb, jpb; t_interconnect* cur_interc = NULL; char* rec_outport_name = NULL; - t_pb* des_pb = NULL; + t_phy_pb* des_pb = NULL; int src_rr_node_index = -1; float load_inv_size = 0.; float total_width; @@ -3002,7 +3019,7 @@ void fprint_spice_testbench_pb_graph_pin_inv_loads_rec(FILE* fp, int* testbench_ /* Get the mode_index */ if (NULL == src_pb) { - mode_index = find_pb_type_idle_mode_index(*(src_pb_graph_pin->parent_node->pb_type)); + mode_index = find_pb_type_physical_mode_index(*(src_pb_graph_pin->parent_node->pb_type)); } else { mode_index = src_pb->mode; } @@ -3355,7 +3372,7 @@ void fprint_spice_testbench_one_cb_mux_loads(FILE* fp, int* testbench_load_cnt, t_ivec*** LL_rr_node_indices) { t_type_ptr cb_out_grid_type = NULL; t_pb_graph_pin* cb_out_pb_graph_pin = NULL; - t_pb* cb_out_pb = NULL; + t_phy_pb* cb_out_pb = NULL; assert(IPIN == src_rr_node->type); /* The assert only works for homogeneous blocks @@ -3370,7 +3387,9 @@ void fprint_spice_testbench_one_cb_mux_loads(FILE* fp, int* testbench_load_cnt, assert(NULL != cb_out_pb_graph_pin); /* Get the pb ! Get the mode_index */ - cb_out_pb = src_rr_node->pb; + if (NULL != src_rr_node->pb) { + cb_out_pb = (t_phy_pb*)(src_rr_node->pb->phy_pb); + } if (IO_TYPE == cb_out_grid_type) { fprintf(fp, "******* IO_TYPE loads *******\n"); @@ -3550,4 +3569,16 @@ t_llist* add_one_spice_tb_info_to_llist(t_llist* cur_head, return new_head; } +char* convert_const_input_value_to_str(int const_input_val) { + switch (const_input_val) { + case 0: + return "sgnd"; + case 1: + return "svdd"; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid value for constant input (=%d).\n", + __FILE__, __LINE__, const_input_val); + exit(1); + } +} diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.h similarity index 98% rename from vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_utils.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.h index 9a14f3f15..8b60f1358 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/spice/spice_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/spice/spice_utils.h @@ -218,7 +218,7 @@ float find_spice_testbench_rr_mux_load_inv_size(t_rr_node* load_rr_node, void fprint_spice_testbench_pb_graph_pin_inv_loads_rec(FILE* fp, int* testbench_load_cnt, int grid_x, int grid_y, t_pb_graph_pin* src_pb_graph_pin, - t_pb* src_pb, + t_phy_pb* src_pb, char* outport_name, boolean consider_parent_node, t_ivec*** LL_rr_node_indices); @@ -249,3 +249,5 @@ void fprint_spice_testbench_one_grid_pin_loads(FILE* fp, int x, int y, t_llist* add_one_spice_tb_info_to_llist(t_llist* cur_head, char* tb_file_path, int num_sim_clock_cycles); + +char* convert_const_input_value_to_str(int const_input_val); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c new file mode 100644 index 000000000..fd6641a1e --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c @@ -0,0 +1,438 @@ +/***********************************/ +/* Synthesizable Verilog Dumping */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "path_delay.h" +#include "stats.h" +#include "route_common.h" + +/* Include FPGA-SPICE utils */ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" + +/* Include SynVerilog headers */ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_submodules.h" +#include "verilog_pbtypes.h" +#include "verilog_routing.h" +#include "verilog_compact_netlist.h" +#include "verilog_top_testbench.h" +#include "verilog_autocheck_top_testbench.h" +#include "verilog_formal_random_top_testbench.h" +#include "verilog_verification_top_netlist.h" +#include "verilog_modelsim_autodeck.h" +#include "verilog_report_timing.h" +#include "verilog_sdc.h" +#include "verilog_formality_autodeck.h" +#include "verilog_sdc_pb_types.h" +#include "verilog_include_netlists.h" + +/***** Subroutines *****/ +/* Alloc array that records Configuration bits for : + * (1) Switch blocks + * (2) Connection boxes + * TODO: Can be improved in alloc strategy to be more memory efficient! + */ +static +void alloc_global_routing_conf_bits() { + int i; + + /* Alloc array for Switch blocks */ + num_conf_bits_sb = (int**)my_malloc((nx+1)*sizeof(int*)); + for (i = 0; i < (nx + 1); i++) { + num_conf_bits_sb[i] = (int*)my_calloc((ny+1), sizeof(int)); + } + + /* Alloc array for Connection blocks */ + num_conf_bits_cbx = (int**)my_malloc((nx+1)*sizeof(int*)); + for (i = 0; i < (nx + 1); i++) { + num_conf_bits_cbx[i] = (int*)my_calloc((ny+1), sizeof(int)); + } + + num_conf_bits_cby = (int**)my_malloc((nx+1)*sizeof(int*)); + for (i = 0; i < (nx + 1); i++) { + num_conf_bits_cby[i] = (int*)my_calloc((ny+1), sizeof(int)); + } + + return; +} + +static +void free_global_routing_conf_bits() { + int i; + + /* Free array for Switch blocks */ + for (i = 0; i < (nx + 1); i++) { + my_free(num_conf_bits_sb[i]); + } + my_free(num_conf_bits_sb); + + /* Free array for Connection box */ + for (i = 0; i < (nx + 1); i++) { + my_free(num_conf_bits_cbx[i]); + } + my_free(num_conf_bits_cbx); + + for (i = 0; i < (nx + 1); i++) { + my_free(num_conf_bits_cby[i]); + } + my_free(num_conf_bits_cby); + + return; +} + +/* Top-level function*/ +void vpr_fpga_verilog(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name) { + /* Timer */ + clock_t t_start; + clock_t t_end; + float run_time_sec; + + int num_clocks = Arch.spice->spice_params.stimulate_params.num_clocks; + /* int vpr_crit_path_delay = Arch.spice->spice_params.stimulate_params.vpr_crit_path_delay; */ + + /* Directory paths */ + char* verilog_dir_formatted = NULL; + char* src_dir_path = NULL; + char* submodule_dir_path= NULL; + char* lb_dir_path = NULL; + char* rr_dir_path = NULL; + char* tcl_dir_path = NULL; + char* sdc_dir_path = NULL; + char* msim_dir_path = NULL; + char* fm_dir_path = NULL; + char* top_netlist_file = NULL; + char* top_netlist_path = NULL; + char* top_testbench_file_name = NULL; + char* top_testbench_file_path = NULL; + char* blif_testbench_file_name = NULL; + char* blif_testbench_file_path = NULL; + char* bitstream_file_name = NULL; + char* bitstream_file_path = NULL; + char* formal_verification_top_netlist_file_name = NULL; + char* formal_verification_top_netlist_file_path = NULL; + char* autocheck_top_testbench_file_name = NULL; + char* autocheck_top_testbench_file_path = NULL; + char* random_top_testbench_file_name = NULL; + char* random_top_testbench_file_path = NULL; + + char* chomped_parent_dir = NULL; + char* chomped_circuit_name = NULL; + + t_sram_orgz_info* sram_verilog_orgz_info = NULL; + + /* Check if the routing architecture we support*/ + if (UNI_DIRECTIONAL != vpr_setup.RoutingArch.directionality) { + vpr_printf(TIO_MESSAGE_ERROR, "FPGA synthesizable Verilog dumping only support uni-directional routing architecture!\n"); + exit(1); + } + + /* We don't support mrFPGA */ +#ifdef MRFPGA_H + if (is_mrFPGA) { + vpr_printf(TIO_MESSAGE_ERROR, "FPGA synthesizable verilog dumping do not support mrFPGA!\n"); + exit(1); + } +#endif + + assert ( TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog); + + /* VerilogGenerator formally starts*/ + vpr_printf(TIO_MESSAGE_INFO, "\nFPGA synthesizable verilog generator starts...\n"); + + /* Start time count */ + t_start = clock(); + + /* Format the directory paths */ + split_path_prog_name(circuit_name, '/', &chomped_parent_dir, &chomped_circuit_name); + + if (NULL != vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.syn_verilog_dump_dir) { + verilog_dir_formatted = format_dir_path(vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.syn_verilog_dump_dir); + } else { + verilog_dir_formatted = format_dir_path(my_strcat(format_dir_path(chomped_parent_dir), default_verilog_dir_name)); + } + + /* SRC directory */ + src_dir_path = format_dir_path(my_strcat(verilog_dir_formatted, default_src_dir_name)); + /* lb directory */ + lb_dir_path = my_strcat(src_dir_path, default_lb_dir_name); + /* routing resources directory */ + rr_dir_path = my_strcat(src_dir_path, default_rr_dir_name); + /* submodule_dir_path */ + submodule_dir_path = my_strcat(src_dir_path, default_submodule_dir_name); + /* SDC_dir_path */ + sdc_dir_path = my_strcat(verilog_dir_formatted, default_sdc_dir_name); + /* tcl_dir_path */ + tcl_dir_path = my_strcat(verilog_dir_formatted, default_tcl_dir_name); + /* msim_dir_path */ + msim_dir_path = my_strcat(verilog_dir_formatted, default_msim_dir_name); + /* fm_dir_path */ + fm_dir_path = my_strcat(verilog_dir_formatted, default_snpsfm_dir_name); + /* Top netlists dir_path */ + top_netlist_file = my_strcat(chomped_circuit_name, verilog_top_postfix); + top_netlist_path = my_strcat(src_dir_path, top_netlist_file); + /* Report timing directory */ + if (NULL == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.report_timing_path) { + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.report_timing_path = my_strcat(verilog_dir_formatted, default_report_timing_rpt_dir_name); + } + + /* Create directories */ + create_dir_path(verilog_dir_formatted); + create_dir_path(src_dir_path); + create_dir_path(lb_dir_path); + create_dir_path(rr_dir_path); + create_dir_path(sdc_dir_path); + create_dir_path(tcl_dir_path); + create_dir_path(fm_dir_path); + create_dir_path(msim_dir_path); + create_dir_path(submodule_dir_path); + + /* assign the global variable of SRAM model */ + assert(NULL != Arch.sram_inf.verilog_sram_inf_orgz); /* Check !*/ + sram_verilog_model = Arch.sram_inf.verilog_sram_inf_orgz->spice_model; + /* initialize the SRAM organization information struct */ + sram_verilog_orgz_info = alloc_one_sram_orgz_info(); + init_sram_orgz_info(sram_verilog_orgz_info, Arch.sram_inf.verilog_sram_inf_orgz->type, sram_verilog_model, nx + 2, ny + 2); + + /* Check all the SRAM port is using the correct SRAM SPICE MODEL */ + config_spice_models_sram_port_spice_model(Arch.spice->num_spice_model, + Arch.spice->spice_models, + Arch.sram_inf.verilog_sram_inf_orgz->spice_model); + + /* Assign global variables of input and output pads */ + iopad_verilog_model = find_iopad_spice_model(Arch.spice->num_spice_model, Arch.spice->spice_models); + assert(NULL != iopad_verilog_model); + + /* zero the counter of each spice_model */ + zero_spice_models_cnt(Arch.spice->num_spice_model, Arch.spice->spice_models); + + /* Initialize the user-defined verilog netlists to be included */ + init_list_include_verilog_netlists(Arch.spice); + + /* Initial global variables about configuration bits */ + alloc_global_routing_conf_bits(); + + /* Initialize the number of configuration bits of all the grids */ + vpr_printf(TIO_MESSAGE_INFO, "Count the number of configuration bits, IO pads in each logic block...\n"); + /* init_grids_num_conf_bits(sram_verilog_orgz_type); */ + init_grids_num_conf_bits(sram_verilog_orgz_info); + init_grids_num_iopads(); + /* init_grids_num_mode_bits(); */ + + dump_verilog_defines_preproc(src_dir_path, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + + dump_verilog_simulation_preproc(src_dir_path, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + + /* Dump routing resources: switch blocks, connection blocks and channel tracks */ + dump_verilog_routing_resources(sram_verilog_orgz_info, src_dir_path, rr_dir_path, Arch, &vpr_setup.RoutingArch, + num_rr_nodes, rr_node, rr_node_indices, rr_indexed_data, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + + /* Dump logic blocks + * Branches to go: + * 1. a compact output + * 2. a full-size output + */ + dump_compact_verilog_logic_blocks(sram_verilog_orgz_info, src_dir_path, lb_dir_path, &Arch, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + + /* Dump internal structures of submodules */ + dump_verilog_submodules(sram_verilog_orgz_info, src_dir_path, submodule_dir_path, + Arch, &vpr_setup.RoutingArch, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + + /* Dump top-level verilog */ + dump_compact_verilog_top_netlist(sram_verilog_orgz_info, chomped_circuit_name, + top_netlist_path, src_dir_path, submodule_dir_path, lb_dir_path, rr_dir_path, + num_rr_nodes, rr_node, rr_node_indices, + num_clocks, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, + *(Arch.spice)); + + /* Dump SDC constraints */ + /* Output SDC to contrain the P&R flow + */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_sdc_pnr) { + verilog_generate_sdc_pnr(sram_verilog_orgz_info, sdc_dir_path, + Arch, &vpr_setup.RoutingArch, + num_rr_nodes, rr_node, rr_node_indices, rr_indexed_data, + nx, ny, grid, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + } + + /* dump_verilog_sdc_file(); */ + + /* dump verilog testbench only for input blif */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_input_blif_testbench) { + blif_testbench_file_name = my_strcat(chomped_circuit_name, blif_testbench_verilog_file_postfix); + blif_testbench_file_path = my_strcat(src_dir_path, blif_testbench_file_name); + dump_verilog_input_blif_testbench(chomped_circuit_name, blif_testbench_file_path, src_dir_path, + num_clocks, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); + /* Free */ + my_free(blif_testbench_file_name); + my_free(blif_testbench_file_path); + } + + /* Free sram_orgz_info: + * Free the allocated sram_orgz_info before, we start bitstream generation ! + */ + free_sram_orgz_info(sram_verilog_orgz_info, + sram_verilog_orgz_info->type); + + /* Force enable bitstream generator when we need to output Verilog top testbench*/ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_testbench) { + vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream = TRUE; + } + + /* Generate bitstream if required, and also Dump bitstream file */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream) { + bitstream_file_name = my_strcat(chomped_circuit_name, fpga_spice_bitstream_output_file_postfix); + bitstream_file_path = my_strcat(src_dir_path, bitstream_file_name); + /* Run bitstream generation */ + vpr_fpga_generate_bitstream(vpr_setup, Arch, circuit_name, bitstream_file_path, &sram_verilog_orgz_info); + my_free(bitstream_file_name); + my_free(bitstream_file_path); + } + + /* dump verilog testbench only for top-level: ONLY valid when bitstream is generated! */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_testbench) { + top_testbench_file_name = my_strcat(chomped_circuit_name, top_testbench_verilog_file_postfix); + top_testbench_file_path = my_strcat(src_dir_path, top_testbench_file_name); + dump_verilog_top_testbench(sram_verilog_orgz_info, chomped_circuit_name, top_testbench_file_path, + src_dir_path, num_clocks, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); + /* Free */ + my_free(top_testbench_file_name); + my_free(top_testbench_file_path); + } + + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_formal_verification_top_netlist) { + formal_verification_top_netlist_file_name = my_strcat(chomped_circuit_name, formal_verification_verilog_file_postfix); + formal_verification_top_netlist_file_path = my_strcat(src_dir_path, formal_verification_top_netlist_file_name); + dump_verilog_formal_verification_top_netlist(sram_verilog_orgz_info, chomped_circuit_name, + formal_verification_top_netlist_file_path, src_dir_path, + num_clocks, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); + /* Output script for formality */ + write_formality_script(vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, + fm_dir_path, + src_dir_path, + chomped_circuit_name, + *(Arch.spice)); + random_top_testbench_file_name = my_strcat(chomped_circuit_name, random_top_testbench_verilog_file_postfix); + random_top_testbench_file_path = my_strcat(src_dir_path, random_top_testbench_file_name); + dump_verilog_random_top_testbench(sram_verilog_orgz_info, chomped_circuit_name, + random_top_testbench_file_path, src_dir_path, num_clocks, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); + /* Free */ + my_free(formal_verification_top_netlist_file_name); + my_free(formal_verification_top_netlist_file_path); + } + + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_autocheck_top_testbench) { + autocheck_top_testbench_file_name = my_strcat(chomped_circuit_name, autocheck_top_testbench_verilog_file_postfix); + autocheck_top_testbench_file_path = my_strcat(src_dir_path, autocheck_top_testbench_file_name); + dump_verilog_autocheck_top_testbench(sram_verilog_orgz_info, chomped_circuit_name, + autocheck_top_testbench_file_path, src_dir_path, num_clocks, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); + /* Free */ + my_free(autocheck_top_testbench_file_name); + my_free(autocheck_top_testbench_file_path); + } + + /* Output Modelsim Autodeck scripts */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_modelsim_autodeck) { + dump_verilog_modelsim_autodeck(sram_verilog_orgz_info, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, + *(Arch.spice), + Arch.spice->spice_params.meas_params.sim_num_clock_cycle, + msim_dir_path, + chomped_circuit_name, + src_dir_path); + } + + /* Output SDC to contrain the mapped FPGA in timing-analysis purpose + */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_sdc_analysis) { + verilog_generate_sdc_analysis(sram_verilog_orgz_info, sdc_dir_path, + chomped_circuit_name, Arch, &vpr_setup.RoutingArch, + num_rr_nodes, rr_node, rr_node_indices, rr_indexed_data, + nx, ny, grid, block, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + } + /* Output routing report_timing script : + */ + if (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_report_timing_tcl) { + verilog_generate_report_timing(sram_verilog_orgz_info, tcl_dir_path, + Arch, &vpr_setup.RoutingArch, + num_rr_nodes, rr_node, rr_node_indices, + vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts); + } + + if ((TRUE == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream) + || (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_top_testbench) + || (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_autocheck_top_testbench) + || (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.print_formal_verification_top_netlist)) { + /* Free sram_orgz_info: + * Free the allocated sram_orgz_info before, we start bitstream generation ! + */ + free_sram_orgz_info(sram_verilog_orgz_info, + sram_verilog_orgz_info->type); + } + + write_include_netlists(src_dir_path, + chomped_circuit_name, + *(Arch.spice) ); + + /* End time count */ + t_end = clock(); + + run_time_sec = (float)(t_end - t_start) / CLOCKS_PER_SEC; + vpr_printf(TIO_MESSAGE_INFO, "Synthesizable verilog dumping took %g seconds\n", run_time_sec); + + /* Free global array */ + free_global_routing_conf_bits(); + + /* Free */ + my_free(verilog_dir_formatted); + my_free(src_dir_path); + my_free(lb_dir_path); + my_free(rr_dir_path); + my_free(msim_dir_path); + my_free(fm_dir_path); + my_free(sdc_dir_path); + my_free(tcl_dir_path); + my_free(top_netlist_file); + my_free(top_netlist_path); + my_free(submodule_dir_path); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.h new file mode 100644 index 000000000..a8135f44b --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.h @@ -0,0 +1,4 @@ + +void vpr_fpga_verilog(t_vpr_setup vpr_setup, + t_arch Arch, + char* circuit_name); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.c new file mode 100644 index 000000000..956e65f5f --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.c @@ -0,0 +1,392 @@ +/***********************************/ +/* Dump Synthesizable Veriolog */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include spice support headers*/ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" + +/* Include verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" +#include "verilog_pbtypes.h" +#include "verilog_decoder.h" +#include "verilog_top_netlist_utils.h" +#include "verilog_top_testbench.h" + +/* Local variables */ +static char* autocheck_testbench_reference_output_postfix = "_benchmark"; +static char* autocheck_testbench_verification_output_postfix = "_verification"; + +/* Local Subroutines declaration */ + +/******** Subroutines ***********/ +static +void dump_verilog_top_auto_testbench_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + t_syn_verilog_opts fpga_verilog_opts){ + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + int iblock, iopad_idx; + t_spice_model* mem_model = NULL; + char* port_name = NULL; + + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + fprintf(fp, "`include \"%s\"\n", fpga_verilog_opts.reference_verilog_benchmark_file); + + fprintf(fp, "module %s%s;\n", circuit_name, modelsim_autocheck_testbench_module_postfix); + /* Local wires */ + /* 1. reset, set, clock signals */ + /* 2. iopad signals */ + + /* Connect to defined signals */ + /* set and reset signals */ + fprintf(fp, "\n"); + dump_verilog_top_testbench_global_ports(fp, global_ports_head, VERILOG_PORT_WIRE); + fprintf(fp, "\n"); + + /* TODO: dump each global signal as reg here */ + + /* Inputs and outputs of I/O pads */ + /* Inout Pads */ + assert(NULL != iopad_verilog_model); + if ((NULL == iopad_verilog_model) + ||(iopad_verilog_model->cnt > 0)) { + /* Malloc and assign port_name */ + port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); + sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); + /* Dump a wired port */ + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + port_name, iopad_verilog_model->cnt - 1, 0); + fprintf(fp, "; //--- FPGA inouts \n"); + /* Free port_name */ + my_free(port_name); + /* Malloc and assign port_name */ + port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + strlen(top_tb_inout_reg_postfix) + 1)); + sprintf(port_name, "%s%s%s", gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix); + /* Dump a wired port */ + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + port_name, iopad_verilog_model->cnt - 1, 0); + fprintf(fp, "; //--- reg for FPGA inouts \n"); + /* Free port_name */ + my_free(port_name); + } + + /* Add a signal to identify the configuration phase is finished */ + fprintf(fp, "reg [0:0] %s;\n", top_tb_config_done_port_name); + /* Programming clock */ + fprintf(fp, "wire [0:0] %s;\n", top_tb_prog_clock_port_name); + fprintf(fp, "reg [0:0] %s%s;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); + /* Operation clock */ + fprintf(fp, "wire [0:0] %s;\n", top_tb_op_clock_port_name); + fprintf(fp, "reg [0:0] %s%s;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); + /* Programming set and reset */ + fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_reset_port_name); + fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_set_port_name); + /* Global set and reset */ + fprintf(fp, "reg [0:0] %s;\n", top_tb_reset_port_name); + fprintf(fp, "reg [0:0] %s;\n", top_tb_set_port_name); + /* Generate stimuli for global ports or connect them to existed signals */ + dump_verilog_top_testbench_global_ports_stimuli(fp, global_ports_head); + + /* Configuration ports depend on the organization of SRAMs */ + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); + fprintf(fp, "; //---- SRAM outputs \n"); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* We put the head of scan-chains here + */ + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, "; //---- Scan-chain head \n"); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Get the number of array BLs/WLs, decoder sizes */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + fprintf(fp, " wire [0:0] %s;\n", + top_netlist_bl_enable_port_name); + fprintf(fp, " wire [0:0] %s;\n", + top_netlist_wl_enable_port_name); + /* Wire en_bl, en_wl to prog_clock */ + fprintf(fp, "assign %s[0:0] = %s[0:0];\n", + top_netlist_bl_enable_port_name, + top_tb_prog_clock_port_name); + fprintf(fp, "assign %s [0:0]= %s[0:0];\n", + top_netlist_wl_enable_port_name, + top_tb_prog_clock_port_name); + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); + fprintf(fp, "; //--- Address of bit lines \n"); + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); + fprintf(fp, "; //--- Address of word lines \n"); + /* data_in is only require by BL decoder of SRAM array + * As for RRAM array, the data_in signal will not be used + */ + if (SPICE_MODEL_DESIGN_CMOS == mem_model->design_tech) { + fprintf(fp, " reg [0:0] %s; // --- Data_in signal for BL decoder, only required by SRAM array \n", + top_netlist_bl_data_in_port_name); + } + /* I add all the Bit lines and Word lines here just for testbench usage + fprintf(fp, " input wire [%d:0] %s_out; //--- Bit lines \n", + sram_verilog_model->cnt - 1, sram_verilog_model->prefix); + fprintf(fp, " input wire [%d:0] %s_outb; //--- Word lines \n", + sram_verilog_model->cnt - 1, sram_verilog_model->prefix); + */ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Add signals from blif benchmark and short-wire them to FPGA I/O PADs + * This brings convenience to checking functionality + */ + fprintf(fp, "//-----Link Blif Benchmark inputs to FPGA IOPADs -----\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + fprintf(fp, "//----- Blif Benchmark inout %s is mapped to FPGA IOPAD %s[%d] -----\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx); + fprintf(fp, "wire %s_%s_%d_;\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx); + fprintf(fp, "assign %s_%s_%d_ = %s%s[%d];\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx, + gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); + // AA: Generate wire and reg to autocheck with benchmark + if(VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, "wire %s%s;\n", + logical_block[iblock].name, + autocheck_testbench_reference_output_postfix); + fprintf(fp, "reg %s%s;\n", + logical_block[iblock].name, + autocheck_testbench_verification_output_postfix); + } + } + } + + return; +} + +static +void dump_verilog_top_auto_testbench_call_benchmark(FILE* fp, + char* reference_verilog_top_name){ + int iblock, iopad_idx; + + fprintf(fp, "// Reference Benchmark instanciation\n"); + fprintf(fp, " %s ref_U0(\n", reference_verilog_top_name); + + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(iblock > 0){ + fprintf(fp, ",\n"); + } + if(VPACK_INPAD == logical_block[iblock].type){ + /* See if this is a clock net */ + if (TRUE == logical_block[iblock].is_clock) { + fprintf(fp, " %s", top_tb_op_clock_port_name); + } else{ + fprintf(fp, " %s_%s_%d_", logical_block[iblock].name, gio_inout_prefix, iopad_idx); + } + } else if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " %s%s", + logical_block[iblock].name, + autocheck_testbench_reference_output_postfix); + } + } + } + fprintf(fp, " );\n"); + fprintf(fp, "// End Benchmark instanciation\n\n"); + + return; +} + +static +int get_simulation_time(int num_prog_clock_cycles, + float prog_clock_period, + int num_op_clock_cycles, + float op_clock_period) { + int total_time_period = 0; + + /* Take into account the prog_reset and reset cycles */ + total_time_period = ((num_prog_clock_cycles + 2) * prog_clock_period + (2 * num_op_clock_cycles * op_clock_period)) * 1000000000; // * 1000000000 is to change the unit to ns rather than second + + return total_time_period; +} + +static +void dump_verilog_timeout_and_vcd(FILE * fp, + char* circuit_name, + t_spice verilog, + t_sram_orgz_info* cur_sram_orgz_info){ + int simulation_time; + + simulation_time = get_simulation_time(get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info), + 1./verilog.spice_params.stimulate_params.prog_clock_freq, + verilog.spice_params.meas_params.sim_num_clock_cycle, + 1./verilog.spice_params.stimulate_params.op_clock_freq); + + fprintf(fp, " // Begin Icarus requirement\n"); + fprintf(fp, "`ifdef %s\n", icarus_simulator_flag); + fprintf(fp, " initial begin\n"); + fprintf(fp, " $dumpfile(%s_autochecked.vcd);\n", circuit_name); + fprintf(fp, " $dumpvars(1, %s%s);\n", circuit_name, + modelsim_autocheck_testbench_module_postfix); + fprintf(fp, " end\n\n"); + fprintf(fp, " initial begin\n"); + fprintf(fp, " $display(\"Simulation start\");\n"); + fprintf(fp, " #%i // Can be changed by the user for his need\n", simulation_time); + fprintf(fp, " $display(\"Simulation End: Time's up\");\n"); + fprintf(fp, " end\n"); + fprintf(fp, "`endif\n\n"); + return; +} + +static +void dump_verilog_top_auto_testbench_check(FILE* fp){ + int iblock, iopad_idx; + fprintf(fp, " // Begin checking\n"); + fprintf(fp, " always@(negedge %s) begin\n", top_tb_op_clock_port_name); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " %s%s <= %s%s ^ %s_%s_%d_ ;\n", + logical_block[iblock].name, + autocheck_testbench_verification_output_postfix, + logical_block[iblock].name, + autocheck_testbench_reference_output_postfix, + logical_block[iblock].name, + gio_inout_prefix, iopad_idx); + } + } + } + fprintf(fp, " end\n\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " always@(posedge %s%s) begin\n", + logical_block[iblock].name, + autocheck_testbench_verification_output_postfix); + fprintf(fp, " if(%s%s) begin\n", + logical_block[iblock].name, + autocheck_testbench_verification_output_postfix); + fprintf(fp, " $display(\"Mismatch on %s%s\");\n", + logical_block[iblock].name, + autocheck_testbench_verification_output_postfix); + fprintf(fp, " $finish;\n"); + fprintf(fp, " end\n"); + fprintf(fp, " end\n\n"); + } + } + } + return; +} + +void dump_verilog_autocheck_top_testbench(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog) { + FILE* fp = NULL; + char* title = my_strcat("FPGA Verilog Testbench for Top-level netlist of Design: ", circuit_name); + + /* Check if the path exists*/ + fp = fopen(top_netlist_name,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!", + __FILE__, __LINE__, top_netlist_name); + exit(1); + } + + vpr_printf(TIO_MESSAGE_INFO, + "Writing Autocheck Testbench for FPGA Top-level Verilog netlist for %s...\n", + circuit_name); + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + /* Start of testbench */ + dump_verilog_top_auto_testbench_ports(fp, cur_sram_orgz_info, circuit_name, fpga_verilog_opts); + + /* Call defined top-level module */ + dump_verilog_top_testbench_call_top_module(cur_sram_orgz_info, fp, circuit_name); + + /* Call defined benchmark */ + dump_verilog_top_auto_testbench_call_benchmark(fp, circuit_name); + + /* Add stimuli for reset, set, clock and iopad signals */ + dump_verilog_top_testbench_stimuli(cur_sram_orgz_info, fp, num_clock, fpga_verilog_opts, verilog); + + /* Add output autocheck */ + dump_verilog_top_auto_testbench_check(fp); + + /* Add Icarus requirement */ + dump_verilog_timeout_and_vcd(fp, circuit_name , verilog, cur_sram_orgz_info); + + /* Testbench ends*/ + fprintf(fp, "endmodule\n"); + + /* Close the file*/ + fclose(fp); + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.h new file mode 100644 index 000000000..a4976f77d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_autocheck_top_testbench.h @@ -0,0 +1,9 @@ + +void dump_verilog_autocheck_top_testbench(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c new file mode 100644 index 000000000..5430be339 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.c @@ -0,0 +1,835 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "spice_mux.h" +#include "fpga_x2p_globals.h" + +/* Include Synthesizable Verilog headers */ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_primitives.h" +#include "verilog_pbtypes.h" +#include "verilog_top_netlist_utils.h" + +/* ONLY for compact Verilog netlists: + * Generate uniformly the prefix of the module name for each grid + */ +static +char* generate_compact_verilog_grid_module_name_prefix(t_type_ptr phy_block_type, + int border_side) { + char* subckt_name = my_strdup(grid_verilog_file_name_prefix); + + /* Check */ + if (IO_TYPE == phy_block_type) { + assert( (-1 < border_side) && (border_side < 4)); + } + + if (IO_TYPE == phy_block_type) { + subckt_name = my_strcat(subckt_name, convert_side_index_to_string(border_side)); + subckt_name = my_strcat(subckt_name, "_"); + } + + return subckt_name; +} + + +/* ONLY for compact Verilog netlists: + * Generate uniformly the module name for each grid + */ +static +char* generate_compact_verilog_grid_module_name(t_type_ptr phy_block_type, + int border_side) { + char* subckt_name = NULL; + + subckt_name = generate_compact_verilog_grid_module_name_prefix(phy_block_type, border_side); + + subckt_name = my_strcat(subckt_name, phy_block_type->name); + + return subckt_name; +} + +/* ONLY for compact Verilog netlists: + * Update the grid_index_low and grid_index_high for each spice_models + * Currently, we focus on three spice_models: SRAMs/SCFFs/IOPADs + */ +static +void compact_verilog_update_one_spice_model_grid_index(t_type_ptr phy_block_type, + int grid_x, int grid_y, + int num_spice_models, + t_spice_model* spice_model) { + int i; + int stamped_cnt = 0; + + for (i = 0; i < num_spice_models; i++) { + /* Only LUT and MUX requires configuration bits*/ + switch (spice_model[i].type) { + case SPICE_MODEL_INVBUF: + case SPICE_MODEL_PASSGATE: + case SPICE_MODEL_LUT: + case SPICE_MODEL_MUX: + case SPICE_MODEL_WIRE: + case SPICE_MODEL_CHAN_WIRE: + case SPICE_MODEL_FF: + case SPICE_MODEL_HARDLOGIC: + case SPICE_MODEL_GATE: + break; + case SPICE_MODEL_SCFF: + case SPICE_MODEL_SRAM: + stamped_cnt = spice_model[i].cnt; + spice_model[i].grid_index_low[grid_x][grid_y] = stamped_cnt; + spice_model[i].grid_index_high[grid_x][grid_y] = stamped_cnt + phy_block_type->capacity * phy_block_type->pb_type->physical_mode_num_conf_bits; + spice_model[i].cnt = spice_model[i].grid_index_high[grid_x][grid_y]; + break; + case SPICE_MODEL_IOPAD: + stamped_cnt = spice_model[i].cnt; + spice_model[i].grid_index_low[grid_x][grid_y] = stamped_cnt; + spice_model[i].grid_index_high[grid_x][grid_y] = stamped_cnt + phy_block_type->capacity * phy_block_type->pb_type->physical_mode_num_iopads; + spice_model[i].cnt = spice_model[i].grid_index_high[grid_x][grid_y]; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid spice_model_type!\n", __FILE__, __LINE__); + exit(1); + } + } + + return; +} + +/* ONLY for compact Verilog netlists: + * Update the grid_index_low and grid_index_high in sram_orgz_info + */ +static +void compact_verilog_update_sram_orgz_info_grid_index(t_sram_orgz_info* cur_sram_orgz_info, + t_type_ptr phy_block_type, + int grid_x, int grid_y) { + int cur_num_conf_bits; + int cur_num_bl, cur_num_wl; + + cur_num_conf_bits = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_num_bl, &cur_num_wl); + + cur_sram_orgz_info->grid_reserved_conf_bits[grid_x][grid_y] = phy_block_type->pb_type->physical_mode_num_reserved_conf_bits; + + cur_sram_orgz_info->grid_conf_bits_lsb[grid_x][grid_y] = cur_num_conf_bits; + + cur_sram_orgz_info->grid_conf_bits_msb[grid_x][grid_y] = cur_num_conf_bits; + + cur_sram_orgz_info->grid_conf_bits_msb[grid_x][grid_y] += phy_block_type->capacity * phy_block_type->pb_type->physical_mode_num_conf_bits; + + cur_num_conf_bits = cur_sram_orgz_info->grid_conf_bits_msb[grid_x][grid_y]; + cur_num_bl = cur_sram_orgz_info->grid_conf_bits_msb[grid_x][grid_y]; + cur_num_wl = cur_sram_orgz_info->grid_conf_bits_msb[grid_x][grid_y]; + + /* Update the counter */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_conf_bits); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, cur_num_bl, cur_num_wl); + + return; +} + +/* ONLY for compact Verilog netlists: + * Update the grid_index_low and grid_index_high for each spice_models + * Currently, we focus on three spice_models: SRAMs/SCFFs/IOPADs + * IMPORTANT: The sequence of for loop should be consistent with + * 1. bitstream logic block + * 2. verilog pbtypes logic block + * 2. spice pbtypes logic block + */ +static +void compact_verilog_update_grid_spice_model_and_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, + int num_spice_models, + t_spice_model* spice_model) { + int ix, iy; + + + /* Check the grid*/ + if ((0 == nx)||(0 == ny)) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid grid size (nx=%d, ny=%d)!\n", __FILE__, __LINE__, nx, ny); + return; + } + + vpr_printf(TIO_MESSAGE_INFO,"Grid size of FPGA: nx=%d ny=%d\n", nx + 1, ny + 1); + assert(NULL != grid); + + /* Print the core logic block one by one + * Note ix=0 and ix = nx + 1 are IO pads. They surround the core logic blocks + */ + vpr_printf(TIO_MESSAGE_INFO,"Generating core grids...\n"); + for (ix = 1; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is not a io */ + assert(IO_TYPE != grid[ix][iy].type); + /* Bypass empty type */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + /* Bypass non-zero offset grid: heterogeneous block may occupy multiple grids */ + if (0 < grid[ix][iy].offset) { + continue; + } + /* Update the grid index low and high */ + compact_verilog_update_one_spice_model_grid_index(grid[ix][iy].type, + ix, iy, + num_spice_models, spice_model); + /* Update all the sram bits */ + compact_verilog_update_sram_orgz_info_grid_index(cur_sram_orgz_info, + grid[ix][iy].type, + ix, iy); + } + } + + vpr_printf(TIO_MESSAGE_INFO,"Generating IO grids...\n"); + /* Print the IO pads */ + /* Top side : x = 1 .. nx + 1, y = nx + 1 */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + /* Update the grid index low and high */ + compact_verilog_update_one_spice_model_grid_index(grid[ix][iy].type, + ix, iy, + num_spice_models, spice_model); + /* Update all the sram bits */ + compact_verilog_update_sram_orgz_info_grid_index(cur_sram_orgz_info, + grid[ix][iy].type, + ix, iy); + } + + /* Right side : x = nx + 1, y = 1 .. ny*/ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + /* Update the grid index low and high */ + compact_verilog_update_one_spice_model_grid_index(grid[ix][iy].type, + ix, iy, + num_spice_models, spice_model); + /* Update all the sram bits */ + compact_verilog_update_sram_orgz_info_grid_index(cur_sram_orgz_info, + grid[ix][iy].type, + ix, iy); + } + + /* Bottom side : x = 1 .. nx + 1, y = 0 */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + /* Update the grid index low and high */ + compact_verilog_update_one_spice_model_grid_index(grid[ix][iy].type, + ix, iy, + num_spice_models, spice_model); + /* Update all the sram bits */ + compact_verilog_update_sram_orgz_info_grid_index(cur_sram_orgz_info, + grid[ix][iy].type, + ix, iy); + } + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + /* Update the grid index low and high */ + compact_verilog_update_one_spice_model_grid_index(grid[ix][iy].type, + ix, iy, + num_spice_models, spice_model); + /* Update all the sram bits */ + compact_verilog_update_sram_orgz_info_grid_index(cur_sram_orgz_info, + grid[ix][iy].type, + ix, iy); + } + + + /* Free */ + + return; +} + +/* Create a Verilog file and dump a module consisting of a I/O block, + * The pins appear in the port list will depend on the selected border side + */ +static +void dump_compact_verilog_one_physical_block(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir_path, + char* subckt_dir_path, + t_type_ptr phy_block_type, + int border_side, + t_arch* arch, + t_syn_verilog_opts fpga_verilog_opts) { + int iz; + int temp_reserved_conf_bits_msb; + int temp_iopad_lsb, temp_iopad_msb; + int temp_conf_bits_lsb, temp_conf_bits_msb; + char* fname = NULL; + FILE* fp = NULL; + char* title = my_strcat("FPGA Verilog Netlist for Design: ", phy_block_type->name); + char* subckt_name = NULL; + char* subckt_name_prefix = NULL; + boolean verilog_module_dumped = FALSE; + + /* Check */ + if (IO_TYPE == phy_block_type) { + assert( (-1 < border_side) && (border_side < 4)); + } + + /* Give a name to the Verilog netlist */ + fname = my_strcat(format_dir_path(subckt_dir_path), phy_block_type->name); + /* Give a special name to IO blocks */ + if (IO_TYPE == phy_block_type) { + fname = my_strcat(fname, "_"); + fname = my_strcat(fname, convert_side_index_to_string(border_side)); + } + fname = my_strcat(fname, verilog_netlist_file_postfix); + + /* Create file handler */ + fp = fopen(fname, "w"); + /* Check if the path exists*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog netlist %s!",__FILE__, __LINE__, fname); + exit(1); + } + + /* Subckt name */ + subckt_name_prefix = generate_compact_verilog_grid_module_name_prefix(phy_block_type, border_side); + + if (IO_TYPE == phy_block_type) { + vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Verilog Netlist (%s) for logic block %s at %s side ...\n", + fname, phy_block_type->name, convert_side_index_to_string(border_side)); + } else { + vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Verilog Netlist (%s) for logic block %s...\n", + fname, phy_block_type->name); + } + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + /* Dump all the submodules */ + for (iz = 0; iz < phy_block_type->capacity; iz++) { + /* We only need to output one Verilog module, others are instanced */ + if (TRUE == verilog_module_dumped) { + continue; + } + /* Comments: Grid [x][y]*/ + fprintf(fp, "//----- Submodule of type_descriptor: %s -----\n", phy_block_type->name); + /* Print a NULL logic block...*/ + dump_verilog_phy_pb_graph_node_rec(cur_sram_orgz_info, fp, subckt_name_prefix, + phy_block_type->pb_graph_head, iz); + fprintf(fp, "//----- END -----\n\n"); + /* Switch Flag on dumping verilog module */ + verilog_module_dumped = TRUE; + } + + /* Subckt name */ + subckt_name = generate_compact_verilog_grid_module_name(phy_block_type, border_side); + + /* Create top module and call all the defined submodule */ + fprintf(fp, "//----- %s, Capactity: %d -----\n", phy_block_type->name, phy_block_type->capacity); + fprintf(fp, "//----- Top Protocol -----\n"); + /* Definition */ + fprintf(fp, "module %s ( \n", subckt_name); + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { + fprintf(fp, ",\n"); + } + + /* Pins */ + if (IO_TYPE == phy_block_type) { + /* Generate a fake (x,y) coordinate that can be used for print pin names */ + /* verilog_compact_generate_fake_xy_for_io_border_side(border_side, &ix, &iy); */ + /* Special Care for I/O grid */ + dump_compact_verilog_io_grid_pins(fp, phy_block_type, border_side, TRUE, FALSE); + } else { + dump_compact_verilog_grid_pins(fp, phy_block_type, TRUE, FALSE); + } + + /* I/O PAD */ + dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, + 0, phy_block_type->capacity * phy_block_type->pb_type->physical_mode_num_iopads - 1, + VERILOG_PORT_INOUT); + + /* Print configuration ports */ + /* Reserved configuration ports */ + temp_reserved_conf_bits_msb = phy_block_type->pb_type->physical_mode_num_reserved_conf_bits; + if (0 < temp_reserved_conf_bits_msb) { + fprintf(fp, ",\n"); + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, temp_reserved_conf_bits_msb - 1, + VERILOG_PORT_INPUT); + } + /* Normal configuration ports */ + temp_conf_bits_msb = phy_block_type->capacity * phy_block_type->pb_type->physical_mode_num_conf_bits; + /* Get the number of sram bits in this submodule!!! */ + if (0 < temp_conf_bits_msb) { + fprintf(fp, ",\n"); + dump_verilog_sram_ports(fp, cur_sram_orgz_info, + 0, temp_conf_bits_msb - 1, + VERILOG_PORT_INPUT); + } + /* Dump ports only visible during formal verification*/ + if (0 < temp_conf_bits_msb) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + 0, + temp_conf_bits_msb - 1, + VERILOG_PORT_INPUT); // Should be modified to be VERILOG_PORT_INPUT + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + + fprintf(fp, ");\n"); + + /* Initialize temporary counter */ + temp_conf_bits_lsb = 0; + temp_iopad_lsb = 0; + + /* Local wires for memory configurations */ + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, + 0, temp_conf_bits_msb - 1); + + + /* Quote all the sub blocks*/ + for (iz = 0; iz < phy_block_type->capacity; iz++) { + /* Local Vdd and Gnd, subckt name*/ + fprintf(fp, "%s ", compact_verilog_get_grid_phy_block_subckt_name(phy_block_type, iz, subckt_name_prefix)); + fprintf(fp, " %s (", gen_verilog_one_phy_block_instance_name(phy_block_type, iz)); + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + /* Print all the pins */ + /* Special Care for I/O grid */ + if (IO_TYPE == phy_block_type) { + dump_compact_verilog_io_grid_block_subckt_pins(fp, phy_block_type, border_side, iz); + } else { + dump_verilog_grid_block_subckt_pins(fp, iz, phy_block_type); + } + + /* Print configuration ports */ + temp_reserved_conf_bits_msb = phy_block_type->pb_type->physical_mode_num_reserved_conf_bits; + temp_conf_bits_msb = temp_conf_bits_lsb + phy_block_type->pb_type->physical_mode_num_conf_bits; + temp_iopad_msb = temp_iopad_lsb + phy_block_type->pb_type->physical_mode_num_iopads; + + /* Print Input Pad and Output Pad */ + fprintf(fp, "\n//---- IOPAD ----\n"); + dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, + temp_iopad_lsb, temp_iopad_msb - 1, + VERILOG_PORT_CONKT); + /* Reserved configuration ports */ + if (0 < temp_reserved_conf_bits_msb) { + fprintf(fp, ",\n"); + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, temp_reserved_conf_bits_msb - 1, + VERILOG_PORT_CONKT); + } + /* Normal configuration ports */ + if (0 < (temp_conf_bits_msb - temp_conf_bits_lsb)) { + fprintf(fp, ",\n"); + fprintf(fp, "//---- SRAM ----\n"); + dump_verilog_sram_local_ports(fp, cur_sram_orgz_info, + temp_conf_bits_lsb, temp_conf_bits_msb - 1, + VERILOG_PORT_CONKT); + } + + /* Dump ports only visible during formal verification*/ + if (0 < (temp_conf_bits_msb - temp_conf_bits_lsb)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + temp_conf_bits_lsb, + temp_conf_bits_msb - 1, + VERILOG_PORT_CONKT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + /* Update temp_sram_lsb */ + temp_conf_bits_lsb = temp_conf_bits_msb; + temp_iopad_lsb = temp_iopad_msb; + fprintf(fp, ");\n"); + } + + fprintf(fp, "endmodule\n"); + fprintf(fp, "//----- END Top Protocol -----\n"); + fprintf(fp, "//----- END Grid %s, Capactity: %d -----\n\n", phy_block_type->name, phy_block_type->capacity); + + /* Check flags */ + assert( temp_conf_bits_msb == phy_block_type->capacity * phy_block_type->pb_type->physical_mode_num_conf_bits ); + + /* Close file handler */ + fclose(fp); + + /* Add fname to the linked list */ + grid_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_verilog_subckt_file_path_head, fname); + + /* Free */ + my_free(fname); + my_free(subckt_name); + my_free(subckt_name_prefix); + + return; +} + +/** Create logic block modules in a compact way: + * 1. Only one module for each I/O on each border side (IO_TYPE) + * 2. Only one module for each CLB (FILL_TYPE) + * 3. Only one module for each heterogeneous block + */ +void dump_compact_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, + t_arch* arch, + t_syn_verilog_opts fpga_verilog_opts) { + int itype, iside, num_sides; + int* stamped_spice_model_cnt = NULL; + t_sram_orgz_info* stamped_sram_orgz_info = NULL; + + /* Create a snapshot on spice_model counter */ + stamped_spice_model_cnt = snapshot_spice_model_counter(arch->spice->num_spice_model, + arch->spice->spice_models); + /* Create a snapshot on sram_orgz_info */ + stamped_sram_orgz_info = snapshot_sram_orgz_info(cur_sram_orgz_info); + + /* Enumerate the types, dump one Verilog module for each */ + for (itype = 0; itype < num_types; itype++) { + if (EMPTY_TYPE == &type_descriptors[itype]) { + /* Bypass empty type or NULL */ + continue; + } else if (IO_TYPE == &type_descriptors[itype]) { + num_sides = 4; + /* Special for I/O block, generate one module for each border side */ + for (iside = 0; iside < num_sides; iside++) { + dump_compact_verilog_one_physical_block(cur_sram_orgz_info, + verilog_dir, subckt_dir, + &type_descriptors[itype], iside, + arch, fpga_verilog_opts); + } + continue; + } else if (FILL_TYPE == &type_descriptors[itype]) { + /* For CLB */ + dump_compact_verilog_one_physical_block(cur_sram_orgz_info, + verilog_dir, subckt_dir, + &type_descriptors[itype], -1, + arch, fpga_verilog_opts); + continue; + } else { + /* For heterogenenous blocks */ + dump_compact_verilog_one_physical_block(cur_sram_orgz_info, + verilog_dir, subckt_dir, + &type_descriptors[itype], -1, + arch, fpga_verilog_opts); + + } + } + + /* Output a header file for all the logic blocks */ + vpr_printf(TIO_MESSAGE_INFO,"Generating header file for grid submodules...\n"); + dump_verilog_subckt_header_file(grid_verilog_subckt_file_path_head, + subckt_dir, + logic_block_verilog_file_name); + + + /* Recover spice_model counter */ + set_spice_model_counter(arch->spice->num_spice_model, + arch->spice->spice_models, + stamped_spice_model_cnt); + + /* Restore sram_orgz_info to the base */ + copy_sram_orgz_info (cur_sram_orgz_info, stamped_sram_orgz_info); + + /* Update the grid_index low and high for spice models + * THIS FUNCTION MUST GO AFTER OUTPUTING PHYSICAL LOGIC BLOCKS!!! + */ + compact_verilog_update_grid_spice_model_and_sram_orgz_info(cur_sram_orgz_info, + arch->spice->num_spice_model, + arch->spice->spice_models); + /* Free */ + free_sram_orgz_info(stamped_sram_orgz_info, stamped_sram_orgz_info->type); + my_free (stamped_spice_model_cnt); + + return; +} + +/* Call defined grid + * Instance unique submodules (I/O, CLB, Heterogeneous block) for the full grids + */ +static +void dump_compact_verilog_defined_one_grid(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int ix, int iy, int border_side) { + char* subckt_name = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + if ((NULL == grid[ix][iy].type) + || (EMPTY_TYPE == grid[ix][iy].type) + ||(0 != grid[ix][iy].offset)) { + return; + } + + subckt_name = generate_compact_verilog_grid_module_name(grid[ix][iy].type, border_side); + + /* Comment lines */ + fprintf(fp, "//----- BEGIN Call Grid[%d][%d] module -----\n", ix, iy); + /* Print the Grid module */ + fprintf(fp, "%s ", subckt_name); /* Call the name of subckt */ + fprintf(fp, "%s ", gen_verilog_one_grid_instance_name(ix, iy)); + fprintf(fp, "("); + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + + if (IO_TYPE == grid[ix][iy].type) { + dump_verilog_io_grid_pins(fp, ix, iy, TRUE, FALSE, FALSE); + } else { + dump_verilog_grid_pins(fp, ix, iy, TRUE, FALSE, FALSE); + } + + /* IO PAD */ + dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, + iopad_verilog_model->grid_index_low[ix][iy], + iopad_verilog_model->grid_index_high[ix][iy] - 1, + VERILOG_PORT_CONKT); + + /* Print configuration ports */ + /* Reserved configuration ports */ + if (0 < cur_sram_orgz_info->grid_reserved_conf_bits[ix][iy]) { + fprintf(fp, ",\n"); + } + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, + cur_sram_orgz_info->grid_reserved_conf_bits[ix][iy] - 1, + VERILOG_PORT_CONKT); + /* Normal configuration ports */ + if (0 < (cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] + - cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy])) { + fprintf(fp, ",\n"); + dump_verilog_sram_local_ports(fp, cur_sram_orgz_info, + cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy], + cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] - 1, + VERILOG_PORT_CONKT); + } + + /* Dump ports only visible during formal verification*/ + if (0 < (cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] - 1 + - cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy])) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy], + cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] - 1, + VERILOG_PORT_CONKT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + fprintf(fp, ");\n"); + /* Comment lines */ + fprintf(fp, "//----- END call Grid[%d][%d] module -----\n\n", ix, iy); + + return; +} + +/* Call defined grid + * Instance unique submodules (I/O, CLB, Heterogeneous block) for the full grids + */ +void dump_compact_verilog_defined_grids(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int ix, iy; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Normal Grids */ + for (ix = 1; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + assert(IO_TYPE != grid[ix][iy].type); + dump_compact_verilog_defined_one_grid(cur_sram_orgz_info, fp, ix, iy, -1); + } + } + + /* IO Grids */ + /* TOP side */ + iy = ny + 1; + for (ix = 1; ix < (nx + 1); ix++) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + assert(IO_TYPE == grid[ix][iy].type); + dump_compact_verilog_defined_one_grid(cur_sram_orgz_info, fp, ix, iy, 0); + } + /* RIGHT side */ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + assert(IO_TYPE == grid[ix][iy].type); + dump_compact_verilog_defined_one_grid(cur_sram_orgz_info, fp, ix, iy, 1); + } + + /* BOTTOM side */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + assert(IO_TYPE == grid[ix][iy].type); + dump_compact_verilog_defined_one_grid(cur_sram_orgz_info, fp, ix, iy, 2); + } + /* LEFT side */ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Bypass EMPTY grid */ + if (EMPTY_TYPE == grid[ix][iy].type) { + continue; + } + assert(IO_TYPE == grid[ix][iy].type); + dump_compact_verilog_defined_one_grid(cur_sram_orgz_info, fp, ix, iy, 3); + } + + + return; +} + +/** Print Top-level SPICE netlist in a compact way + * Instance unique submodules (I/O, CLB, Heterogeneous block) for the full grids + */ +void dump_compact_verilog_top_netlist(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + char* submodule_dir_path, + char* lb_dir_path, + char* rr_dir_path, + int LL_num_rr_nodes, + t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog) { + FILE* fp = NULL; + char* formatted_dir_path = NULL; + char* temp_include_file_path = NULL; + char* title = my_strcat("FPGA Verilog Netlist for Design: ", circuit_name); + + /* Check if the path exists*/ + fp = fopen(top_netlist_name,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog netlist %s!",__FILE__, __LINE__, top_netlist_name); + exit(1); + } + + vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Top-level Compact Verilog Netlist for %s...\n", circuit_name); + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + /* Include user-defined sub-circuit netlist */ + fprintf(fp, "//----- Include User-defined netlists -----\n"); + init_include_user_defined_verilog_netlists(verilog); + dump_include_user_defined_verilog_netlists(fp, verilog); + + /* Special subckts for Top-level SPICE netlist */ + fprintf(fp, "//------ Include subckt netlists: Basic Primitives -----\n"); + formatted_dir_path = format_dir_path(submodule_dir_path); + temp_include_file_path = my_strcat(formatted_dir_path, submodule_verilog_file_name); + fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); + my_free(temp_include_file_path); + + fprintf(fp, "//------ Include subckt netlists: Logic Blocks -----\n"); + formatted_dir_path = format_dir_path(lb_dir_path); + temp_include_file_path = my_strcat(formatted_dir_path, logic_block_verilog_file_name); + fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); + my_free(temp_include_file_path); + + fprintf(fp, "//----- Include subckt netlists: Routing structures (Switch Boxes, Channels, Connection Boxes) -----\n"); + formatted_dir_path = format_dir_path(rr_dir_path); + temp_include_file_path = my_strcat(formatted_dir_path, routing_verilog_file_name); + fprintf(fp, "// `include \"%s\"\n", temp_include_file_path); + my_free(temp_include_file_path); + + /* Print all global wires*/ + dump_verilog_top_netlist_ports(cur_sram_orgz_info, fp, num_clock, circuit_name, verilog); + + dump_verilog_top_netlist_internal_wires(cur_sram_orgz_info, fp); + + /* Quote Routing structures: Channels */ + dump_verilog_defined_channels(fp, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + + /* Quote Routing structures: Switch Boxes */ + dump_verilog_defined_switch_boxes(cur_sram_orgz_info, fp); + + /* Quote Routing structures: Connection Boxes */ + dump_verilog_defined_connection_boxes(cur_sram_orgz_info, fp); + + /* Quote defined Logic blocks subckts (Grids) */ + dump_compact_verilog_defined_grids(cur_sram_orgz_info, fp); + + /* Apply CLB to CLB direct connections */ + dump_verilog_clb2clb_directs(fp, num_clb2clb_directs, clb2clb_direct); + + /* Dump configuration circuits */ + dump_verilog_configuration_circuits(cur_sram_orgz_info, fp); + + /* verilog ends*/ + fprintf(fp, "endmodule\n"); + + /* Close the file*/ + fclose(fp); + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h new file mode 100644 index 000000000..e74cd8432 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_compact_netlist.h @@ -0,0 +1,28 @@ +void dump_compact_verilog_one_physical_block(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir_path, + char* subckt_dir_path, + t_type_ptr phy_block_type, + int border_side, + t_arch* arch, + t_syn_verilog_opts fpga_verilog_opts); + +void dump_compact_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, + t_arch* arch, + t_syn_verilog_opts fpga_verilog_opts); + +void dump_compact_verilog_top_netlist(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + char* submodule_dir_path, + char* lb_dir_path, + char* rr_dir_path, + int LL_num_rr_nodes, + t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.c new file mode 100644 index 000000000..91acabf24 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.c @@ -0,0 +1,689 @@ +/***********************************/ +/* Synthesizable Verilog Dumping */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "path_delay.h" +#include "stats.h" + +/* Include FPGA-SPICE utils */ +#include "linkedlist.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" + +/* Include verilog utils */ +#include "verilog_global.h" +#include "verilog_utils.h" + +/***** Subroutines *****/ + +void dump_verilog_decoder_memory_bank_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_dump_verilog_port_type dump_port_type) { + t_spice_model* mem_model = NULL; + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + char split_sign; + + split_sign = determine_verilog_generic_port_split_sign(dump_port_type); + + /* Only accept two types of dump_port_type here! */ + assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); + + /* Check */ + assert (cur_sram_orgz_info->type == SPICE_SRAM_MEMORY_BANK); + + /* A valid file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Depending on the memory technology*/ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + /* Depend on the memory technology */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_bl_enable_port_name, 0, 0); + fprintf(fp, "%c //--- BL enable port \n", split_sign); + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_wl_enable_port_name, 0, 0); + fprintf(fp, "%c //--- WL enable port \n", split_sign); + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_bl_data_in_port_name, 0, 0); + fprintf(fp, "%c //--- BL data input port \n", split_sign); + break; + case SPICE_MODEL_DESIGN_RRAM: + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_bl_enable_port_name, 0, 0); + fprintf(fp, "%c //--- BL enable port \n", split_sign); + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_wl_enable_port_name, 0, 0); + fprintf(fp, "%c //--- WL enable port \n", split_sign); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); + fprintf(fp, "%c //--- Address of bit lines \n", split_sign); + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); + fprintf(fp, " //--- Address of word lines \n"); + + return; +} + + +static +void dump_verilog_decoder(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + t_spice_model* mem_model = NULL; + boolean bl_inverted = FALSE; + boolean wl_inverted = FALSE; + + /* Check */ + assert(SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get number of BLs,WLs and decoder sizes */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, + &bl_decoder_size, &wl_decoder_size); + + /* Different design technology requires different BL decoder logic */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + /* Find if we need an inversion of the BL */ + check_mem_model_blwl_inverted(mem_model, SPICE_MODEL_PORT_BL, &bl_inverted); + check_mem_model_blwl_inverted(mem_model, SPICE_MODEL_PORT_WL, &wl_inverted); + + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: /* CMOS SRAM*/ + /* SRAM technology requires its BL decoder has an additional input called data_in + * only the selected BL will be set to the value of data_in, other BLs will be in high-resistance state + */ + /* Start the BL decoder module definition */ + fprintf(fp, "//----- BL Decoder convert %d bits to binary %d bits -----\n", + bl_decoder_size, num_array_bl); + fprintf(fp, "module bl_decoder%dto%d (\n", + bl_decoder_size, num_array_bl); + fprintf(fp, "input wire enable,\n"); + fprintf(fp, "input wire [%d:0] addr_in,\n", + bl_decoder_size - 1); + fprintf(fp, "input wire data_in,\n"); + fprintf(fp, "output reg [0:%d] addr_out\n", + num_array_bl - 1); + fprintf(fp, ");\n"); + + /* Wee need to know the default value of bl port and wl port */ + + /* Internal logics */ + + fprintf(fp, "always@(addr_out,addr_in,enable, data_in)\n"); + fprintf(fp, "begin\n"); + fprintf(fp, "\taddr_out = %d'bz;\n", num_array_bl); + fprintf(fp, "\tif (1'b1 == enable) begin\n"); + fprintf(fp, "\t\taddr_out[addr_in] = data_in;\n"); + fprintf(fp, "\tend\n"); + fprintf(fp, "end\n"); + + fprintf(fp, "endmodule\n"); + break; + case SPICE_MODEL_DESIGN_RRAM: /* RRAM */ + /* For RRAM technology, BL decoder should be same as the WL decoder */ + /* Start the BL decoder module definition */ + fprintf(fp, "//----- BL Decoder convert %d bits to binary %d bits -----\n", + bl_decoder_size, num_array_bl); + fprintf(fp, "module bl_decoder%dto%d (\n", + bl_decoder_size, num_array_bl); + fprintf(fp, "input wire enable,\n"); + fprintf(fp, "input wire [%d:0] addr_in,\n", + bl_decoder_size-1); + fprintf(fp, "output reg [0:%d] addr_out\n", + num_array_bl-1); + fprintf(fp, ");\n"); + + /* Internal logics */ + fprintf(fp, "always@(addr_out,addr_in,enable)\n"); + fprintf(fp, "begin\n"); + if (TRUE == bl_inverted) { + fprintf(fp, "\taddr_out = %d'b1;\n", num_array_bl); + } else { + assert (FALSE == bl_inverted); + fprintf(fp, "\taddr_out = %d'b0;\n", num_array_bl); + } + fprintf(fp, "\tif (1'b1 == enable) begin\n"); + if (TRUE == bl_inverted) { + fprintf(fp, "\t\taddr_out[addr_in] = 1'b0;\n"); + } else { + assert (FALSE == bl_inverted); + fprintf(fp, "\t\taddr_out[addr_in] = 1'b1;\n"); + } + fprintf(fp, "\tend\n"); + fprintf(fp, "end\n"); + + fprintf(fp, "endmodule\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology [CMOS|RRAM] for memory technology!\n", + __FILE__, __LINE__); + exit(1); + } + + /* WL decoder logic is the same whatever SRAM or RRAM technology is considered */ + /* Start the WL module definition */ + fprintf(fp, "//----- WL Decoder convert %d bits to binary %d bits -----\n", + wl_decoder_size, num_array_wl); + fprintf(fp, "module wl_decoder%dto%d (\n", + wl_decoder_size, num_array_wl); + fprintf(fp, "input wire enable,\n"); + fprintf(fp, "input wire [%d:0] addr_in,\n", + wl_decoder_size-1); + fprintf(fp, "output reg [0:%d] addr_out\n", + num_array_bl-1); + fprintf(fp, ");\n"); + + /* Internal logics */ + fprintf(fp, "always@(addr_out,addr_in,enable)\n"); + fprintf(fp, "begin\n"); + if (TRUE == wl_inverted) { + fprintf(fp, "\taddr_out = %d'b1;\n", num_array_wl); + } else { + assert (FALSE == wl_inverted); + fprintf(fp, "\taddr_out = %d'b0;\n", num_array_wl); + } + fprintf(fp, "\tif (1'b1 == enable) begin\n"); + if (TRUE == wl_inverted) { + fprintf(fp, "\t\taddr_out[addr_in] = 1'b0;\n"); + } else { + assert (FALSE == wl_inverted); + fprintf(fp, "\t\taddr_out[addr_in] = 1'b1;\n"); + } + fprintf(fp, "\tend\n"); + fprintf(fp, "end\n"); + + fprintf(fp, "endmodule\n"); + + return; +} + +/* For standalone-SRAM configuration organization: + * Dump the module of configuration module which connect configuration ports to SRAMs/SCFFs + */ +static +void dump_verilog_standalone_sram_config_module(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + int i, num_mem_bits; + + /* Check */ + assert(SPICE_SRAM_STANDALONE == cur_sram_orgz_info->type); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler!",__FILE__, __LINE__); + exit(1); + } + + /* Get the total memory bits */ + num_mem_bits = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Dump each SRAM */ + fprintf(fp, "//------ Configuration Peripheral for Standalone SRAMs -----\n"); + fprintf(fp, "module %s (\n", + verilog_config_peripheral_prefix); + /* Dump port map*/ + fprintf(fp, "input %s_in[%d:%d],\n", + sram_verilog_model->prefix, + 0, num_mem_bits - 1); + fprintf(fp, "output %s_out[%d:%d],\n", + sram_verilog_model->prefix, + 0, num_mem_bits - 1); + fprintf(fp, "output %s_outb[%d:%d]);\n", + sram_verilog_model->prefix, + 0, num_mem_bits - 1); + + for (i = 0; i < num_mem_bits; i++) { + /* Input and 2 outputs */ + fprintf(fp, "assign %s_out[%d] = %s_in[%d];\n", + sram_verilog_model->prefix, i, + sram_verilog_model->prefix, i); + fprintf(fp, ");\n"); + } + fprintf(fp, "endmodule\n"); + fprintf(fp, "//------ END Standalone SRAMs -----\n"); + + return; +} + + +/* For scan-chain configuration organization: + * Dump the module of configuration module which connect configuration ports to SRAMs/SCFFs + */ +static +void dump_verilog_scan_chain_config_module(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + int i, num_mem_bits; + + /* Check */ + assert(SPICE_SRAM_SCAN_CHAIN == cur_sram_orgz_info->type); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); + exit(1); + } + + /* Get the total memory bits */ + num_mem_bits = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Dump each Scan-chain FF */ + fprintf(fp, "//------ Configuration Peripheral for Scan-chain FFs -----\n"); + fprintf(fp, "module %s (\n", + verilog_config_peripheral_prefix); + /* Port map definition */ + /* Scan-chain input*/ + dump_verilog_generic_port(fp, VERILOG_PORT_INPUT, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, ",\n"); + /* Scan-chain regular inputs */ + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 1, -1, VERILOG_PORT_OUTPUT); + fprintf(fp, ",\n"); + fprintf(fp, "input "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 1, 0, VERILOG_PORT_WIRE); + fprintf(fp, ");\n"); + + /* Connect scan-chain input to the first scan-chain input */ + fprintf(fp, " "); + fprintf(fp, "assign "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, 0, -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, ";\n"); + + /* Verilog Module body */ + /* Connect the head of current scff to the tail of previous scff*/ + fprintf(fp, " "); + fprintf(fp, "assign "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 1, num_mem_bits - 1, -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 2, 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + fprintf(fp, "endmodule\n"); + fprintf(fp, "//------ END Scan-chain FFs -----\n"); + + return; +} + +/* For Memory-bank configuration organization: + * Dump the module of configuration module which connect configuration ports to SRAMs/SCFFs + */ +static +void dump_verilog_membank_config_module(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + t_spice_model* mem_model = NULL; + int iinv, icol, irow; + int num_bl, num_wl; + int num_array_bl, num_array_wl; + int num_reserved_bl, num_reserved_wl; + int cur_bl_lsb, cur_wl_lsb; + int cur_bl_msb, cur_wl_msb; + int bl_decoder_size, wl_decoder_size; + int num_blb_ports, num_wlb_ports; + t_spice_model_port** blb_port = NULL; + t_spice_model_port** wlb_port = NULL; + t_spice_model* blb_inv_spice_model = NULL; + t_spice_model* wlb_inv_spice_model = NULL; + + /* Check */ + assert(SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type); + assert(NULL != cur_sram_orgz_info->mem_bank_info); + + /* A valid file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Depending on the memory technology*/ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + /* Get the total number of BLs and WLs */ + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &num_bl, &num_wl); + /* Get the reserved BLs and WLs */ + get_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, &num_reserved_bl, &num_reserved_wl); + + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + /* Get BLB and WLB ports */ + find_blb_wlb_ports_spice_model(mem_model, &num_blb_ports, &blb_port, + &num_wlb_ports, &wlb_port); + /* Get inverter spice_model */ + + /* Dump each SRAM */ + fprintf(fp, "//------ Configuration Peripheral for Memory-bank -----\n"); + fprintf(fp, "module %s (\n", + verilog_config_peripheral_prefix); + /* Port map */ + /* Ports for memory decoders */ + dump_verilog_decoder_memory_bank_ports(cur_sram_orgz_info, fp, VERILOG_PORT_INPUT); + fprintf(fp, ",\n"); + /* Ports for all the SRAM cells */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + assert( 0 == num_reserved_bl ); + assert( 0 == num_reserved_wl ); + /* Declare normal BL / WL inputs */ + fprintf(fp, " input wire [%d:%d] %s%s, //---- Normal Bit lines \n", + 0, num_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); + fprintf(fp, " input wire [%d:%d] %s%s //---- Normal Word lines\n", + 0, num_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); + /* Declare inverted wires if needed */ + if (1 == num_blb_ports) { + fprintf(fp, ", \n"); + } else { + fprintf(fp, ");\n"); + } + if (1 == num_blb_ports) { + fprintf(fp, " input wire [%d:%d] %s%s //---- Inverted Normal Bit lines \n", + 0, num_bl - 1, mem_model->prefix, top_netlist_normal_blb_port_postfix); + } + if (1 == num_wlb_ports) { + fprintf(fp, ", \n"); + } else { + fprintf(fp, ");\n"); + } + if (1 == num_wlb_ports) { + fprintf(fp, " input wire [%d:%d] %s%s //---- Inverted Normal Word lines \n", + 0, num_wl - 1, mem_model->prefix, top_netlist_normal_wlb_port_postfix); + fprintf(fp, ");\n"); + } + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Check: there should be reserved BLs and WLs */ + assert( 0 < num_reserved_bl ); + assert( 0 < num_reserved_wl ); + /* Declare reserved and normal conf_bits ports */ + fprintf(fp, " input wire [0:%d] %s%s, //---- Reserved Bit lines \n", + num_reserved_bl - 1, mem_model->prefix, top_netlist_reserved_bl_port_postfix); + fprintf(fp, " input wire [0:%d] %s%s, //---- Reserved Word lines \n", + num_reserved_wl - 1, mem_model->prefix, top_netlist_reserved_wl_port_postfix); + fprintf(fp, " input wire [%d:%d] %s%s, //---- Normal Bit lines \n", + num_reserved_bl, num_array_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); + fprintf(fp, " input wire [%d:%d] %s%s); //---- Normal Word lines \n", + num_reserved_wl, num_array_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Important!!!: + * BL/WL should always start from LSB to MSB! + * In order to follow this convention in primitive nodes. + */ + fprintf(fp, "\n"); + /* No. of BLs and WLs in the array */ + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_bl_port_name, 0, num_array_bl - 1); + fprintf(fp, "; //--- Array Bit lines bus \n"); + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_wl_port_name, 0, num_array_wl - 1); + fprintf(fp, "; //--- Array Bit lines bus \n"); + if (1 == num_blb_ports) { + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_blb_port_name, 0, num_array_bl - 1); + fprintf(fp, "; //--- Inverted Array Bit lines bus \n"); + } + if (1 == num_wlb_ports) { + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_wlb_port_name, 0, num_array_wl - 1); + fprintf(fp, "; //--- Inverted Array Word lines bus \n"); + } + fprintf(fp, "\n"); + + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + assert( 0 == num_reserved_bl ); + assert( 0 == num_reserved_wl ); + /* SRAMs are place in an array + * BLs of SRAMs in the same column are connected to a common BL + * BLs of SRAMs in the same row are connected to a common WL + */ + /* Declare inverted wires if needed */ + if (1 == num_blb_ports) { + /* get inv_spice_model */ + blb_inv_spice_model = blb_port[0]->inv_spice_model; + /* Make an inversion of the BL */ + for (iinv = 0; iinv < num_array_bl; iinv++) { + fprintf(fp, " %s %s_blb_%d (%s[%d], %s[%d]);\n", + blb_inv_spice_model->name, blb_inv_spice_model->prefix, + iinv, + top_netlist_array_bl_port_name, iinv, + top_netlist_array_blb_port_name, iinv); + } + } + if (1 == num_wlb_ports) { + /* get inv_spice_model */ + wlb_inv_spice_model = wlb_port[0]->inv_spice_model; + /* Make an inversion of the WL */ + for (iinv = 0; iinv < num_array_wl; iinv++) { + fprintf(fp, " %s %s_wlb_%d (%s[%d], %s[%d]);\n", + wlb_inv_spice_model->name, wlb_inv_spice_model->prefix, + iinv, + top_netlist_array_wl_port_name, iinv, + top_netlist_array_wlb_port_name, iinv); + } + } + + /* Connections for columns */ + for (icol = 0; icol < num_array_bl; icol++) { + cur_bl_lsb = icol * num_array_bl; + cur_bl_msb = (icol + 1) * num_array_bl - 1; + /* Check if the msb exceeds the upbound of num_bl */ + if (cur_bl_msb > num_bl - 1) { + cur_bl_msb = num_bl - 1; + } + /* connect to the BLs of all the SRAMs in the column */ + fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", + mem_model->prefix, top_netlist_normal_bl_port_postfix, cur_bl_lsb, cur_bl_msb, + top_netlist_array_bl_port_name, 0, cur_bl_msb - cur_bl_lsb); + if (1 == num_blb_ports) { + fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", + mem_model->prefix, top_netlist_normal_blb_port_postfix, cur_bl_lsb, cur_bl_msb, + top_netlist_array_blb_port_name, 0, cur_bl_msb - cur_bl_lsb); + } + /* Finish if MSB meets the upbound */ + if (cur_bl_msb == num_bl - 1) { + break; + } + } + /* Connections for rows */ + for (irow = 0; irow < num_array_wl; irow++) { + cur_wl_lsb = irow * num_array_wl; + cur_wl_msb = (irow + 1) * num_array_wl - 1; + /* Check if the msb exceeds the upbound of num_bl */ + if (cur_wl_msb > num_wl - 1) { + cur_wl_msb = num_wl - 1; + } + /* connect to the BLs of all the SRAMs in the column */ + for (icol = cur_wl_lsb; icol < cur_wl_msb + 1; icol++) { + fprintf(fp, " assign %s%s[%d] = %s[%d];\n", + mem_model->prefix, top_netlist_normal_wl_port_postfix, icol, + top_netlist_array_wl_port_name, irow); + if (1 == num_wlb_ports) { + fprintf(fp, " assign %s%s[%d] = %s[%d];\n", + mem_model->prefix, top_netlist_normal_wlb_port_postfix, icol, + top_netlist_array_wlb_port_name, irow); + } + } + /* Finish if MSB meets the upbound */ + if (cur_wl_msb == num_wl - 1) { + break; + } + } + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Check: there should be reserved BLs and WLs */ + assert( 0 < num_reserved_bl ); + assert( 0 < num_reserved_wl ); + /* Declare reserved and normal conf_bits ports */ + fprintf(fp, " wire [0:%d] %s%s; //---- Reserved Bit lines \n", + num_reserved_bl - 1, mem_model->prefix, top_netlist_reserved_bl_port_postfix); + fprintf(fp, " wire [0:%d] %s%s; //---- Reserved Word lines \n", + num_reserved_wl - 1, mem_model->prefix, top_netlist_reserved_wl_port_postfix); + fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Bit lines \n", + num_reserved_bl, num_array_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); + fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Word lines \n", + num_reserved_wl, num_array_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); + /* Connect reserved conf_bits and normal conf_bits to the bus */ + fprintf(fp, " assign %s%s[0:%d] = %s[0:%d];\n", + mem_model->prefix, top_netlist_reserved_bl_port_postfix, num_reserved_bl - 1, + top_netlist_array_bl_port_name, num_reserved_bl - 1); + fprintf(fp, " assign %s%s[0:%d] = %s[0:%d];\n", + mem_model->prefix, top_netlist_reserved_wl_port_postfix, num_reserved_wl - 1, + top_netlist_array_wl_port_name, num_reserved_wl - 1); + fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", + mem_model->prefix, top_netlist_normal_bl_port_postfix, num_reserved_bl, num_array_bl - 1, + top_netlist_array_bl_port_name, num_reserved_bl, num_array_bl - 1); + fprintf(fp, " assign %s%s[%d:%d] = %s[%d:%d];\n", + mem_model->prefix, top_netlist_normal_wl_port_postfix, num_reserved_wl, num_array_wl - 1, + top_netlist_array_wl_port_name, num_reserved_wl, num_array_wl - 1); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Comment lines */ + fprintf(fp, "//----- BEGIN call decoders for memory bank controller -----\n"); + + /* Dump Decoders for Bit lines and Word lines */ + /* Two huge decoders + * TODO: divide to a number of small decoders ? + */ + /* Bit lines decoder */ + fprintf(fp, " "); + fprintf(fp, "bl_decoder%dto%d mem_bank_bl_decoder (", + bl_decoder_size, num_array_bl); + /* Prefix of BL & WL is fixed, in order to simplify grouping nets */ + fprintf(fp, "%s, %s[%d:0], ", + top_netlist_bl_enable_port_name, + top_netlist_addr_bl_port_name, bl_decoder_size - 1); + /* Port map depends on the memory technology */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + /* Data input port of BL decoder, only required by SRAM array */ + fprintf(fp, "%s, ", + top_netlist_bl_data_in_port_name); + break; + case SPICE_MODEL_DESIGN_RRAM: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + fprintf(fp, "%s[0:%d]", + top_netlist_array_bl_port_name, num_array_bl - 1); + fprintf(fp, ");\n"); + + /* Word lines decoder is the same for both technology */ + fprintf(fp, " "); + fprintf(fp, "wl_decoder%dto%d mem_bank_wl_decoder (", + wl_decoder_size, num_array_wl); + fprintf(fp, "%s, %s[%d:0], ", + top_netlist_wl_enable_port_name, + top_netlist_addr_wl_port_name, wl_decoder_size - 1); + fprintf(fp, "%s[0:%d]", + top_netlist_array_wl_port_name, num_array_wl - 1); + fprintf(fp, ");\n"); + fprintf(fp, "//----- END call decoders for memory bank controller -----\n\n"); + + /* Comment lines */ + fprintf(fp, "endmodule\n"); + fprintf(fp, "//----- END configuration peripheral for memory-bank -----\n\n"); + +} + +/* Top-level function */ +void dump_verilog_config_peripherals(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir_path, + char* submodule_dir_path) { + FILE* fp = NULL; + + char* verilog_name = my_strcat(submodule_dir_path, config_peripheral_verilog_file_name); + + /* Open file and file handler */ + fp = fopen(verilog_name, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create decoder SPICE netlist %s", + __FILE__, __LINE__, verilog_name); + exit(1); + } + /* Generate file header*/ + vpr_printf(TIO_MESSAGE_INFO, "Writing configuration peripheral verilog netlist...\n"); + + /* Generate the descriptions*/ + dump_verilog_file_header(fp, " Verilog Configuration Peripheral"); + + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_scan_chain_config_module(fp, cur_sram_orgz_info); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Dump verilog decoder */ + dump_verilog_decoder(fp, cur_sram_orgz_info); + dump_verilog_membank_config_module(fp, cur_sram_orgz_info); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Close the file*/ + fclose(fp); + + /* Add fname to the linked list */ + submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.h new file mode 100644 index 000000000..943f92ca7 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_decoder.h @@ -0,0 +1,8 @@ + +void dump_verilog_decoder_memory_bank_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_config_peripherals(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir_path, + char* submodule_dir); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.c new file mode 100644 index 000000000..7cf108756 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.c @@ -0,0 +1,408 @@ +/***********************************/ +/* Dump Synthesizable Veriolog */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include spice support headers*/ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" + +/* Include verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" +#include "verilog_pbtypes.h" +#include "verilog_decoder.h" +#include "verilog_top_netlist_utils.h" +#include "verilog_top_testbench.h" + +/* Local variables */ +static char* formal_random_top_tb_postfix = "_top_formal_verification_random_tb"; +static char* gfpga_postfix = "_gfpga"; +static char* bench_postfix = "_bench"; +static char* flag_postfix = "_flag"; +static char* def_clk_name = "clk"; +static char* clock_input_name = NULL; + +/* Local Subroutines declaration */ + +/******** Subroutines ***********/ +static +void dump_verilog_top_random_testbench_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + t_syn_verilog_opts fpga_verilog_opts){ + int iblock, iopad_idx; + boolean bench_as_clk = FALSE; + t_spice_model* mem_model = NULL; + char* port_name = NULL; + + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + fprintf(fp, "`include \"%s\"\n", fpga_verilog_opts.reference_verilog_benchmark_file); + + fprintf(fp, "module %s%s;\n", circuit_name, formal_random_top_tb_postfix); +// Instantiate register for inputs stimulis + fprintf(fp, "//----- Shared inputs\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_INPAD == logical_block[iblock].type) { + fprintf(fp, " reg %s;\n", logical_block[iblock].name); + if(logical_block[iblock].is_clock) + bench_as_clk = TRUE; + } + } + } + if(FALSE == bench_as_clk) + fprintf(fp, " reg %s;\n", def_clk_name); +// Instantiate wire for gfpga output + fprintf(fp, "\n//----- GFPGA outputs\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, " wire %s%s;\n", logical_block[iblock].name, gfpga_postfix); + } + } + } +// Instantiate wire for benchmark output + fprintf(fp, "\n`ifdef %s\n//----- Benchmark outputs\n", autochecked_simulation_flag); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, " wire %s%s;\n", logical_block[iblock].name, bench_postfix); + } + } + } +// Instantiate register for output comparison + fprintf(fp, "\n//----- Output flags\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, " reg %s%s;\n", logical_block[iblock].name, flag_postfix); + } + } + } fprintf(fp, "`endif\n"); + + return; +} + +static +void dump_verilog_top_random_testbench_call_benchmark(FILE* fp, + char* reference_verilog_top_name){ + int iblock, iopad_idx; + + fprintf(fp, "`ifdef %s\n", autochecked_simulation_flag); + fprintf(fp, "// Reference Benchmark instanciation\n"); + fprintf(fp, " %s ref_U0(\n", reference_verilog_top_name); + + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(iblock > 0){ + fprintf(fp, ",\n"); + } + if(VPACK_INPAD == logical_block[iblock].type){ + fprintf(fp, " %s", logical_block[iblock].name); + } else if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " %s%s", + logical_block[iblock].name, + bench_postfix); + } + } + } + fprintf(fp, " );\n"); + fprintf(fp, "// End Benchmark instanciation\n`endif\n\n"); + + return; +} + +static +int get_simulation_time(int num_prog_clock_cycles, + float prog_clock_period, + int num_op_clock_cycles, + float op_clock_period) { + int total_time_period = 0; + + /* Take into account the prog_reset and reset cycles */ + total_time_period = ((num_prog_clock_cycles + 2) * prog_clock_period + (2 * num_op_clock_cycles * op_clock_period)) * 1000000000; // * 1000000000 is to change the unit to ns rather than second + + return total_time_period; +} + +static +void dump_verilog_timeout_and_vcd(FILE * fp, + char* circuit_name, + t_spice verilog, + t_sram_orgz_info* cur_sram_orgz_info){ + int simulation_time; + + simulation_time = get_simulation_time(get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info), + 1./verilog.spice_params.stimulate_params.prog_clock_freq, + verilog.spice_params.meas_params.sim_num_clock_cycle, + 1./verilog.spice_params.stimulate_params.op_clock_freq); + + fprintf(fp, " // Begin Icarus requirement\n"); + fprintf(fp, "`ifdef %s\n", icarus_simulator_flag); + fprintf(fp, " initial begin\n"); + fprintf(fp, " $dumpfile(%s_autochecked.vcd);\n", circuit_name); + fprintf(fp, " $dumpvars(1, %s%s);\n", circuit_name, + modelsim_autocheck_testbench_module_postfix); + fprintf(fp, " end\n\n"); + fprintf(fp, " initial begin\n"); + fprintf(fp, " $display(\"Simulation start\");\n"); + fprintf(fp, " #%i // Can be changed by the user for his need\n", simulation_time); + fprintf(fp, " $display(\"Simulation End: Time's up\");\n"); + fprintf(fp, " end\n"); + fprintf(fp, "`endif\n\n"); + return; +} + +static +void dump_verilog_top_random_testbench_check(FILE* fp){ + int iblock, iopad_idx; + fprintf(fp, " // Begin checking\n"); + fprintf(fp, " always@(negedge %s) begin\n", clock_input_name); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " %s%s <= %s%s ^ %s%s ;\n", logical_block[iblock].name, + flag_postfix, + logical_block[iblock].name, + gfpga_postfix, + logical_block[iblock].name, + bench_postfix); + } + } + } + fprintf(fp, " end\n\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " always@(posedge %s%s) begin\n", logical_block[iblock].name, + flag_postfix); + fprintf(fp, " if(%s%s) begin\n", logical_block[iblock].name, + flag_postfix); + fprintf(fp, " $display(\"Mismatch on %s%s\");\n", logical_block[iblock].name, + gfpga_postfix); + fprintf(fp, " $finish;\n"); + fprintf(fp, " end\n"); + fprintf(fp, " end\n"); + } + } + } + return; +} + +static +void dump_verilog_random_testbench_call_top_module(FILE* fp, + char* circuit_name) { + int iblock, iopad_idx; + + fprintf(fp, "// GFPGA instanciation\n"); + fprintf(fp, " %s%s DUT(\n", circuit_name, formal_verification_top_postfix); + + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(iblock > 0){ + fprintf(fp, ",\n"); + } + if(VPACK_INPAD == logical_block[iblock].type){ + fprintf(fp, " %s", logical_block[iblock].name); + } else if(VPACK_OUTPAD == logical_block[iblock].type){ + fprintf(fp, " %s%s", + logical_block[iblock].name, + gfpga_postfix); + } + } + } + fprintf(fp, " );\n"); + fprintf(fp, "// End GFPGA instanciation\n\n"); +} + +static +void dump_verilog_top_random_stimuli(FILE* fp, + t_spice verilog){ + int iblock, iopad_idx; + char* reset_input_name = NULL; + + fprintf(fp, "//----- Initialization\n"); + fprintf(fp, " initial begin\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_INPAD == logical_block[iblock].type) { + fprintf(fp, " %s <= 1'b0;\n", logical_block[iblock].name); + if(logical_block[iblock].is_clock) + clock_input_name = logical_block[iblock].name; + /* if(logical_block[iblock].is_reset) + reset_input_name = logical_block[iblock].name; */ + } + } + } + if(NULL == clock_input_name){ + clock_input_name = def_clk_name; + fprintf(fp, " %s <= 1'b0;\n", def_clk_name); + } + fprintf(fp, " while(1) begin\n"); + fprintf(fp, " #%.1f\n", ((0.5/verilog.spice_params.stimulate_params.op_clock_freq)/verilog_sim_timescale)); + fprintf(fp, " %s <= !%s;\n", clock_input_name, clock_input_name); + fprintf(fp, " end\n"); + fprintf(fp, " end\n\n"); +/* fprintf(fp, "//----- Reset Stimulis\n"); // Not ready yet to determine if input is reset + fprintf(fp, " initial begin\n"); + fprintf(fp, " #%.3f\n",(rand() % 10) + 0.001); + fprintf(fp, " %s <= !%s;\n", reset_input_name, reset_input_name); + fprintf(fp, " #%.3f\n",(rand() % 10) + 0.001); + fprintf(fp, " %s <= !%s;\n", reset_input_name, reset_input_name); + fprintf(fp, " while(1) begin\n"); + fprintf(fp, " #%.3f\n", (rand() % 15) + 0.5); + fprintf(fp, " %s <= !%s;\n", reset_input_name, reset_input_name); + fprintf(fp, " #%.3f\n", (rand() % 10000) + 200); + fprintf(fp, " %s <= !%s;\n", reset_input_name, reset_input_name); + fprintf(fp, " end\n"); + fprintf(fp, " end\n\n"); */ + fprintf(fp, "//----- Input Stimulis\n"); + fprintf(fp, " always@(negedge %s) begin\n", clock_input_name); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_INPAD == logical_block[iblock].type) { + //if((logical_block[iblock].is_clock || logical_block[iblock].is_reset ) == 0 ) + if(logical_block[iblock].is_clock == 0 ) + fprintf(fp, " %s <= $random;\n", logical_block[iblock].name); + } + } + } + fprintf(fp, " end\n\n"); + return; +} + +void dump_verilog_random_top_testbench(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog) { + FILE* fp = NULL; + char* title = my_strcat("FPGA Verilog Testbench for Formal Top-level netlist of Design: ", circuit_name); + + /* Check if the path exists*/ + fp = fopen(top_netlist_name,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!", + __FILE__, __LINE__, top_netlist_name); + exit(1); + } + + vpr_printf(TIO_MESSAGE_INFO, + "Writing Random Testbench for FPGA Top-level Verilog netlist for %s...\n", + circuit_name); + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir_path); + verilog_include_simulation_defines_file(fp, verilog_dir_path); + + /* Start of testbench */ + dump_verilog_top_random_testbench_ports(fp, cur_sram_orgz_info, circuit_name, fpga_verilog_opts); + + /* Call defined top-level module */ + dump_verilog_random_testbench_call_top_module(fp, circuit_name); + + /* Call defined benchmark */ + dump_verilog_top_random_testbench_call_benchmark(fp, circuit_name); + + /* Add stimuli for reset, set, clock and iopad signals */ + dump_verilog_top_random_stimuli(fp, verilog); + + /* Add output autocheck */ + fprintf(fp, "`ifdef %s\n", autochecked_simulation_flag); + dump_verilog_top_random_testbench_check(fp); + fprintf(fp, "`endif\n\n"); + + /* Add Icarus requirement */ + dump_verilog_timeout_and_vcd(fp, circuit_name , verilog, cur_sram_orgz_info); + + /* Testbench ends*/ + fprintf(fp, "endmodule\n"); + + /* Close the file*/ + fclose(fp); + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.h new file mode 100644 index 000000000..20a9f68f3 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.h @@ -0,0 +1,9 @@ + +void dump_verilog_random_top_testbench(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.c new file mode 100644 index 000000000..56eb60497 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.c @@ -0,0 +1,139 @@ +// Formality runsim +// Need to declare formality_script_name_postfix = "formality_script.tcl"; +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "path_delay.h" +#include "stats.h" + +/* Include FPGA-SPICE utils */ +#include "linkedlist.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_globals.h" + +/* Include verilog utils */ +#include "verilog_global.h" +#include "verilog_utils.h" + +static +void formality_include_user_defined_verilog_netlists(FILE* fp, + t_spice spice) { + int i; + + /* A valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d])Invalid File Handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Include user-defined sub-circuit netlist */ + for (i = 0; i < spice.num_include_netlist; i++) { + if (0 == spice.include_netlists[i].included) { + assert(NULL != spice.include_netlists[i].path); + fprintf(fp, "%s ", spice.include_netlists[i].path); + spice.include_netlists[i].included = 1; + } else { + assert(1 == spice.include_netlists[i].included); + } + } + + return; +} + +void write_formality_script (t_syn_verilog_opts fpga_verilog_opts, + char* fm_dir_formatted, + char* src_dir_formatted, + char* chomped_circuit_name, + t_spice spice){ + int iblock; + char* formality_script_file_name = NULL; + char* benchmark_path = NULL; + char* original_output_name = NULL; +/* int output_length; */ +/* int pos; */ + FILE* fp = NULL; + + if(TRUE == fpga_verilog_opts.print_autocheck_top_testbench){ + benchmark_path = fpga_verilog_opts.reference_verilog_benchmark_file; + } else { + benchmark_path = "Insert verilog benchmark path"; + } + + formality_script_file_name = my_strcat(fm_dir_formatted, my_strcat(chomped_circuit_name, formality_script_name_postfix)); + fp = fopen(formality_script_file_name, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create formality script %s", + __FILE__, __LINE__, formality_script_file_name); + exit(1); + } + + /* Load Verilog benchmark as reference */ + fprintf(fp, "read_verilog -container r -libname WORK -05 { %s }\n", benchmark_path); + /* Set reference top */ + fprintf(fp, "set_top r:/WORK/%s\n", chomped_circuit_name); + /* Load generated verilog as implemnetation */ + fprintf(fp, "read_verilog -container i -libname WORK -05 { "); + fprintf(fp, "%s%s%s ", src_dir_formatted, + chomped_circuit_name, + verilog_top_postfix); + fprintf(fp, "%s%s%s ", src_dir_formatted, + chomped_circuit_name, + formal_verification_verilog_file_postfix); + init_include_user_defined_verilog_netlists(spice); + formality_include_user_defined_verilog_netlists(fp, spice); + fprintf(fp, "%s%s%s ", src_dir_formatted, + default_rr_dir_name, + routing_verilog_file_name); + fprintf(fp, "%s%s%s ", src_dir_formatted, + default_lb_dir_name, + logic_block_verilog_file_name); + fprintf(fp, "%s%s%s ", src_dir_formatted, + default_submodule_dir_name, + submodule_verilog_file_name); + fprintf(fp, "}\n"); + /* Set implementation top */ + fprintf(fp, "set_top i:/WORK/%s\n", my_strcat(chomped_circuit_name, formal_verification_top_postfix)); + /* Run matching */ + fprintf(fp, "match\n"); + /* Add manual matching for the outputs */ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + original_output_name = NULL; + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type) + ||(VPACK_OUTPAD == logical_block[iblock].type)); + if(VPACK_OUTPAD == logical_block[iblock].type){ + /* output_length = strlen(logical_block[iblock].name); */ + original_output_name = logical_block[iblock].name + 4; + /* printf("%s", original_output_name); */ + fprintf(fp, "set_user_match r:/WORK/%s/%s i:/WORK/%s/%s[0] -type port -noninverted\n", + chomped_circuit_name, + original_output_name, + my_strcat(chomped_circuit_name, formal_verification_top_postfix), + my_strcat(logical_block[iblock].name, formal_verification_top_module_port_postfix)); + } + } + } + /* Run verification */ + fprintf(fp, "verify\n"); + /* Script END */ + fclose(fp); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.h new file mode 100644 index 000000000..6a8ca29c1 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formality_autodeck.h @@ -0,0 +1,5 @@ +void write_formality_script (t_syn_verilog_opts fpga_verilog_opts, + char* fm_dir_formatted, + char* src_dir_formatted, + char* chomped_circuit_name, + t_spice spice); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.c new file mode 100644 index 000000000..e0f4b26c9 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.c @@ -0,0 +1,140 @@ +/***********************************/ +/* Synthesizable Verilog Dumping */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include "spice_types.h" +#include "linkedlist.h" +#include "fpga_x2p_globals.h" +#include "verilog_global.h" + +char* verilog_netlist_file_postfix = ".v"; +float verilog_sim_timescale = 1e-9; // Verilog Simulation time scale (minimum time unit) : 1ns +char* verilog_timing_preproc_flag = "ENABLE_TIMING"; // the flag to enable timing definition during compilation +char* verilog_signal_init_preproc_flag = "ENABLE_SIGNAL_INITIALIZATION"; // the flag to enable signal initialization during compilation +char* verilog_formal_verification_preproc_flag = "ENABLE_FORMAL_VERIFICATION"; // the flag to enable formal verification during compilation +char* initial_simulation_flag = "INITIAL_SIMULATION"; // the flag to enable initial functional verification +char* autochecked_simulation_flag = "AUTOCHECKED_SIMULATION"; // the flag to enable autochecked functional verification +char* formal_simulation_flag = "FORMAL_SIMULATION"; // the flag to enable formal functional verification + +char* default_verilog_dir_name = "syn_verilogs/"; +char* default_src_dir_name = "SRC/"; +char* default_lb_dir_name = "lb/"; +char* default_rr_dir_name = "routing/"; +char* default_submodule_dir_name = "sub_module/"; +char* default_tcl_dir_name = "SCRIPTS/"; +char* default_sdc_dir_name = "SDC/"; +char* default_msim_dir_name = "MSIM/"; +char* default_snpsfm_dir_name = "SNPS_FM/"; +char* default_modelsim_dir_name = "msim_projects/"; +char* default_report_timing_rpt_dir_name = "RPT/"; +char* autocheck_testbench_postfix = "_autocheck"; + +char* modelsim_project_name_postfix = "_fpga_msim"; +char* modelsim_proc_script_name_postfix = "_proc.tcl"; +char* modelsim_top_script_name_postfix = "_runsim.tcl"; +char* modelsim_testbench_module_postfix = "_top_tb"; +char* modelsim_autocheck_testbench_module_postfix = "_autocheck_top_tb"; +char* modelsim_simulation_time_unit = "ms"; + +char* formal_verification_top_module_postfix = "_top_formal_verification"; +char* formal_verification_top_module_port_postfix = "_fm"; +char* formal_verification_top_module_uut_name = "U0_formal_verification"; + +// Formality script generation variables +char* formality_script_name_postfix = "_formality_script.tcl"; +char* formal_verification_top_postfix = "_top_formal_verification"; +// End of Formality script generation variables + +// Icarus variables and flag +char* icarus_simulator_flag = "ICARUS_SIMULATOR"; // the flag to enable specific Verilog code in testbenches +// End of Icarus variables and flag + +char* verilog_top_postfix = "_top.v"; +char* formal_verification_verilog_file_postfix = "_top_formal_verification.v"; +char* top_testbench_verilog_file_postfix = "_top_tb.v"; /* !!! must be consist with the modelsim_testbench_module_postfix */ +char* autocheck_top_testbench_verilog_file_postfix = "_autocheck_top_tb.v"; /* !!! must be consist with the modelsim_autocheck_testbench_module_postfix */ +char* random_top_testbench_verilog_file_postfix = "_formal_random_top_tb.v"; +char* blif_testbench_verilog_file_postfix = "_blif_tb.v"; +char* defines_verilog_file_name = "fpga_defines.v"; +char* defines_verilog_simulation_file_name = "define_simulation.v"; +char* submodule_verilog_file_name = "sub_module.v"; +char* logic_block_verilog_file_name = "logic_blocks.v"; +char* luts_verilog_file_name = "luts.v"; +char* routing_verilog_file_name = "routing.v"; +char* muxes_verilog_file_name = "muxes.v"; +char* memories_verilog_file_name = "memories.v"; +char* wires_verilog_file_name = "wires.v"; +char* essentials_verilog_file_name = "inv_buf_passgate.v"; +char* config_peripheral_verilog_file_name = "config_peripherals.v"; +char* user_defined_template_verilog_file_name = "user_defined_templates.v"; + +/* File names for Report Timing */ +char* trpt_sb_file_name = "report_timing_sb.tcl"; +char* trpt_routing_file_name = "report_timing_routing.tcl"; + +/* File names for SDC*/ +char* sdc_analysis_file_name = "fpga_top_analysis.sdc"; +char* sdc_break_loop_file_name = "break_loop.sdc"; +char* sdc_constrain_routing_chan_file_name = "routing_channels.sdc"; +char* sdc_constrain_cb_file_name = "cb.sdc"; +char* sdc_constrain_sb_file_name = "sb.sdc"; +char* sdc_clock_period_file_name = "clb_clock.sdc"; +char* sdc_constrain_pb_type_file_name = "clb_constraints.sdc"; + +char* verilog_mux_basis_posfix = "_basis"; +char* verilog_mux_special_basis_posfix = "_special_basis"; +char* verilog_mem_posfix = "_mem"; +char* verilog_config_peripheral_prefix = "config_peripheral"; + +/* Prefix for subckt Verilog netlists */ +char* grid_verilog_file_name_prefix = "grid_"; +char* chanx_verilog_file_name_prefix = "chanx_"; +char* chany_verilog_file_name_prefix = "chany_"; +char* sb_verilog_file_name_prefix = "sb_"; +char* cbx_verilog_file_name_prefix = "cbx_"; +char* cby_verilog_file_name_prefix = "cby_"; + +/* SRAM SPICE MODEL should be set as global*/ +t_spice_model* sram_verilog_model = NULL; + +/* Input and Output Pad spice model. should be set as global */ +t_spice_model* iopad_verilog_model = NULL; + +/* Linked-list that stores all the configuration bits */ +t_llist* conf_bits_head = NULL; + +/* Linked-list that stores submodule Verilog file mames */ +t_llist* grid_verilog_subckt_file_path_head = NULL; +t_llist* routing_verilog_subckt_file_path_head = NULL; +t_llist* submodule_verilog_subckt_file_path_head = NULL; + +int verilog_default_signal_init_value = 0; + +char* top_netlist_bl_enable_port_name = "en_bl"; +char* top_netlist_wl_enable_port_name = "en_wl"; +char* top_netlist_bl_data_in_port_name = "data_in"; +char* top_netlist_addr_bl_port_name = "addr_bl"; +char* top_netlist_addr_wl_port_name = "addr_wl"; +char* top_netlist_array_bl_port_name = "bl_bus"; +char* top_netlist_array_wl_port_name = "wl_bus"; +char* top_netlist_array_blb_port_name = "blb_bus"; +char* top_netlist_array_wlb_port_name = "wlb_bus"; +char* top_netlist_reserved_bl_port_postfix = "_reserved_bl"; +char* top_netlist_reserved_wl_port_postfix = "_reserved_wl"; +char* top_netlist_normal_bl_port_postfix = "_bl"; +char* top_netlist_normal_wl_port_postfix = "_wl"; +char* top_netlist_normal_blb_port_postfix = "_blb"; +char* top_netlist_normal_wlb_port_postfix = "_wlb"; +char* top_netlist_scan_chain_head_prefix = "sc_in"; + +char* top_tb_reset_port_name = "greset"; +char* top_tb_set_port_name = "gset"; +char* top_tb_prog_reset_port_name = "prog_reset"; +char* top_tb_prog_set_port_name = "prog_set"; +char* top_tb_config_done_port_name = "config_done"; +char* top_tb_op_clock_port_name = "op_clock"; +char* top_tb_prog_clock_port_name = "prog_clock"; +char* top_tb_inout_reg_postfix = "_reg"; +char* top_tb_clock_reg_postfix = "_reg"; + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h new file mode 100644 index 000000000..4a204cf30 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_global.h @@ -0,0 +1,146 @@ +/* global parameters for dumping synthesizable verilog */ + +extern char* verilog_netlist_file_postfix; +extern float verilog_sim_timescale; +extern char* verilog_timing_preproc_flag; // the flag to enable timing definition during compilation +extern char* verilog_signal_init_preproc_flag; // the flag to enable signal initialization during compilation +extern char* verilog_formal_verification_preproc_flag; // the flag to enable formal verification during compilation +extern char* initial_simulation_flag; +extern char* autochecked_simulation_flag; +extern char* formal_simulation_flag; + +extern char* default_verilog_dir_name; +extern char* default_src_dir_name; +extern char* default_lb_dir_name; +extern char* default_rr_dir_name; +extern char* default_submodule_dir_name; +extern char* default_tcl_dir_name; +extern char* default_sdc_dir_name; +extern char* default_msim_dir_name; +extern char* default_snpsfm_dir_name; +extern char* default_modelsim_dir_name; +extern char* default_report_timing_rpt_dir_name; +extern char* autocheck_testbench_postfix; + +extern char* modelsim_project_name_postfix; +extern char* modelsim_proc_script_name_postfix; +extern char* modelsim_top_script_name_postfix; +extern char* modelsim_testbench_module_postfix; +extern char* modelsim_autocheck_testbench_module_postfix; +extern char* modelsim_simulation_time_unit; + +extern char* formal_verification_top_module_postfix; +extern char* formal_verification_top_module_port_postfix; +extern char* formal_verification_top_module_uut_name; + +// Formality script generation variables +extern char* formality_script_name_postfix; +extern char* formal_verification_top_postfix; +// End of Formality script generation variables + +// Icarus variables and flag +extern char* icarus_simulator_flag; +// End of Icarus variables and flag + +extern char* verilog_top_postfix; +extern char* formal_verification_verilog_file_postfix; +extern char* top_testbench_verilog_file_postfix; +extern char* autocheck_top_testbench_verilog_file_postfix; +extern char* random_top_testbench_verilog_file_postfix; +extern char* blif_testbench_verilog_file_postfix; +extern char* defines_verilog_file_name; +extern char* defines_verilog_simulation_file_name; +extern char* submodule_verilog_file_name; +extern char* logic_block_verilog_file_name; +extern char* luts_verilog_file_name; +extern char* routing_verilog_file_name; +extern char* muxes_verilog_file_name; +extern char* memories_verilog_file_name; +extern char* wires_verilog_file_name; +extern char* essentials_verilog_file_name; +extern char* config_peripheral_verilog_file_name; +extern char* user_defined_template_verilog_file_name; + +extern char* trpt_sb_file_name; +extern char* trpt_routing_file_name; + +extern char* sdc_analysis_file_name; +extern char* sdc_break_loop_file_name; +extern char* sdc_clock_period_file_name; +extern char* sdc_constrain_routing_chan_file_name; +extern char* sdc_constrain_cb_file_name; +extern char* sdc_constrain_sb_file_name; +extern char* sdc_constrain_pb_type_file_name; + +extern char* verilog_mux_basis_posfix; +extern char* verilog_mux_special_basis_posfix; +extern char* verilog_mem_posfix; +extern char* verilog_config_peripheral_prefix; + +/* Prefix for subckt Verilog netlists */ +extern char* grid_verilog_file_name_prefix; +extern char* chanx_verilog_file_name_prefix; +extern char* chany_verilog_file_name_prefix; +extern char* sb_verilog_file_name_prefix; +extern char* cbx_verilog_file_name_prefix; +extern char* cby_verilog_file_name_prefix; + +extern t_spice_model* sram_verilog_model; + +/* Input and Output Pad spice model. should be set as global */ +extern t_spice_model* inpad_verilog_model; +extern t_spice_model* outpad_verilog_model; +extern t_spice_model* iopad_verilog_model; + +/* Linked-list that stores all the configuration bits */ +extern t_llist* conf_bits_head; + +/* Linked-list that stores submodule Verilog file mames */ +extern t_llist* grid_verilog_subckt_file_path_head; +extern t_llist* routing_verilog_subckt_file_path_head; +extern t_llist* submodule_verilog_subckt_file_path_head; + +extern int verilog_default_signal_init_value; + +extern char* top_netlist_bl_enable_port_name; +extern char* top_netlist_wl_enable_port_name; +extern char* top_netlist_bl_data_in_port_name; +extern char* top_netlist_addr_bl_port_name; +extern char* top_netlist_addr_wl_port_name; +extern char* top_netlist_array_bl_port_name; +extern char* top_netlist_array_wl_port_name; +extern char* top_netlist_array_blb_port_name; +extern char* top_netlist_array_wlb_port_name; +extern char* top_netlist_reserved_bl_port_postfix; +extern char* top_netlist_reserved_wl_port_postfix; +extern char* top_netlist_normal_bl_port_postfix; +extern char* top_netlist_normal_wl_port_postfix; +extern char* top_netlist_normal_blb_port_postfix; +extern char* top_netlist_normal_wlb_port_postfix; +extern char* top_netlist_scan_chain_head_prefix; + +extern char* top_tb_reset_port_name; +extern char* top_tb_set_port_name; +extern char* top_tb_prog_reset_port_name; +extern char* top_tb_prog_set_port_name; +extern char* top_tb_config_done_port_name; +extern char* top_tb_op_clock_port_name; +extern char* top_tb_prog_clock_port_name; +extern char* top_tb_inout_reg_postfix; +extern char* top_tb_clock_reg_postfix; + +enum e_dump_verilog_port_type { +VERILOG_PORT_INPUT, +VERILOG_PORT_OUTPUT, +VERILOG_PORT_INOUT, +VERILOG_PORT_WIRE, +VERILOG_PORT_REG, +VERILOG_PORT_CONKT +}; + +enum e_verilog_tb_type { +VERILOG_TB_TOP, +VERILOG_TB_BLIF_TOP, +VERILOG_TB_AUTOCHECK_TOP, +VERILOG_TB_FORMAL_VERIFICATION +}; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.c new file mode 100644 index 000000000..fbb9f618a --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.c @@ -0,0 +1,120 @@ +// Formality runsim +// Need to declare formality_script_name_postfix = "formality_script.tcl"; +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "path_delay.h" +#include "stats.h" + +/* Include FPGA-SPICE utils */ +#include "linkedlist.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_globals.h" + +/* Include verilog utils */ +#include "verilog_global.h" +#include "verilog_utils.h" + +static +void include_netlists_include_user_defined_verilog_netlists(FILE* fp, + t_spice spice) { + int i; + + /* A valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d])Invalid File Handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Include user-defined sub-circuit netlist */ + for (i = 0; i < spice.num_include_netlist; i++) { + if (0 == spice.include_netlists[i].included) { + assert(NULL != spice.include_netlists[i].path); + fprintf(fp, "`include \"%s\"\n", spice.include_netlists[i].path); + spice.include_netlists[i].included = 1; + } else { + assert(1 == spice.include_netlists[i].included); + } + } + + return; +} + +void write_include_netlists (char* src_dir_formatted, + char* chomped_circuit_name, + t_spice spice){ + + char* include_netlists_file_name = NULL; +/* int output_length; */ +/* int pos; */ + FILE* fp = NULL; + + include_netlists_file_name = my_strcat(src_dir_formatted, my_strcat(chomped_circuit_name, "_include_netlists.v")); + fp = fopen(include_netlists_file_name, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create formality script %s", + __FILE__, __LINE__, include_netlists_file_name); + exit(1); + } + + /* Print the title */ + dump_verilog_file_header(fp, "Netlists Summary"); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, src_dir_formatted); + verilog_include_simulation_defines_file(fp, src_dir_formatted); + + + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + chomped_circuit_name, + verilog_top_postfix); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + chomped_circuit_name, + formal_verification_verilog_file_postfix); + fprintf(fp, " `ifdef %s\n", formal_simulation_flag); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + chomped_circuit_name, + random_top_testbench_verilog_file_postfix); + fprintf(fp, " `endif\n"); + fprintf(fp, "`elsif %s\n", initial_simulation_flag); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + chomped_circuit_name, + top_testbench_verilog_file_postfix); + fprintf(fp, "`elsif %s\n", autochecked_simulation_flag); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + chomped_circuit_name, + autocheck_top_testbench_verilog_file_postfix); + fprintf(fp, "`endif\n"); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + default_rr_dir_name, + routing_verilog_file_name); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + default_lb_dir_name, + logic_block_verilog_file_name); + fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, + default_submodule_dir_name, + submodule_verilog_file_name); + init_include_user_defined_verilog_netlists(spice); + include_netlists_include_user_defined_verilog_netlists(fp, spice); + + fclose(fp); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h new file mode 100644 index 000000000..e89a6345b --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h @@ -0,0 +1,3 @@ +void write_include_netlists (char* src_dir_formatted, + char* chomped_circuit_name, + t_spice spice); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.c similarity index 57% rename from vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.c index a4872194c..2cedbda8f 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_modelsim_autodeck.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.c @@ -23,8 +23,8 @@ /* Include FPGA-SPICE utils */ #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_globals.h" /* Include verilog utils */ #include "verilog_global.h" @@ -84,6 +84,7 @@ void modelsim_include_user_defined_verilog_netlists(FILE* fp, * Total simulation time = number of programming clock cycles * programming clock period * + number of operating clock cycles * operating clock period */ +static float get_verilog_modelsim_simulation_time_period(float time_unit, int num_prog_clock_cycles, float prog_clock_period, @@ -98,12 +99,10 @@ float get_verilog_modelsim_simulation_time_period(float time_unit, return total_time_period; } +static void dump_verilog_modelsim_proc_script(char* modelsim_proc_filename, char* modelsim_ini_path, - char* circuit_name, - boolean include_timing, - boolean init_sim, - char* modelsim_project_name) { + char* circuit_name) { FILE* fp = NULL; char* circuit_top_tb_name = NULL; @@ -154,13 +153,7 @@ void dump_verilog_modelsim_proc_script(char* modelsim_proc_filename, fprintf(fp, " \n"); fprintf(fp, "proc add_waves {} {\n"); - fprintf(fp, " add wave -position insertpoint sim:/%s/prog_clock \\\n\ - sim:/%s/op_clock \\\n\ - sim:/%s/in_* \\\n\ - sim:/%s/out_*\n", circuit_top_tb_name, - circuit_top_tb_name, - circuit_top_tb_name, - circuit_top_tb_name); + fprintf(fp, " add wave -position insertpoint sim:/%s/*\n", circuit_top_tb_name); fprintf(fp, "}\n"); @@ -176,19 +169,7 @@ void dump_verilog_modelsim_proc_script(char* modelsim_proc_filename, fprintf(fp, " #Add the verilog files\n"); fprintf(fp, " add_files_project $verilog_files\n"); fprintf(fp, " #Compile all the files\n"); -// fprintf(fp, " project compileall\n"); // removed to allow compilation with define -// Begin of compilation with Define - fprintf(fp, " set myFiles [project filenames]\n"); - fprintf(fp, " foreach x $myFiles {\n"); - fprintf(fp, " vlog "); - if(TRUE == include_timing){ - fprintf(fp, "+define+%s ", verilog_timing_preproc_flag); - } - if(TRUE == init_sim){ - fprintf(fp, "+define+%s ", verilog_init_sim_preproc_flag); - } - fprintf(fp, "$x\n }\n"); -// End of compilation with Define + fprintf(fp, " project compileall\n"); fprintf(fp, " #Start the simulation\n"); fprintf(fp, " vsim $projectname.%s -voptargs=+acc\n", circuit_top_tb_name); fprintf(fp, " #Add the waves \n"); @@ -201,30 +182,14 @@ void dump_verilog_modelsim_proc_script(char* modelsim_proc_filename, fprintf(fp, "#Top proc to recompile files and re run the simulation\n"); fprintf(fp, "proc top_rerun_sim {simtime unit} {\n"); -// Save format - fprintf(fp, " #Save actual format\n"); - fprintf(fp, " set myLoc [pwd]\n"); - fprintf(fp, " write format wave -window .main_pane.wave.interior.cs.body.pw.wf $myLoc/relaunch.do\n"); -// Quit simulation - fprintf(fp, " quit -sim\n"); -// Recompile file fprintf(fp, " #Compile updated verilog files\n"); - fprintf(fp, " set myFiles [project filenames]\n"); - fprintf(fp, " foreach x $myFiles {\n"); - fprintf(fp, " vlog "); - if(TRUE == include_timing){ - fprintf(fp, "+define+%s ", verilog_timing_preproc_flag); - } - if(TRUE == init_sim){ - fprintf(fp, "+define+%s ", verilog_init_sim_preproc_flag); - } - fprintf(fp, "$x\n }\n"); -// Restart the Simulation - fprintf(fp, " set projectname %s\n", modelsim_project_name); - fprintf(fp, " vsim $projectname.%s -voptargs=+acc -do relaunch.do\n", circuit_top_tb_name); -// Relaunch the Simulation + fprintf(fp, " project compileoutofdate\n"); + fprintf(fp, " #restart the simulation\n"); + fprintf(fp, " restart -force\n"); fprintf(fp, " #run the simulation\n"); - fprintf(fp, " run $simtime $unit\n"); + fprintf(fp, " runsim $simtime $unit\n"); + fprintf(fp, " #Fit the window view\n"); + fprintf(fp, " wave zoom full\n"); fprintf(fp, "}\n"); /* Close File handler */ @@ -236,6 +201,7 @@ void dump_verilog_modelsim_proc_script(char* modelsim_proc_filename, return; } +static void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename, char* modelsim_ini_path, char* circuit_name, @@ -245,7 +211,7 @@ void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename, FILE* fp = NULL; char* circuit_top_tb_name = NULL; - circuit_top_tb_name = my_strcat(circuit_name, modelsim_auto_testbench_module_postfix); + circuit_top_tb_name = my_strcat(circuit_name, my_strcat(autocheck_testbench_postfix, modelsim_testbench_module_postfix)); /* Create Modelsim proc file */ /* Open file and file handler */ @@ -292,13 +258,7 @@ void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename, fprintf(fp, " \n"); fprintf(fp, "proc add_waves {} {\n"); - fprintf(fp, " add wave -position insertpoint sim:/%s/prog_clock \\\n\ - sim:/%s/op_clock \\\n\ - sim:/%s/in_* \\\n\ - sim:/%s/out_* \n", circuit_top_tb_name, - circuit_top_tb_name, - circuit_top_tb_name, - circuit_top_tb_name); + fprintf(fp, " add wave -position insertpoint sim:/%s/*\n", circuit_top_tb_name); fprintf(fp, "}\n"); @@ -323,7 +283,7 @@ void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename, fprintf(fp, "+define+%s ", verilog_timing_preproc_flag); } if(TRUE == init_sim){ - fprintf(fp, "+define+%s ", verilog_init_sim_preproc_flag); + fprintf(fp, "+define+%s ", verilog_signal_init_preproc_flag); } fprintf(fp, "$x\n }\n"); // End of compilation with Define @@ -354,7 +314,7 @@ void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename, fprintf(fp, "+define+%s ", verilog_timing_preproc_flag); } if(TRUE == init_sim){ - fprintf(fp, "+define+%s ", verilog_init_sim_preproc_flag); + fprintf(fp, "+define+%s ", verilog_signal_init_preproc_flag); } fprintf(fp, "$x\n }\n"); // Restart the Simulation @@ -374,144 +334,8 @@ void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename, return; } -void dump_verilog_modelsim_proc_auto_preconf_script(char* modelsim_proc_filename, - char* modelsim_ini_path, - char* circuit_name, - boolean include_timing, - boolean init_sim, - char* modelsim_project_name) { - FILE* fp = NULL; - char* circuit_top_tb_name = NULL; - - circuit_top_tb_name = my_strcat(circuit_name, modelsim_auto_preconf_testbench_module_postfix); - - /* Create Modelsim proc file */ - /* Open file and file handler */ - fp = fopen(modelsim_proc_filename, "w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create Modelsim simulation deck auto-generation scripts: %s", - __FILE__, __LINE__, modelsim_proc_filename); - exit(1); - } - - fprintf(fp, "proc create_project {projectname project_path} {\n"); - fprintf(fp, " #Switch to the modelsim folder to create the project\n"); - fprintf(fp, " set libname $projectname\n"); - fprintf(fp, " set initfile %s\n", modelsim_ini_path); - fprintf(fp, " project new $project_path/$projectname $projectname $libname $initfile 0\n"); - fprintf(fp, "}\n"); - - fprintf(fp, " \n"); - - fprintf(fp, "proc create_project_with_close {projectname modelsim_path} {\n"); - fprintf(fp, " #Get the current project name\n"); - fprintf(fp, " set project_env [project env]\n"); - fprintf(fp, " if {$project_env eq \"\"} {\n"); - fprintf(fp, " #If string empty (no project)\n"); - fprintf(fp, " create_project $projectname $modelsim_path\n"); - fprintf(fp, " } else {\n"); - fprintf(fp, " #If string not empty (a project is loaded so clsoe it first)\n"); - fprintf(fp, " project close\n"); - fprintf(fp, " create_project $projectname $modelsim_path\n"); - fprintf(fp, " }\n"); - fprintf(fp, " }\n"); - - fprintf(fp, " \n"); - - fprintf(fp, "proc add_files_project {verilog_files} {\n"); - fprintf(fp, " #Get the length of the list\n"); - fprintf(fp, " set listlength [llength $verilog_files]\n"); - fprintf(fp, " #Add the verilog files one by one\n"); - fprintf(fp, " for {set x 0} {$x<$listlength} {incr x} {\n"); - fprintf(fp, " project addfile [lindex $verilog_files $x]\n"); - fprintf(fp, " }\n"); - fprintf(fp, "}\n"); - - fprintf(fp, " \n"); - - fprintf(fp, "proc add_waves {} {\n"); - fprintf(fp, " add wave -position insertpoint sim:/%s/prog_clock \\\n\ - sim:/%s/op_clock \\\n\ - sim:/%s/in_* \\\n\ - sim:/%s/out_*\n", circuit_top_tb_name, - circuit_top_tb_name, - circuit_top_tb_name, - circuit_top_tb_name); - fprintf(fp, "}\n"); - - - fprintf(fp, "proc runsim {simtime unit} {\n"); - fprintf(fp, " run $simtime $unit\n"); - fprintf(fp, "}\n"); - - - fprintf(fp, "#Top procedure to create enw project\n"); - fprintf(fp, "proc top_create_new_project {projectname verilog_files modelsim_path simtime unit} {\n"); - fprintf(fp, " #Create the project\n"); - fprintf(fp, " create_project_with_close $projectname $modelsim_path\n"); - fprintf(fp, " #Add the verilog files\n"); - fprintf(fp, " add_files_project $verilog_files\n"); - fprintf(fp, " #Compile all the files\n"); -// fprintf(fp, " project compileall\n"); // removed to allow compilation with define -// Begin of compilation with Define - fprintf(fp, " set myFiles [project filenames]\n"); - fprintf(fp, " foreach x $myFiles {\n"); - fprintf(fp, " vlog "); - if(TRUE == include_timing){ - fprintf(fp, "+define+%s ", verilog_timing_preproc_flag); - } - if(TRUE == init_sim){ - fprintf(fp, "+define+%s ", verilog_init_sim_preproc_flag); - } - fprintf(fp, "$x\n }\n"); -// End of compilation with Define - fprintf(fp, " #Start the simulation\n"); - fprintf(fp, " vsim $projectname.%s -voptargs=+acc\n", circuit_top_tb_name); - fprintf(fp, " #Add the waves \n"); - fprintf(fp, " add_waves\n"); - fprintf(fp, " #run the simulation\n"); - fprintf(fp, " runsim $simtime $unit\n"); - fprintf(fp, " #Fit the window view\n"); - fprintf(fp, " wave zoom full\n"); - fprintf(fp, "}\n"); - - fprintf(fp, "#Top proc to recompile files and re run the simulation\n"); - fprintf(fp, "proc top_rerun_sim {simtime unit} {\n"); -// Save format - fprintf(fp, " #Save actual format\n"); - fprintf(fp, " set myLoc [pwd]\n"); - fprintf(fp, " write format wave -window .main_pane.wave.interior.cs.body.pw.wf $myLoc/relaunch.do\n"); -// Quit simulation - fprintf(fp, " quit -sim\n"); -// Recompile file - fprintf(fp, " #Compile updated verilog files\n"); - fprintf(fp, " set myFiles [project filenames]\n"); - fprintf(fp, " foreach x $myFiles {\n"); - fprintf(fp, " vlog "); - if(TRUE == include_timing){ - fprintf(fp, "+define+%s ", verilog_timing_preproc_flag); - } - if(TRUE == init_sim){ - fprintf(fp, "+define+%s ", verilog_init_sim_preproc_flag); - } - fprintf(fp, "$x\n }\n"); -// Restart the Simulation - fprintf(fp, " set projectname %s\n", modelsim_project_name); - fprintf(fp, " vsim $projectname.%s -voptargs=+acc -do relaunch.do\n", circuit_top_tb_name); -// Relaunch the Simulation - fprintf(fp, " #run the simulation\n"); - fprintf(fp, " run $simtime $unit\n"); - fprintf(fp, "}\n"); - - /* Close File handler */ - fclose(fp); - - /* Free */ - my_free(circuit_top_tb_name); - - return; -} +static void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename, char* modelsim_proc_script_filename, char* modelsim_project_path, @@ -519,7 +343,8 @@ void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename, char* modelsim_project_name, float sim_time, char* sim_time_unit, - t_spice spice) { + t_spice spice, + char* src_dir_path) { FILE* fp = NULL; /* Create Modelsim proc file */ @@ -536,7 +361,7 @@ void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename, fprintf(fp, "\n"); fprintf(fp, "#in ms\n"); - fprintf(fp, "set simtime %.18g\n", sim_time); + fprintf(fp, "set simtime %.10g\n", sim_time); fprintf(fp, "set unit %s\n", sim_time_unit); fprintf(fp, "\n"); @@ -546,7 +371,8 @@ void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename, fprintf(fp, "\n"); fprintf(fp, "#Path were the verilog files are located\n"); - fprintf(fp, "set verilog_path \"%s\"\n", modelsim_project_path); + fprintf(fp, "set script_path \"%s\"\n", modelsim_project_path); + fprintf(fp, "set verilog_path \"%s\"\n", src_dir_path); fprintf(fp, "set verilog_files [list \\\n"); /* TODO: include verilog files */ fprintf(fp, " ${verilog_path}${benchmark}%s \\\n", @@ -566,7 +392,7 @@ void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename, fprintf(fp, "\n"); fprintf(fp, "#Source the tcl script\n"); - fprintf(fp, "source ${verilog_path}%s\n", modelsim_proc_script_filename); + fprintf(fp, "source ${script_path}%s\n", modelsim_proc_script_filename); fprintf(fp, "\n"); fprintf(fp, "#Execute the top level procedure\n"); @@ -581,6 +407,7 @@ void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename, return; } +static void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filename, char* modelsim_proc_auto_script_filename, char* modelsim_project_path, @@ -588,7 +415,8 @@ void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filena char* modelsim_project_name, float sim_time, char* sim_time_unit, - t_spice spice) { + t_spice spice, + char* src_dir_path) { FILE* fp = NULL; /* Create Modelsim proc file */ @@ -605,7 +433,7 @@ void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filena fprintf(fp, "\n"); fprintf(fp, "#in ms\n"); - fprintf(fp, "set simtime %.18g\n", sim_time); + fprintf(fp, "set simtime %.4g\n", sim_time); fprintf(fp, "set unit %s\n", sim_time_unit); fprintf(fp, "\n"); @@ -615,13 +443,15 @@ void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filena fprintf(fp, "\n"); fprintf(fp, "#Path were the verilog files are located\n"); - fprintf(fp, "set verilog_path \"%s\"\n", modelsim_project_path); + fprintf(fp, "set script_path \"%s\"\n", modelsim_project_path); + fprintf(fp, "set verilog_path \"%s\"\n", src_dir_path); fprintf(fp, "set verilog_files [list \\\n"); /* TODO: include verilog files */ fprintf(fp, " ${verilog_path}${benchmark}%s \\\n", verilog_top_postfix); - fprintf(fp, " ${verilog_path}${benchmark}%s \\\n", - top_auto_testbench_verilog_file_postfix); + fprintf(fp, " ${verilog_path}${benchmark}%s%s \\\n", + autocheck_testbench_postfix, top_testbench_verilog_file_postfix); + /* User-defined verilog netlists */ init_include_user_defined_verilog_netlists(spice); modelsim_include_user_defined_verilog_netlists(fp, spice); @@ -635,7 +465,7 @@ void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filena fprintf(fp, "\n"); fprintf(fp, "#Source the tcl script\n"); - fprintf(fp, "source ${verilog_path}%s\n", modelsim_proc_auto_script_filename); + fprintf(fp, "source ${script_path}%s\n", modelsim_proc_auto_script_filename); fprintf(fp, "\n"); fprintf(fp, "#Execute the top level procedure\n"); @@ -650,136 +480,55 @@ void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filena return; } -void dump_verilog_modelsim_top_auto_preconf_script(char* modelsim_top_auto_script_filename, - char* modelsim_proc_auto_script_filename, - char* modelsim_project_path, - char* circuit_name, - char* modelsim_project_name, - float sim_time, - char* sim_time_unit, - t_spice spice) { - FILE* fp = NULL; - - /* Create Modelsim proc file */ - /* Open file and file handler */ - fp = fopen(modelsim_top_auto_script_filename, "w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create Modelsim simulation deck auto-generation scripts: %s", - __FILE__, __LINE__, modelsim_top_auto_script_filename); - exit(1); - } - - fprintf(fp, "set projectname %s\n", modelsim_project_name); - fprintf(fp, "set benchmark %s\n", circuit_name); - fprintf(fp, "\n"); - - fprintf(fp, "#in ms\n"); - fprintf(fp, "set simtime 150\n"); - fprintf(fp, "set unit us\n"); - fprintf(fp, "\n"); - - fprintf(fp, "#Path were both tcl script are located\n"); - fprintf(fp, "set project_path \"%s%s\"\n", modelsim_project_path, default_modelsim_dir_name); - fprintf(fp, "\n"); - - fprintf(fp, "#Path were the verilog files are located\n"); - fprintf(fp, "set verilog_path \"%s\"\n", modelsim_project_path); - fprintf(fp, "set verilog_files [list \\\n"); - /* TODO: include verilog files */ - fprintf(fp, " ${verilog_path}${benchmark}%s \\\n", - verilog_top_postfix); - fprintf(fp, " ${verilog_path}${benchmark}%s \\\n", - top_auto_preconf_testbench_verilog_file_postfix); - /* User-defined verilog netlists */ - init_include_user_defined_verilog_netlists(spice); - modelsim_include_user_defined_verilog_netlists(fp, spice); - - fprintf(fp, " ${verilog_path}%s%s \\\n", - default_lb_dir_name, logic_block_verilog_file_name); - fprintf(fp, " ${verilog_path}%s%s \\\n", - default_rr_dir_name, routing_verilog_file_name); - fprintf(fp, " ${verilog_path}%s%s ] \n", - default_submodule_dir_name, submodule_verilog_file_name); - fprintf(fp, "\n"); - - fprintf(fp, "#Source the tcl script\n"); - fprintf(fp, "source ${verilog_path}%s\n", modelsim_proc_auto_script_filename); - fprintf(fp, "\n"); - - fprintf(fp, "#Execute the top level procedure\n"); - fprintf(fp, "top_create_new_project $projectname $verilog_files $project_path $simtime $unit\n"); - fprintf(fp, "\n"); - - fprintf(fp, "#Relaunch simulation\n"); - - /* Close File handler */ - fclose(fp); - - return; -} /***** Top-level function *****/ void dump_verilog_modelsim_autodeck(t_sram_orgz_info* cur_sram_orgz_info, + t_syn_verilog_opts fpga_verilog_opts, t_spice spice, int num_operating_clock_cycles, char* verilog_dir_formatted, char* chomped_circuit_name, - char* simulator_ini_path, - boolean include_timing, - boolean init_sim, - boolean print_top_tb, - boolean print_top_auto_tb, - boolean tb_preconf) { + char* src_dir_path) { char* modelsim_project_name = NULL; char* modelsim_proc_script_filename = NULL; char* modelsim_top_script_filename = NULL; char* modelsim_proc_auto_script_filename = NULL; char* modelsim_top_auto_script_filename = NULL; - char* modelsim_proc_auto_preconf_script_filename = NULL; - char* modelsim_top_auto_preconf_script_filename = NULL; - char* auto_tb_postfix = "_autocheck"; - char* auto_preconf_tb_postfix = "_preconf_autocheck"; float simulation_time_period = 0.; /* Determine the project name for Modelsim */ modelsim_project_name = my_strcat(chomped_circuit_name, modelsim_project_name_postfix); modelsim_top_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, modelsim_top_script_name_postfix)); modelsim_proc_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, modelsim_proc_script_name_postfix)); - modelsim_top_auto_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, my_strcat(auto_tb_postfix, modelsim_top_script_name_postfix))); - modelsim_proc_auto_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, my_strcat(auto_tb_postfix, modelsim_proc_script_name_postfix))); - modelsim_top_auto_preconf_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, my_strcat(auto_preconf_tb_postfix, modelsim_top_script_name_postfix))); - modelsim_proc_auto_preconf_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, my_strcat(auto_preconf_tb_postfix, modelsim_proc_script_name_postfix))); + + modelsim_top_auto_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, my_strcat(autocheck_testbench_postfix, modelsim_top_script_name_postfix))); + modelsim_proc_auto_script_filename = my_strcat(verilog_dir_formatted, my_strcat(chomped_circuit_name, my_strcat(autocheck_testbench_postfix, modelsim_proc_script_name_postfix))); /* Generate files */ vpr_printf(TIO_MESSAGE_INFO, "Writing Modelsim simulation deck auto-generation scripts...\n"); /* Check */ /* Modelsim ini path must be valid!*/ - if (NULL == simulator_ini_path) { + if (NULL == fpga_verilog_opts.modelsim_ini_path) { vpr_printf(TIO_MESSAGE_INFO, "(FILE:%s, [LINE%d])Invalid Modelsim ini path!\n", __FILE__, __LINE__); exit(1); } /* Dump the Modelsim process function file */ - if(print_top_tb){ - dump_verilog_modelsim_proc_script(modelsim_proc_script_filename, - simulator_ini_path, chomped_circuit_name, - include_timing, init_sim, - modelsim_project_name); + if (fpga_verilog_opts.print_top_testbench){ + dump_verilog_modelsim_proc_script(modelsim_proc_script_filename, + fpga_verilog_opts.modelsim_ini_path, chomped_circuit_name); } - if(print_top_auto_tb){ + + if (fpga_verilog_opts.print_autocheck_top_testbench){ dump_verilog_modelsim_proc_auto_script(modelsim_proc_auto_script_filename, - simulator_ini_path, chomped_circuit_name, - include_timing, init_sim, - modelsim_project_name); - } - if(tb_preconf){ - dump_verilog_modelsim_proc_auto_preconf_script( modelsim_proc_auto_preconf_script_filename, - simulator_ini_path, chomped_circuit_name, - include_timing, init_sim, - modelsim_project_name); + fpga_verilog_opts.modelsim_ini_path, chomped_circuit_name, + fpga_verilog_opts.include_timing, fpga_verilog_opts.include_signal_init, + modelsim_project_name); } + + /* Compute simulation time period */ simulation_time_period = get_verilog_modelsim_simulation_time_period(convert_modelsim_time_unit_to_float(modelsim_simulation_time_unit), get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info), @@ -788,34 +537,32 @@ void dump_verilog_modelsim_autodeck(t_sram_orgz_info* cur_sram_orgz_info, 1./spice.spice_params.stimulate_params.op_clock_freq); /* Dump the Modelsim top-level script file */ - if(print_top_tb){ + if (fpga_verilog_opts.print_top_testbench){ dump_verilog_modelsim_top_script(modelsim_top_script_filename, - my_strcat(chomped_circuit_name, modelsim_proc_script_name_postfix), - verilog_dir_formatted, - chomped_circuit_name, modelsim_project_name, - simulation_time_period, modelsim_simulation_time_unit, - spice); + my_strcat(chomped_circuit_name, modelsim_proc_script_name_postfix), + verilog_dir_formatted, + chomped_circuit_name, modelsim_project_name, + simulation_time_period, modelsim_simulation_time_unit, + spice, + src_dir_path); } - if(print_top_auto_tb){ + + if (fpga_verilog_opts.print_autocheck_top_testbench){ dump_verilog_modelsim_top_auto_script(modelsim_top_auto_script_filename, - my_strcat(chomped_circuit_name, my_strcat(auto_tb_postfix, modelsim_proc_script_name_postfix)), - verilog_dir_formatted, - chomped_circuit_name, modelsim_project_name, - simulation_time_period, modelsim_simulation_time_unit, - spice); - } - if(tb_preconf){ - dump_verilog_modelsim_top_auto_preconf_script(modelsim_top_auto_preconf_script_filename, - my_strcat(chomped_circuit_name, my_strcat( auto_preconf_tb_postfix, modelsim_proc_script_name_postfix)), - verilog_dir_formatted, - chomped_circuit_name, modelsim_project_name, - simulation_time_period, modelsim_simulation_time_unit, - spice); + my_strcat(chomped_circuit_name, my_strcat(autocheck_testbench_postfix, modelsim_proc_script_name_postfix)), + verilog_dir_formatted, + chomped_circuit_name, modelsim_project_name, + simulation_time_period, modelsim_simulation_time_unit, + spice, + src_dir_path); } + /* Free */ my_free(modelsim_project_name); my_free(modelsim_proc_script_filename); my_free(modelsim_top_script_filename); + my_free(modelsim_proc_auto_script_filename); + my_free(modelsim_top_auto_script_filename); return; } diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.h new file mode 100644 index 000000000..2131ff36c --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_modelsim_autodeck.h @@ -0,0 +1,8 @@ + +void dump_verilog_modelsim_autodeck(t_sram_orgz_info* cur_sram_orgz_info, + t_syn_verilog_opts fpga_verilog_opts, + t_spice spice, + int num_operating_clock_cycles, + char* verilog_dir_formatted, + char* chomped_circuit_name, + char* src_dir_path); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_pbtypes.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c similarity index 58% rename from vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_pbtypes.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c index dbbd241b5..67447c3ed 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_pbtypes.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c @@ -18,17 +18,21 @@ #include "globals.h" #include "rr_graph.h" #include "vpr_utils.h" +#include "route_common.h" /* Include SPICE support headers*/ #include "linkedlist.h" -#include "fpga_spice_utils.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" #include "spice_mux.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_globals.h" /* Include Synthesizable Verilog headers */ #include "verilog_global.h" #include "verilog_utils.h" -#include "verilog_lut.h" #include "verilog_primitives.h" #include "verilog_pbtypes.h" @@ -145,43 +149,6 @@ void match_pb_types_verilog_model_rec(t_pb_type* cur_pb_type, return; } -int verilog_find_path_id_between_pb_rr_nodes(t_rr_node* local_rr_graph, - int src_node, - int des_node) { - int path_id = -1; - int prev_edge = -1; - int path_count = 0; - int iedge; - t_interconnect* cur_interc = NULL; - - /* Check */ - assert(NULL != local_rr_graph); - assert((0 == src_node)||(0 < src_node)); - assert((0 == des_node)||(0 < des_node)); - - prev_edge = local_rr_graph[des_node].prev_edge; - check_pb_graph_edge(*(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge])); - assert(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge]->output_pins[0] == local_rr_graph[des_node].pb_graph_pin); - - cur_interc = local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge]->interconnect; - /* Search des_node input edges */ - for (iedge = 0; iedge < local_rr_graph[des_node].pb_graph_pin->num_input_edges; iedge++) { - if (local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]->input_pins[0] - == local_rr_graph[src_node].pb_graph_pin) { - /* Strict check */ - assert(local_rr_graph[src_node].pb_graph_pin->output_edges[prev_edge] - == local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]); - path_id = path_count; - break; - } - if (cur_interc == local_rr_graph[des_node].pb_graph_pin->input_edges[iedge]->interconnect) { - path_count++; - } - } - - return path_id; -} - /* Find the interconnection type of pb_graph_pin edges*/ enum e_interconnect verilog_find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin) { enum e_interconnect interc_type; @@ -407,7 +374,7 @@ void dump_verilog_pb_type_bus_ports(FILE* fp, int num_pb_type_clk_port = 0; t_port** pb_type_clk_ports = NULL; - char* formatted_port_prefix = chomp_verilog_node_prefix(port_prefix); + char* formatted_port_prefix = chomp_verilog_prefix(port_prefix); /* A counter to stats the number of dumped ports and pins */ int num_dumped_port = 0; @@ -554,7 +521,8 @@ void dump_verilog_pb_type_ports(FILE* fp, int use_global_clock, t_pb_type* cur_pb_type, boolean dump_port_type, - boolean dump_last_comma) { + boolean dump_last_comma, + boolean require_explicit_port_map) { int iport, ipin; int num_pb_type_input_port = 0; t_port** pb_type_input_ports = NULL; @@ -568,7 +536,7 @@ void dump_verilog_pb_type_ports(FILE* fp, int num_pb_type_clk_port = 0; t_port** pb_type_clk_ports = NULL; - char* formatted_port_prefix = chomp_verilog_node_prefix(port_prefix); + char* formatted_port_prefix = chomp_verilog_prefix(port_prefix); /* A counter to stats the number of dumped ports and pins */ int num_dumped_port = 0; @@ -604,9 +572,21 @@ void dump_verilog_pb_type_ports(FILE* fp, } } if (TRUE == dump_port_type) { - fprintf(fp, "inout wire"); + fprintf(fp, "inout wire "); + } else if ((NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ".%s(", + pb_type_inout_ports[iport]->spice_model_port->lib_name); + } + fprintf(fp, "%s", + gen_verilog_one_pb_type_pin_name(formatted_port_prefix, pb_type_inout_ports[iport], ipin)); + if ((FALSE == dump_port_type) + && (NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ") "); } - fprintf(fp, "%s__%s_%d_ ", formatted_port_prefix, pb_type_inout_ports[iport]->name, ipin); /* Update the counter */ num_dumped_port++; } @@ -635,9 +615,21 @@ void dump_verilog_pb_type_ports(FILE* fp, } } if (TRUE == dump_port_type) { - fprintf(fp, "input wire"); + fprintf(fp, "input wire "); + } else if ((NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ".%s(", + pb_type_input_ports[iport]->spice_model_port->lib_name); + } + fprintf(fp, "%s", + gen_verilog_one_pb_type_pin_name(formatted_port_prefix, pb_type_input_ports[iport], ipin)); + if ((FALSE == dump_port_type) + && (NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ") "); } - fprintf(fp, " %s__%s_%d_", formatted_port_prefix, pb_type_input_ports[iport]->name, ipin); /* Update the counter */ num_dumped_port++; } @@ -665,9 +657,21 @@ void dump_verilog_pb_type_ports(FILE* fp, } } if (TRUE == dump_port_type) { - fprintf(fp, "output wire"); + fprintf(fp, "output wire "); + } else if ((NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ".%s(", + pb_type_output_ports[iport]->spice_model_port->lib_name); + } + fprintf(fp, "%s", + gen_verilog_one_pb_type_pin_name(formatted_port_prefix, pb_type_output_ports[iport], ipin)); + if ((FALSE == dump_port_type) + && (NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ") "); } - fprintf(fp, " %s__%s_%d_", formatted_port_prefix, pb_type_output_ports[iport]->name, ipin); /* Update the counter */ num_dumped_port++; } @@ -698,9 +702,21 @@ void dump_verilog_pb_type_ports(FILE* fp, } } if (TRUE == dump_port_type) { - fprintf(fp, "input wire"); + fprintf(fp, "input wire "); + } else if ((NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ".%s(", + pb_type_clk_ports[iport]->spice_model_port->lib_name); + } + fprintf(fp, "%s", + gen_verilog_one_pb_type_pin_name(formatted_port_prefix, pb_type_clk_ports[iport], ipin)); + if ((FALSE == dump_port_type) + && (NULL != cur_pb_type->spice_model) + && (TRUE == require_explicit_port_map) + && (TRUE == cur_pb_type->spice_model->dump_explicit_port_map)) { + fprintf(fp, ") "); } - fprintf(fp, " %s__%s_%d_", formatted_port_prefix, pb_type_clk_ports[iport]->name, ipin); /* Update the counter */ num_dumped_port++; } @@ -731,7 +747,7 @@ void dump_verilog_pb_type_ports(FILE* fp, void dump_verilog_dangling_des_pb_graph_pin_interc(FILE* fp, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, char* parent_pin_prefix) { t_pb_graph_node* des_pb_graph_node = NULL; t_pb_type* des_pb_type = NULL; @@ -741,7 +757,7 @@ void dump_verilog_dangling_des_pb_graph_pin_interc(FILE* fp, char* des_pin_prefix = NULL; /* char* formatted_parent_pin_prefix = format_verilog_node_prefix(parent_pin_prefix);*/ /* Complete a "_" at the end if needed*/ - //char* chomped_parent_pin_prefix = chomp_verilog_node_prefix(parent_pin_prefix); /* Remove a "_" at the end if needed*/ + //char* chomped_parent_pin_prefix = chomp_verilog_prefix(parent_pin_prefix); /* Remove a "_" at the end if needed*/ /* Check the file handler*/ if (NULL == fp) { @@ -813,8 +829,8 @@ void dump_verilog_dangling_des_pb_graph_pin_interc(FILE* fp, */ if (des_pb_type == cur_mode->parent_pb_type) { /* Interconnection from parent pb_type*/ des_pin_prefix = (char*)my_malloc(sizeof(char)* - (5 + strlen(cur_mode->name) + 2 )); - sprintf(des_pin_prefix, "mode_%s_", cur_mode->name); + (strlen(cur_mode->name) + 1 + 1 )); + sprintf(des_pin_prefix, "%s_", cur_mode->name); } else { des_pin_prefix = (char*)my_malloc(sizeof(char)* (strlen(des_pb_type->name) + 1 + strlen(my_itoa(des_pb_type_index)) + 1 + 1)); @@ -833,13 +849,13 @@ void dump_verilog_dangling_des_pb_graph_pin_interc(FILE* fp, return; } -void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_node, - t_pb_graph_node* des_pb_graph_node, - enum e_pin2pin_interc_type pin2pin_interc_type, - t_interconnect* pin2pin_interc, - char* parent_pin_prefix, - char** src_pin_prefix, - char** des_pin_prefix) { +void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_pin* src_pb_graph_pin, + t_pb_graph_pin* des_pb_graph_pin, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, + t_interconnect* pin2pin_interc, + char* parent_pin_prefix, + char** src_pin_prefix, + char** des_pin_prefix) { t_pb_type* src_pb_type = NULL; int src_pb_type_index = -1; @@ -847,13 +863,13 @@ void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_ int des_pb_type_index = -1; /* Check the pb_graph_nodes*/ - if (NULL == src_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: src_pb_graph_node.\n", + if (NULL == src_pb_graph_pin) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: src_pb_graph_pin.\n", __FILE__, __LINE__); exit(1); } - if (NULL == des_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: des_pb_graph_node.\n", + if (NULL == des_pb_graph_pin) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pointer: des_pb_graph_pin.\n", __FILE__, __LINE__); exit(1); } @@ -864,10 +880,10 @@ void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_ } /* Initialize */ - src_pb_type = src_pb_graph_node->pb_type; - src_pb_type_index = src_pb_graph_node->placement_index; - des_pb_type = des_pb_graph_node->pb_type; - des_pb_type_index = des_pb_graph_node->placement_index; + src_pb_type = src_pb_graph_pin->parent_node->pb_type; + src_pb_type_index = src_pb_graph_pin->parent_node->placement_index; + des_pb_type = des_pb_graph_pin->parent_node->pb_type; + des_pb_type_index = des_pb_graph_pin->parent_node->placement_index; assert(NULL == (*src_pin_prefix)); assert(NULL == (*des_pin_prefix)); @@ -883,14 +899,14 @@ void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_ * src_pin_prefix = _[] * des_pin_prefix = mode[]_[]_ */ - if (src_pb_type == des_pb_type->parent_mode->parent_pb_type) { /* Interconnection from parent pb_type*/ + if (src_pb_type == des_pb_type->parent_mode->parent_pb_type) { /* Interconnection from parent pb_type*/ /* (*src_pin_prefix) = my_strdup(chomped_parent_pin_prefix); */ /*Simplify the prefix, make the SPICE netlist readable*/ (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* - (5 + strlen(des_pb_type->parent_mode->name) + 2)); - sprintf((*src_pin_prefix), "mode_%s_", des_pb_type->parent_mode->name); + (strlen(des_pb_type->parent_mode->parent_pb_type->name) + 1 + 1)); + sprintf((*src_pin_prefix), "%s_", des_pb_type->parent_mode->parent_pb_type->name); } else { /* (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* @@ -933,32 +949,27 @@ void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_ formatted_parent_pin_prefix, pin2pin_interc_parent_mode->name, src_pb_type->name, src_pb_type_index); */ /*Simplify the prefix, make the SPICE netlist readable*/ - (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* - (strlen(src_pb_type->name) + 1 + strlen(my_itoa(src_pb_type_index)) + 1 + 1)); - sprintf((*src_pin_prefix), "%s_%d_", - src_pb_type->name, src_pb_type_index); - if (des_pb_type == src_pb_type->parent_mode->parent_pb_type) { /* Interconnection from parent pb_type*/ + if (des_pb_type == src_pb_type) { /* src pin is an input of parent pb_type*/ /* (*des_pin_prefix) = my_strdup(chomped_parent_pin_prefix); */ /*Simplify the prefix, make the SPICE netlist readable*/ - (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* - (5 + strlen(src_pb_type->parent_mode->name) + 2)); - sprintf((*des_pin_prefix), "mode_%s_", src_pb_type->parent_mode->name); + (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* + (strlen(pin2pin_interc->parent_mode->parent_pb_type->name) + 1 + 1)); + sprintf((*src_pin_prefix), "%s_", pin2pin_interc->parent_mode->parent_pb_type->name); } else { - /* - (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* - (strlen(formatted_parent_pin_prefix) + 5 + strlen(pin2pin_interc_parent_mode->name) - + 2 + strlen(des_pb_type->name) + 1 + strlen(my_itoa(des_pb_type_index)) + 1 + 1)); - sprintf((*des_pin_prefix), "%smode[%s]_%s[%d]", - formatted_parent_pin_prefix, pin2pin_interc_parent_mode->name, des_pb_type->name, des_pb_type_index); - */ - /*Simplify the prefix, make the SPICE netlist readable*/ - (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* - (strlen(des_pb_type->name) + 1 + strlen(my_itoa(des_pb_type_index)) + 1 + 1)); - sprintf((*des_pin_prefix), "%s_%d_", - des_pb_type->name, des_pb_type_index); + (*src_pin_prefix) = (char*)my_malloc(sizeof(char)* + (strlen(src_pb_type->name) + 1 + strlen(my_itoa(src_pb_type_index)) + 1 + 1)); + sprintf((*src_pin_prefix), "%s_%d_", + src_pb_type->name, src_pb_type_index); } + /* + (*des_pin_prefix) = my_strdup(chomped_parent_pin_prefix); + */ + /*Simplify the prefix, make the SPICE netlist readable*/ + (*des_pin_prefix) = (char*)my_malloc(sizeof(char)* + (strlen(pin2pin_interc->parent_mode->parent_pb_type->name) + 1 + 1)); + sprintf((*des_pin_prefix), "%s_", pin2pin_interc->parent_mode->parent_pb_type->name); break; default: vpr_printf(TIO_MESSAGE_ERROR,"(File:%s [LINE%d])Invalid pin to pin interconnection type!\n", @@ -1004,12 +1015,12 @@ void verilog_find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pi * | * input_pins, edges, output_pins */ -void dump_verilog_pb_graph_pin_interc(FILE* fp, +void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* parent_pin_prefix, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, t_pb_graph_pin* des_pb_graph_pin, - t_mode* cur_mode, - int select_edge) { + t_mode* cur_mode) { int i, iedge, ipin; int fan_in = 0; t_interconnect* cur_interc = NULL; @@ -1021,7 +1032,7 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, t_pb_graph_node* des_pb_graph_node = NULL; - char* formatted_parent_pin_prefix = chomp_verilog_node_prefix(parent_pin_prefix); /* Complete a "_" at the end if needed*/ + char* formatted_parent_pin_prefix = chomp_verilog_prefix(parent_pin_prefix); /* Complete a "_" at the end if needed*/ char* src_pin_prefix = NULL; char* des_pin_prefix = NULL; @@ -1033,6 +1044,9 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, int num_mux_reserved_conf_bits = 0; int cur_bl, cur_wl; t_spice_model* mem_model = NULL; + char* mem_subckt_name = NULL; + char* hierarchical_name = NULL; + char* mux_name = NULL; /* Check the file handler*/ if (NULL == fp) { @@ -1047,7 +1061,7 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, */ fan_in = 0; cur_interc = NULL; - verilog_find_interc_fan_in_des_pb_graph_pin(des_pb_graph_pin, cur_mode, &cur_interc, &fan_in); + find_interc_fan_in_des_pb_graph_pin(des_pb_graph_pin, cur_mode, &cur_interc, &fan_in); if ((NULL == cur_interc)||(0 == fan_in)) { /* No interconnection matched */ /* Connect this pin to GND for better convergence */ @@ -1059,28 +1073,7 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, return; } /* Initialize the interconnection type that will be implemented in SPICE netlist*/ - switch (cur_interc->type) { - case DIRECT_INTERC: - assert(1 == fan_in); - verilog_interc_type = DIRECT_INTERC; - break; - case COMPLETE_INTERC: - if (1 == fan_in) { - verilog_interc_type = DIRECT_INTERC; - } else { - assert((2 == fan_in)||(2 < fan_in)); - verilog_interc_type = MUX_INTERC; - } - break; - case MUX_INTERC: - assert((2 == fan_in)||(2 < fan_in)); - verilog_interc_type = MUX_INTERC; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", - __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); - exit(1); - } + verilog_interc_type = determine_actual_pb_interc_type(cur_interc, fan_in); /* This time, (2nd round), we print the subckt, according to interc type*/ switch (verilog_interc_type) { case DIRECT_INTERC: @@ -1110,14 +1103,16 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, /* Des pin, node, pb_type */ des_pb_graph_node = des_pb_graph_pin->parent_node; /* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/ - generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_node, des_pb_graph_node, pin2pin_interc_type, - cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); + generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type, + cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); + src_pin_prefix = chomp_verilog_prefix(src_pin_prefix); + des_pin_prefix = chomp_verilog_prefix(des_pin_prefix); /* Call the subckt that has already been defined before */ fprintf(fp, "%s ", cur_interc->spice_model->name); fprintf(fp, "%s_%d_ (", cur_interc->spice_model->prefix, cur_interc->spice_model->cnt); cur_interc->spice_model->cnt++; /* Stats the number of spice_model used*/ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Print the pin names! Input and output @@ -1155,6 +1150,22 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, /* Create a local bus */ fprintf(fp, "wire [0:%d] in_bus_%s_size%d_%d_ ;\n", fan_in - 1, cur_interc->spice_model->name, fan_in, cur_interc->spice_model->cnt); + + /* Generation of the name for the SDC */ + + // It is actually better to generate the hierarchical name with the pin because otherwise we have issues with the path and miss some of them. + //hierarchical_name = gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(des_pb_graph_pin); + // testing without the hierarchy because this functions includes the current nodes sometimes whereas there should be nothing about certain muxes + hierarchical_name = ""; + + mux_name = (char *) my_malloc(sizeof(char)*(strlen(cur_interc->spice_model->name) + + 5 + strlen(my_itoa(fan_in)) + 1 + strlen(my_itoa(cur_interc->spice_model->cnt + 2)))); + sprintf(mux_name, "%s_size%d_%d_", + cur_interc->spice_model->name, fan_in, cur_interc->spice_model->cnt); + + des_pb_graph_pin->name_mux = my_strcat(hierarchical_name,mux_name); + free(mux_name); + ipin = 0; for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { if (cur_mode != des_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode) { @@ -1166,20 +1177,28 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, src_pb_graph_pin = des_pb_graph_pin->input_edges[iedge]->input_pins[0]; src_pb_graph_node = src_pb_graph_pin->parent_node; src_pb_type = src_pb_graph_node->pb_type; + /* Des pin, node, pb_type */ des_pb_graph_node = des_pb_graph_pin->parent_node; /* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/ - generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_node, des_pb_graph_node, pin2pin_interc_type, - cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); + generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type, + cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); + src_pin_prefix = chomp_verilog_prefix(src_pin_prefix); + /* We need to find out if the des_pb_graph_pin is in the mode we want !*/ /* Print */ fprintf(fp, "assign in_bus_%s_size%d_%d_[%d] = ", cur_interc->spice_model->name, fan_in, cur_interc->spice_model->cnt, ipin); fprintf(fp, "%s__%s_%d_ ; \n", src_pin_prefix, src_pb_graph_pin->port->name, src_pb_graph_pin->pin_number); + /* Baudouin Chauviere: SDC Generation */ + des_pb_graph_pin->input_edges[iedge]->nb_mux = cur_interc->spice_model->cnt; + des_pb_graph_pin->input_edges[iedge]->nb_pin = ipin; + /* END */ + + ipin++; /* Free */ - my_free(src_pin_prefix); my_free(des_pin_prefix); src_pin_prefix = NULL; des_pin_prefix = NULL; @@ -1187,109 +1206,80 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, assert(ipin == fan_in); /* Print SRAMs that configure this MUX */ /* cur_num_sram = sram_verilog_model->cnt; */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, &cur_bl, &cur_wl); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); /* connect to reserved BL/WLs ? */ num_mux_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(cur_interc->spice_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, fan_in); /* Get the number of configuration bits required by this MUX */ num_mux_conf_bits = count_num_conf_bits_one_spice_model(cur_interc->spice_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, + fan_in); + + /* Get the number of SRAM bits required by this MUX */ + num_mux_sram_bits = count_num_sram_bits_one_spice_model(cur_interc->spice_model, fan_in); /* Dump the configuration port bus */ - dump_verilog_mux_config_bus(fp, cur_interc->spice_model, sram_verilog_orgz_info, + dump_verilog_mux_config_bus(fp, cur_interc->spice_model, cur_sram_orgz_info, fan_in, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits); + /* Dump ports only visible during formal verification*/ + if (0 < num_mux_conf_bits) { + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + dump_verilog_formal_verification_mux_sram_ports_wiring(fp, cur_sram_orgz_info, + cur_interc->spice_model, fan_in, + cur_num_sram, + cur_num_sram + num_mux_conf_bits - 1); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } /* Call the subckt that has already been defined before */ fprintf(fp, "%s_size%d ", cur_interc->spice_model->name, fan_in); fprintf(fp, "%s_size%d_%d_ (", cur_interc->spice_model->prefix, fan_in, cur_interc->spice_model->cnt); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Inputs */ fprintf(fp, "in_bus_%s_size%d_%d_, ", cur_interc->spice_model->name, fan_in, cur_interc->spice_model->cnt); /* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/ - generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_node, des_pb_graph_node, pin2pin_interc_type, + generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type, cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix); + des_pin_prefix = chomp_verilog_prefix(des_pin_prefix); /* Outputs */ fprintf(fp, "%s__%s_%d_, ", des_pin_prefix, des_pb_graph_pin->port->name, des_pb_graph_pin->pin_number); /* Different design technology requires different configuration bus! */ - dump_verilog_mux_config_bus_ports(fp, cur_interc->spice_model, sram_verilog_orgz_info, + dump_verilog_mux_config_bus_ports(fp, cur_interc->spice_model, cur_sram_orgz_info, fan_in, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits); fprintf(fp, ");\n"); - assert(select_edge < fan_in); - /* SRAMs */ - switch (cur_interc->spice_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - decode_cmos_mux_sram_bits(cur_interc->spice_model, fan_in, select_edge, - &num_mux_sram_bits, &mux_sram_bits, &mux_level); - break; - case SPICE_MODEL_DESIGN_RRAM: - decode_verilog_rram_mux(cur_interc->spice_model, fan_in, select_edge, - &num_mux_sram_bits, &mux_sram_bits, &mux_level); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", - __FILE__, __LINE__, cur_interc->spice_model->name); - } - - /* Print the encoding in SPICE netlist for debugging */ - switch (cur_interc->spice_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - fprintf(fp, "//----- SRAM bits for MUX[%d], level=%d, select_path_id=%d. -----\n", - cur_interc->spice_model->cnt, mux_level, select_edge); - fprintf(fp, "//----- From LSB(LEFT) TO MSB (RIGHT) -----\n"); - fprintf(fp, "//-----"); - fprint_commented_sram_bits(fp, num_mux_sram_bits, mux_sram_bits); - fprintf(fp, "-----\n"); - break; - case SPICE_MODEL_DESIGN_RRAM: - fprintf(fp, "//----- BL/WL bits for 4T1R MUX[%d], level=%d, select_path_id=%d. -----\n", - cur_interc->spice_model->cnt, mux_level, select_edge); - fprintf(fp, "//----- From LSB(LEFT) TO MSB (RIGHT) -----\n"); - fprintf(fp, "//---- BL: "); - fprint_commented_sram_bits(fp, num_mux_sram_bits/2, mux_sram_bits); - fprintf(fp, "-----\n"); - fprintf(fp, "//----- From LSB(LEFT) TO MSB (RIGHT) -----\n"); - fprintf(fp, "//---- WL: "); - fprint_commented_sram_bits(fp, num_mux_sram_bits/2, mux_sram_bits + num_mux_sram_bits/2); - fprintf(fp, "-----\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", - __FILE__, __LINE__, cur_interc->spice_model->name); - } - - /* Store the configuraion bit to linked-list */ - add_mux_conf_bits_to_llist(fan_in, sram_verilog_orgz_info, - num_mux_sram_bits, mux_sram_bits, - cur_interc->spice_model); - - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); /* Dump sram modules */ switch (cur_interc->spice_model->design_tech) { case SPICE_MODEL_DESIGN_CMOS: - /* SRAM-based MUX required dumping SRAMs! */ - for (i = 0; i < num_mux_sram_bits; i++) { - dump_verilog_mux_sram_submodule(fp, sram_verilog_orgz_info, cur_interc->spice_model, fan_in, - mem_model); /* use the mem_model in sram_verilog_orgz_info */ - } + /* Call the memory module defined for this SRAM-based MUX! */ + mem_subckt_name = generate_verilog_mux_subckt_name(cur_interc->spice_model, fan_in, verilog_mem_posfix); + fprintf(fp, "%s %s_%d_ ( ", + mem_subckt_name, mem_subckt_name, cur_interc->spice_model->cnt); + dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, cur_interc->spice_model, fan_in, + mem_model, cur_num_sram, cur_num_sram + num_mux_conf_bits - 1); + fprintf(fp, ");\n"); + /* update the number of memory bits */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); break; case SPICE_MODEL_DESIGN_RRAM: /* RRAM-based MUX does not need any SRAM dumping * But we have to get the number of configuration bits required by this MUX * and update the number of memory bits */ - update_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info, cur_num_sram + num_mux_conf_bits); - update_sram_orgz_info_num_blwl(sram_verilog_orgz_info, + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, cur_bl + num_mux_conf_bits, cur_wl + num_mux_conf_bits); break; @@ -1305,6 +1295,7 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, my_free(mux_sram_bits); my_free(src_pin_prefix); my_free(des_pin_prefix); + my_free(mem_subckt_name); break; default: vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", @@ -1315,15 +1306,77 @@ void dump_verilog_pb_graph_pin_interc(FILE* fp, return; } +/* Print the SPICE interconnections of a port defined in pb_graph */ +void dump_verilog_pb_graph_port_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* formatted_pin_prefix, + t_pb_graph_node* cur_pb_graph_node, + enum e_spice_pb_port_type pb_port_type, + t_mode* cur_mode) { + int iport, ipin; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + switch (pb_port_type) { + case SPICE_PB_PORT_INPUT: + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + /* Get the selected edge of current pin*/ + dump_verilog_pb_graph_pin_interc(cur_sram_orgz_info, + fp, + formatted_pin_prefix, /* parent_pin_prefix */ + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->input_pins[iport][ipin]), + cur_mode); + } + } + break; + case SPICE_PB_PORT_OUTPUT: + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + dump_verilog_pb_graph_pin_interc(cur_sram_orgz_info, + fp, + formatted_pin_prefix, /* parent_pin_prefix */ + OUTPUT2OUTPUT_INTERC, + &(cur_pb_graph_node->output_pins[iport][ipin]), + cur_mode); + } + } + break; + case SPICE_PB_PORT_CLOCK: + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + dump_verilog_pb_graph_pin_interc(cur_sram_orgz_info, + fp, + formatted_pin_prefix, /* parent_pin_prefix */ + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + cur_mode); + } + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pb port type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + /* Print the SPICE interconnections according to pb_graph */ -void dump_verilog_pb_graph_interc(FILE* fp, +void dump_verilog_pb_graph_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* pin_prefix, t_pb_graph_node* cur_pb_graph_node, - t_pb* cur_pb, - int select_mode_index, - int is_idle) { - int iport, ipin; + int select_mode_index) { int ipb, jpb; t_mode* cur_mode = NULL; t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; @@ -1333,11 +1386,6 @@ void dump_verilog_pb_graph_interc(FILE* fp, char* formatted_pin_prefix = format_verilog_node_prefix(pin_prefix); /* Complete a "_" at the end if needed*/ - int node_index = -1; - int prev_node = -1; - int path_id = -1; - t_rr_node* pb_rr_nodes = NULL; - /* Check the file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", @@ -1361,40 +1409,10 @@ void dump_verilog_pb_graph_interc(FILE* fp, * | * input_pins, edges, output_pins */ - for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { - for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { - /* If this is a idle block, we set 0 to the selected edge*/ - if (is_idle) { - assert(NULL == cur_pb); - dump_verilog_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - OUTPUT2OUTPUT_INTERC, - &(cur_pb_graph_node->output_pins[iport][ipin]), - cur_mode, - 0); - } else { - /* Get the selected edge of current pin*/ - assert(NULL != cur_pb); - pb_rr_nodes = cur_pb->rr_graph; - node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; // - } else { - /* Find the path_id */ - path_id = verilog_find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - dump_verilog_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - OUTPUT2OUTPUT_INTERC, - &(cur_pb_graph_node->output_pins[iport][ipin]), - cur_mode, - path_id); - } - } - } + dump_verilog_pb_graph_port_interc(cur_sram_orgz_info, fp, formatted_pin_prefix, + cur_pb_graph_node, + SPICE_PB_PORT_OUTPUT, + cur_mode); /* We check input_pins of child_pb_graph_node and its the input_edges * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node @@ -1406,95 +1424,17 @@ void dump_verilog_pb_graph_interc(FILE* fp, for (ipb = 0; ipb < cur_pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { for (jpb = 0; jpb < cur_pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { child_pb_graph_node = &(cur_pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]); - /* If this is a idle block, we set 0 to the selected edge*/ - if (is_idle) { - assert(NULL == cur_pb); - /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - dump_verilog_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - 0); - } - } - /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - dump_verilog_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - 0); - } - } - continue; - } - assert(NULL != cur_pb); - child_pb = &(cur_pb->child_pbs[ipb][jpb]); - /* Check if child_pb is empty */ - if (NULL != child_pb->name) { - is_child_pb_idle = 0; - } else { - is_child_pb_idle = 1; - } - /* Get pb_rr_graph of current pb*/ - pb_rr_nodes = child_pb->rr_graph; /* For each child_pb_graph_node input pins*/ - for (iport = 0; iport < child_pb_graph_node->num_input_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_input_pins[iport]; ipin++) { - if (is_child_pb_idle) { - } else { - /* Get the index of the edge that are selected to pass signal*/ - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; // - } else { - /* Find the path_id */ - path_id = verilog_find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - } - /* Write the interconnection*/ - dump_verilog_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->input_pins[iport][ipin]), - cur_mode, - path_id); - } - } + dump_verilog_pb_graph_port_interc(cur_sram_orgz_info, fp, formatted_pin_prefix, + child_pb_graph_node, + SPICE_PB_PORT_INPUT, + cur_mode); /* TODO: for clock pins, we should do the same work */ - for (iport = 0; iport < child_pb_graph_node->num_clock_ports; iport++) { - for (ipin = 0; ipin < child_pb_graph_node->num_clock_pins[iport]; ipin++) { - if (is_child_pb_idle) { - } else { - /* Get the index of the edge that are selected to pass signal*/ - node_index = child_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster; - prev_node = pb_rr_nodes[node_index].prev_node; - /* Make sure this pb_rr_node is not OPEN and is not a primitive output*/ - if (OPEN == prev_node) { - path_id = 0; // - } else { - /* Find the path_id */ - path_id = verilog_find_path_id_between_pb_rr_nodes(pb_rr_nodes, prev_node, node_index); - assert(-1 != path_id); - } - } - /* Write the interconnection*/ - dump_verilog_pb_graph_pin_interc(fp, - formatted_pin_prefix, /* parent_pin_prefix */ - INPUT2INPUT_INTERC, - &(child_pb_graph_node->clock_pins[iport][ipin]), - cur_mode, - path_id); - } - } + dump_verilog_pb_graph_port_interc(cur_sram_orgz_info, fp, formatted_pin_prefix, + child_pb_graph_node, + SPICE_PB_PORT_CLOCK, + cur_mode); + } } @@ -1537,6 +1477,7 @@ void dump_verilog_pb_graph_primitive_node(FILE* fp, + strlen(cur_pb_type->name) + 1 + strlen(my_itoa(pb_type_index)) + 1 + 1)); /* Plus the '0' at the end of string*/ sprintf(subckt_name, "%s%s_%d_", formatted_subckt_prefix, cur_pb_type->name, pb_type_index); + subckt_name = chomp_verilog_prefix(subckt_name); /* Check if defines an included netlist*/ if (NULL == verilog_model->model_netlist) { if (LUT_CLASS == cur_pb_type->class_type) { @@ -1554,7 +1495,7 @@ void dump_verilog_pb_graph_primitive_node(FILE* fp, fprintf(fp, "module %s (", subckt_name); /* subckt_port_name = format_verilog_node_prefix(subckt_name); */ /* Inputs, outputs, inouts, clocks */ - dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type, TRUE, FALSE); + dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type, TRUE, FALSE, FALSE); /* SRAM ports */ fprintf(fp, ");\n"); /* Include the spice_model*/ @@ -1562,7 +1503,7 @@ void dump_verilog_pb_graph_primitive_node(FILE* fp, verilog_model->cnt++; /* Stats the number of verilog_model used*/ /* Make input, output, inout, clocks connected*/ /* IMPORTANT: (sequence of these ports should be changed!) */ - dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type, FALSE, FALSE); + dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type, FALSE, FALSE, TRUE); fprintf(fp, ");"); /* Print end of subckt*/ fprintf(fp, "endmodule\n"); @@ -1573,17 +1514,12 @@ void dump_verilog_pb_graph_primitive_node(FILE* fp, } /* Print the subckt of a primitive pb */ -void dump_verilog_pb_primitive_verilog_model(FILE* fp, +void dump_verilog_pb_primitive_verilog_model(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_prefix, - t_pb* prim_pb, t_pb_graph_node* prim_pb_graph_node, int pb_index, - t_spice_model* verilog_model, - int is_idle, - t_rr_node* pb_rr_graph) { - t_pb_type* prim_pb_type = NULL; - t_logical_block* mapped_logical_block = NULL; - + t_spice_model* verilog_model) { /* Check the file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", @@ -1592,697 +1528,59 @@ void dump_verilog_pb_primitive_verilog_model(FILE* fp, } /* Check cur_pb_graph_node*/ if (NULL == prim_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node.\n", + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node.\n", __FILE__, __LINE__); exit(1); } /* Initialize */ - prim_pb_type = prim_pb_graph_node->pb_type; - - switch (is_idle) { - case PRIMITIVE_WIRED_LUT: - mapped_logical_block = NULL; - break; - case PRIMITIVE_IDLE: - mapped_logical_block = NULL; - break; - case PRIMITIVE_NORMAL: - mapped_logical_block = &logical_block[prim_pb->logical_block]; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n", - __FILE__, __LINE__, is_idle); - exit(1); - } - /* Asserts*/ assert(pb_index == prim_pb_graph_node->placement_index); - assert(0 == strcmp(verilog_model->name, prim_pb_type->spice_model->name)); - switch (is_idle) { - case PRIMITIVE_WIRED_LUT: - assert(NULL == prim_pb); - break; - case PRIMITIVE_IDLE: - assert(NULL == prim_pb); - break; - case PRIMITIVE_NORMAL: - if (NULL == prim_pb) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb.\n", - __FILE__, __LINE__); - exit(1); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, - "(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n", - __FILE__, __LINE__, is_idle); - exit(1); - } + assert(0 == strcmp(verilog_model->name, prim_pb_graph_node->pb_type->spice_model->name)); /* According to different type, we print netlist*/ switch (verilog_model->type) { case SPICE_MODEL_LUT: /* If this is a idle block we should set sram_bits to zero*/ - dump_verilog_pb_primitive_lut(fp, subckt_prefix, prim_pb, mapped_logical_block, prim_pb_graph_node, - pb_index, verilog_model, is_idle, pb_rr_graph); + dump_verilog_pb_primitive_lut(cur_sram_orgz_info, fp, subckt_prefix, prim_pb_graph_node, + pb_index, verilog_model); break; case SPICE_MODEL_FF: assert(NULL != verilog_model->model_netlist); /* TODO : We should learn trigger type and initial value!!! and how to apply them!!! */ - dump_verilog_pb_primitive_ff(fp, subckt_prefix, mapped_logical_block, prim_pb_graph_node, - pb_index, verilog_model); + dump_verilog_pb_generic_primitive(cur_sram_orgz_info, fp, subckt_prefix, prim_pb_graph_node, + pb_index, verilog_model); break; case SPICE_MODEL_IOPAD: assert(NULL != verilog_model->model_netlist); - dump_verilog_pb_primitive_io(fp, subckt_prefix, mapped_logical_block, prim_pb_graph_node, - pb_index, verilog_model); + dump_verilog_pb_generic_primitive (cur_sram_orgz_info, fp, subckt_prefix, prim_pb_graph_node, + pb_index, verilog_model); break; case SPICE_MODEL_HARDLOGIC: assert(NULL != verilog_model->model_netlist); - dump_verilog_pb_primitive_hardlogic(fp, subckt_prefix, mapped_logical_block, prim_pb_graph_node, - pb_index, verilog_model); - break; - case SPICE_MODEL_VDD: - /* TODO: Add codes for VDD */ - break; - case SPICE_MODEL_GND: - /* TODO: Add codes for GND */ + dump_verilog_pb_generic_primitive(cur_sram_orgz_info, fp, subckt_prefix, prim_pb_graph_node, + pb_index, verilog_model); break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of verilog_model(%s), should be [LUT|FF|HARD_LOGIC|IO]!\n", __FILE__, __LINE__, verilog_model->name); exit(1); - break; } return; } -/* Print idle pb_types recursively - * search the idle_mode until we reach the leaf node +/* Print physical mode of pb_types and configure it to the physical pb_types recursively + * search the physical_mode until we reach the leaf node + * Now we only dump one Verilog for each pb_type, and instance them when num_pb > 1 */ -void dump_verilog_idle_pb_graph_node_rec(FILE* fp, - char* subckt_prefix, - t_pb_graph_node* cur_pb_graph_node, - int pb_type_index) { - int mode_index, ipb, jpb, child_mode_index; - t_pb_type* cur_pb_type = NULL; - char* subckt_name = NULL; - char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - char* pass_on_prefix = NULL; - char* child_pb_type_prefix = NULL; - char* subckt_port_prefix = NULL; - - int child_pb_num_reserved_conf_bits = 0; - int child_pb_num_conf_bits = 0; - int child_pb_num_iopads = 0; - - int num_reserved_conf_bits = 0; - int num_conf_bits = 0; - int stamped_sram_cnt = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - int stamped_sram_lsb = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - - int stamped_iopad_cnt = iopad_verilog_model->cnt; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - /* Check cur_pb_graph_node*/ - if (NULL == cur_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node.\n", - __FILE__, __LINE__); - exit(1); - } - cur_pb_type = cur_pb_graph_node->pb_type; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Pass the SPICE mode prefix on, - * mode[]_ - */ - pass_on_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(pb_type_index)) + 7 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1 + 1)); - sprintf(pass_on_prefix, "%s%s_%d__mode_%s__", - formatted_subckt_prefix, cur_pb_type->name, pb_type_index, cur_pb_type->modes[mode_index].name); - /* Recursive*/ - dump_verilog_idle_pb_graph_node_rec(fp, pass_on_prefix, - &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), jpb); - /* Free */ - my_free(pass_on_prefix); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - switch (cur_pb_type->class_type) { - case LUT_CLASS: - /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, pb_type_index, - cur_pb_type->spice_model, 1, NULL); - /* update the number of SRAM, I/O pads */ - stamped_sram_cnt += cur_pb_type->default_mode_num_conf_bits; - break; - case LATCH_CLASS: - assert(0 == cur_pb_type->num_modes); - /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, pb_type_index, cur_pb_type->spice_model, 1, NULL); - /* update the number of SRAM, I/O pads */ - /* update stamped sram counter */ - stamped_sram_cnt += cur_pb_type->default_mode_num_conf_bits; - break; - case UNKNOWN_CLASS: - case MEMORY_CLASS: - /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, pb_type_index, cur_pb_type->spice_model, 1, NULL); - /* update the number of SRAM, I/O pads */ - /* update stamped sram counter */ - stamped_sram_cnt += cur_pb_type->default_mode_num_conf_bits; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", - __FILE__, __LINE__, cur_pb_type->name); - exit(1); - } - /* Check */ - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); - assert(stamped_iopad_cnt == iopad_verilog_model->cnt); - /* Finish job for primitive node, return */ - return; - } - - /* Find the mode that define_idle_mode*/ - mode_index = find_pb_type_idle_mode_index((*cur_pb_type)); - /* Create a new subckt */ - /* mode[] - */ - subckt_name = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(pb_type_index)) + 7 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - /* Definition*/ - sprintf(subckt_name, "%s%s_%d__mode_%s_", - formatted_subckt_prefix, cur_pb_type->name, pb_type_index, cur_pb_type->modes[mode_index].name); - /* Comment lines */ - fprintf(fp, "//----- Idle programmable logic block Verilog module %s -----\n", subckt_name); - fprintf(fp, "module %s (", subckt_name); - fprintf(fp, "\n"); - /* Inputs, outputs, inouts, clocks */ - subckt_port_prefix = (char*)my_malloc(sizeof(char)* - (5 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(subckt_port_prefix, "mode_%s_", cur_pb_type->modes[mode_index].name); - /* - dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type); - */ - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { - fprintf(fp, ",\n"); - } - /* Simplify the port prefix, make SPICE netlist readable */ - dump_verilog_pb_type_ports(fp, subckt_port_prefix, 0, cur_pb_type, TRUE, FALSE); - /* Print Input Pad and Output Pad */ - dump_verilog_grid_common_port(fp, iopad_verilog_model, - gio_inout_prefix, - stamped_iopad_cnt, iopad_verilog_model->cnt - 1, - VERILOG_PORT_INPUT); - /* Print Configuration ports */ - /* sram_verilog_model->cnt should be updated because all the child pbs have been dumped - * stamped_sram_cnt remains the old sram_verilog_model->cnt before all the child pbs are dumped - * Note by far, sram_verilog_model->cnt could be smaller than num_conf_bits - * because the interconnection of current pb_type/pb has not yet dumped, which may contain - * a few configuration bits. - */ - num_reserved_conf_bits = cur_pb_type->default_mode_num_reserved_conf_bits; - if (0 < num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, num_reserved_conf_bits - 1, - VERILOG_PORT_INPUT); - num_conf_bits = cur_pb_type->default_mode_num_conf_bits; - if (0 < num_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - stamped_sram_cnt, stamped_sram_cnt + num_conf_bits - 1, - VERILOG_PORT_INPUT); - /* Finish with local vdd and gnd */ - fprintf(fp, ");\n"); - - /* Definition ends*/ - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* we should make sure this placement index == child_pb_type[jpb]*/ - assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); - /* If the pb_type_children is a leaf node, we don't use the mode to name it, - * else we can use the mode to name it - */ - if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model) { /* Not a leaf node*/ - child_mode_index = find_pb_type_idle_mode_index(cur_pb_type->modes[mode_index].pb_type_children[ipb]); - fprintf(fp, "%s_%s_%d__mode_%s_ ", - subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb, - cur_pb_type->modes[mode_index].pb_type_children[ipb].modes[child_mode_index].name); - } else { /* Have a verilog model definition, this is a leaf node*/ - fprintf(fp, "%s_%s_%d_ ", - subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); - } - /* Collect information of child pb_type */ - child_pb_num_reserved_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_reserved_conf_bits; - child_pb_num_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_conf_bits; - child_pb_num_iopads = cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_iopads; - - /* mode[]_[] - */ - fprintf(fp, "%s_%d_ (", cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); - fprintf(fp, "\n"); - /* dump global ports */ - /* If the child node is a primitive, we only dump global ports belonging to this primitive */ - if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model) { - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - } else { - if (0 < rec_dump_verilog_spice_model_global_ports(fp, - cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model, - FALSE, TRUE)) { - fprintf(fp, ",\n"); - } - } - /* Pass the SPICE mode prefix on, - * mode[]_[] - * [] - */ - /* Simplify the prefix! */ - child_pb_type_prefix = (char*)my_malloc(sizeof(char)* - (strlen(cur_pb_type->modes[mode_index].pb_type_children[ipb].name) + 1 - + strlen(my_itoa(jpb)) + 1 + 1)); - sprintf(child_pb_type_prefix, "%s_%d_", - cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); - /* Print inputs, outputs, inouts, clocks - * NO SRAMs !!! They have already been fixed in the bottom level - */ - dump_verilog_pb_type_ports(fp, child_pb_type_prefix, 0, &(cur_pb_type->modes[mode_index].pb_type_children[ipb]),FALSE, FALSE); - /* Print I/O pads */ - dump_verilog_grid_common_port(fp, iopad_verilog_model, - gio_inout_prefix, - stamped_iopad_cnt, - stamped_iopad_cnt + child_pb_num_iopads - 1, - VERILOG_PORT_CONKT); - /* update stamped outpad counter */ - stamped_iopad_cnt += child_pb_num_iopads; - /* Print configuration ports */ - if (0 < child_pb_num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, child_pb_num_reserved_conf_bits - 1, - VERILOG_PORT_CONKT); - if (0 < child_pb_num_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - stamped_sram_cnt, - stamped_sram_cnt + child_pb_num_conf_bits - 1, - VERILOG_PORT_CONKT); - /* update stamped sram counter */ - stamped_sram_cnt += child_pb_num_conf_bits; - fprintf(fp, ");\n"); /* Local vdd and gnd*/ - /* Finish */ - my_free(child_pb_type_prefix); - } - } - /* Print interconnections, set is_idle as TRUE*/ - dump_verilog_pb_graph_interc(fp, subckt_name, cur_pb_graph_node, NULL, mode_index, 1); - /* Check each pins of pb_graph_node */ - /* Check and update stamped_sram_cnt */ - assert(!(stamped_sram_cnt > (stamped_sram_lsb + num_conf_bits))); - stamped_sram_cnt = stamped_sram_lsb + num_conf_bits; - /* End the subckt */ - fprintf(fp, "endmodule\n"); - /* Comment lines */ - fprintf(fp, "//----- END Idle programmable logic block Verilog module %s -----\n\n", subckt_name); - /* Free subckt name*/ - my_free(subckt_name); - - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); - assert(stamped_iopad_cnt == iopad_verilog_model->cnt); - - return; -} - -/* Print SPICE netlist for each pb and corresponding pb_graph_node*/ -void dump_verilog_pb_graph_node_rec(FILE* fp, - char* subckt_prefix, - t_pb* cur_pb, - t_pb_graph_node* cur_pb_graph_node, - int pb_type_index, - t_rr_node* pb_rr_graph) { - int mode_index, ipb, jpb, child_mode_index; - t_pb_type* cur_pb_type = NULL; - char* subckt_name = NULL; - char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ - char* pass_on_prefix = NULL; - char* child_pb_type_prefix = NULL; - - char* subckt_port_prefix = NULL; - - int num_reserved_conf_bits = 0; - int num_conf_bits = 0; - int child_pb_num_reserved_conf_bits = 0; - int child_pb_num_conf_bits = 0; - int child_pb_num_iopads = 0; - - int stamped_sram_cnt = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - int stamped_sram_lsb = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - - int stamped_iopad_cnt = iopad_verilog_model->cnt; - t_pb* child_pb = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - /* Check cur_pb_graph_node*/ - if (NULL == cur_pb_graph_node) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node.\n", - __FILE__, __LINE__); - exit(1); - } - cur_pb_type = cur_pb_graph_node->pb_type; - - /* For wired LUTs only */ - if (NULL == cur_pb) { - assert(NULL != cur_pb_type->spice_model); - assert (LUT_CLASS == cur_pb_type->class_type); - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, PRIMITIVE_WIRED_LUT, pb_rr_graph); - /* update the number of SRAM, I/O pads */ - /* update stamped iopad counter */ - /* stamped_iopad_cnt += cur_pb->num_iopads; */ - /* update stamped sram counter */ - /* stamped_sram_cnt += cur_pb->num_conf_bits; */ - /* Check */ - /* - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); - assert(stamped_iopad_cnt == iopad_verilog_model->cnt); - */ - return; - } - - mode_index = cur_pb->mode; - - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { - /* recursive for the child_pbs*/ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* Pass the SPICE mode prefix on, - * []_mode[]_ - */ - pass_on_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(pb_type_index)) + 7 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1 + 1)); - sprintf(pass_on_prefix, "%s%s_%d__mode_%s__", - formatted_subckt_prefix, cur_pb_type->name, pb_type_index, cur_pb_type->modes[mode_index].name); - /* Recursive*/ - /* Refer to pack/output_clustering.c [LINE 392] */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - dump_verilog_pb_graph_node_rec(fp, pass_on_prefix, &(cur_pb->child_pbs[ipb][jpb]), - cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb , cur_pb->rr_graph); - /* For wired LUT */ - } else if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - &(cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb]), - cur_pb->rr_graph)) { - /* Reach here means that this LUT is in wired mode (a buffer) - * Print the Verilog of wired LUTs - */ - dump_verilog_pb_graph_node_rec(fp, pass_on_prefix, NULL, - &(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), - jpb, cur_pb->rr_graph); - } else { - /* Check if this pb has no children, no children mean idle*/ - dump_verilog_idle_pb_graph_node_rec(fp, pass_on_prefix, - cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb); - } - /* Free */ - my_free(pass_on_prefix); - } - } - } - - /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { - switch (cur_pb_type->class_type) { - case LUT_CLASS: - child_pb = get_lut_child_pb(cur_pb, mode_index); - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - child_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, child_pb->rr_graph); - /* update the number of SRAM, I/O pads */ - /* update stamped iopad counter */ - stamped_iopad_cnt += cur_pb->num_iopads; - /* update stamped sram counter */ - stamped_sram_cnt += cur_pb->num_conf_bits; - break; - case LATCH_CLASS: - assert(0 == cur_pb_type->num_modes); - /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - cur_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, cur_pb->rr_graph); - /* update the number of SRAM, I/O pads */ - /* update stamped iopad counter */ - stamped_iopad_cnt += cur_pb->num_iopads; - /* update stamped sram counter */ - stamped_sram_cnt += cur_pb->num_conf_bits; - break; - case MEMORY_CLASS: - child_pb = get_hardlogic_child_pb(cur_pb, mode_index); - /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - child_pb, cur_pb_graph_node, - pb_type_index, cur_pb_type->spice_model, 0, cur_pb->rr_graph); - /* update the number of SRAM, I/O pads */ - /* update stamped iopad counter */ - stamped_iopad_cnt += cur_pb->num_iopads; - /* update stamped sram counter */ - stamped_sram_cnt += cur_pb->num_conf_bits; - break; - case UNKNOWN_CLASS: - /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - cur_pb, cur_pb_graph_node, pb_type_index, cur_pb_type->spice_model, 0, cur_pb->rr_graph); - /* update the number of SRAM, I/O pads */ - /* update stamped iopad counter */ - stamped_iopad_cnt += cur_pb->num_iopads; - /* update stamped sram counter */ - stamped_sram_cnt += cur_pb->num_conf_bits; - break; - default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", - __FILE__, __LINE__, cur_pb_type->name); - exit(1); - } - /* Check */ - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); - assert(stamped_iopad_cnt == iopad_verilog_model->cnt); - /* Finish job for primitive node, return */ - return; - } - - /* Create a new subckt */ - /* mode[] - */ - subckt_name = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(pb_type_index)) + 7 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - /* Definition*/ - sprintf(subckt_name, "%s%s_%d__mode_%s_", - formatted_subckt_prefix, cur_pb_type->name, pb_type_index, cur_pb_type->modes[mode_index].name); - /* Comment lines */ - fprintf(fp, "//----- Programmable logic block Verilog module %s -----\n", subckt_name); - fprintf(fp, "module %s (", subckt_name); - /* Inputs, outputs, inouts, clocks */ - subckt_port_prefix = (char*)my_malloc(sizeof(char)* - (5 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(subckt_port_prefix, "mode_%s_", cur_pb_type->modes[mode_index].name); - /* - dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type); - */ - /* Print global set and reset */ - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { - fprintf(fp, ",\n"); - } - /* Simplify the prefix! Make the SPICE netlist readable*/ - dump_verilog_pb_type_ports(fp, subckt_port_prefix, 0, cur_pb_type, TRUE, FALSE); - /* Print Input Pad and Output Pad */ - dump_verilog_grid_common_port(fp, iopad_verilog_model, - gio_inout_prefix, - stamped_iopad_cnt, iopad_verilog_model->cnt - 1, - VERILOG_PORT_INPUT); - /* Print Configuration ports */ - /* sram_verilog_model->cnt should be updated because all the child pbs have been dumped - * stamped_sram_cnt remains the old sram_verilog_model->cnt before all the child pbs are dumped - * Note by far, sram_verilog_model->cnt could be smaller than num_conf_bits - * because the interconnection of current pb_type/pb has not yet dumped, which may contain - * a few configuration bits. - */ - num_reserved_conf_bits = cur_pb->num_reserved_conf_bits; - if (0 < num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, num_reserved_conf_bits - 1, - VERILOG_PORT_INPUT); - num_conf_bits = cur_pb->num_conf_bits; - if (0 < num_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - stamped_sram_cnt, stamped_sram_cnt + num_conf_bits - 1, - VERILOG_PORT_INPUT); - /* Finish with local vdd and gnd */ - fprintf(fp, ");\n"); - /* Definition ends*/ - - /* Quote all child pb_types */ - for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { - /* Each child may exist multiple times in the hierarchy*/ - for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { - /* we should make sure this placement index == child_pb_type[jpb]*/ - assert(jpb == cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb].placement_index); - /* mode[]_[] - */ - /* Find the pb_type_children mode */ - if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) { - child_mode_index = cur_pb->child_pbs[ipb][jpb].mode; - child_pb_num_reserved_conf_bits = cur_pb->child_pbs[ipb][jpb].num_reserved_conf_bits; - child_pb_num_conf_bits = cur_pb->child_pbs[ipb][jpb].num_conf_bits; - child_pb_num_iopads = cur_pb->child_pbs[ipb][jpb].num_iopads; - } else /*if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model)*/ { /* Find the idle_mode_index, if this is not a leaf node */ - child_mode_index = find_pb_type_idle_mode_index(cur_pb_type->modes[mode_index].pb_type_children[ipb]); - child_pb_num_reserved_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_reserved_conf_bits; - child_pb_num_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_conf_bits; - child_pb_num_iopads = cur_pb_type->modes[mode_index].pb_type_children[ipb].default_mode_num_iopads; - } - /* If the pb_type_children is a leaf node, we don't use the mode to name it, - * else we can use the mode to name it - */ - if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model) { /* Not a leaf node*/ - fprintf(fp, "%s_%s_%d__mode_%s_ ", - subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb, - cur_pb_type->modes[mode_index].pb_type_children[ipb].modes[child_mode_index].name); - } else { /* Have a verilog model definition, this is a leaf node*/ - fprintf(fp, "%s_%s_%d_ ", - subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); - } - fprintf(fp, "%s_%d_ (", cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); - fprintf(fp, "\n"); - /* dump global ports */ - /* If the child node is a primitive, we only dump global ports belonging to this primitive */ - if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model) { - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - } else { - if (0 < rec_dump_verilog_spice_model_global_ports(fp, - cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model, - FALSE, TRUE)) { - fprintf(fp, ",\n"); - } - } - /* Pass the SPICE mode prefix on, - * mode[]_[] - */ - /* Simplify the prefix! Make the SPICE netlist readable*/ - child_pb_type_prefix = (char*)my_malloc(sizeof(char)* - (strlen(cur_pb_type->modes[mode_index].pb_type_children[ipb].name) + 1 - + strlen(my_itoa(jpb)) + 1 + 1)); - sprintf(child_pb_type_prefix, "%s_%d_", - cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); - /* Print inputs, outputs, inouts, clocks - * NO SRAMs !!! They have already been fixed in the bottom level - */ - dump_verilog_pb_type_ports(fp, child_pb_type_prefix, 0, &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), FALSE, FALSE); - /* Print I/O pads */ - dump_verilog_grid_common_port(fp, iopad_verilog_model, - gio_inout_prefix, - stamped_iopad_cnt, - stamped_iopad_cnt + child_pb_num_iopads - 1, - VERILOG_PORT_CONKT); - /* update stamped outpad counter */ - stamped_iopad_cnt += child_pb_num_iopads; - /* Print configuration ports */ - if (0 < child_pb_num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, child_pb_num_reserved_conf_bits - 1, - VERILOG_PORT_CONKT); - if (0 < child_pb_num_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - stamped_sram_cnt, - stamped_sram_cnt + child_pb_num_conf_bits - 1, - VERILOG_PORT_CONKT); - /* update stamped sram counter */ - stamped_sram_cnt += child_pb_num_conf_bits; - - fprintf(fp, "); \n"); /* Local vdd and gnd*/ - my_free(child_pb_type_prefix); - } - } - /* Print interconnections, set is_idle as TRUE*/ - dump_verilog_pb_graph_interc(fp, subckt_name, cur_pb_graph_node, cur_pb, mode_index, 0); - /* Check each pins of pb_graph_node */ - /* Check and update stamped_sram_cnt */ - assert(!(stamped_sram_cnt > (stamped_sram_lsb + num_conf_bits))); - stamped_sram_cnt = stamped_sram_lsb + num_conf_bits; - /* End the subckt */ - fprintf(fp, "endmodule\n"); - /* Comment lines */ - fprintf(fp, "//----- END Programmable logic block Verilog module %s -----\n\n", subckt_name); - - /* Free subckt name*/ - my_free(subckt_name); - - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); - assert(stamped_iopad_cnt == iopad_verilog_model->cnt); - - return; -} - -/* Print physical mode of pb_types and configure it to the idle pb_types recursively - * search the idle_mode until we reach the leaf node - */ -void dump_verilog_phy_pb_graph_node_rec(FILE* fp, +void dump_verilog_phy_pb_graph_node_rec(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_prefix, - t_pb* cur_pb, t_pb_graph_node* cur_pb_graph_node, int pb_type_index) { - int mode_index, ipb, jpb, child_mode_index, is_idle; + int mode_index, ipb, jpb, child_mode_index; t_pb_type* cur_pb_type = NULL; - t_pb* child_pb = NULL; char* subckt_name = NULL; char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ char* pass_on_prefix = NULL; @@ -2292,15 +1590,17 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, int child_pb_num_reserved_conf_bits = 0; int child_pb_num_conf_bits = 0; int child_pb_num_iopads = 0; - + + t_spice_model* mem_model = NULL; int num_reserved_conf_bits = 0; int num_conf_bits = 0; - int stamped_sram_cnt = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - int stamped_sram_lsb = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); + int stamped_sram_cnt = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + int stamped_sram_lsb = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); int stamped_iopad_cnt = iopad_verilog_model->cnt; - t_rr_node* pb_rr_graph = NULL; + /* A flag to mark if verilog module has been dumped */ + boolean verilog_module_dumped = FALSE; /* Check the file handler*/ if (NULL == fp) { @@ -2317,71 +1617,63 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, cur_pb_type = cur_pb_graph_node->pb_type; - is_idle = 1; - if (NULL != cur_pb) { - is_idle = 0; - pb_rr_graph = cur_pb->rr_graph; - } else { - pb_rr_graph = NULL; - } - /* Recursively finish all the child pb_types*/ - if (NULL == cur_pb_type->spice_model) { + if (FALSE == is_primitive_pb_type(cur_pb_type)) { /* Find the mode that define_idle_mode*/ mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + /* Initialize that the current verilog module has not been dumped */ + verilog_module_dumped = FALSE; for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + if (TRUE == verilog_module_dumped) { + /* Necessary step for the SDC generation, since the name is copied inside + * pf the verilog dumping and we skip it here */ + rec_copy_name_mux_in_node(&(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][0]), + &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb])); + continue; + } /* Pass the SPICE mode prefix on, * mode[]_ */ pass_on_prefix = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(pb_type_index)) + 7 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1 + 1)); - sprintf(pass_on_prefix, "%s%s_%d__mode_%s__", - formatted_subckt_prefix, cur_pb_type->name, pb_type_index, cur_pb_type->modes[mode_index].name); + (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + + 6 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1 + 1)); + sprintf(pass_on_prefix, "%s%s_mode_%s__", + formatted_subckt_prefix, cur_pb_type->name, cur_pb_type->modes[mode_index].name); /* Recursive*/ /* Refer to pack/output_clustering.c [LINE 392] */ /* Find the child pb that is mapped, and the mapping info is not stored in the physical mode ! */ - child_pb = get_child_pb_for_phy_pb_graph_node(cur_pb, ipb, jpb); - dump_verilog_phy_pb_graph_node_rec(fp, pass_on_prefix, child_pb, - &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), jpb); + dump_verilog_phy_pb_graph_node_rec(cur_sram_orgz_info, fp, pass_on_prefix, + &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), jpb); /* Free */ my_free(pass_on_prefix); + /* Make the current module has been dumped */ + verilog_module_dumped = TRUE; } } } /* Check if this has defined a spice_model*/ - if (NULL != cur_pb_type->spice_model) { + if (TRUE == is_primitive_pb_type(cur_pb_type)) { switch (cur_pb_type->class_type) { case LUT_CLASS: - /* Consider the num_pb, create all the subckts*/ - if (1 == is_idle) { - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - NULL, cur_pb_graph_node, pb_type_index, - cur_pb_type->spice_model, is_idle, NULL); /* last param means idle */ - } else { - child_pb = get_lut_child_pb(cur_pb, mode_index); - /* Special care for LUT !!! - * Mapped logical block information is stored in child_pbs - */ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - child_pb, cur_pb_graph_node, pb_type_index, - cur_pb_type->spice_model, is_idle, child_pb->rr_graph); /* last param means idle */ - } + dump_verilog_pb_primitive_verilog_model(cur_sram_orgz_info, fp, formatted_subckt_prefix, + cur_pb_graph_node, pb_type_index, + cur_pb_type->spice_model); /* last param means idle */ + break; case LATCH_CLASS: assert(0 == cur_pb_type->num_modes); /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - cur_pb, cur_pb_graph_node, pb_type_index, - cur_pb_type->spice_model, is_idle, pb_rr_graph); /* last param means idle */ + dump_verilog_pb_primitive_verilog_model(cur_sram_orgz_info, fp, formatted_subckt_prefix, + cur_pb_graph_node, pb_type_index, + cur_pb_type->spice_model); /* last param means idle */ break; case UNKNOWN_CLASS: case MEMORY_CLASS: /* Consider the num_pb, create all the subckts*/ - dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix, - cur_pb, cur_pb_graph_node, pb_type_index, - cur_pb_type->spice_model, is_idle, pb_rr_graph); /* last param means idle */ + dump_verilog_pb_primitive_verilog_model(cur_sram_orgz_info, fp, formatted_subckt_prefix, + cur_pb_graph_node , pb_type_index, + cur_pb_type->spice_model); /* last param means idle */ break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Unknown class type of pb_type(%s)!\n", @@ -2394,7 +1686,7 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, /* update stamped sram counter */ stamped_sram_cnt += cur_pb_type->physical_mode_num_conf_bits; /* Check */ - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); + assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)); assert(stamped_iopad_cnt == iopad_verilog_model->cnt); /* Finish for primitive node, return */ return; @@ -2406,18 +1698,19 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, /* mode[] */ subckt_name = (char*)my_malloc(sizeof(char)* - (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + 1 - + strlen(my_itoa(pb_type_index)) + 7 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); + (strlen(formatted_subckt_prefix) + strlen(cur_pb_type->name) + + 6 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); /* Definition*/ - sprintf(subckt_name, "%s%s_%d__mode_%s_", - formatted_subckt_prefix, cur_pb_type->name, pb_type_index, cur_pb_type->modes[mode_index].name); + sprintf(subckt_name, "%s%s_mode_%s_", + formatted_subckt_prefix, cur_pb_type->name, cur_pb_type->modes[mode_index].name); /* Comment lines */ fprintf(fp, "//----- Physical programmable logic block Verilog module %s -----\n", subckt_name); fprintf(fp, "module %s (", subckt_name); /* Inputs, outputs, inouts, clocks */ subckt_port_prefix = (char*)my_malloc(sizeof(char)* - (5 + strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); - sprintf(subckt_port_prefix, "mode_%s_", cur_pb_type->modes[mode_index].name); + (strlen(cur_pb_type->modes[mode_index].name) + 1 + 1)); + /*sprintf(subckt_port_prefix, "%s_", cur_pb_type->modes[mode_index].name);*/ + sprintf(subckt_port_prefix, "%s_", cur_pb_type->name); /* dump_verilog_pb_type_ports(fp, subckt_name, 0, cur_pb_type); */ @@ -2427,12 +1720,12 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, fprintf(fp, ",\n"); } /* Simplify the port prefix, make SPICE netlist readable */ - dump_verilog_pb_type_ports(fp, subckt_port_prefix, 0, cur_pb_type, TRUE, FALSE); + dump_verilog_pb_type_ports(fp, subckt_port_prefix, 0, cur_pb_type, TRUE, FALSE, FALSE); /* Print Input Pad and Output Pad */ dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, stamped_iopad_cnt, iopad_verilog_model->cnt - 1, - VERILOG_PORT_INPUT); + VERILOG_PORT_INOUT); /* Print Configuration ports */ /* sram_verilog_model->cnt should be updated because all the child pbs have been dumped * stamped_sram_cnt remains the old sram_verilog_model->cnt before all the child pbs are dumped @@ -2444,20 +1737,38 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, if (0 < num_reserved_conf_bits) { fprintf(fp, ",\n"); } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, 0, num_reserved_conf_bits - 1, VERILOG_PORT_INPUT); num_conf_bits = cur_pb_type->physical_mode_num_conf_bits; if (0 < num_conf_bits) { fprintf(fp, ",\n"); } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_sram_ports(fp, cur_sram_orgz_info, stamped_sram_cnt, stamped_sram_cnt + num_conf_bits - 1, VERILOG_PORT_INPUT); + /* Dump ports only visible during formal verification*/ + if (0 < num_conf_bits) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + stamped_sram_cnt, + stamped_sram_cnt + num_conf_bits - 1, + VERILOG_PORT_INPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + /* Finish with local vdd and gnd */ fprintf(fp, ");\n"); - /* Definition ends*/ + + /* Local wires for memory configurations */ + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, + stamped_sram_cnt, + stamped_sram_cnt + num_conf_bits - 1); + /* Quote all child pb_types */ for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { /* Each child may exist multiple times in the hierarchy*/ @@ -2468,13 +1779,13 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, * else we can use the mode to name it */ if (NULL == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model) { /* Not a leaf node*/ - child_mode_index = find_pb_type_idle_mode_index(cur_pb_type->modes[mode_index].pb_type_children[ipb]); - fprintf(fp, "%s_%s_%d__mode_%s_ ", - subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb, + child_mode_index = find_pb_type_physical_mode_index(cur_pb_type->modes[mode_index].pb_type_children[ipb]); + fprintf(fp, "%s_%s_mode_%s_ ", + subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, cur_pb_type->modes[mode_index].pb_type_children[ipb].modes[child_mode_index].name); } else { /* Have a verilog model definition, this is a leaf node*/ - fprintf(fp, "%s_%s_%d_ ", - subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); + fprintf(fp, "%s_%s ", + subckt_name, cur_pb_type->modes[mode_index].pb_type_children[ipb].name); } /* Collect information of child pb_type */ child_pb_num_reserved_conf_bits = cur_pb_type->modes[mode_index].pb_type_children[ipb].physical_mode_num_reserved_conf_bits; @@ -2483,7 +1794,8 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, /* mode[]_[] */ - fprintf(fp, "%s_%d_ (", cur_pb_type->modes[mode_index].pb_type_children[ipb].name, jpb); + fprintf(fp, "%s (", + gen_verilog_one_pb_graph_node_instance_name(&(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]))); fprintf(fp, "\n"); /* dump global ports */ /* If the child node is a primitive, we only dump global ports belonging to this primitive */ @@ -2494,7 +1806,7 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, } else { if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model, - FALSE, TRUE)) { + FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } } @@ -2511,7 +1823,7 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, /* Print inputs, outputs, inouts, clocks * NO SRAMs !!! They have already been fixed in the bottom level */ - dump_verilog_pb_type_ports(fp, child_pb_type_prefix, 0, &(cur_pb_type->modes[mode_index].pb_type_children[ipb]),FALSE, FALSE); + dump_verilog_pb_type_ports(fp, child_pb_type_prefix, 0, &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), FALSE, FALSE, FALSE); /* Print I/O pads */ dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, @@ -2523,121 +1835,114 @@ void dump_verilog_phy_pb_graph_node_rec(FILE* fp, /* Print configuration ports */ if (0 < child_pb_num_reserved_conf_bits) { fprintf(fp, ",\n"); + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, child_pb_num_reserved_conf_bits - 1, + VERILOG_PORT_CONKT); } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, child_pb_num_reserved_conf_bits - 1, - VERILOG_PORT_CONKT); if (0 < child_pb_num_conf_bits) { fprintf(fp, ",\n"); + dump_verilog_sram_local_ports(fp, cur_sram_orgz_info, + stamped_sram_cnt, + stamped_sram_cnt + child_pb_num_conf_bits - 1, + VERILOG_PORT_CONKT); } - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - stamped_sram_cnt, - stamped_sram_cnt + child_pb_num_conf_bits - 1, - VERILOG_PORT_CONKT); + /* Dump ports only visible during formal verification*/ + if (0 < child_pb_num_conf_bits) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + stamped_sram_cnt, + stamped_sram_cnt + child_pb_num_conf_bits - 1, + VERILOG_PORT_CONKT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + /* update stamped sram counter */ stamped_sram_cnt += child_pb_num_conf_bits; fprintf(fp, ");\n"); /* Local vdd and gnd*/ + /* Update mem bits */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, stamped_sram_cnt); my_free(child_pb_type_prefix); } } /* Print interconnections, set is_idle as TRUE*/ - dump_verilog_pb_graph_interc(fp, subckt_name, cur_pb_graph_node, cur_pb, mode_index, is_idle); + dump_verilog_pb_graph_interc(cur_sram_orgz_info, fp, subckt_name, cur_pb_graph_node, mode_index); /* Check each pins of pb_graph_node */ /* Check and update stamped_sram_cnt */ + /* Now we only dump one Verilog for each pb_type, and instance them when num_pb > 1 + * the asserts are no longer valid assert(!(stamped_sram_cnt > (stamped_sram_lsb + num_conf_bits))); stamped_sram_cnt = stamped_sram_lsb + num_conf_bits; + */ /* End the subckt */ fprintf(fp, "endmodule\n"); /* Comment lines */ - fprintf(fp, "//----- END Idle programmable logic block Verilog module %s -----\n\n", subckt_name); + fprintf(fp, "//----- END Physical programmable logic block Verilog module %s -----\n\n", subckt_name); /* Free subckt name*/ my_free(subckt_name); - assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); + /* + assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)); assert(stamped_iopad_cnt == iopad_verilog_model->cnt); + */ return; } -/* Print the SPICE netlist of a block that has been mapped */ -void dump_verilog_block(FILE* fp, - char* subckt_name, - int x, - int y, - int z, - t_type_ptr type_descriptor, - t_block* mapped_block) { - t_pb* top_pb = NULL; - t_pb_graph_node* top_pb_graph_node = NULL; +void rec_copy_name_mux_in_node(t_pb_graph_node* master_node, + t_pb_graph_node* target_node) { - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); + int ipb, jpb, mode_index; + int i_pin, i_port; + t_pb_type* cur_pb_type = NULL; + + /* Desend to the leaf nodes */ + cur_pb_type = master_node->pb_type; + + /* Recursively finish all the child pb_types*/ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + /* Find the mode that define_idle_mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + rec_copy_name_mux_in_node(&(master_node->child_pb_graph_nodes[mode_index][ipb][0]), + &(target_node->child_pb_graph_nodes[mode_index][ipb][jpb])); + } + } + } + + + + /* Input pins */ + for (i_port = 0; i_port< master_node->num_input_ports; i_port++) { + for (i_pin = 0; i_pin < master_node->num_input_pins[i_port]; i_pin++) { + target_node->input_pins[i_port][i_pin].name_mux = master_node->input_pins[i_port][i_pin].name_mux; + } + } + /* Output pins */ + for (i_port = 0; i_port< master_node->num_output_ports; i_port++) { + for (i_pin = 0; i_pin < master_node->num_output_pins[i_port]; i_pin++) { + target_node->output_pins[i_port][i_pin].name_mux = master_node->output_pins[i_port][i_pin].name_mux; + + } + } + /* Clock pins */ + for (i_port = 0; i_port< master_node->num_clock_ports; i_port++) { + for (i_pin = 0; i_pin < master_node->num_clock_pins[i_port]; i_pin++) { + target_node->clock_pins[i_port][i_pin].name_mux = master_node->clock_pins[i_port][i_pin].name_mux; + } } - /* check */ - assert(x == mapped_block->x); - assert(y == mapped_block->y); - assert(type_descriptor == mapped_block->type); - assert(NULL != type_descriptor); - - /* Print SPICE netlist according to the hierachy of type descriptor recursively*/ - /* Go for the pb_types*/ - top_pb_graph_node = type_descriptor->pb_graph_head; - assert(NULL != top_pb_graph_node); - top_pb = mapped_block->pb; - assert(NULL != top_pb); - - /* Recursively find all mode and print netlist*/ - /* IMPORTANT: type_descriptor just say we have a block that in global view, how it connects to global routing arch. - * Inside the type_descripor, there is a top_pb_graph_node(pb_graph_head), describe the top pb_type defined. - * The index of such top pb_type is always 0. - */ - dump_verilog_pb_graph_node_rec(fp, subckt_name, top_pb, top_pb_graph_node, z, top_pb->rr_graph); - return; } - - -/* Print an idle logic block - * Find the idle_mode in arch files, - * And print the verilog netlist into file - */ -void dump_verilog_idle_block(FILE* fp, - char* subckt_name, - int x, - int y, - int z, - t_type_ptr type_descriptor) { - t_pb_graph_node* top_pb_graph_node = NULL; - - /* Check the file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Ensure we have a valid type_descriptor*/ - assert(NULL != type_descriptor); - - /* Go for the pb_types*/ - top_pb_graph_node = type_descriptor->pb_graph_head; - assert(NULL != top_pb_graph_node); - - /* Recursively find all idle mode and print netlist*/ - dump_verilog_idle_pb_graph_node_rec(fp, subckt_name, top_pb_graph_node, z); - - return; -} - /* Print an physical logic block * Find the physical_mode in arch files, * And print the verilog netlist into file */ -void dump_verilog_physical_block(FILE* fp, +void dump_verilog_physical_block(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_name, int x, int y, @@ -2669,7 +1974,7 @@ void dump_verilog_physical_block(FILE* fp, } /* Recursively find all idle mode and print netlist*/ - dump_verilog_phy_pb_graph_node_rec(fp, subckt_name, top_pb, top_pb_graph_node, z); + dump_verilog_phy_pb_graph_node_rec(cur_sram_orgz_info, fp, subckt_name, top_pb_graph_node, z); return; } @@ -2680,7 +1985,7 @@ void dump_verilog_physical_block(FILE* fp, void dump_verilog_grid_pins(FILE* fp, int x, int y, - int top_level, + boolean top_level, boolean dump_port_type, boolean dump_last_comma) { int iheight, side, ipin, class_id; @@ -2737,13 +2042,7 @@ void dump_verilog_grid_pins(FILE* fp, } } /* This pin appear at this side! */ - if (1 == top_level) { - fprintf(fp, " grid_%d__%d__pin_%d__%d__%d_", x, y, - iheight, side, ipin); - } else { - fprintf(fp, " %s_height_%d__pin_%d_", - convert_side_index_to_string(side), iheight, ipin); - } + fprintf(fp, " %s", gen_verilog_grid_one_pin_name(x, y, iheight, side, ipin, top_level)); /* Update counter */ num_dumped_port++; side_pin_index++; @@ -2772,7 +2071,7 @@ void dump_verilog_grid_pins(FILE* fp, */ void dump_verilog_io_grid_pins(FILE* fp, int x, int y, - int top_level, + boolean top_level, boolean dump_port_type, boolean dump_last_comma) { int iheight, side, ipin; @@ -2836,13 +2135,7 @@ void dump_verilog_io_grid_pins(FILE* fp, } } /* This pin appear at this side! */ - if (1 == top_level) { - fprintf(fp, " grid_%d__%d__pin_%d__%d__%d_", x, y, - iheight, side, ipin); - } else { - fprintf(fp, " %s_height_%d__pin_%d_", - convert_side_index_to_string(side), iheight, ipin); - } + fprintf(fp, " %s", gen_verilog_grid_one_pin_name(x, y, iheight, side, ipin, top_level)); /* Update counter */ num_dumped_port++; side_pin_index++; @@ -2962,8 +2255,8 @@ char* verilog_get_grid_phy_block_subckt_name(int x, int y, int z, /* Print the pins of grid subblocks */ void dump_verilog_grid_block_subckt_pins(FILE* fp, - int z, - t_type_ptr type_descriptor) { + int z, + t_type_ptr type_descriptor) { int iport, ipin, side, dump_pin_cnt; int grid_pin_index, pin_height, side_pin_index; t_pb_graph_node* top_pb_graph_node = NULL; @@ -3087,31 +2380,7 @@ void dump_verilog_io_grid_block_subckt_pins(FILE* fp, /* identify the location of IO grid and * decide which side of ports we need */ - if (0 == x) { - /* Left side */ - assert((0 < y)&&(y < (ny + 1))); - /* Print Right side ports*/ - side = RIGHT; - } else if ((nx + 1) == x) { - /* Right side */ - assert((0 < y)&&(y < (ny + 1))); - /* Print Left side ports*/ - side = LEFT; - } else if (0 == y) { - /* Bottom Side */ - assert((0 < x)&&(x < (nx + 1))); - /* Print TOP side ports */ - side = TOP; - } else if ((ny + 1) == y) { - /* TOP Side */ - assert((0 < x)&&(x < (nx + 1))); - /* Print BOTTOM side ports */ - side = BOTTOM; - } else { - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid co-ordinators(x=%d, y=%d) for I/O grid!\n", - __FILE__, __LINE__, x, y); - exit(1); - } + side = determine_io_grid_side(x, y); dump_pin_cnt = 0; @@ -3187,218 +2456,9 @@ void dump_verilog_io_grid_block_subckt_pins(FILE* fp, return; } -/* Print the SPICE netlist for a grid blocks */ -void dump_verilog_grid_blocks(char* subckt_dir, - int ix, int iy, - t_arch* arch) { - int subckt_name_str_len = 0; - char* subckt_name = NULL; - t_block* mapped_block = NULL; - int iz; - int cur_block_index = 0; - int capacity; - int cur_num_mem_bit; - int num_reserved_conf_bits; - int temp_reserved_conf_bits_msb; - int temp_conf_bits_lsb, temp_conf_bits_msb; - int temp_iopad_lsb, temp_iopad_msb; - FILE* fp = NULL; - char* fname = NULL; - - /* Check */ - assert((!(0 > ix))&&(!(ix > (nx + 1)))); - assert((!(0 > iy))&&(!(iy > (ny + 1)))); - - /* Make a snapshot for the number of memory bits */ - cur_num_mem_bit = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - - /* Update the grid_index_low for each spice_model */ - update_spice_models_grid_index_low(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models); - - /* generate_grid_subckt, type_descriptor of each grid defines the capacity, - * for example, each grid may contains more than one top-level pb_types, such as I/O - */ - if ((NULL == grid[ix][iy].type) - ||(EMPTY_TYPE == grid[ix][iy].type) - ||(0 != grid[ix][iy].offset)) { - /* Update the grid_index_high for each spice_model */ - update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models); - return; - } - - /* Create file handler */ - fp = verilog_create_one_subckt_file(subckt_dir, "Logic Block ", grid_verilog_file_name_prefix, ix, iy, &fname); - - capacity= grid[ix][iy].type->capacity; - assert(0 < capacity); - - /* Make the sub-circuit name*/ - /* Name format: grid[][]_*/ - subckt_name_str_len = 4 + 1 + strlen(my_itoa(ix)) + 2 - + strlen(my_itoa(iy)) + 1 + 1 + 1; /* Plus '0' at the end of string*/ - subckt_name = (char*)my_malloc(sizeof(char)*subckt_name_str_len); - sprintf(subckt_name, "grid_%d__%d__", ix, iy); - - cur_block_index = 0; - /* check capacity and if this has been mapped */ - for (iz = 0; iz < capacity; iz++) { - /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ - mapped_block = search_mapped_block(ix, iy, iz); - /* Comments: Grid [x][y]*/ - fprintf(fp, "//----- Grid[%d][%d] type_descriptor: %s[%d] -----\n", ix, iy, grid[ix][iy].type->name, iz); - if (NULL == mapped_block) { - /* Print a NULL logic block...*/ - dump_verilog_idle_block(fp, subckt_name, ix, iy, iz, grid[ix][iy].type); - } else { - if (iz == mapped_block->z) { - // assert(mapped_block == &(block[grid[ix][iy].blocks[cur_block_index]])); - cur_block_index++; - } - /* Print a logic block with specific configurations*/ - dump_verilog_block(fp, subckt_name, ix, iy, iz, grid[ix][iy].type, mapped_block); - } - fprintf(fp, "//----- END -----\n\n"); - } - assert(cur_block_index == grid[ix][iy].usage); - - /* Update the grid_index_high for each spice_model */ - update_spice_models_grid_index_high(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models); - - /* Print grid[x][y] top-level module */ - fprintf(fp, "//----- Grid[%d][%d], Capactity: %d -----\n", ix, iy, capacity); - fprintf(fp, "//----- Top Protocol -----\n"); - /* Definition */ - fprintf(fp, "module grid_%d__%d_( \n", ix, iy); - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { - fprintf(fp, ",\n"); - } - - /* Pins */ - /* Special Care for I/O grid */ - if (IO_TYPE == grid[ix][iy].type) { - dump_verilog_io_grid_pins(fp, ix, iy, 0, TRUE, FALSE); - } else { - dump_verilog_grid_pins(fp, ix, iy, 0, TRUE, FALSE); - } - - /* IO PAD */ - dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, - iopad_verilog_model->grid_index_low[ix][iy], - iopad_verilog_model->grid_index_high[ix][iy] - 1, - VERILOG_PORT_INPUT); - - /* Print configuration ports */ - /* Reserved configuration ports */ - if (NULL == mapped_block) { - num_reserved_conf_bits = grid[ix][iy].type->pb_type->default_mode_num_reserved_conf_bits; - } else { - num_reserved_conf_bits = mapped_block->pb->num_reserved_conf_bits; - } - if (0 < num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, - num_reserved_conf_bits - 1, - VERILOG_PORT_INPUT); - /* Normal configuration ports */ - if (0 < (get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info) - cur_num_mem_bit)) { - fprintf(fp, ",\n"); - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - cur_num_mem_bit, - get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info) - 1, - VERILOG_PORT_INPUT); - } - fprintf(fp, ");\n"); - - /* Record LSB and MSB of reserved_conf_bits and regular conf_bits in sram_orgz_info */ - sram_verilog_orgz_info->grid_reserved_conf_bits[ix][iy] = num_reserved_conf_bits; - sram_verilog_orgz_info->grid_conf_bits_lsb[ix][iy] = cur_num_mem_bit; - sram_verilog_orgz_info->grid_conf_bits_msb[ix][iy] = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - - /* Initialize temporary counter */ - temp_conf_bits_lsb = cur_num_mem_bit; - temp_iopad_lsb = iopad_verilog_model->grid_index_low[ix][iy]; - - /* Quote all the sub blocks*/ - for (iz = 0; iz < capacity; iz++) { - /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ - mapped_block = search_mapped_block(ix, iy, iz); - /* Local Vdd and Gnd, subckt name*/ - fprintf(fp, "%s ", verilog_get_grid_block_subckt_name(ix, iy, iz, subckt_name, mapped_block)); - fprintf(fp, " grid_%d__%d__%d_ (", ix, iy, iz); - fprintf(fp, "\n"); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); - } - /* Print all the pins */ - /* Special Care for I/O grid */ - if (IO_TYPE == grid[ix][iy].type) { - dump_verilog_io_grid_block_subckt_pins(fp, ix, iy, iz, grid[ix][iy].type); - } else { - dump_verilog_grid_block_subckt_pins(fp, iz, grid[ix][iy].type); - } - /* Print configuration ports */ - if (NULL == mapped_block) { - temp_reserved_conf_bits_msb = grid[ix][iy].type->pb_type->default_mode_num_reserved_conf_bits; - temp_conf_bits_msb = temp_conf_bits_lsb + grid[ix][iy].type->pb_type->default_mode_num_conf_bits; - temp_iopad_msb = temp_iopad_lsb + grid[ix][iy].type->pb_type->default_mode_num_iopads; - } else { - temp_reserved_conf_bits_msb = mapped_block->pb->num_reserved_conf_bits; - temp_conf_bits_msb = temp_conf_bits_lsb + mapped_block->pb->num_conf_bits; - temp_iopad_msb = temp_iopad_lsb + mapped_block->pb->num_iopads; - } - /* Print Input Pad and Output Pad */ - fprintf(fp, "\n//---- IOPAD ----\n"); - dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, - temp_iopad_lsb, - temp_iopad_msb - 1, - VERILOG_PORT_CONKT); - /* Reserved configuration ports */ - if (0 < temp_reserved_conf_bits_msb) { - fprintf(fp, ",\n"); - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, - 0, temp_reserved_conf_bits_msb - 1, - VERILOG_PORT_CONKT); - } - /* Normal configuration ports */ - assert(!(0 > temp_conf_bits_msb - temp_conf_bits_lsb)); - if (0 < (temp_conf_bits_msb - temp_conf_bits_lsb)) { - fprintf(fp, ",\n"); - fprintf(fp, "//---- SRAM ----\n"); - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - temp_conf_bits_lsb, temp_conf_bits_msb - 1, - VERILOG_PORT_CONKT); - } - /* Update temp_sram_lsb */ - temp_conf_bits_lsb = temp_conf_bits_msb; - fprintf(fp, ");\n"); - } - - fprintf(fp, "endmodule\n"); - fprintf(fp, "//----- END Top Protocol -----\n"); - fprintf(fp, "//----- END Grid[%d][%d], Capactity: %d -----\n\n", ix, iy, capacity); - - assert(temp_conf_bits_msb == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); - - /* Close file*/ - fclose(fp); - - /* Add fname to the linked list */ - grid_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(grid_verilog_subckt_file_path_head, fname); - - /* Free */ - my_free(subckt_name); - my_free(fname); - - return; -} - /* Print the SPICE netlist for a I/O grid blocks */ -void dump_verilog_physical_grid_blocks(char* subckt_dir, +void dump_verilog_physical_grid_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* subckt_dir, int ix, int iy, t_arch* arch) { int subckt_name_str_len = 0; @@ -3411,13 +2471,15 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, int temp_iopad_lsb, temp_iopad_msb; FILE* fp = NULL; char* fname = NULL; + t_spice_model* cur_mem_model = NULL; /* Check */ assert((!(0 > ix))&&(!(ix > (nx + 1)))); assert((!(0 > iy))&&(!(iy > (ny + 1)))); /* Make a snapshot for the number of memory bits */ - cur_num_mem_bit = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); + cur_num_mem_bit = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_mem_model); /* Update the grid_index_low for each spice_model */ update_spice_models_grid_index_low(ix, iy, arch->spice->num_spice_model, arch->spice->spice_models); @@ -3451,7 +2513,7 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, /* Comments: Grid [x][y]*/ fprintf(fp, "//----- Grid[%d][%d] type_descriptor: %s[%d] -----\n", ix, iy, grid[ix][iy].type->name, iz); /* Print a NULL logic block...*/ - dump_verilog_physical_block(fp, subckt_name, ix, iy, iz, grid[ix][iy].type); + dump_verilog_physical_block(cur_sram_orgz_info, fp, subckt_name, ix, iy, iz, grid[ix][iy].type); fprintf(fp, "//----- END -----\n\n"); } @@ -3462,7 +2524,7 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, fprintf(fp, "//----- Grid[%d][%d], Capactity: %d -----\n", ix, iy, capacity); fprintf(fp, "//----- Top Protocol -----\n"); /* Definition */ - fprintf(fp, "module grid_%d__%d_( \n", ix, iy); + fprintf(fp, "module %s ( \n", gen_verilog_one_grid_module_name(ix, iy)); fprintf(fp, "\n"); /* dump global ports */ if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { @@ -3472,9 +2534,9 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, /* Pins */ /* Special Care for I/O grid */ if (IO_TYPE == grid[ix][iy].type) { - dump_verilog_io_grid_pins(fp, ix, iy, 0, TRUE, FALSE); + dump_verilog_io_grid_pins(fp, ix, iy, FALSE, TRUE, FALSE); } else { - dump_verilog_grid_pins(fp, ix, iy, 0, TRUE, FALSE); + dump_verilog_grid_pins(fp, ix, iy, FALSE, TRUE, FALSE); } /* IO PAD */ @@ -3488,35 +2550,53 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, temp_reserved_conf_bits_msb = grid[ix][iy].type->pb_type->physical_mode_num_reserved_conf_bits; if (0 < temp_reserved_conf_bits_msb) { fprintf(fp, ",\n"); - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, 0, temp_reserved_conf_bits_msb - 1, VERILOG_PORT_INPUT); } /* Normal configuration ports */ - if (0 < (get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info) - cur_num_mem_bit)) { + if (0 < (get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info) - cur_num_mem_bit)) { fprintf(fp, ",\n"); - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_sram_ports(fp, cur_sram_orgz_info, cur_num_mem_bit, - get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info) - 1, + get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info) - 1, VERILOG_PORT_INPUT); } + /* Dump ports only visible during formal verification*/ + if (0 < (get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info) - 1 - cur_num_mem_bit)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_num_mem_bit, + get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info) - 1, + VERILOG_PORT_INPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + fprintf(fp, ");\n"); /* Record LSB and MSB of reserved_conf_bits and regular conf_bits in sram_orgz_info */ - sram_verilog_orgz_info->grid_reserved_conf_bits[ix][iy] = temp_reserved_conf_bits_msb; - sram_verilog_orgz_info->grid_conf_bits_lsb[ix][iy] = cur_num_mem_bit; - sram_verilog_orgz_info->grid_conf_bits_msb[ix][iy] = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); + cur_sram_orgz_info->grid_reserved_conf_bits[ix][iy] = temp_reserved_conf_bits_msb; + cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy] = cur_num_mem_bit; + cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); /* Initialize temporary counter */ temp_conf_bits_lsb = cur_num_mem_bit; temp_iopad_lsb = iopad_verilog_model->grid_index_low[ix][iy]; + /* Local wires for memory configurations */ + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, + cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy], + cur_sram_orgz_info->grid_conf_bits_msb[ix][iy]); + /* Quote all the sub blocks*/ for (iz = 0; iz < capacity; iz++) { /* Local Vdd and Gnd, subckt name*/ fprintf(fp, "%s ", verilog_get_grid_phy_block_subckt_name(ix, iy, iz, subckt_name, NULL)); - fprintf(fp, " grid_%d__%d__%d_ (", ix, iy, iz); + fprintf(fp, " %s (", gen_verilog_one_block_instance_name(ix, iy, iz)); fprintf(fp, "\n"); /* dump global ports */ if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { @@ -3544,18 +2624,31 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, /* Reserved configuration ports */ if (0 < temp_reserved_conf_bits_msb) { fprintf(fp, ",\n"); - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, 0, temp_reserved_conf_bits_msb - 1, VERILOG_PORT_CONKT); } /* Normal configuration ports */ - if (0 < (temp_conf_bits_msb - temp_conf_bits_lsb)) { + if (0 < (temp_conf_bits_msb - 1 - temp_conf_bits_lsb)) { fprintf(fp, ",\n"); fprintf(fp, "//---- SRAM ----\n"); - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, - temp_conf_bits_lsb, temp_conf_bits_msb - 1, - VERILOG_PORT_CONKT); + dump_verilog_sram_local_ports(fp, cur_sram_orgz_info, + temp_conf_bits_lsb, temp_conf_bits_msb - 1, + VERILOG_PORT_CONKT); } + /* Dump ports only visible during formal verification*/ + if (0 < (temp_conf_bits_msb - 1 - temp_conf_bits_lsb)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + temp_conf_bits_lsb, + temp_conf_bits_msb - 1, + VERILOG_PORT_INPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + /* Update temp_sram_lsb */ temp_conf_bits_lsb = temp_conf_bits_msb; temp_iopad_lsb = temp_iopad_msb; @@ -3567,7 +2660,7 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, fprintf(fp, "//----- END Grid[%d][%d], Capactity: %d -----\n\n", ix, iy, capacity); /* Check */ - assert(temp_conf_bits_msb == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); + assert(temp_conf_bits_msb == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)); assert(temp_iopad_msb == iopad_verilog_model->grid_index_high[ix][iy]); /* Close the file */ @@ -3588,8 +2681,9 @@ void dump_verilog_physical_grid_blocks(char* subckt_dir, * will be printed. May have an additional option that only * output the used logic blocks */ -void dump_verilog_logic_blocks(char* subckt_dir, - t_arch* arch) { +void dump_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* subckt_dir, + t_arch* arch) { int ix, iy; /* Check the grid*/ @@ -3611,39 +2705,41 @@ void dump_verilog_logic_blocks(char* subckt_dir, assert(IO_TYPE != grid[ix][iy].type); /* Ensure a valid usage */ assert((0 == grid[ix][iy].usage)||(0 < grid[ix][iy].usage)); - dump_verilog_grid_blocks(subckt_dir, ix, iy, arch); + dump_verilog_physical_grid_blocks(cur_sram_orgz_info, subckt_dir, ix, iy, arch); } } vpr_printf(TIO_MESSAGE_INFO,"Generating IO grids...\n"); /* Print the IO pads */ - /* Left side: x = 0, y = 1 .. ny*/ - ix = 0; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch); - } - /* Right side : x = nx + 1, y = 1 .. ny*/ - ix = nx + 1; - for (iy = 1; iy < (ny + 1); iy++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch); - } - /* Bottom side : x = 1 .. nx + 1, y = 0 */ - iy = 0; - for (ix = 1; ix < (nx + 1); ix++) { - /* Ensure this is a io */ - assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch); - } /* Top side : x = 1 .. nx + 1, y = nx + 1 */ iy = ny + 1; for (ix = 1; ix < (nx + 1); ix++) { /* Ensure this is a io */ assert(IO_TYPE == grid[ix][iy].type); - dump_verilog_physical_grid_blocks(subckt_dir, ix, iy, arch); + dump_verilog_physical_grid_blocks(cur_sram_orgz_info, subckt_dir, ix, iy, arch); + } + + /* Right side : x = nx + 1, y = 1 .. ny*/ + ix = nx + 1; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + dump_verilog_physical_grid_blocks(cur_sram_orgz_info, subckt_dir, ix, iy, arch); + } + + /* Bottom side : x = 1 .. nx + 1, y = 0 */ + iy = 0; + for (ix = 1; ix < (nx + 1); ix++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + dump_verilog_physical_grid_blocks(cur_sram_orgz_info, subckt_dir, ix, iy, arch); + } + /* Left side: x = 0, y = 1 .. ny*/ + ix = 0; + for (iy = 1; iy < (ny + 1); iy++) { + /* Ensure this is a io */ + assert(IO_TYPE == grid[ix][iy].type); + dump_verilog_physical_grid_blocks(cur_sram_orgz_info, subckt_dir, ix, iy, arch); } /* Output a header file for all the logic blocks */ @@ -3656,3 +2752,4 @@ void dump_verilog_logic_blocks(char* subckt_dir, return; } + diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_pbtypes.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.h similarity index 57% rename from vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_pbtypes.h rename to vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.h index 589e6cf74..2b2695336 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_pbtypes.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.h @@ -30,73 +30,63 @@ void dump_verilog_pb_type_ports(FILE* fp, int use_global_clock, t_pb_type* cur_pb_type, boolean dump_port_type, - boolean dump_last_comma); + boolean dump_last_comma, + boolean require_explicit_port_map); void dump_verilog_dangling_des_pb_graph_pin_interc(FILE* fp, t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, - enum e_pin2pin_interc_type pin2pin_interc_type, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, char* parent_pin_prefix); -void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_node* src_pb_graph_node, - t_pb_graph_node* des_pb_graph_node, - enum e_pin2pin_interc_type pin2pin_interc_type, - t_interconnect* pin2pin_interc, - char* parent_pin_prefix, - char** src_pin_prefix, - char** des_pin_prefix); +void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_pin* src_pb_graph_pin, + t_pb_graph_pin* des_pb_graph_pin, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, + t_interconnect* pin2pin_interc, + char* parent_pin_prefix, + char** src_pin_prefix, + char** des_pin_prefix); void verilog_find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin, t_mode* cur_mode, t_interconnect** cur_interc, int* fan_in); -void dump_verilog_pb_graph_pin_interc(FILE* fp, - char* parent_pin_prefix, - enum e_pin2pin_interc_type pin2pin_interc_type, - t_pb_graph_pin* des_pb_graph_pin, - t_mode* cur_mode, - int is_idle); +void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* parent_pin_prefix, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, + t_pb_graph_pin* des_pb_graph_pin, + t_mode* cur_mode); -void dump_verilog_pb_graph_interc(FILE* fp, +void dump_verilog_pb_graph_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* pin_prefix, t_pb_graph_node* cur_pb_graph_node, - int select_mode_index, - int is_idle); + int select_mode_index); void dump_verilog_pb_graph_primitive_node(FILE* fp, char* subckt_prefix, - t_pb* cur_pb, t_pb_graph_node* cur_pb_graph_node, int pb_type_index); -void dump_verilog_pb_primitive_verilog_model(FILE* fp, - char* subckt_prefix, - t_pb* prim_pb, - t_pb_graph_node* prim_pb_graph_node, - int pb_index, - t_spice_model* verilog_model, - int is_idle, - t_rr_node* pb_rr_graph); +void dump_verilog_pb_primitive_verilog_model(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* subckt_prefix, + t_pb* prim_pb, + t_pb_graph_node* prim_pb_graph_node, + int pb_index, + t_spice_model* verilog_model, + int is_idle); -void dump_verilog_idle_pb_graph_node_rec(FILE* fp, - char* subckt_prefix, - t_pb_graph_node* cur_pb_graph_node, - int pb_type_index); - -void dump_verilog_pb_graph_node_rec(FILE* fp, - char* subckt_prefix, - t_pb* cur_pb, - t_pb_graph_node* cur_pb_graph_node, - int pb_type_index, - t_rr_node* pb_rr_graph); - -void dump_verilog_phy_pb_graph_node_rec(FILE* fp, +void dump_verilog_phy_pb_graph_node_rec(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_prefix, t_pb_graph_node* cur_pb_graph_node, int pb_type_index); -void dump_verilog_block(FILE* fp, +void dump_verilog_block(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_name, int x, int y, @@ -104,7 +94,8 @@ void dump_verilog_block(FILE* fp, t_type_ptr type_descriptor, t_block* mapped_block); -void dump_verilog_physical_block(FILE* fp, +void dump_verilog_physical_block(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_name, int x, int y, @@ -113,13 +104,13 @@ void dump_verilog_physical_block(FILE* fp, void dump_verilog_grid_pins(FILE* fp, int x, int y, - int top_level, + boolean top_level, boolean dump_port_type, boolean dump_last_comma); void dump_verilog_io_grid_pins(FILE* fp, int x, int y, - int top_level, + boolean top_level, boolean dump_port_type, boolean dump_last_comma); @@ -139,20 +130,23 @@ void dump_verilog_io_grid_block_subckt_pins(FILE* fp, int z, t_type_ptr type_descriptor); -void dump_verilog_grid_blocks(FILE* fp, - int ix, - int iy); +void dump_verilog_grid_blocks(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int ix, int iy); -void dump_verilog_physical_grid_blocks(FILE* fp, - int ix, - int iy, - t_arch* arch); +void dump_verilog_physical_grid_blocks(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int ix, int iy, + t_arch* arch); -void dump_verilog_idle_block(FILE* fp, +void dump_verilog_idle_block(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, char* subckt_name, - int x, - int y, - int z, + int x, int y, int z, t_type_ptr type_descriptor); -void dump_verilog_logic_blocks(char* subckt_dir, t_arch* arch); +void dump_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* subckt_dir, t_arch* arch); + +void rec_copy_name_mux_in_node(t_pb_graph_node* master_node, + t_pb_graph_node* target_node); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.c new file mode 100644 index 000000000..cda30f670 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.c @@ -0,0 +1,746 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "rr_graph_swseg.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" + +/* Include verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_pbtypes.h" +#include "verilog_primitives.h" + +/* Subroutines */ +/* Dump a hard logic primitive node + * This primitive can be a FF or a hard_logic, or an iopad */ +void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* subckt_prefix, + t_pb_graph_node* prim_pb_graph_node, + int index, + t_spice_model* verilog_model) { + int num_pad_port = 0; /* INOUT port */ + t_spice_model_port** pad_ports = NULL; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_output_port = 0; + t_spice_model_port** output_ports = NULL; + int num_clock_port = 0; + t_spice_model_port** clock_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + int num_sram = 0; + /* int* sram_bits = NULL; */ + + char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ + t_pb_type* prim_pb_type = NULL; + char* port_prefix = NULL; + + /* For each SRAM, we could have multiple BLs/WLs */ + int num_bl_ports = 0; + t_spice_model_port** bl_port = NULL; + int num_wl_ports = 0; + t_spice_model_port** wl_port = NULL; + int num_bl_per_sram = 0; + int num_wl_per_sram = 0; + + int cur_num_sram = 0; + int num_conf_bits = 0; + int num_reserved_conf_bits = 0; + t_spice_model* mem_model = NULL; + int cur_bl, cur_wl; + + char* mem_subckt_name = NULL; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Ensure a valid pb_graph_node */ + if (NULL == prim_pb_graph_node) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Find ports*/ + pad_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INOUT, &num_pad_port, TRUE); + input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + clock_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_CLOCK, &num_clock_port, TRUE); + sram_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + + /* Asserts */ + assert((SPICE_MODEL_IOPAD == verilog_model->type) /* Support IO PAD which matches the physical design */ + || (SPICE_MODEL_FF == verilog_model->type) /* Support IO PAD which matches the physical design */ + || (SPICE_MODEL_HARDLOGIC == verilog_model->type)); /* Support IO PAD which matches the physical design */ + + /* Initialize */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + prim_pb_type = prim_pb_graph_node->pb_type; + + /* Generate Subckt for pb_type*/ + /* Simplify the port prefix, make SPICE netlist readable */ + port_prefix = (char*)my_malloc(sizeof(char)* + (strlen(prim_pb_type->name) + 1)); + sprintf(port_prefix, "%s", prim_pb_type->name); + + /* Print Comment lines depends on the type of this SPICE model */ + fprintf(fp, "//----- %s Verilog module: %s%s -----\n", + generate_string_spice_model_type(verilog_model->type), + formatted_subckt_prefix, port_prefix); + /* Definition line */ + fprintf(fp, "module %s%s (", formatted_subckt_prefix, port_prefix); + fprintf(fp, "\n"); + /* Only dump the global ports belonging to a spice_model + */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, TRUE, FALSE)) { + fprintf(fp, ",\n"); + } + + /* TODO: assert this is physical mode */ + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + /* Get current counter of mem_bits, bl and wl */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + + /* print ports --> input ports */ + dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, TRUE, FALSE, FALSE); + + /* IOPADs requires a specical port to output */ + if (SPICE_MODEL_IOPAD == verilog_model->type) { + fprintf(fp, ",\n"); + /* Print output port */ + fprintf(fp, "inout [%d:%d] %s%s\n", + verilog_model->cnt, verilog_model->cnt, + gio_inout_prefix, verilog_model->prefix); + } + + /* Print SRAM ports */ + /* connect to reserved BL/WLs ? */ + num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model, cur_sram_orgz_info->type, 0); + /* Get the number of configuration bits required by this MUX */ + num_conf_bits = count_num_conf_bits_one_spice_model(verilog_model, cur_sram_orgz_info->type, 0); + /* Reserved sram ports */ + if (0 < num_reserved_conf_bits) { + fprintf(fp, ",\n"); + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, num_reserved_conf_bits - 1, + VERILOG_PORT_INPUT); + } + /* Normal sram ports */ + if (0 < num_conf_bits) { + fprintf(fp, ",\n"); + dump_verilog_sram_ports(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_sram - 1, + VERILOG_PORT_INPUT); + + } + /* Dump ports only visible during formal verification*/ + if (0 < num_conf_bits) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_num_sram, + cur_num_sram + num_conf_bits - 1, + VERILOG_PORT_INPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + + /* Local vdd and gnd*/ + fprintf(fp, ");\n"); + + if (0 < num_sram_port) { + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_sram - 1); + } + + if (0 < num_sram_port) { + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + /* Local wires */ + /* Find the number of BLs/WLs of each SRAM */ + /* Detect the SRAM SPICE model linked to this SRAM port */ + assert(NULL != sram_ports[0]->spice_model); + assert(SPICE_MODEL_SRAM == sram_ports[0]->spice_model->type); + find_bl_wl_ports_spice_model(sram_ports[0]->spice_model, + &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); + assert(1 == num_bl_ports); + assert(1 == num_wl_ports); + num_bl_per_sram = bl_port[0]->size; + num_wl_per_sram = wl_port[0]->size; + break; + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + } + /* Definition ends*/ + + /* Dump the configuration port bus */ + if ((0 < num_reserved_conf_bits) + || (0 < num_conf_bits)) { + dump_verilog_mem_config_bus(fp, mem_model, cur_sram_orgz_info, + cur_num_sram, num_reserved_conf_bits, num_conf_bits); + /* Dump ports only visible during formal verification*/ + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + dump_verilog_formal_verification_sram_ports_wiring(fp, cur_sram_orgz_info, + cur_num_sram, + cur_num_sram + num_conf_bits - 1); + fprintf(fp, "`endif\n"); + } + + /* Call the subckt*/ + fprintf(fp, "%s %s_%d_ (", verilog_model->name, verilog_model->prefix, verilog_model->cnt); + fprintf(fp, "\n"); + /* Only dump the global ports belonging to a spice_model + * Disable recursive here ! + */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); + } + + /* assert */ + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + /* print ports --> input ports */ + dump_verilog_pb_type_ports(fp, port_prefix, 0, prim_pb_type, FALSE, FALSE, TRUE); + + /* IOPADs requires a specical port to output */ + if (SPICE_MODEL_IOPAD == verilog_model->type) { + fprintf(fp, ",\n"); + assert(1 == num_pad_port); + assert(NULL != pad_ports[0]); + /* Add explicit port mapping if required */ + if (TRUE == verilog_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + pad_ports[0]->lib_name); + } + /* Print inout port */ + fprintf(fp, "%s%s[%d]", gio_inout_prefix, + verilog_model->prefix, verilog_model->cnt); + if (TRUE == verilog_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + } + /* Print SRAM ports */ + /* Connect srams: TODO: to find the SRAM model used by this Verilog model */ + if (0 < num_sram) { + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + /* Add explicit port mapping if required */ + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + assert( 1 == num_sram_port); + assert( NULL != sram_ports[0]); + fprintf(fp, ".%s(", + sram_ports[0]->lib_name); + } + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_sram - 1, + 0, VERILOG_PORT_CONKT); + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } + + /* Check if we have an inverterd prefix */ + if (NULL == sram_ports[0]->inv_prefix) { + break; + } + fprintf(fp, ", "); + /* Add explicit port mapping if required */ + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + assert( 1 == num_sram_port); + assert( NULL != sram_ports[0]); + fprintf(fp, ".%s(", + sram_ports[0]->inv_prefix); + } + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_sram - 1, + 1, VERILOG_PORT_CONKT); + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } + break; + case SPICE_SRAM_MEMORY_BANK: + /* Add explicit port mapping if required */ + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + assert( 1 == num_sram_port); + assert( NULL != sram_ports[0]); + fprintf(fp, ".%s(", + sram_ports[0]->lib_name); + } + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_sram - 1, + 0, VERILOG_PORT_CONKT); + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } + /* Check if we have an inverterd prefix */ + if (NULL == sram_ports[0]->inv_prefix) { + break; + } + fprintf(fp, ", "); + /* Add explicit port mapping if required */ + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + assert( 1 == num_sram_port); + assert( NULL != sram_ports[0]); + fprintf(fp, ".%s(", + sram_ports[0]->inv_prefix); + } + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_sram - 1, + 1, VERILOG_PORT_CONKT); + if ( (0 < num_sram) + && (TRUE == verilog_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + } + + /* Local vdd and gnd, verilog_model name, + * TODO: Global vdd for i/o pad to split? + */ + fprintf(fp, ");\n"); + + /* Call SRAM subckt */ + /* what is the SRAM bit of a mode? */ + /* If logical block is not NULL, we need to decode the sram bit */ + /* SRAM bits are decoded in bitstream generator! NOT here + if (NULL != mapped_logical_block) { + assert(NULL != mapped_logical_block->pb->pb_graph_node->pb_type->mode_bits); + sram_bits = decode_mode_bits(mapped_logical_block->pb->pb_graph_node->pb_type->mode_bits, &expected_num_sram); + assert(expected_num_sram == num_sram); + } else { + sram_bits = (int*)my_calloc(num_sram, sizeof(int)); + for (i = 0; i < num_sram; i++) { + sram_bits[i] = sram_ports[0]->default_val; + } + } + */ + + /* Call the memory module defined for this SRAM-based MUX! */ + if (0 < num_sram_port) { + mem_subckt_name = generate_verilog_mem_subckt_name(verilog_model, mem_model, verilog_mem_posfix); + fprintf(fp, "%s %s_%d_ ( ", + mem_subckt_name, mem_subckt_name, verilog_model->cnt); + dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, verilog_model, -1, + mem_model, cur_num_sram, cur_num_sram + num_sram - 1); + fprintf(fp, ");\n"); + /* update the number of memory bits */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_sram); + } + + /* End */ + fprintf(fp, "endmodule\n"); + /* Comment lines */ + fprintf(fp, "//----- END %s Verilog module: %s%s -----\n\n", + generate_string_spice_model_type(verilog_model->type), + formatted_subckt_prefix, port_prefix); + + /* Update the verilog_model counter */ + verilog_model->cnt++; + + /*Free*/ + free(formatted_subckt_prefix); + free(port_prefix); + my_free(input_ports); + my_free(output_ports); + my_free(pad_ports); + my_free(clock_ports); + my_free(sram_ports); + /* my_free(sram_bits); */ + + return; +} + +void dump_verilog_pb_primitive_lut(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* subckt_prefix, + t_pb_graph_node* prim_pb_graph_node, + int index, + t_spice_model* verilog_model) { + int i, ipin; + int lut_size = 0; + int num_input_port = 0; + t_spice_model_port** input_ports = NULL; + int num_output_port = 0; + t_spice_model_port** output_ports = NULL; + int num_sram_port = 0; + t_spice_model_port** sram_ports = NULL; + + int num_lut_sram = 0; + int num_mode_sram = 0; + t_spice_model_port* lut_sram_port = NULL; + t_spice_model_port* mode_bit_port = NULL; + + int num_pb_type_input_port = 0; + t_port** pb_type_input_ports = NULL; + + int num_pb_type_output_port = 0; + t_port** pb_type_output_ports = NULL; + + char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); /* Complete a "_" at the end if needed*/ + t_pb_type* cur_pb_type = NULL; + char* port_prefix = NULL; + int cur_num_sram = 0; + int num_sram = 0; + /* For each SRAM, we could have multiple BLs/WLs */ + int num_bl_ports = 0; + t_spice_model_port** bl_port = NULL; + int num_wl_ports = 0; + t_spice_model_port** wl_port = NULL; + int num_bl_per_sram = 0; + int num_wl_per_sram = 0; + int num_conf_bits = 0; + int num_reserved_conf_bits = 0; + int cur_bl, cur_wl; + t_spice_model* mem_model = NULL; + char* mem_subckt_name = NULL; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Ensure a valid pb_graph_node */ + if (NULL == prim_pb_graph_node) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb_graph_node!\n", + __FILE__, __LINE__); + exit(1); + } + /* Asserts */ + assert(SPICE_MODEL_LUT == verilog_model->type); + + /* Determine size of LUT*/ + input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + assert(1 == num_input_port); + lut_size = input_ports[0]->size; + /* Find SRAM ports for truth tables and mode bits */ + sram_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + assert((1 == num_sram_port) || (2 == num_sram_port)); + for (i = 0; i < num_sram_port; i++) { + if (FALSE == sram_ports[i]->mode_select) { + lut_sram_port = sram_ports[i]; + num_lut_sram = sram_ports[i]->size; + assert (num_lut_sram == (int)pow(2.,(double)(lut_size))); + } else { + assert (TRUE == sram_ports[i]->mode_select); + mode_bit_port = sram_ports[i]; + num_mode_sram = sram_ports[i]->size; + } + } + /* Must have a lut_sram_port, while mode_bit_port is optional */ + assert (NULL != lut_sram_port); + + /* Count the number of configuration bits */ + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + /* Get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + /* Find the number of BLs/WLs of each SRAM */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + /* Detect the SRAM SPICE model linked to this SRAM port */ + assert(NULL != sram_ports[0]->spice_model); + assert(SPICE_MODEL_SRAM == sram_ports[0]->spice_model->type); + find_bl_wl_ports_spice_model(sram_ports[0]->spice_model, + &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); + assert(1 == num_bl_ports); + assert(1 == num_wl_ports); + num_bl_per_sram = bl_port[0]->size; + num_wl_per_sram = wl_port[0]->size; + /* Asserts */ + assert(num_bl_per_sram == num_wl_per_sram); + break; + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Disable Generate sram bits*/ + /* SRAM bits are decoded in bitstream generator! NOT here + sram_bits = generate_lut_sram_bits(truth_table_length, truth_table, + lut_size, sram_ports[0]->default_val); + */ + + /* Print the subckts*/ + cur_pb_type = prim_pb_graph_node->pb_type; + + /* Comment lines */ + fprintf(fp, "//----- LUT Verilog module: %s%s_%d_ -----\n", + formatted_subckt_prefix, cur_pb_type->name, index); + + /* Simplify the prefix, make the SPICE netlist readable*/ + port_prefix = (char*)my_malloc(sizeof(char)* + (strlen(cur_pb_type->name) + 1)); + sprintf(port_prefix, "%s", cur_pb_type->name); + + /* Subckt definition*/ + fprintf(fp, "module %s%s (", + formatted_subckt_prefix, cur_pb_type->name); + fprintf(fp, "\n"); + /* Only dump the global ports belonging to a spice_model */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, TRUE, FALSE)) { + fprintf(fp, ",\n"); + } + /* Print inputs, outputs, inouts, clocks, NO SRAMs*/ + dump_verilog_pb_type_ports(fp, port_prefix, 0, cur_pb_type, TRUE, TRUE, FALSE); + /* Print SRAM ports */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + /* connect to reserved BL/WLs ? */ + num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model, cur_sram_orgz_info->type, 0); + /* Get the number of configuration bits required by this MUX */ + num_conf_bits = count_num_conf_bits_one_spice_model(verilog_model, cur_sram_orgz_info->type, 0); + /* Reserved sram ports */ + if ( 0 < num_reserved_conf_bits) { + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, num_reserved_conf_bits - 1, + VERILOG_PORT_INPUT); + fprintf(fp, ",\n"); + } + /* Normal sram ports */ + if (0 < num_conf_bits) { + dump_verilog_sram_ports(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_conf_bits - 1, + VERILOG_PORT_INPUT); + } + /* Dump ports only visible during formal verification*/ + if (0 < num_conf_bits) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_num_sram, + cur_num_sram + num_conf_bits - 1, + VERILOG_PORT_INPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + + /* Local Vdd and gnd*/ + fprintf(fp, ");\n"); + /* Definition ends*/ + + /* Specify inputs are wires */ + pb_type_input_ports = find_pb_type_ports_match_spice_model_port_type(cur_pb_type, SPICE_MODEL_PORT_INPUT, &num_pb_type_input_port); + assert(1 == num_pb_type_input_port); + fprintf(fp, "wire [0:%d] %s__%s;\n", + input_ports[0]->size - 1, port_prefix, pb_type_input_ports[0]->name); + for (i = 0; i < input_ports[0]->size; i++) { + fprintf(fp, "assign %s__%s[%d] = %s__%s_%d_;\n", + port_prefix, pb_type_input_ports[0]->name, i, + port_prefix, pb_type_input_ports[0]->name, i); + } + /* Specify outputs are wires */ + pb_type_output_ports = find_pb_type_ports_match_spice_model_port_type(cur_pb_type, SPICE_MODEL_PORT_OUTPUT, &num_pb_type_output_port); + for (i = 0; i < num_pb_type_output_port; i++) { + fprintf(fp, "wire [0:%d] %s__%s;\n", + output_ports[i]->size - 1, port_prefix, pb_type_output_ports[i]->name); + } + /* Make sure we have the same number outputs */ + assert (num_pb_type_output_port == num_output_port); + for (i = 0; i < num_output_port; i++) { + for (ipin = 0; ipin < output_ports[i]->size; ipin++) { + fprintf(fp, "assign %s__%s_%d_ = %s__%s[%d];\n", + port_prefix, pb_type_output_ports[i]->name, ipin, + port_prefix, pb_type_output_ports[i]->name, ipin); + } + } + + /* Specify SRAM output are wires */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, cur_num_sram, cur_num_sram + num_sram - 1); + + /* Dump ports only visible during formal verification*/ + if ((0 < num_reserved_conf_bits) + || (0 < num_conf_bits)) { + dump_verilog_mem_config_bus(fp, mem_model, cur_sram_orgz_info, + cur_num_sram, num_reserved_conf_bits, num_conf_bits); + + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + dump_verilog_formal_verification_sram_ports_wiring(fp, cur_sram_orgz_info, + cur_num_sram, + cur_num_sram + num_sram - 1); + fprintf(fp, "`endif\n"); + } + + /* + fprintf(fp, "wire [%d:%d] %s_out;\n", + cur_num_sram, cur_num_sram + num_sram - 1, mem_model->prefix); + fprintf(fp, "wire [%d:%d] %s_outb;\n", + cur_num_sram, cur_num_sram + num_sram - 1, mem_model->prefix); + */ + + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Call LUT subckt*/ + fprintf(fp, "%s %s_%d_ (", verilog_model->name, verilog_model->prefix, verilog_model->cnt); + fprintf(fp, "\n"); + /* if we have to add global ports when dumping submodules of LUTs + * otherwise, the port map here does not match that of submodules + * Only dump the global ports belonging to a spice_model + * DISABLE recursive here ! + */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, FALSE)) { + fprintf(fp, ",\n"); + } + /* Connect inputs*/ + /* Connect outputs*/ + fprintf(fp, "//----- Input and output ports -----\n"); + dump_verilog_pb_type_bus_ports(fp, port_prefix, 0, cur_pb_type, FALSE, TRUE); + fprintf(fp, "\n//----- SRAM ports -----\n"); + + /* check */ + assert (num_sram == num_lut_sram + num_mode_sram); + /* Connect srams: TODO: to find the SRAM model used by this Verilog model */ + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + /* TODO: switch depending on the type of configuration circuit */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_lut_sram - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ", "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_lut_sram - 1, + 1, VERILOG_PORT_CONKT); + if (0 < num_mode_sram) { + fprintf(fp, ", "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram + num_lut_sram, cur_num_sram + num_lut_sram + num_mode_sram - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ", "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram + num_lut_sram, cur_num_sram + num_lut_sram + num_mode_sram - 1, + 1, VERILOG_PORT_CONKT); + } + break; + case SPICE_SRAM_MEMORY_BANK: + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_lut_sram - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ", "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_lut_sram - 1, + 1, VERILOG_PORT_CONKT); + if (0 < num_mode_sram) { + fprintf(fp, ", "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram + num_lut_sram, cur_num_sram + num_lut_sram + num_mode_sram - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ", "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram + num_lut_sram, cur_num_sram + num_lut_sram + num_mode_sram - 1, + 1, VERILOG_PORT_CONKT); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + /* vdd should be connected to special global wire gvdd_lut and gnd, + * Every LUT has a special VDD for statistics + */ + fprintf(fp, ");\n"); + + /* Call SRAM subckts only + * when Configuration organization style is memory bank */ + /* No. of SRAMs is different from the number of configuration lines. + * Especially when SRAMs/RRAMs are configured with BL/WLs + */ + num_sram = count_num_sram_bits_one_spice_model(verilog_model, -1); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Call the memory module defined for this SRAM-based MUX! */ + mem_subckt_name = generate_verilog_mem_subckt_name(verilog_model, mem_model, verilog_mem_posfix); + fprintf(fp, "%s %s_%d_ ( ", + mem_subckt_name, mem_subckt_name, verilog_model->cnt); + dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, verilog_model, -1, + mem_model, cur_num_sram, cur_num_sram + num_sram - 1); + fprintf(fp, ");\n"); + /* update the number of memory bits */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_sram); + + /* End of subckt*/ + fprintf(fp, "endmodule\n"); + + /* Comment lines */ + fprintf(fp, "//----- END LUT Verilog module: %s%s_%d_ -----\n\n", + formatted_subckt_prefix, cur_pb_type->name, index); + + /* Update counter */ + verilog_model->cnt++; + + /*Free*/ + my_free(formatted_subckt_prefix); + my_free(input_ports); + my_free(output_ports); + my_free(sram_ports); + my_free(mem_subckt_name); + /* my_free(sram_bits); */ + my_free(port_prefix); + + return; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.h new file mode 100644 index 000000000..81788ad20 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_primitives.h @@ -0,0 +1,15 @@ + + +void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* subckt_prefix, + t_pb_graph_node* prim_pb_graph_node, + int index, + t_spice_model* spice_model); + +void dump_verilog_pb_primitive_lut(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* subckt_prefix, + t_pb_graph_node* prim_pb_graph_node, + int index, + t_spice_model* spice_model); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.c new file mode 100644 index 000000000..f94fe21eb --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.c @@ -0,0 +1,1454 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_rr_graph_utils.h" +#include "fpga_x2p_globals.h" + +/* Include Verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" +#include "verilog_tcl_utils.h" + +/* options for report timing */ +typedef struct s_trpt_opts t_trpt_opts; +struct s_trpt_opts { + char* sdc_dir; + boolean longest_path_only; + boolean report_pb_timing; + boolean report_cb_timing; + boolean report_sb_timing; + boolean report_routing_timing; + boolean print_thru_pins; +}; + +typedef struct s_wireL_cnt t_wireL_cnt; +struct s_wireL_cnt { + int L_wire; + FILE* file_handler; + int cnt; +}; + +/***** Subroutines *****/ +char* gen_verilog_one_routing_report_timing_Lwire_dir_path(char* report_timing_path, + int L_wire) { + char* ret = NULL; + char* formatted_path = format_dir_path(report_timing_path); + + /* The report will be named after L_path*/ + ret = (char*) my_malloc (sizeof(char) * (strlen(formatted_path) + + 1 + strlen(my_itoa(L_wire)) + + 6 + 1)); + + sprintf(ret, + "%sL%d_wire/", + formatted_path, L_wire); + + return ret; +} + +char* gen_verilog_one_routing_report_timing_rpt_name(char* report_timing_path, + int L_wire, + int path_id) { + char* ret = NULL; + char* formatted_path = gen_verilog_one_routing_report_timing_Lwire_dir_path(report_timing_path, L_wire); + + /* The report will be named after L_path*/ + ret = (char*) my_malloc (sizeof(char) * (strlen(formatted_path) + + 1 + strlen(my_itoa(L_wire)) + + 5 + strlen(my_itoa(path_id)) + + 5)); + + sprintf(ret, + "%sL%d_path%d.rpt", + formatted_path, L_wire, path_id); + + return ret; +} + +FILE* create_wireL_report_timing_tcl_file_handler(t_trpt_opts trpt_opts, + int L_wire) { + FILE* fp = NULL; + char* sdc_dir_path = NULL; + char* L_wire_str = (char*) my_malloc(sizeof(char) * (1 + strlen(my_itoa(L_wire)) + 2)); + char* descr = NULL; + char* sdc_fname = NULL; + + sprintf(L_wire_str, "L%d_", L_wire); + + sdc_dir_path = gen_verilog_one_routing_report_timing_Lwire_dir_path(trpt_opts.sdc_dir, L_wire); + + /* Create dir path*/ + create_dir_path(sdc_dir_path); + + /* Create the file handler */ + sdc_fname = my_strcat(sdc_dir_path, L_wire_str); + sdc_fname = my_strcat(sdc_fname, trpt_routing_file_name); + + /* Create a file*/ + fp = fopen(sdc_fname, "w"); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, sdc_fname); + exit(1); + } + + descr = (char*)my_malloc(sizeof(char) * (strlen("Report Timing for L-") + + strlen(my_itoa(L_wire)) + + strlen(" wires") + 1)); + sprintf(descr, "Report Timing for L-%d wires", L_wire); + + /* Generate SDC header */ + dump_verilog_sdc_file_header(fp, descr); + + /* Free */ + my_free(descr); + my_free(sdc_dir_path); + my_free(L_wire_str); + my_free(sdc_fname); + + return fp; +} + +/* Find a wire length in the linked list, + * And return the counter if we found, + * Otherwise, we allocate a new member to the linked list */ +t_llist* get_wire_L_counter_in_llist(t_llist* rr_path_cnt, + t_trpt_opts trpt_opts, + int L_wire, + t_wireL_cnt** ret_cnt) { + t_llist* temp = rr_path_cnt; + t_wireL_cnt* temp_cnt = NULL; + + while (NULL != temp) { + temp_cnt = (t_wireL_cnt*)(temp->dptr); + if (L_wire == temp_cnt->L_wire) { + /* We find it! Return here */ + (*ret_cnt) = temp_cnt; + return rr_path_cnt; + } + /* Go to next */ + temp = temp->next; + } + /* If temp is empty, we have to allocate a new node */ + if (NULL == temp) { + temp = insert_llist_node_before_head(rr_path_cnt); + /* Allocate new wireL */ + temp_cnt = (t_wireL_cnt*)my_malloc(sizeof(t_wireL_cnt)); + /* Initialization */ + temp_cnt->L_wire = L_wire; + temp_cnt->file_handler = create_wireL_report_timing_tcl_file_handler(trpt_opts, L_wire); + temp_cnt->cnt = 0; + temp->dptr = (void*)temp_cnt; + /* Prepare the counter to return */ + (*ret_cnt) = temp_cnt; + } + + return temp; +} + +void fclose_wire_L_file_handler_in_llist(t_llist* rr_path_cnt) { + t_llist* temp = rr_path_cnt; + t_wireL_cnt* temp_cnt = NULL; + + while (NULL != temp) { + temp_cnt = (t_wireL_cnt*)(temp->dptr); + fclose(temp_cnt->file_handler); + /* Go to next */ + temp = temp->next; + } + + return; +} + +void update_wire_L_counter_in_llist(t_llist* rr_path_cnt, + int L_wire, + int path_cnt) { + t_llist* temp = rr_path_cnt; + t_wireL_cnt* temp_cnt = NULL; + + while (NULL != temp) { + temp_cnt = (t_wireL_cnt*)(temp->dptr); + if (L_wire == temp_cnt->L_wire) { + /* We find it! Return here */ + temp_cnt->cnt = path_cnt; + return; + } + /* Go to next */ + temp = temp->next; + } + + /* We must find something! */ + assert (NULL != temp); + + return; +} + +void free_wire_L_llist(t_llist* rr_path_cnt) { + t_llist* temp = rr_path_cnt; + + while (NULL != temp) { + my_free(temp->dptr); + temp->dptr = NULL; + /* Go to next */ + temp = temp->next; + } + + free_llist(rr_path_cnt); + + return; +} + +/* Reporting timing from a SB input to an output + */ +void verilog_generate_one_report_timing_within_sb(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* src_rr_node, + t_rr_node* des_rr_node) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ( (CHANX == src_rr_node->type) || (CHANY == src_rr_node->type) || (OPIN == src_rr_node->type) ); + assert ( (CHANX == des_rr_node->type) || (CHANY == des_rr_node->type) ); + + fprintf(fp, "report_timing -from "); + + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + /* Find which side the ending pin locates, and determine the coordinate */ + dump_verilog_one_sb_routing_pin(fp, cur_sb_info, src_rr_node); + + fprintf(fp, " -to "); + + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + /* Find which side the ending pin locates, and determine the coordinate */ + dump_verilog_one_sb_chan_pin(fp, cur_sb_info, des_rr_node, OUT_PORT); + + fprintf(fp, " -point_to_point"); + fprintf(fp, " -unconstrained"); + + return; +} + + +/* Reporting timing from a SB output to another CB input + */ +void verilog_generate_one_report_timing_sb_to_cb(FILE* fp, + t_sb* src_sb_info, + t_rr_node* src_rr_node, + t_cb* des_cb_info, + t_rr_node* des_rr_node) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ( (CHANX == src_rr_node->type) || (CHANY == src_rr_node->type) ); + assert ( (IPIN == des_rr_node->type) ); + + fprintf(fp, "report_timing -from "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(src_sb_info)); + /* output pin name */ + dump_verilog_one_sb_chan_pin(fp, src_sb_info, + src_rr_node, OUT_PORT); + fprintf(fp, " -to "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_cb_instance_name(des_cb_info)); + /* output pin name */ + fprintf(fp, "%s", + gen_verilog_routing_channel_one_midout_name( des_cb_info, + src_rr_node->ptc_num)); + + fprintf(fp, " -point_to_point"); + fprintf(fp, " -unconstrained"); + + return; +} + +/* Reporting timing from a SB output to another SB input + */ +void verilog_generate_one_report_timing_sb_to_sb(FILE* fp, + t_sb* src_sb_info, + t_rr_node* src_rr_node, + t_sb* des_sb_info, + t_rr_node* des_rr_node) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ( (CHANX == src_rr_node->type) || (CHANY == src_rr_node->type) ); + assert ( (CHANX == des_rr_node->type) || (CHANY == des_rr_node->type) ); + + fprintf(fp, "report_timing -from "); + + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(src_sb_info)); + /* Find which side the ending pin locates, and determine the coordinate */ + dump_verilog_one_sb_chan_pin(fp, src_sb_info, src_rr_node, OUT_PORT); + + fprintf(fp, " -to "); + + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(des_sb_info)); + /* Find which side the ending pin locates, and determine the coordinate */ + dump_verilog_one_sb_chan_pin(fp, des_sb_info, des_rr_node, IN_PORT); + + fprintf(fp, " -point_to_point"); + fprintf(fp, " -unconstrained"); + + return; +} + + +void build_ending_rr_node_for_one_sb_wire(t_rr_node* wire_rr_node, + t_rr_node* LL_rr_node, + int* num_end_rr_nodes, + t_rr_node*** end_rr_node) { + int x_end, y_end; + int inode, iedge; + int cur_node = 0; + t_cb* next_cb = NULL; + t_sb* next_sb = NULL; + + /* Initialization */ + (*num_end_rr_nodes) = 0; + + /* Find where the destination pin belongs to */ + get_chan_rr_node_end_coordinate(wire_rr_node, &x_end, &y_end); + + for (iedge = 0; iedge < wire_rr_node->num_edges; iedge++) { + inode = wire_rr_node->edges[iedge]; + /* Build a list of ending rr_node we care */ + /* Find the SB/CB block that it belongs to */ + switch (LL_rr_node[inode].type) { + case IPIN: + /* Get the coordinate of ending CB */ + next_cb = get_chan_rr_node_ending_cb(wire_rr_node, &(LL_rr_node[inode])); + /* This will not be the longest path unless the cb is close to the ending SB */ + if ((next_cb->x != x_end) || (next_cb->y != y_end)) { + break; + } + (*num_end_rr_nodes)++; + break; + case CHANX: + case CHANY: + /* Get the coordinate of ending SB */ + next_sb = get_chan_rr_node_ending_sb(wire_rr_node, &(LL_rr_node[inode])); + /* This will not be the longest path unless the cb is close to the ending SB */ + if ((next_sb->x != x_end) || (next_sb->y != y_end)) { + break; + } + (*num_end_rr_nodes)++; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of ending point rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + } + + /* Malloc */ + (*end_rr_node) = (t_rr_node**) my_calloc((*num_end_rr_nodes), sizeof(t_rr_node*)); + + cur_node = 0; + for (iedge = 0; iedge < wire_rr_node->num_edges; iedge++) { + inode = wire_rr_node->edges[iedge]; + /* Build a list of ending rr_node we care */ + /* Find the SB/CB block that it belongs to */ + switch (LL_rr_node[inode].type) { + case IPIN: + /* Get the coordinate of ending CB */ + next_cb = get_chan_rr_node_ending_cb(wire_rr_node, &(LL_rr_node[inode])); + /* This will not be the longest path unless the cb is close to the ending SB */ + if ((next_cb->x != x_end) || (next_cb->y != y_end)) { + break; + } + (*end_rr_node)[cur_node] = &(LL_rr_node[inode]); + cur_node++; + break; + case CHANX: + case CHANY: + /* Get the coordinate of ending SB */ + next_sb = get_chan_rr_node_ending_sb(wire_rr_node, &(LL_rr_node[inode])); + /* This will not be the longest path unless the cb is close to the ending SB */ + if ((next_sb->x != x_end) || (next_sb->y != y_end)) { + break; + } + (*end_rr_node)[cur_node] = &(LL_rr_node[inode]); + cur_node++; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of ending point rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + } + + /* Check */ + assert( (*num_end_rr_nodes) == cur_node); + + return; +} + +/* Generate the report timing commands for a through wire across two SBs + * This includes a sb-to-sb wire and a within-sb wire + * -------- -------- + * | src_sb | |des_sb | + * | |----->|------>| + * |[x-1][y]| | [x][y]| + * -------- -------- + */ +void verilog_generate_report_timing_one_sb_thru_segments(FILE* fp, + t_sb* src_sb_info, + t_rr_node* src_rr_node, + t_sb* des_sb_info, + t_rr_node* des_rr_node, + char* rpt_name) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + + /* Report timing for the downstream segements, from a SB output to an adjacent SB input */ + verilog_generate_one_report_timing_sb_to_sb(fp, src_sb_info, src_rr_node, + des_sb_info, des_rr_node); + + if (NULL != rpt_name) { + fprintf(fp, " >> %s\n", rpt_name); + } else { + fprintf(fp, "\n"); + } + + /* Report timing for the downstream segements, within a SB */ + verilog_generate_one_report_timing_within_sb(fp, des_sb_info, + des_rr_node, des_rr_node); + + if (NULL != rpt_name) { + fprintf(fp, " >> %s\n", rpt_name); + } else { + fprintf(fp, "\n"); + } + + return; +} + +/* Generate the report timing commands for a through wire across two SBs + * This includes either a sb-to-sb wire or a sb-to-cb wire + * -------- ------- + * | src_sb | |des_cb | + * | |----->|------>| + * |[x-1][y]| | [x][y]| + * -------- ------- + */ +void verilog_generate_report_timing_one_sb_ending_segments(FILE* fp, + t_sb* src_sb_info, + t_rr_node* src_rr_node, + t_rr_node* des_rr_node, + char* rpt_name) { + t_cb* next_cb = NULL; + t_sb* next_sb = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + switch (des_rr_node->type) { + case IPIN: + /* Get the coordinate of ending CB */ + next_cb = get_chan_rr_node_ending_cb(src_rr_node, des_rr_node); + verilog_generate_one_report_timing_sb_to_cb(fp, src_sb_info, src_rr_node, + next_cb, des_rr_node); + break; + case CHANX: + case CHANY: + /* Get the coordinate of ending SB */ + next_sb = get_chan_rr_node_ending_sb(src_rr_node, des_rr_node); + verilog_generate_one_report_timing_sb_to_sb(fp, src_sb_info, src_rr_node, + next_sb, src_rr_node); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of ending point rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + + if (NULL != rpt_name) { + fprintf(fp, " >> %s\n", rpt_name); + } else { + fprintf(fp, "\n"); + } + + return; +} + +/* Print the pins of SBs that a routing wire will go through + * from the src_rr_node to the des_rr_node + */ +void dump_verilog_one_sb_wire_segemental_report_timing(FILE* fp, + t_syn_verilog_opts fpga_verilog_opts, + t_sb* src_sb_info, + t_rr_node* drive_rr_node, + t_rr_node* src_rr_node, + t_rr_node* des_rr_node, + int path_cnt) { + int L_wire; + int ix, iy; + int cur_sb_x, cur_sb_y; + int end_sb_x, end_sb_y; + t_cb* next_cb = NULL; + t_sb* next_sb = NULL; + char* rpt_name = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ((INC_DIRECTION == src_rr_node->direction) + ||(DEC_DIRECTION == src_rr_node->direction)); + assert ((CHANX == src_rr_node->type) + ||(CHANY == src_rr_node->type)); + + L_wire = get_rr_node_wire_length(src_rr_node); + + /* Get report name */ + rpt_name = gen_verilog_one_routing_report_timing_rpt_name(fpga_verilog_opts.report_timing_path, + L_wire, path_cnt); + + /* Start printing report timing info */ + fprintf(fp, "# L%d wire, Path ID: %d\n", + L_wire, + path_cnt); + /* Report timing for the SB MUX delay, from the drive_rr_node to the wire_rr_node */ + verilog_generate_one_report_timing_within_sb(fp, src_sb_info, + drive_rr_node, + src_rr_node); + if (NULL != rpt_name) { + fprintf(fp, " > %s\n", rpt_name); + } else { + fprintf(fp, "\n"); + } + + /* Switch depends on the type of des_rr_node */ + switch(des_rr_node->type) { + /* Range of SBs that on the path + * --------- + * | | + * | des_sb | + * | [x][y] | + * --------- + * /|\ + * | + * --------- + * | | + * | thru_cb | + * | | + * --------- + * /|\ + * | + * -------- ------- --------- ------- -------- + * | | | | | | | | | | + * | des_sb |<---|thru_cb|<---| src_sb |--->|thru_cb|--->| des_sb | + * |[x-1][y]| | [x][y]| | | | [x][y]| |[x][y] | + * -------- ------- --------- ------- -------- + * | + * \|/ + * --------- + * | | + * | thru_cb | + * | | + * --------- + * | + * \|/ + * --------- + * | | + * | des_sb | + * | [x][y-1]| + * --------- + */ + case IPIN: + /* Get the coordinate of ending CB */ + next_cb = get_chan_rr_node_ending_cb(src_rr_node, des_rr_node); + assert(next_cb->type == src_rr_node->type); + /* 4 cases: */ + if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + end_sb_x = next_cb->x; + end_sb_y = next_cb->y; + } else if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + end_sb_x = next_cb->x; + end_sb_y = next_cb->y; + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + end_sb_x = next_cb->x - 1; + end_sb_y = next_cb->y; + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + end_sb_x = next_cb->x; + end_sb_y = next_cb->y - 1; + } + break; + /* Range of SBs that on the path + * --------- + * | | + * | des_sb | + * | [x][y+1]| + * --------- + * /|\ + * | + * --------- + * | | + * | thru_sb | + * | | + * --------- + * /|\ + * | + * -------- ------- --------- ------- -------- + * | | | | | | | | | | + * | des_sb |<---|thru_sb|<---| src_sb |--->|thru_sb|--->| des_sb | + * |[x-1][y]| | [x][y]| | | | [x][y]| |[x+1][y]| + * -------- ------- --------- ------- -------- + * | + * \|/ + * --------- + * | | + * | thru_sb | + * | | + * --------- + * | + * \|/ + * --------- + * | | + * | des_sb | + * | [x][y-1]| + * --------- + */ + case CHANX: + case CHANY: + /* Get the coordinate of ending CB */ + next_sb = get_chan_rr_node_ending_sb(src_rr_node, des_rr_node); + end_sb_x = next_sb->x; + end_sb_y = next_sb->y; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of rr_node!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get the base coordinate of src_sb */ + cur_sb_x = src_sb_info->x; + cur_sb_y = src_sb_info->y; + /* 4 cases: */ + if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + /* Follow the graph above, go through X channel */ + for (ix = src_sb_info->x; ix < end_sb_x; ix++) { + /* If this is the ending point, we add a ending segment */ + if (ix == end_sb_x - 1) { + verilog_generate_report_timing_one_sb_ending_segments(fp, + &(sb_info[ix][cur_sb_y]), src_rr_node, + des_rr_node, + rpt_name); + + continue; + } + /* Report timing for the downstream segements, from a SB output to an adjacent CB input */ + verilog_generate_report_timing_one_sb_thru_segments(fp, + &(sb_info[ix][cur_sb_y]), src_rr_node, + &(sb_info[ix + 1][cur_sb_y]), src_rr_node, + rpt_name); + } + } else if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + /* Follow the graph above, go through Y channel */ + for (iy = src_sb_info->y; iy < end_sb_y; iy++) { + /* If this is the ending point, we add a ending segment */ + if (iy == end_sb_y - 1) { + verilog_generate_report_timing_one_sb_ending_segments(fp, + &(sb_info[cur_sb_x][iy]), src_rr_node, + des_rr_node, + rpt_name); + continue; + } + /* Report timing for the downstream segements, from a SB output to an adjacent CB input */ + verilog_generate_report_timing_one_sb_thru_segments(fp, + &(sb_info[cur_sb_x][iy]), src_rr_node, + &(sb_info[cur_sb_x][iy + 1]), src_rr_node, + rpt_name); + } + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + /* Follow the graph above, go through X channel */ + for (ix = src_sb_info->x - 1; ix > end_sb_x; ix--) { + /* If this is the ending point, we add a ending segment */ + if (ix == end_sb_x + 1) { + verilog_generate_report_timing_one_sb_ending_segments(fp, + &(sb_info[ix][cur_sb_y]), src_rr_node, + des_rr_node, + rpt_name); + continue; + } + /* Report timing for the downstream segements, from a SB output to an adjacent CB input */ + verilog_generate_report_timing_one_sb_thru_segments(fp, + &(sb_info[ix][cur_sb_y]), src_rr_node, + &(sb_info[ix - 1][cur_sb_y]), src_rr_node, + rpt_name); + } + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + /* Follow the graph above, go through Y channel */ + for (iy = src_sb_info->y - 1; iy > end_sb_y; iy--) { + /* If this is the ending point, we add a ending segment */ + if (iy == end_sb_y + 1) { + verilog_generate_report_timing_one_sb_ending_segments(fp, + &(sb_info[cur_sb_x][iy]), src_rr_node, + des_rr_node, + rpt_name); + continue; + } + /* Report timing for the downstream segements, from a SB output to an adjacent CB input */ + verilog_generate_report_timing_one_sb_thru_segments(fp, + &(sb_info[cur_sb_x][iy]), src_rr_node, + &(sb_info[cur_sb_x][iy - 1]), src_rr_node, + rpt_name); + } + } + + /* Free */ + my_free(rpt_name); + + return; +} + + +/* Print the pins of SBs that a routing wire will go through + * from the src_rr_node to the des_rr_node + */ +void dump_verilog_sb_through_routing_pins(FILE* fp, + t_sb* src_sb_info, + t_rr_node* src_rr_node, + t_rr_node* des_rr_node) { + int ix, iy; + int cur_sb_x, cur_sb_y; + int end_sb_x, end_sb_y; + t_cb* next_cb; + t_sb* next_sb; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ((INC_DIRECTION == src_rr_node->direction) + ||(DEC_DIRECTION == src_rr_node->direction)); + assert ((CHANX == src_rr_node->type) + ||(CHANY == src_rr_node->type)); + + /* Switch depends on the type of des_rr_node */ + switch(des_rr_node->type) { + /* Range of SBs that on the path + * --------- + * | | + * | des_sb | + * | [x][y] | + * --------- + * /|\ + * | + * --------- + * | | + * | thru_cb | + * | | + * --------- + * /|\ + * | + * -------- ------- --------- ------- -------- + * | | | | | | | | | | + * | des_sb |<---|thru_cb|<---| src_sb |--->|thru_cb|--->| des_sb | + * |[x-1][y]| | [x][y]| | | | [x][y]| |[x][y] | + * -------- ------- --------- ------- -------- + * | + * \|/ + * --------- + * | | + * | thru_cb | + * | | + * --------- + * | + * \|/ + * --------- + * | | + * | des_sb | + * | [x][y-1]| + * --------- + */ + case IPIN: + /* Get the coordinate of ending CB */ + next_cb = get_chan_rr_node_ending_cb(src_rr_node, des_rr_node); + assert(next_cb->type == src_rr_node->type); + /* 4 cases: */ + if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + end_sb_x = next_cb->x; + end_sb_y = next_cb->y; + } else if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + end_sb_x = next_cb->x; + end_sb_y = next_cb->y; + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + end_sb_x = next_cb->x - 1; + end_sb_y = next_cb->y; + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + end_sb_x = next_cb->x; + end_sb_y = next_cb->y - 1; + } + break; + /* Range of SBs that on the path + * --------- + * | | + * | des_sb | + * | [x][y+1]| + * --------- + * /|\ + * | + * --------- + * | | + * | thru_sb | + * | | + * --------- + * /|\ + * | + * -------- ------- --------- ------- -------- + * | | | | | | | | | | + * | des_sb |<---|thru_sb|<---| src_sb |--->|thru_sb|--->| des_sb | + * |[x-1][y]| | [x][y]| | | | [x][y]| |[x+1][y]| + * -------- ------- --------- ------- -------- + * | + * \|/ + * --------- + * | | + * | thru_sb | + * | | + * --------- + * | + * \|/ + * --------- + * | | + * | des_sb | + * | [x][y-1]| + * --------- + */ + case CHANX: + case CHANY: + /* Get the coordinate of ending CB */ + next_sb = get_chan_rr_node_ending_sb(src_rr_node, des_rr_node); + end_sb_x = next_sb->x; + end_sb_y = next_sb->y; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of rr_node!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get the base coordinate of src_sb */ + cur_sb_x = src_sb_info->x; + cur_sb_y = src_sb_info->y; + /* 4 cases: */ + if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + /* Follow the graph above, go through X channel */ + for (ix = src_sb_info->x + 1; ix < end_sb_x; ix++) { + /* Print an IN_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[ix][cur_sb_y])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[ix][cur_sb_y]), src_rr_node, IN_PORT); + /* Print an OUT_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[ix][cur_sb_y])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[ix][cur_sb_y]), src_rr_node, OUT_PORT); + } + } else if ((INC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + /* Follow the graph above, go through Y channel */ + for (iy = src_sb_info->y + 1; iy < end_sb_y; iy++) { + /* Print an IN_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[cur_sb_x][iy])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[cur_sb_x][iy]), src_rr_node, IN_PORT); + /* Print an OUT_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[cur_sb_x][iy])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[cur_sb_x][iy]), src_rr_node, OUT_PORT); + } + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANX == src_rr_node->type)) { + /* Follow the graph above, go through X channel */ + for (ix = src_sb_info->x - 1; ix > end_sb_x; ix--) { + /* Print an IN_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[ix][cur_sb_y])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[ix][cur_sb_y]), src_rr_node, IN_PORT); + /* Print an OUT_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[ix][cur_sb_y])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[ix][cur_sb_y]), src_rr_node, OUT_PORT); + } + } else if ((DEC_DIRECTION == src_rr_node->direction) + &&(CHANY == src_rr_node->type)) { + /* Follow the graph above, go through Y channel */ + for (iy = src_sb_info->y - 1; iy > end_sb_y; iy--) { + /* Print an IN_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[cur_sb_x][iy])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[cur_sb_x][iy]), src_rr_node, IN_PORT); + /* Print an OUT_PORT*/ + fprintf(fp, " "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(&sb_info[cur_sb_x][iy])); + dump_verilog_one_sb_chan_pin(fp, &(sb_info[cur_sb_x][iy]), src_rr_node, OUT_PORT); + } + } + + return; +} + +/* Report timing for a routing wire, + * Support uni-directional routing architecture + * Each routing wire start from an OPIN + * We check each fan-out to find all possible ending point: + * An ending point is supposed to be an OPIN or CHANX or CHANY + */ +void verilog_generate_one_routing_wire_report_timing(FILE* fp, + t_trpt_opts sdc_opts, + int L_wire, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int iedge, jedge, inode; + int track_idx; + int path_cnt = 0; + t_sb* next_sb = NULL; + t_cb* next_cb = NULL; + int x_end, y_end; + boolean sb_dumped = FALSE; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + assert( ( CHANX == wire_rr_node->type ) + || ( CHANY == wire_rr_node->type )); + track_idx = wire_rr_node->ptc_num; + + /* We only care a specific length of wires */ + if (L_wire != (abs(wire_rr_node->xlow - wire_rr_node->xhigh + wire_rr_node->ylow - wire_rr_node->yhigh) + 1)) { + return; + } + + /* Find the starting points */ + for (iedge = 0; iedge < wire_rr_node->num_drive_rr_nodes; iedge++) { + sb_dumped = FALSE; + /* Find the ending points*/ + for (jedge = 0; jedge < wire_rr_node->num_edges; jedge++) { + /* Find where the destination pin belongs to */ + get_chan_rr_node_end_coordinate(wire_rr_node, &x_end, &y_end); + /* Reciever could be IPIN or CHANX or CHANY */ + inode = wire_rr_node->edges[jedge]; + /* Find the SB/CB block that it belongs to */ + switch (LL_rr_node[inode].type) { + case IPIN: + /* Get the coordinate of ending CB */ + next_cb = get_chan_rr_node_ending_cb(wire_rr_node, &(LL_rr_node[inode])); + /* This will not be the longest path unless the cb is close to the ending SB */ + if ((TRUE == sdc_opts.longest_path_only) + && ((next_cb->x != x_end) || (next_cb->y != y_end))) { + continue; + } + /* Driver could be OPIN or CHANX or CHANY, + * and it must be in the cur_sb_info + */ + /* Start printing report timing info */ + fprintf(fp, "# L%d wire, Path %d\n", + abs(wire_rr_node->xlow - wire_rr_node->xhigh + wire_rr_node->ylow - wire_rr_node->yhigh) + 1, + path_cnt); + fprintf(fp, "report_timing -from "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + /* output pin name */ + dump_verilog_one_sb_routing_pin(fp, cur_sb_info, + wire_rr_node->drive_rr_nodes[iedge]); + fprintf(fp, " -to "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_cb_instance_name(next_cb)); + /* output pin name */ + fprintf(fp, "%s", + gen_verilog_routing_channel_one_midout_name( next_cb, + track_idx)); + /* Print through pins */ + if (TRUE == sdc_opts.print_thru_pins) { + fprintf(fp, " -through_pins "); + dump_verilog_sb_through_routing_pins(fp, cur_sb_info, wire_rr_node, &(LL_rr_node[inode])); + } else { + fprintf(fp, " -point_to_point\n"); + } + fprintf(fp, " -unconstrained\n"); + path_cnt++; + break; + case CHANX: + case CHANY: + /* Get the coordinate of ending SB */ + next_sb = get_chan_rr_node_ending_sb(wire_rr_node, &(LL_rr_node[inode])); + /* This will not be the longest path unless the cb is close to the ending SB */ + if ((TRUE == sdc_opts.longest_path_only) + && ((next_sb->x != x_end) || (next_sb->y != y_end))) { + continue; + } + if (TRUE == sb_dumped) { + continue; + } + /* Driver could be OPIN or CHANX or CHANY, + * and it must be in the cur_sb_info + */ + /* Start printing report timing info */ + fprintf(fp, "# L%d wire, Path %d\n", + abs(wire_rr_node->xlow - wire_rr_node->xhigh + wire_rr_node->ylow - wire_rr_node->yhigh) + 1, + path_cnt); + fprintf(fp, "report_timing -from "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + /* output pin name */ + dump_verilog_one_sb_routing_pin(fp, cur_sb_info, + wire_rr_node->drive_rr_nodes[iedge]); + fprintf(fp, " -to "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(next_sb)); + /* Find which side the ending pin locates, and determine the coordinate */ + dump_verilog_one_sb_routing_pin(fp, next_sb, + wire_rr_node); + /* Print through pins */ + if (TRUE == sdc_opts.print_thru_pins) { + fprintf(fp, " -through_pins "); + dump_verilog_sb_through_routing_pins(fp, cur_sb_info, + wire_rr_node, &(LL_rr_node[inode])); + } else { + fprintf(fp, " -point_to_point\n"); + } + fprintf(fp, " -unconstrained\n"); + path_cnt++; + /* Set the flag */ + sb_dumped = TRUE; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of ending point rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + /* Get the user-constrained delay of this routing wire */ + /* Find the pins/ports of SBs that this wire may across */ + /* Output the Report Timing commands */ + } + } + + return; +} + +/* Generate report timing for each routing wires/segments */ +void verilog_generate_routing_wires_report_timing(FILE* fp, + t_trpt_opts sdc_opts, + int L_wire, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int ix, iy; + int side, itrack; + t_sb* cur_sb_info = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* We start from a SB[x][y] */ + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 0; iy < (ny + 1); iy++) { + cur_sb_info = &(sb_info[ix][iy]); + for (side = 0; side < cur_sb_info->num_sides; side++) { + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + assert((CHANX == cur_sb_info->chan_rr_node[side][itrack]->type) + ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); + /* We only care the output port and it should indicate a SB mux */ + if ( (OUT_PORT != cur_sb_info->chan_rr_node_direction[side][itrack]) + || (FALSE != check_drive_rr_node_imply_short(*cur_sb_info, cur_sb_info->chan_rr_node[side][itrack], side))) { + continue; + } + /* Bypass if we have only 1 driving node */ + if (1 == cur_sb_info->chan_rr_node[side][itrack]->num_drive_rr_nodes) { + continue; + } + /* Reach here, it means a valid starting point of a routing wire */ + verilog_generate_one_routing_wire_report_timing(fp, sdc_opts, L_wire, &(sb_info[ix][iy]), + cur_sb_info->chan_rr_node[side][itrack], + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + } + } + } + + return; +} + +void verilog_generate_sb_report_timing(t_sram_orgz_info* cur_sram_orgz_info, + t_trpt_opts sdc_opts, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts) { + char* sdc_fname = NULL; + FILE* fp = NULL; + int iseg; + int L_max = OPEN; + + /* Create the file handler */ + sdc_fname = my_strcat(format_dir_path(sdc_opts.sdc_dir), trpt_sb_file_name); + + /* Create a file*/ + fp = fopen(sdc_fname, "w"); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, sdc_fname); + exit(1); + } + + /* Generate SDC header */ + dump_verilog_sdc_file_header(fp, "Report Timing for Switch blocks"); + + vpr_printf(TIO_MESSAGE_INFO, + "Generating TCL script to report timing for Switch Blocks: %s\n", + sdc_fname); + /* Find the longest wires: we only care defined length of wires? */ + for (iseg = 0; iseg < arch.num_segments; iseg++) { + /* Bypass zero frequency sgements */ + if (0 == arch.Segments[iseg].frequency) { + continue; + } + if ((OPEN == L_max) || (L_max < arch.Segments[iseg].length)) { + L_max = arch.Segments[iseg].length; + } + } + /* In some case, FPGA array size is smaller than any segments. + * Therefore, to be strict non-segment timing will be reported + * We added the FPGA array size for report timing + */ + if ((L_max > nx) && (L_max > ny)) { + if (nx != ny) { + verilog_generate_routing_wires_report_timing(fp, sdc_opts, + nx, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + verilog_generate_routing_wires_report_timing(fp, sdc_opts, + ny, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } else { + verilog_generate_routing_wires_report_timing(fp, sdc_opts, + nx, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + } else { + /* We only care defined length of wires? */ + for (iseg = 0; iseg < arch.num_segments; iseg++) { + /* Bypass zero frequency sgements */ + if (0 == arch.Segments[iseg].frequency) { + continue; + } + verilog_generate_routing_wires_report_timing(fp, sdc_opts, arch.Segments[iseg].length, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + } + + /* close file*/ + fclose(fp); + + return; +} + +/* Report timing for a routing wire divided in segements, + * Support uni-directional routing architecture + * Each routing wire start from an OPIN + * We check each fan-out to find all possible ending point: + * An ending point is supposed to be an OPIN or CHANX or CHANY + * We consider the farest ending point and report timing for each segements on the path + * We output TCL commands to sum up the segmental delay + */ +void verilog_generate_one_routing_segmental_report_timing(FILE* fp, + t_syn_verilog_opts fpga_verilog_opts, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + int* path_cnt) { + int iedge, jedge; + int num_end_rr_nodes = 0; + t_rr_node** end_rr_node = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + assert( ( CHANX == wire_rr_node->type ) + || ( CHANY == wire_rr_node->type )); + + /* Find the farest ending points!*/ + build_ending_rr_node_for_one_sb_wire(wire_rr_node, LL_rr_node, + &num_end_rr_nodes, &end_rr_node); + + /* Find the starting points */ + for (iedge = 0; iedge < wire_rr_node->num_drive_rr_nodes; iedge++) { + /* Find the ending points*/ + for (jedge = 0; jedge < num_end_rr_nodes; jedge++) { + /* Report timing */ + dump_verilog_one_sb_wire_segemental_report_timing(fp, fpga_verilog_opts, + cur_sb_info, + wire_rr_node->drive_rr_nodes[iedge], + wire_rr_node, + end_rr_node[jedge], + *path_cnt); + /* Update counter */ + (*path_cnt)++; + } + } + + /* Free */ + my_free(end_rr_node); + + return; +} + +void verilog_generate_routing_report_timing(t_sram_orgz_info* cur_sram_orgz_info, + t_trpt_opts trpt_opts, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts) { + FILE* fp = NULL; + int ix, iy; + int L_wire; + int side, itrack; + t_sb* cur_sb_info = NULL; + t_llist* rr_path_cnt = NULL; + t_wireL_cnt* wireL_cnt = NULL; + int path_cnt = 0; + + vpr_printf(TIO_MESSAGE_INFO, + "Generating TCL script to report timing for routing wires\n"); + + /* We start from a SB[x][y] */ + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 0; iy < (ny + 1); iy++) { + cur_sb_info = &(sb_info[ix][iy]); + for (side = 0; side < cur_sb_info->num_sides; side++) { + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + assert((CHANX == cur_sb_info->chan_rr_node[side][itrack]->type) + ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); + /* We only care the output port and it should indicate a SB mux */ + if ( (OUT_PORT != cur_sb_info->chan_rr_node_direction[side][itrack]) + || (FALSE != check_drive_rr_node_imply_short(*cur_sb_info, cur_sb_info->chan_rr_node[side][itrack], side))) { + continue; + } + /* Bypass if we have only 1 driving node */ + if (1 == cur_sb_info->chan_rr_node[side][itrack]->num_drive_rr_nodes) { + continue; + } + /* Check if L_wire exists in the linked list */ + L_wire = get_rr_node_wire_length(cur_sb_info->chan_rr_node[side][itrack]); + /* Get counter */ + rr_path_cnt = get_wire_L_counter_in_llist(rr_path_cnt, trpt_opts, L_wire, &wireL_cnt); + path_cnt = wireL_cnt->cnt; + fp = wireL_cnt->file_handler; + /* This is a new L-wire, create the file handler and the mkdir command to the TCL script */ + if (0 == path_cnt) { + fprintf(fp, "exec mkdir -p %s\n", + gen_verilog_one_routing_report_timing_Lwire_dir_path(fpga_verilog_opts.report_timing_path, L_wire)); + } + /* Restore the disable_timing for the SB outputs on the path */ + fprintf(fp, "# Restore disable timing for the following Switch Block output:\n"); + restore_disable_timing_one_sb_output(fp, + cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack]); + fprintf(fp, "# Report timing for all the paths using this output:\n"); + /* Dump report_timing command */ + verilog_generate_one_routing_segmental_report_timing(fp, fpga_verilog_opts, + cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack], + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, &path_cnt); + /* Disable the timing again */ + fprintf(fp, "# Set disable timing for the following Switch Block output:\n"); + set_disable_timing_one_sb_output(fp, + cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack]); + /* Update the wire L*/ + update_wire_L_counter_in_llist(rr_path_cnt, L_wire, path_cnt); + } + } + } + } + + /* close file*/ + fclose_wire_L_file_handler_in_llist(rr_path_cnt); + + /* Free */ + free_wire_L_llist(rr_path_cnt); + + return; +} + +/* Output a log file to guide routing report_timing */ +void verilog_generate_report_timing(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts) { + t_trpt_opts trpt_opts; + + /* Initialize */ + trpt_opts.report_pb_timing = TRUE; + trpt_opts.report_sb_timing = FALSE; + trpt_opts.report_cb_timing = TRUE; + trpt_opts.report_routing_timing = TRUE; + trpt_opts.longest_path_only = TRUE; + trpt_opts.print_thru_pins = TRUE; + trpt_opts.sdc_dir = my_strdup(sdc_dir); + + /* Part 1. Report timing for Programmable Logic Blocks */ + + /* Part 2. Report timing for Connection Blocks */ + + /* Part 3. Report timing for Switch Blocks */ + if (TRUE == trpt_opts.report_sb_timing) { + verilog_generate_sb_report_timing(cur_sram_orgz_info, trpt_opts, + arch, routing_arch, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + fpga_verilog_opts); + } + + /* Part 3. Report timing for routing segments of SB wires */ + if (TRUE == trpt_opts.report_routing_timing) { + verilog_generate_routing_report_timing(cur_sram_orgz_info, trpt_opts, + arch, routing_arch, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + fpga_verilog_opts); + } + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.h new file mode 100644 index 000000000..97c7a1b1d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_report_timing.h @@ -0,0 +1,9 @@ + +void verilog_generate_report_timing(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts); + diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c similarity index 80% rename from vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c index 2305058ce..c51e8ebaa 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Include vpr structs*/ #include "util.h" @@ -18,28 +19,35 @@ #include "rr_graph_util.h" #include "rr_graph.h" #include "rr_graph2.h" +#include "route_common.h" #include "vpr_utils.h" /* Include SPICE support headers*/ #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_backannotate_utils.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" /* Include Verilog support headers*/ #include "verilog_global.h" #include "verilog_utils.h" -#include "verilog_lut.h" -#include "verilog_primitives.h" #include "verilog_routing.h" -void dump_verilog_routing_chan_subckt(char* subckt_dir, +void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, int x, int y, t_rr_type chan_type, int LL_num_rr_nodes, t_rr_node* LL_rr_node, t_ivec*** LL_rr_node_indices, - int num_segment, t_segment_inf* segments) { + t_rr_indexed_data* LL_rr_indexed_data, + int num_segment, t_segment_inf* segments, + t_syn_verilog_opts fpga_verilog_opts) { int itrack, iseg, cost_index; char* chan_prefix = NULL; int chan_width = 0; @@ -57,14 +65,16 @@ void dump_verilog_routing_chan_subckt(char* subckt_dir, case CHANX: /* Create file handler */ fp = verilog_create_one_subckt_file(subckt_dir, "Routing Channel - X direction ", chanx_verilog_file_name_prefix, x, y, &fname); - chan_prefix = "chanx"; + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir); /* Comment lines */ fprintf(fp, "//----- Verilog Module of Channel X [%d][%d] -----\n", x, y); break; case CHANY: /* Create file handler */ fp = verilog_create_one_subckt_file(subckt_dir, "Routing Channel - Y direction ", chany_verilog_file_name_prefix, x, y, &fname); - chan_prefix = "chany"; + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir); /* Comment lines */ fprintf(fp, "//----- Verilog Module Channel Y [%d][%d] -----\n", x, y); break; @@ -79,7 +89,8 @@ void dump_verilog_routing_chan_subckt(char* subckt_dir, LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); /* Chan subckt definition */ - fprintf(fp, "module %s_%d__%d_ ( \n", chan_prefix, x, y); + fprintf(fp, "module %s ( \n", + gen_verilog_one_routing_channel_module_name(chan_type, x, y)); fprintf(fp, "\n"); /* dump global ports */ if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { @@ -134,7 +145,7 @@ void dump_verilog_routing_chan_subckt(char* subckt_dir, /* Print segments models*/ for (itrack = 0; itrack < chan_width; itrack++) { cost_index = chan_rr_nodes[itrack]->cost_index; - iseg = rr_indexed_data[cost_index].seg_index; + iseg = LL_rr_indexed_data[cost_index].seg_index; /* Check */ assert((!(iseg < 0))&&(iseg < num_segment)); /* short connecting inputs and outputs: @@ -283,7 +294,7 @@ void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, if (TRUE == dump_port_type) { fprintf(fp, "%s ", verilog_port_type); } - fprintf(fp, " grid_%d__%d__pin_%d__%d__%d_", x, y, height, side, pin_index); + fprintf(fp, "%s", gen_verilog_grid_one_pin_name(x, y, height, side, pin_index, TRUE)); if (TRUE == dump_port_type) { fprintf(fp, ",\n"); } @@ -534,7 +545,8 @@ void dump_verilog_switch_box_chan_port(FILE* fp, * 2. The actual fan-in of cur_rr_node is 0. In this case, * The cur_rr_node need to connected to the drive_rr_node */ -void dump_verilog_switch_box_short_interc(FILE* fp, +void dump_verilog_switch_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, t_sb* cur_sb_info, int chan_side, t_rr_node* cur_rr_node, @@ -626,14 +638,15 @@ void dump_verilog_switch_box_short_interc(FILE* fp, } /* Print the SPICE netlist of multiplexer that drive this rr_node */ -void dump_verilog_switch_box_mux(FILE* fp, +void dump_verilog_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, t_sb* cur_sb_info, int chan_side, t_rr_node* cur_rr_node, int mux_size, t_rr_node** drive_rr_nodes, int switch_index) { - int i, inode, side, index, input_cnt = 0; + int inode, side, index, input_cnt = 0; int grid_x, grid_y; t_spice_model* verilog_model = NULL; int mux_level, path_id, cur_num_sram; @@ -643,6 +656,7 @@ void dump_verilog_switch_box_mux(FILE* fp, int num_mux_reserved_conf_bits = 0; int cur_bl, cur_wl; t_spice_model* mem_model = NULL; + char* mem_subckt_name = NULL; /* Check the file handler*/ if (NULL == fp) { @@ -667,7 +681,13 @@ void dump_verilog_switch_box_mux(FILE* fp, fprintf(fp, "wire [0:%d] %s_size%d_%d_inbus;\n", mux_size - 1, verilog_model->prefix, mux_size, verilog_model->cnt); - + char* name_mux = (char *) my_malloc(sizeof(char)*(strlen(verilog_model->prefix) + 5 + + strlen(my_itoa(mux_size)) + 1 + + strlen(my_itoa(verilog_model->cnt)) + 5)); + sprintf(name_mux, "/%s_size%d_%d_/in", verilog_model->prefix, mux_size, verilog_model->cnt); + char* path_hierarchy = (char *) my_malloc(sizeof(char)*(strlen(gen_verilog_one_sb_instance_name(cur_sb_info)))); + path_hierarchy = gen_verilog_one_sb_instance_name(cur_sb_info); + cur_rr_node->name_mux = my_strcat(path_hierarchy,name_mux); /* Input ports*/ /* Connect input ports to bus */ for (inode = 0; inode < mux_size; inode++) { @@ -715,20 +735,37 @@ void dump_verilog_switch_box_mux(FILE* fp, /* Print SRAMs that configure this MUX */ /* cur_num_sram = sram_verilog_model->cnt; */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, &cur_bl, &cur_wl); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); /* connect to reserved BL/WLs ? */ num_mux_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, mux_size); /* Get the number of configuration bits required by this MUX */ num_mux_conf_bits = count_num_conf_bits_one_spice_model(verilog_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, mux_size); /* Dump the configuration port bus */ - dump_verilog_mux_config_bus(fp, verilog_model, sram_verilog_orgz_info, + dump_verilog_mux_config_bus(fp, verilog_model, cur_sram_orgz_info, mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits); + + /* Dump ports visible only during formal verification */ + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + /* + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_num_sram, + cur_num_sram + num_mux_conf_bits - 1, + VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + */ + dump_verilog_formal_verification_mux_sram_ports_wiring(fp, cur_sram_orgz_info, + verilog_model, mux_size, + cur_num_sram, + cur_num_sram + num_mux_conf_bits - 1); + + fprintf(fp, "`endif\n"); /* Now it is the time print the SPICE netlist of MUX*/ fprintf(fp, "%s_size%d %s_size%d_%d_ (", @@ -736,7 +773,7 @@ void dump_verilog_switch_box_mux(FILE* fp, verilog_model->prefix, mux_size, verilog_model->cnt); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } @@ -749,31 +786,28 @@ void dump_verilog_switch_box_mux(FILE* fp, fprintf(fp, ", "); /* Different design technology requires different configuration bus! */ - dump_verilog_mux_config_bus_ports(fp, verilog_model, sram_verilog_orgz_info, + dump_verilog_mux_config_bus_ports(fp, verilog_model, cur_sram_orgz_info, mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits); fprintf(fp, ");\n"); /* Configuration bits for this MUX*/ - path_id = -1; + path_id = DEFAULT_PATH_ID; for (inode = 0; inode < mux_size; inode++) { if (drive_rr_nodes[inode] == &(rr_node[cur_rr_node->prev_node])) { - path_id = inode; + path_id = inode; + cur_rr_node->id_path = inode; break; } } - if (!((-1 != path_id)&&(path_id < mux_size))) { - assert((-1 != path_id)&&(path_id < mux_size)); - } - /* Depend on both technology and structure of this MUX*/ switch (verilog_model->design_tech) { case SPICE_MODEL_DESIGN_CMOS: decode_cmos_mux_sram_bits(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; case SPICE_MODEL_DESIGN_RRAM: - decode_verilog_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); + decode_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; default: vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", @@ -808,28 +842,27 @@ void dump_verilog_switch_box_mux(FILE* fp, __FILE__, __LINE__, verilog_model->name); } - /* Store the configuraion bit to linked-list */ - add_mux_conf_bits_to_llist(mux_size, sram_verilog_orgz_info, - num_mux_sram_bits, mux_sram_bits, - verilog_model); - - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); /* Dump sram modules */ switch (verilog_model->design_tech) { case SPICE_MODEL_DESIGN_CMOS: - /* SRAM-based MUX required dumping SRAMs! */ - for (i = 0; i < num_mux_sram_bits; i++) { - dump_verilog_mux_sram_submodule(fp, sram_verilog_orgz_info, verilog_model, mux_size, - mem_model); /* use the mem_model in sram_verilog_orgz_info */ - } + /* Call the memory module defined for this SRAM-based MUX! */ + mem_subckt_name = generate_verilog_mux_subckt_name(verilog_model, mux_size, verilog_mem_posfix); + fprintf(fp, "%s %s_%d_ ( ", + mem_subckt_name, mem_subckt_name, verilog_model->cnt); + dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, verilog_model, mux_size, mem_model, + cur_num_sram, cur_num_sram + num_mux_conf_bits - 1); + fprintf(fp, ");\n"); + /* update the number of memory bits */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); break; case SPICE_MODEL_DESIGN_RRAM: /* RRAM-based MUX does not need any SRAM dumping * But we have to get the number of configuration bits required by this MUX * and update the number of memory bits */ - update_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info, cur_num_sram + num_mux_conf_bits); - update_sram_orgz_info_num_blwl(sram_verilog_orgz_info, + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, cur_bl + num_mux_conf_bits, cur_wl + num_mux_conf_bits); break; @@ -844,12 +877,14 @@ void dump_verilog_switch_box_mux(FILE* fp, /* Free */ my_free(mux_sram_bits); + my_free(mem_subckt_name); return; } /* Count the number of configuration bits of a rr_node*/ -int count_verilog_switch_box_interc_conf_bits(t_sb cur_sb_info, int chan_side, +int count_verilog_switch_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb cur_sb_info, int chan_side, t_rr_node* cur_rr_node) { int num_conf_bits = 0; int switch_idx = 0; @@ -877,14 +912,15 @@ int count_verilog_switch_box_interc_conf_bits(t_sb cur_sb_info, int chan_side, assert(-1 < switch_idx); assert(SPICE_MODEL_MUX == switch_inf[switch_idx].spice_model->type); num_conf_bits = count_num_conf_bits_one_spice_model(switch_inf[switch_idx].spice_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, num_drive_rr_nodes); return num_conf_bits; } } /* Count the number of reserved configuration bits of a rr_node*/ -int count_verilog_switch_box_interc_reserved_conf_bits(t_sb cur_sb_info, int chan_side, +int count_verilog_switch_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb cur_sb_info, int chan_side, t_rr_node* cur_rr_node) { int num_reserved_conf_bits = 0; int switch_idx = 0; @@ -913,14 +949,15 @@ int count_verilog_switch_box_interc_reserved_conf_bits(t_sb cur_sb_info, int cha assert(SPICE_MODEL_MUX == switch_inf[switch_idx].spice_model->type); num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(switch_inf[switch_idx].spice_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, num_drive_rr_nodes); return num_reserved_conf_bits; } } -void dump_verilog_switch_box_interc(FILE* fp, +void dump_verilog_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, t_sb* cur_sb_info, int chan_side, t_rr_node* cur_rr_node) { @@ -956,17 +993,17 @@ void dump_verilog_switch_box_interc(FILE* fp, if (0 == num_drive_rr_nodes) { /* Print a special direct connection*/ - dump_verilog_switch_box_short_interc(fp, cur_sb_info, chan_side, cur_rr_node, + dump_verilog_switch_box_short_interc(cur_sram_orgz_info, fp, cur_sb_info, chan_side, cur_rr_node, num_drive_rr_nodes, cur_rr_node); } else if (1 == num_drive_rr_nodes) { /* Print a direct connection*/ - dump_verilog_switch_box_short_interc(fp, cur_sb_info, chan_side, cur_rr_node, - num_drive_rr_nodes, drive_rr_nodes[0]); + dump_verilog_switch_box_short_interc(cur_sram_orgz_info, fp, cur_sb_info, chan_side, cur_rr_node, + num_drive_rr_nodes, drive_rr_nodes[DEFAULT_SWITCH_ID]); } else if (1 < num_drive_rr_nodes) { /* Print the multiplexer, fan_in >= 2 */ - dump_verilog_switch_box_mux(fp, cur_sb_info, chan_side, cur_rr_node, + dump_verilog_switch_box_mux(cur_sram_orgz_info, fp, cur_sb_info, chan_side, cur_rr_node, num_drive_rr_nodes, drive_rr_nodes, - cur_rr_node->drive_switches[0]); + cur_rr_node->drive_switches[DEFAULT_SWITCH_ID]); } /*Nothing should be done else*/ /* Free */ @@ -975,7 +1012,8 @@ void dump_verilog_switch_box_interc(FILE* fp, } /* Count the number of configuration bits of a Switch Box */ -int count_verilog_switch_box_reserved_conf_bits(t_sb* cur_sb_info) { +int count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb* cur_sb_info) { int side, itrack; int num_reserved_conf_bits = 0; int temp_num_reserved_conf_bits = 0; @@ -985,7 +1023,7 @@ int count_verilog_switch_box_reserved_conf_bits(t_sb* cur_sb_info) { switch (cur_sb_info->chan_rr_node_direction[side][itrack]) { case OUT_PORT: temp_num_reserved_conf_bits = - count_verilog_switch_box_interc_reserved_conf_bits(*cur_sb_info, side, + count_verilog_switch_box_interc_reserved_conf_bits(cur_sram_orgz_info, *cur_sb_info, side, cur_sb_info->chan_rr_node[side][itrack]); /* Always select the largest number of reserved conf_bits */ if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { @@ -1006,7 +1044,8 @@ int count_verilog_switch_box_reserved_conf_bits(t_sb* cur_sb_info) { } /* Count the number of configuration bits of a Switch Box */ -int count_verilog_switch_box_conf_bits(t_sb* cur_sb_info) { +int count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb* cur_sb_info) { int side, itrack; int num_conf_bits = 0; @@ -1014,7 +1053,7 @@ int count_verilog_switch_box_conf_bits(t_sb* cur_sb_info) { for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { switch (cur_sb_info->chan_rr_node_direction[side][itrack]) { case OUT_PORT: - num_conf_bits += count_verilog_switch_box_interc_conf_bits(*cur_sb_info, side, + num_conf_bits += count_verilog_switch_box_interc_conf_bits(cur_sram_orgz_info, *cur_sb_info, side, cur_sb_info->chan_rr_node[side][itrack]); break; case IN_PORT: @@ -1063,9 +1102,12 @@ int count_verilog_switch_box_conf_bits(t_sb* cur_sb_info) { * | | | | * -------------- -------------- */ -void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, +void dump_verilog_routing_switch_box_subckt(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, char* subckt_dir, + t_sb* cur_sb_info, int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices) { + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts) { int itrack, inode, side, ix, iy, x, y; int cur_num_sram, num_conf_bits, num_reserved_conf_bits, esti_sram_cnt; FILE* fp = NULL; @@ -1079,11 +1121,11 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, y = cur_sb_info->y; /* Count the number of configuration bits to be consumed by this Switch block */ - num_conf_bits = count_verilog_switch_box_conf_bits(cur_sb_info); + num_conf_bits = count_verilog_switch_box_conf_bits(cur_sram_orgz_info, cur_sb_info); /* Count the number of reserved configuration bits to be consumed by this Switch block */ - num_reserved_conf_bits = count_verilog_switch_box_reserved_conf_bits(cur_sb_info); + num_reserved_conf_bits = count_verilog_switch_box_reserved_conf_bits(cur_sram_orgz_info, cur_sb_info); /* Estimate the sram_verilog_model->cnt */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); esti_sram_cnt = cur_num_sram + num_conf_bits; /* Record the index */ cur_sb_info->num_reserved_conf_bits = num_reserved_conf_bits; @@ -1093,11 +1135,13 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, /* Create file handler */ fp = verilog_create_one_subckt_file(subckt_dir, "Switch Block ", sb_verilog_file_name_prefix, cur_sb_info->x, cur_sb_info->y, &fname); + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir); + /* Comment lines */ fprintf(fp, "//----- Verilog Module of Switch Box[%d][%d] -----\n", cur_sb_info->x, cur_sb_info->y); /* Print the definition of subckt*/ - fprintf(fp, "module sb_%d__%d_ ( \n", cur_sb_info->x, cur_sb_info->y); - fprintf(fp, "\n"); + fprintf(fp, "module %s ( \n", gen_verilog_one_sb_module_name(cur_sb_info)); /* dump global ports */ if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { fprintf(fp, ",\n"); @@ -1110,14 +1154,16 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { switch (cur_sb_info->chan_rr_node_direction[side][itrack]) { case OUT_PORT: - fprintf(fp, " output %s_%d__%d__out_%d_,\n", - convert_chan_type_to_string(cur_sb_info->chan_rr_node[side][itrack]->type), - ix, iy, itrack); + fprintf(fp, " output %s,\n", + gen_verilog_routing_channel_one_pin_name(cur_sb_info->chan_rr_node[side][itrack], + ix, iy, itrack, + cur_sb_info->chan_rr_node_direction[side][itrack])); break; case IN_PORT: - fprintf(fp, " input %s_%d__%d__in_%d_,\n", - convert_chan_type_to_string(cur_sb_info->chan_rr_node[side][itrack]->type), - ix, iy, itrack); + fprintf(fp, " input %s,\n", + gen_verilog_routing_channel_one_pin_name(cur_sb_info->chan_rr_node[side][itrack], + ix, iy, itrack, + cur_sb_info->chan_rr_node_direction[side][itrack])); break; default: vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of chany[%d][%d]_track[%d]!\n", @@ -1127,6 +1173,7 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, } /* Dump OPINs of adjacent CLBs */ for (inode = 0; inode < cur_sb_info->num_opin_rr_nodes[side]; inode++) { + fprintf(fp, " "); dump_verilog_grid_side_pin_with_given_index(fp, OPIN, /* This is an input of a SB */ cur_sb_info->opin_rr_node[side][inode]->ptc_num, cur_sb_info->opin_rr_node_grid_side[side][inode], @@ -1139,24 +1186,35 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, /* Put down configuration port */ /* output of each configuration bit */ /* Reserved sram ports */ - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, 0, cur_sb_info->num_reserved_conf_bits - 1, VERILOG_PORT_INPUT); if (0 < cur_sb_info->num_reserved_conf_bits) { fprintf(fp, ",\n"); } /* Normal sram ports */ - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_sram_ports(fp, cur_sram_orgz_info, cur_sb_info->conf_bits_lsb, cur_sb_info->conf_bits_msb - 1, VERILOG_PORT_INPUT); + + /* Dump ports only visible during formal verification*/ + if (0 < (cur_sb_info->conf_bits_msb - 1 - cur_sb_info->conf_bits_lsb)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_sb_info->conf_bits_lsb, + cur_sb_info->conf_bits_msb - 1, + VERILOG_PORT_OUTPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } fprintf(fp, "); \n"); /* Local wires for memory configurations */ - /* - dump_verilog_sram_config_bus_internal_wires(fp, sram_verilog_orgz_info, + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, cur_sb_info->conf_bits_lsb, cur_sb_info->conf_bits_msb - 1); - */ /* Put down all the multiplexers */ for (side = 0; side < cur_sb_info->num_sides; side++) { @@ -1167,7 +1225,7 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); /* We care INC_DIRECTION tracks at this side*/ if (OUT_PORT == cur_sb_info->chan_rr_node_direction[side][itrack]) { - dump_verilog_switch_box_interc(fp, cur_sb_info, side, cur_sb_info->chan_rr_node[side][itrack]); + dump_verilog_switch_box_interc(cur_sram_orgz_info, fp, cur_sb_info, side, cur_sb_info->chan_rr_node[side][itrack]); } } } @@ -1178,7 +1236,7 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, fprintf(fp, "//----- END Verilog Module of Switch Box[%d][%d] -----\n\n", x, y); /* Check */ - assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); + assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)); /* Close file handler */ fclose(fp); @@ -1193,7 +1251,8 @@ void dump_verilog_routing_switch_box_subckt(char* subckt_dir, t_sb* cur_sb_info, } /* Count the number of configuration bits of a rr_node*/ -int count_verilog_connection_box_interc_conf_bits(t_rr_node* cur_rr_node) { +int count_verilog_connection_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* cur_rr_node) { int num_conf_bits = 0; int switch_idx = 0; int num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes; @@ -1213,14 +1272,15 @@ int count_verilog_connection_box_interc_conf_bits(t_rr_node* cur_rr_node) { assert(-1 < switch_idx); assert(SPICE_MODEL_MUX == switch_inf[switch_idx].spice_model->type); num_conf_bits = count_num_conf_bits_one_spice_model(switch_inf[switch_idx].spice_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, num_drive_rr_nodes); return num_conf_bits; } } /* Count the number of configuration bits of a rr_node*/ -int count_verilog_connection_box_interc_reserved_conf_bits(t_rr_node* cur_rr_node) { +int count_verilog_connection_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* cur_rr_node) { int num_reserved_conf_bits = 0; int switch_idx = 0; int num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes; @@ -1241,33 +1301,36 @@ int count_verilog_connection_box_interc_reserved_conf_bits(t_rr_node* cur_rr_nod assert(SPICE_MODEL_MUX == switch_inf[switch_idx].spice_model->type); num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(switch_inf[switch_idx].spice_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, num_drive_rr_nodes); return num_reserved_conf_bits; } } -int count_verilog_connection_box_one_side_conf_bits(int num_ipin_rr_nodes, +int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + int num_ipin_rr_nodes, t_rr_node** ipin_rr_node) { int num_conf_bits = 0; int inode; for (inode = 0; inode < num_ipin_rr_nodes; inode++) { - num_conf_bits += count_verilog_connection_box_interc_conf_bits(ipin_rr_node[inode]); + num_conf_bits += count_verilog_connection_box_interc_conf_bits(cur_sram_orgz_info, ipin_rr_node[inode]); } return num_conf_bits; } -int count_verilog_connection_box_one_side_reserved_conf_bits(int num_ipin_rr_nodes, +int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + int num_ipin_rr_nodes, t_rr_node** ipin_rr_node) { int num_reserved_conf_bits = 0; int temp_num_reserved_conf_bits = 0; int inode; for (inode = 0; inode < num_ipin_rr_nodes; inode++) { - temp_num_reserved_conf_bits = count_verilog_connection_box_interc_reserved_conf_bits(ipin_rr_node[inode]); + temp_num_reserved_conf_bits = count_verilog_connection_box_interc_reserved_conf_bits(cur_sram_orgz_info, + ipin_rr_node[inode]); if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { num_reserved_conf_bits = temp_num_reserved_conf_bits; } @@ -1277,7 +1340,8 @@ int count_verilog_connection_box_one_side_reserved_conf_bits(int num_ipin_rr_nod } /* SRC rr_node is the IPIN of a grid.*/ -void dump_verilog_connection_box_short_interc(FILE* fp, +void dump_verilog_connection_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, t_cb* cur_cb_info, t_rr_node* src_rr_node) { t_rr_node* drive_rr_node = NULL; @@ -1346,15 +1410,16 @@ void dump_verilog_connection_box_short_interc(FILE* fp, FALSE); /* Do not specify the direction of this pin */ /* End */ - fprintf(fp, "\n"); + fprintf(fp, ";\n"); return; } -void dump_verilog_connection_box_mux(FILE* fp, +void dump_verilog_connection_box_mux(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, t_cb* cur_cb_info, t_rr_node* src_rr_node) { - int i, mux_size, cur_num_sram, input_cnt = 0; + int mux_size, cur_num_sram, input_cnt = 0; t_rr_node** drive_rr_nodes = NULL; int inode, mux_level, path_id, switch_index; t_spice_model* verilog_model = NULL; @@ -1366,6 +1431,7 @@ void dump_verilog_connection_box_mux(FILE* fp, int num_mux_reserved_conf_bits = 0; int cur_bl, cur_wl; t_spice_model* mem_model = NULL; + char* mem_subckt_name = NULL; /* Check the file handler*/ if (NULL == fp) { @@ -1382,19 +1448,27 @@ void dump_verilog_connection_box_mux(FILE* fp, drive_rr_nodes = src_rr_node->drive_rr_nodes; /* Configuration bits for MUX*/ - path_id = -1; + path_id = DEFAULT_PATH_ID; for (inode = 0; inode < mux_size; inode++) { if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) { path_id = inode; + src_rr_node->id_path = inode; break; } } - assert((-1 != path_id)&&(path_id < mux_size)); - - switch_index = src_rr_node->drive_switches[path_id]; + switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID]; verilog_model = switch_inf[switch_index].spice_model; + + char* name_mux = (char *) my_malloc(sizeof(char)*(strlen(verilog_model->prefix) + 5 + + strlen(my_itoa(mux_size)) + 1 + + strlen(my_itoa(verilog_model->cnt)) + 5)); + sprintf(name_mux, "/%s_size%d_%d_/in", verilog_model->prefix, mux_size, verilog_model->cnt); + char* path_hierarchy = (char *) my_malloc(sizeof(char)*(strlen(gen_verilog_one_cb_instance_name(cur_cb_info)))); + path_hierarchy = gen_verilog_one_cb_instance_name(cur_cb_info); + src_rr_node->name_mux = my_strcat(path_hierarchy,name_mux); + /* Specify the input bus */ fprintf(fp, "wire [0:%d] %s_size%d_%d_inbus;\n", mux_size - 1, @@ -1422,28 +1496,45 @@ void dump_verilog_connection_box_mux(FILE* fp, /* Print SRAMs that configure this MUX */ /* cur_num_sram = sram_verilog_model->cnt; */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); - get_sram_orgz_info_num_blwl(sram_verilog_orgz_info, &cur_bl, &cur_wl); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); /* connect to reserved BL/WLs ? */ num_mux_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, mux_size); /* Get the number of configuration bits required by this MUX */ num_mux_conf_bits = count_num_conf_bits_one_spice_model(verilog_model, - sram_verilog_orgz_info->type, + cur_sram_orgz_info->type, mux_size); /* Dump the configuration port bus */ - dump_verilog_mux_config_bus(fp, verilog_model, sram_verilog_orgz_info, + dump_verilog_mux_config_bus(fp, verilog_model, cur_sram_orgz_info, mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits); + /* Dump ports visible only during formal verification */ + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + /* + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_num_sram, + cur_num_sram + num_mux_conf_bits - 1, + VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + */ + dump_verilog_formal_verification_mux_sram_ports_wiring(fp, cur_sram_orgz_info, + verilog_model, mux_size, + cur_num_sram, + cur_num_sram + num_mux_conf_bits - 1); + + fprintf(fp, "`endif\n"); + + /* Call the MUX SPICE model */ fprintf(fp, "%s_size%d %s_size%d_%d_ (", verilog_model->name, mux_size, verilog_model->prefix, mux_size, verilog_model->cnt); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } @@ -1468,7 +1559,7 @@ void dump_verilog_connection_box_mux(FILE* fp, fprintf(fp, ", "); /* Different design technology requires different configuration bus! */ - dump_verilog_mux_config_bus_ports(fp, verilog_model, sram_verilog_orgz_info, + dump_verilog_mux_config_bus_ports(fp, verilog_model, cur_sram_orgz_info, mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits); @@ -1479,7 +1570,7 @@ void dump_verilog_connection_box_mux(FILE* fp, decode_cmos_mux_sram_bits(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; case SPICE_MODEL_DESIGN_RRAM: - decode_verilog_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); + decode_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level); break; default: vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n", @@ -1513,28 +1604,27 @@ void dump_verilog_connection_box_mux(FILE* fp, __FILE__, __LINE__, verilog_model->name); } - /* Store the configuraion bit to linked-list */ - add_mux_conf_bits_to_llist(mux_size, sram_verilog_orgz_info, - num_mux_sram_bits, mux_sram_bits, - verilog_model); - - get_sram_orgz_info_mem_model(sram_verilog_orgz_info, &mem_model); + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); /* Dump sram modules */ switch (verilog_model->design_tech) { case SPICE_MODEL_DESIGN_CMOS: - /* SRAM-based MUX required dumping SRAMs! */ - for (i = 0; i < num_mux_sram_bits; i++) { - dump_verilog_mux_sram_submodule(fp, sram_verilog_orgz_info, verilog_model, mux_size, - mem_model); /* use the mem_model in sram_verilog_orgz_info */ - } + /* Call the memory module defined for this SRAM-based MUX! */ + mem_subckt_name = generate_verilog_mux_subckt_name(verilog_model, mux_size, verilog_mem_posfix); + fprintf(fp, "%s %s_%d_ ( ", + mem_subckt_name, mem_subckt_name, verilog_model->cnt); + dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, verilog_model, mux_size, mem_model, + cur_num_sram, cur_num_sram + num_mux_conf_bits - 1); + fprintf(fp, ");\n"); + /* update the number of memory bits */ + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); break; case SPICE_MODEL_DESIGN_RRAM: /* RRAM-based MUX does not need any SRAM dumping * But we have to get the number of configuration bits required by this MUX * and update the number of memory bits */ - update_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info, cur_num_sram + num_mux_conf_bits); - update_sram_orgz_info_num_blwl(sram_verilog_orgz_info, + update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits); + update_sram_orgz_info_num_blwl(cur_sram_orgz_info, cur_bl + num_mux_conf_bits, cur_wl + num_mux_conf_bits); break; @@ -1548,11 +1638,13 @@ void dump_verilog_connection_box_mux(FILE* fp, /* Free */ my_free(mux_sram_bits); + my_free(mem_subckt_name); return; } -void dump_verilog_connection_box_interc(FILE* fp, +void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, t_cb* cur_cb_info, t_rr_node* src_rr_node) { /* Check the file handler*/ @@ -1568,17 +1660,18 @@ void dump_verilog_connection_box_interc(FILE* fp, if (1 == src_rr_node->fan_in) { /* Print a direct connection*/ - dump_verilog_connection_box_short_interc(fp, cur_cb_info, src_rr_node); + dump_verilog_connection_box_short_interc(cur_sram_orgz_info, fp, cur_cb_info, src_rr_node); } else if (1 < src_rr_node->fan_in) { /* Print the multiplexer, fan_in >= 2 */ - dump_verilog_connection_box_mux(fp, cur_cb_info, src_rr_node); + dump_verilog_connection_box_mux(cur_sram_orgz_info, fp, cur_cb_info, src_rr_node); } /*Nothing should be done else*/ return; } /* Count the number of configuration bits of a connection box */ -int count_verilog_connection_box_conf_bits(t_cb* cur_cb_info) { +int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_cb* cur_cb_info) { int side; int side_cnt = 0; int num_conf_bits = 0; @@ -1592,7 +1685,9 @@ int count_verilog_connection_box_conf_bits(t_cb* cur_cb_info) { assert(0 < cur_cb_info->num_ipin_rr_nodes[side]); assert(NULL != cur_cb_info->ipin_rr_node[side]); /* Count the number of configuration bits */ - num_conf_bits += count_verilog_connection_box_one_side_conf_bits(cur_cb_info->num_ipin_rr_nodes[side], cur_cb_info->ipin_rr_node[side]); + num_conf_bits += count_verilog_connection_box_one_side_conf_bits(cur_sram_orgz_info, + cur_cb_info->num_ipin_rr_nodes[side], + cur_cb_info->ipin_rr_node[side]); } /* Make sure only 2 sides of IPINs are printed */ assert((1 == side_cnt)||(2 == side_cnt)); @@ -1601,7 +1696,8 @@ int count_verilog_connection_box_conf_bits(t_cb* cur_cb_info) { } /* Count the number of reserved configuration bits of a connection box */ -int count_verilog_connection_box_reserved_conf_bits(t_cb* cur_cb_info) { +int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_cb* cur_cb_info) { int side; int side_cnt = 0; int num_reserved_conf_bits = 0; @@ -1616,7 +1712,9 @@ int count_verilog_connection_box_reserved_conf_bits(t_cb* cur_cb_info) { assert(0 < cur_cb_info->num_ipin_rr_nodes[side]); assert(NULL != cur_cb_info->ipin_rr_node[side]); /* Count the number of reserved configuration bits */ - temp_num_reserved_conf_bits = count_verilog_connection_box_one_side_reserved_conf_bits(cur_cb_info->num_ipin_rr_nodes[side], cur_cb_info->ipin_rr_node[side]); + temp_num_reserved_conf_bits = count_verilog_connection_box_one_side_reserved_conf_bits(cur_sram_orgz_info, + cur_cb_info->num_ipin_rr_nodes[side], + cur_cb_info->ipin_rr_node[side]); /* Only consider the largest reserved configuration bits */ if (temp_num_reserved_conf_bits > num_reserved_conf_bits) { num_reserved_conf_bits = temp_num_reserved_conf_bits; @@ -1652,9 +1750,12 @@ int count_verilog_connection_box_reserved_conf_bits(t_cb* cur_cb_info) { * | | Connection | | * --------------Box_Y[x][y-1]-------------- */ -void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_info, +void dump_verilog_routing_connection_box_subckt(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, char* subckt_dir, + t_cb* cur_cb_info, int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices) { + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts) { int itrack, inode, side, x, y; int side_cnt = 0; FILE* fp = NULL; @@ -1674,6 +1775,10 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i case CHANX: /* Create file handler */ fp = verilog_create_one_subckt_file(subckt_dir, "Connection Block - X direction ", cbx_verilog_file_name_prefix, cur_cb_info->x, cur_cb_info->y, &fname); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir); + /* Comment lines */ fprintf(fp, "//----- Verilog Module of Connection Box -X direction [%d][%d] -----\n", x, y); fprintf(fp, "module "); @@ -1682,6 +1787,9 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i case CHANY: /* Create file handler */ fp = verilog_create_one_subckt_file(subckt_dir, "Connection Block - Y direction ", cby_verilog_file_name_prefix, cur_cb_info->x, cur_cb_info->y, &fname); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir); /* Comment lines */ fprintf(fp, "//----- Verilog Module of Connection Box -Y direction [%d][%d] -----\n", x, y); fprintf(fp, "module "); @@ -1709,10 +1817,9 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i assert (0 < cur_cb_info->chan_width[side]); side_cnt++; for (itrack = 0; itrack < cur_cb_info->chan_width[side]; itrack++) { - fprintf(fp, "input %s_%d__%d__midout_%d_, \n", - convert_chan_type_to_string(cur_cb_info->type), - cur_cb_info->x, cur_cb_info->y, itrack); - fprintf(fp, "\n"); + fprintf(fp, "input %s, \n", + gen_verilog_routing_channel_one_midout_name( cur_cb_info, + itrack)); } } /*check side_cnt */ @@ -1738,7 +1845,6 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i cur_cb_info->ipin_rr_node[side][inode]->ylow, TRUE); - fprintf(fp, "\n"); } } /* Make sure only 2 sides of IPINs are printed */ @@ -1746,11 +1852,11 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i /* Count the number of configuration bits */ /* Count the number of configuration bits to be consumed by this Switch block */ - num_conf_bits = count_verilog_connection_box_conf_bits(cur_cb_info); + num_conf_bits = count_verilog_connection_box_conf_bits(cur_sram_orgz_info, cur_cb_info); /* Count the number of reserved configuration bits to be consumed by this Switch block */ - num_reserved_conf_bits = count_verilog_connection_box_reserved_conf_bits(cur_cb_info); + num_reserved_conf_bits = count_verilog_connection_box_reserved_conf_bits(cur_sram_orgz_info, cur_cb_info); /* Estimate the sram_verilog_model->cnt */ - cur_num_sram = get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info); + cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); esti_sram_cnt = cur_num_sram + num_conf_bits; /* Record index */ cur_cb_info->num_reserved_conf_bits = num_reserved_conf_bits; @@ -1760,25 +1866,37 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i /* Put down configuration port */ /* output of each configuration bit */ /* Reserved sram ports */ - dump_verilog_reserved_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, 0, cur_cb_info->num_reserved_conf_bits - 1, VERILOG_PORT_INPUT); if (0 < cur_cb_info->num_reserved_conf_bits) { fprintf(fp, ",\n"); } /* Normal sram ports */ - dump_verilog_sram_ports(fp, sram_verilog_orgz_info, + dump_verilog_sram_ports(fp, cur_sram_orgz_info, cur_cb_info->conf_bits_lsb, cur_cb_info->conf_bits_msb - 1, VERILOG_PORT_INPUT); + + /* Dump ports only visible during formal verification*/ + if (0 < (cur_cb_info->conf_bits_msb - 1 - cur_cb_info->conf_bits_lsb)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_cb_info->conf_bits_lsb, + cur_cb_info->conf_bits_msb - 1, + VERILOG_PORT_OUTPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + /* subckt definition ends with svdd and sgnd*/ fprintf(fp, ");\n"); /* Local wires for memory configurations */ - /* - dump_verilog_sram_config_bus_internal_wires(fp, sram_verilog_orgz_info, + dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info, cur_cb_info->conf_bits_lsb, cur_cb_info->conf_bits_msb - 1); - */ /* Record LSB and MSB of reserved_conf_bits and normal conf_bits */ @@ -1793,7 +1911,8 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i assert(0 < cur_cb_info->num_ipin_rr_nodes[side]); assert(NULL != cur_cb_info->ipin_rr_node[side]); for (inode = 0; inode < cur_cb_info->num_ipin_rr_nodes[side]; inode++) { - dump_verilog_connection_box_interc(fp, cur_cb_info, cur_cb_info->ipin_rr_node[side][inode]); + dump_verilog_connection_box_interc(cur_sram_orgz_info, fp, cur_cb_info, + cur_cb_info->ipin_rr_node[side][inode]); } } @@ -1813,7 +1932,7 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i } /* Check */ - assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info)); + assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)); /* Close file handler */ fclose(fp); @@ -1829,11 +1948,15 @@ void dump_verilog_routing_connection_box_subckt(char* subckt_dir, t_cb* cur_cb_i /* Top Function*/ /* Build the routing resource SPICE sub-circuits*/ -void dump_verilog_routing_resources(char* subckt_dir, +void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, t_arch arch, t_det_routing_arch* routing_arch, int LL_num_rr_nodes, t_rr_node* LL_rr_node, - t_ivec*** LL_rr_node_indices) { + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + t_syn_verilog_opts fpga_verilog_opts) { int ix, iy; assert(UNI_DIRECTIONAL == routing_arch->directionality); @@ -1860,18 +1983,18 @@ void dump_verilog_routing_resources(char* subckt_dir, vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Channels...\n"); for (iy = 0; iy < (ny + 1); iy++) { for (ix = 1; ix < (nx + 1); ix++) { - dump_verilog_routing_chan_subckt(subckt_dir, ix, iy, CHANX, - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, - arch.num_segments, arch.Segments); + dump_verilog_routing_chan_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, ix, iy, CHANX, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, LL_rr_indexed_data, + arch.num_segments, arch.Segments, fpga_verilog_opts); } } /* Y - channels [1...ny][0..nx]*/ vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Channels...\n"); for (ix = 0; ix < (nx + 1); ix++) { for (iy = 1; iy < (ny + 1); iy++) { - dump_verilog_routing_chan_subckt(subckt_dir, ix, iy, CHANY, - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, - arch.num_segments, arch.Segments); + dump_verilog_routing_chan_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, ix, iy, CHANY, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, LL_rr_indexed_data, + arch.num_segments, arch.Segments, fpga_verilog_opts); } } @@ -1880,8 +2003,9 @@ void dump_verilog_routing_resources(char* subckt_dir, for (iy = 0; iy < (ny + 1); iy++) { /* vpr_printf(TIO_MESSAGE_INFO, "Writing Switch Boxes[%d][%d]...\n", ix, iy); */ update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models); - dump_verilog_routing_switch_box_subckt(subckt_dir, &(sb_info[ix][iy]), - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + dump_verilog_routing_switch_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(sb_info[ix][iy]), + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + fpga_verilog_opts); update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models); } } @@ -1894,8 +2018,9 @@ void dump_verilog_routing_resources(char* subckt_dir, update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models); if ((TRUE == is_cb_exist(CHANX, ix, iy)) &&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) { - dump_verilog_routing_connection_box_subckt(subckt_dir, &(cbx_info[ix][iy]), - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + dump_verilog_routing_connection_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(cbx_info[ix][iy]), + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + fpga_verilog_opts); } update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models); } @@ -1907,8 +2032,9 @@ void dump_verilog_routing_resources(char* subckt_dir, update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models); if ((TRUE == is_cb_exist(CHANY, ix, iy)) &&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) { - dump_verilog_routing_connection_box_subckt(subckt_dir, &(cby_info[ix][iy]), - LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + dump_verilog_routing_connection_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(cby_info[ix][iy]), + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices, + fpga_verilog_opts); } update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models); } diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.h new file mode 100644 index 000000000..6f02a5f88 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.h @@ -0,0 +1,126 @@ + +void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, + int x, int y, + t_rr_type chan_type, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + int num_segment, t_segment_inf* segments, + t_syn_verilog_opts fpga_verilog_opts); + +void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, + int pin_index, int side, + int x, int y, + boolean dump_port_type); + +void dump_verilog_grid_side_pins(FILE* fp, + t_rr_type pin_type, int x, int y, int side, + boolean dump_port_type); + +void dump_verilog_switch_box_chan_port(FILE* fp, + t_sb* cur_sb_info, + int chan_side, + t_rr_node* cur_rr_node, + enum PORTS cur_rr_node_direction); + +void dump_verilog_switch_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_sb* cur_sb_info, + int chan_side, + t_rr_node* cur_rr_node, + int actual_fan_in, + t_rr_node* drive_rr_node); + +void dump_verilog_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_sb* cur_sb_info, + int chan_side, + t_rr_node* cur_rr_node, + int mux_size, + t_rr_node** drive_rr_nodes, + int switch_index); + +int count_verilog_switch_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb cur_sb_info, int chan_side, + t_rr_node* cur_rr_node); + +int count_verilog_switch_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb cur_sb_info, int chan_side, + t_rr_node* cur_rr_node); + +void dump_verilog_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_sb* cur_sb_info, + int chan_side, + t_rr_node* cur_rr_node); + +int count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb cur_sb_info); + +int count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_sb cur_sb_info); + +void dump_verilog_routing_switch_box_subckt(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, char* subckt_dir, + t_sb* cur_sb_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts); + + +void dump_verilog_connection_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_cb* cur_cb_info, + t_rr_node* src_rr_node); + +void dump_verilog_connection_box_mux(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_cb* cur_cb_info, + t_rr_node* src_rr_node); + +void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_cb* cur_cb_info, + t_rr_node* src_rr_node); + + +int count_verilog_connection_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* cur_rr_node); + +int count_verilog_connection_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_rr_node* cur_rr_node); + +int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + int num_ipin_rr_nodes, + t_rr_node** ipin_rr_node); + +int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + int num_ipin_rr_nodes, + t_rr_node** ipin_rr_node); + +int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_cb* cur_cb_info); + +int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, + t_cb* cur_cb_info); + +void dump_verilog_routing_connection_box_subckt(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, char* subckt_dir, + t_cb* cur_cb_info, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_syn_verilog_opts fpga_verilog_opts); + + +void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* subckt_dir, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + t_syn_verilog_opts fpga_verilog_opts); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c new file mode 100644 index 000000000..430fa4ca0 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c @@ -0,0 +1,1922 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_rr_graph_utils.h" +#include "fpga_x2p_globals.h" + +/* Include Verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" +#include "verilog_tcl_utils.h" +#include "verilog_sdc_pb_types.h" +#include "verilog_sdc.h" + +/* options for report timing */ +typedef struct s_sdc_opts t_sdc_opts; +struct s_sdc_opts { + char* sdc_dir; + boolean constrain_sbs; + boolean constrain_cbs; + boolean constrain_pbs; + boolean constrain_routing_channels; + boolean break_loops; + boolean break_loops_mux; +}; + +float get_switch_sdc_tmax (t_switch_inf* cur_switch_inf) { + return cur_switch_inf->R * cur_switch_inf->Cout + cur_switch_inf->Tdel; +} + +float get_routing_seg_sdc_tmax (t_segment_inf* cur_seg) { + return cur_seg->Rmetal * cur_seg->Cmetal; +} + +boolean is_rr_node_to_be_disable_for_analysis(t_rr_node* cur_rr_node) { + /* Conditions to enable timing analysis for a node + * 1st condition: it have a valid vpack_net_number + * 2nd condition: it is not an parasitic net + * 3rd condition: it is not a global net + */ + if ( (OPEN != cur_rr_node->vpack_net_num) + && (FALSE == cur_rr_node->is_parasitic_net) + && (FALSE == vpack_net[cur_rr_node->vpack_net_num].is_global) + && (FALSE == vpack_net[cur_rr_node->vpack_net_num].is_const_gen) ){ + return FALSE; + } + return TRUE; +} + +/* TO avoid combinational loops caused by memories + * We disable all the timing paths starting from an output of memory cell + */ +void verilog_generate_sdc_break_loop_sram(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + t_spice_model* mem_model = NULL; + int iport, ipin; + char* port_name = NULL; + + int num_output_ports = 0; + t_spice_model_port** output_ports = NULL; + + /* Check */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert (NULL != mem_model); + + /* Find the output ports of mem_model */ + output_ports = find_spice_model_ports(mem_model, SPICE_MODEL_PORT_OUTPUT, &num_output_ports, TRUE); + + for (iport = 0; iport < num_output_ports; iport++) { + for (ipin = 0; ipin < output_ports[iport]->size; ipin++) { + if (TRUE == mem_model->dump_explicit_port_map) { + port_name = output_ports[iport]->lib_name; + } else { + port_name = output_ports[iport]->prefix; + } + /* Disable the timing for all the memory cells */ + fprintf(fp, + "set_disable_timing [get_pins -filter \"name == %s", + port_name); + if (1 < output_ports[iport]->size) { + fprintf(fp, "[%d]", ipin); + } + fprintf(fp, "\" "); + fprintf(fp, + "-of [get_cells -hier -filter \"ref_lib_cell_name == %s\"]]\n", + mem_model->name); + } + } + + /* Free */ + my_free(output_ports); + + return; +} + +/* Statisitcs for input sizes and structures of MUXes + * used in FPGA architecture + * Disable timing starting from any MUX outputs + */ +void verilog_generate_sdc_break_loop_mux(FILE* fp, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch) { + /* We have linked list whichs stores spice model information of multiplexer*/ + t_llist* muxes_head = NULL; + t_llist* temp = NULL; + t_spice_mux_model* cur_spice_mux_model = NULL; + + int num_input_ports = 0; + t_spice_model_port** input_ports = NULL; + int num_output_ports = 0; + t_spice_model_port** output_ports = NULL; + + char* SPC_cell_suffix = "_SPC"; + + /* Check */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Alloc the muxes*/ + muxes_head = stats_spice_muxes(num_switch, switches, spice, routing_arch); + + /* Print mux netlist one by one*/ + temp = muxes_head; + while(temp) { + assert(NULL != temp->dptr); + cur_spice_mux_model = (t_spice_mux_model*)(temp->dptr); + input_ports = find_spice_model_ports(cur_spice_mux_model->spice_model, SPICE_MODEL_PORT_INPUT, &num_input_ports, TRUE); + output_ports = find_spice_model_ports(cur_spice_mux_model->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_ports, TRUE); + assert(1 == num_input_ports); + assert(1 == num_input_ports); + /* Check the Input port size */ + if ( (NULL != cur_spice_mux_model->spice_model->verilog_netlist) + && (cur_spice_mux_model->size != input_ports[0]->size)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])User-defined MUX SPICE MODEL(%s) size(%d) unmatch with the architecture needs(%d)!\n", + __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, input_ports[0]->size,cur_spice_mux_model->size); + exit(1); + } + /* Use the user defined ports, Bypass LUT MUXes */ + if (SPICE_MODEL_MUX == cur_spice_mux_model->spice_model->type) { + fprintf(fp, + "set_disable_timing [get_pins -filter \"name =~ %s*\" ", + output_ports[0]->prefix); + fprintf(fp, + "-of [get_cells -hier -filter \"ref_lib_cell_name == %s\"]]\n", + gen_verilog_one_mux_module_name(cur_spice_mux_model->spice_model, cur_spice_mux_model->size)); + /* For SPC cells*/ + fprintf(fp, + "set_disable_timing [get_pins -filter \"name =~ %s*\" ", + output_ports[0]->prefix); + fprintf(fp, + "-of [get_cells -hier -filter \"ref_lib_cell_name =~ %s%s*\"]]\n", + gen_verilog_one_mux_module_name(cur_spice_mux_model->spice_model, cur_spice_mux_model->size), + SPC_cell_suffix); + } + /* Free */ + my_free(output_ports); + my_free(input_ports); + /* Move on to the next*/ + temp = temp->next; + } + + /* remember to free the linked list*/ + free_muxes_llist(muxes_head); + + return; +} + +void verilog_generate_sdc_clock_period(t_sdc_opts sdc_opts, + float critical_path_delay) { + FILE* fp = NULL; + char* fname = my_strcat(sdc_opts.sdc_dir, sdc_clock_period_file_name); + t_llist* temp = NULL; + t_spice_model_port* temp_port = NULL; + int ipin; + float clock_period = 10.; + int iport; + int num_clock_ports = 0; + t_spice_model_port** clock_port = NULL; + + vpr_printf(TIO_MESSAGE_INFO, + "Generating SDC for constraining clocks in P&R flow: %s ...\n", + fname); + + /* Print the muxes netlist*/ + fp = fopen(fname, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, fname); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_sdc_file_header(fp, "Clock contraints for PnR"); + + /* Create clock */ + /* Get clock port from the global port */ + get_fpga_x2p_global_all_clock_ports(global_ports_head, &num_clock_ports, &clock_port); + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Create clock #\n"); + fprintf(fp, + "##################################################\n"); + + /* Create a clock */ + for (iport = 0; iport < num_clock_ports; iport++) { + fprintf(fp, "create_clock "); + fprintf(fp, "%s -period %.4g -waveform {0 %.4g}\n", + clock_port[iport]->prefix, + critical_path_delay, critical_path_delay/2); + } + + + /* Find the global clock ports */ + temp = global_ports_head; + while (NULL != temp) { + /* Get the port */ + temp_port = (t_spice_model_port*)(temp->dptr); + /* We only care clock ports */ + if (SPICE_MODEL_PORT_CLOCK == temp_port->type) { + /* Go to next */ + temp = temp->next; + continue; + } + + for (ipin = 0; ipin < temp_port->size; ipin++) { + fprintf(fp, + "create_clock -name {%s[%d]} -period %.2g -waveform {0.00 %.2g} [list [get_ports {%s[%d]}]]\n", + temp_port->prefix, ipin, + clock_period, clock_period/2, + temp_port->prefix, ipin); + fprintf(fp, + "set_drive 0 %s[%d]\n", + temp_port->prefix, ipin); + } + /* Go to next */ + temp = temp->next; + } + + /* close file */ + fclose(fp); + + return; +} + +void verilog_generate_sdc_break_loop_sb(FILE* fp, + int LL_nx, int LL_ny) { + int ix, iy; + t_sb* cur_sb_info = NULL; + int side, itrack; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Go for each SB */ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 0; iy < (LL_ny + 1); iy++) { + cur_sb_info = &(sb_info[ix][iy]); + for (side = 0; side < cur_sb_info->num_sides; side++) { + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + assert((CHANX == cur_sb_info->chan_rr_node[side][itrack]->type) + ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); + /* We only care the output port and it should indicate a SB mux */ + if ( (OUT_PORT != cur_sb_info->chan_rr_node_direction[side][itrack]) + || (FALSE != check_drive_rr_node_imply_short(*cur_sb_info, cur_sb_info->chan_rr_node[side][itrack], side))) { + continue; + } + /* Bypass if we have only 1 driving node */ + if (1 == cur_sb_info->chan_rr_node[side][itrack]->num_drive_rr_nodes) { + continue; + } + /* Disable timing here */ + set_disable_timing_one_sb_output(fp, cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack]); + } + } + } + } + + return; +} + +void verilog_generate_sdc_break_loops(t_sram_orgz_info* cur_sram_orgz_info, + t_sdc_opts sdc_opts, + int LL_nx, int LL_ny, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch) { + FILE* fp = NULL; + char* fname = my_strcat(sdc_opts.sdc_dir, sdc_break_loop_file_name); + + vpr_printf(TIO_MESSAGE_INFO, + "Generating SDC for breaking combinational loops in P&R flow: %s ...\n", + fname); + + /* Create file handler */ + fp = fopen(fname, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, fname); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_sdc_file_header(fp, "Break Combinational Loops for PnR"); + + /* 1. Break loops from Memory Cells */ + verilog_generate_sdc_break_loop_sram(fp, cur_sram_orgz_info); + + /* 2. Break loops from Multiplexer Output */ + if (TRUE == sdc_opts.break_loops_mux) { + verilog_generate_sdc_break_loop_mux(fp, num_switch, switches, spice, routing_arch); + } + + /* 3. Break loops from any SB output */ + verilog_generate_sdc_break_loop_sb(fp, LL_nx, LL_ny); + + /* Close the file*/ + fclose(fp); + + /* Free strings */ + my_free(fname); + + return; +} + +/* Constrain a path within a Switch block, + * If this indicates a metal wire, we constraint to be 0 delay + */ +void verilog_generate_sdc_constrain_one_sb_path(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* src_rr_node, + t_rr_node* des_rr_node, + float tmax) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ((OPIN == src_rr_node->type) + ||(CHANX == src_rr_node->type) + ||(CHANY == src_rr_node->type)); + assert ((CHANX == des_rr_node->type) + ||(CHANY == des_rr_node->type)); + + fprintf(fp, "set_max_delay"); + + fprintf(fp, " -from "); + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + dump_verilog_one_sb_routing_pin(fp, cur_sb_info, src_rr_node); + + fprintf(fp, " -to "); + + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + dump_verilog_one_sb_chan_pin(fp, cur_sb_info, des_rr_node, OUT_PORT); + + /* If src_node == des_node, this is a metal wire */ + fprintf(fp, " %.2g", tmax); + + fprintf(fp, "\n"); + + return; +} + +void verilog_generate_sdc_constrain_one_sb_mux(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node) { + int iedge, switch_id; + float switch_delay = 0.; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + assert( ( CHANX == wire_rr_node->type ) + || ( CHANY == wire_rr_node->type )); + + /* Find the starting points */ + for (iedge = 0; iedge < wire_rr_node->num_drive_rr_nodes; iedge++) { + /* Get the switch delay */ + switch_id = wire_rr_node->drive_switches[iedge]; + switch_delay = get_switch_sdc_tmax (&(switch_inf[switch_id])); + /* Constrain a path */ + verilog_generate_sdc_constrain_one_sb_path(fp, cur_sb_info, + wire_rr_node->drive_rr_nodes[iedge], + wire_rr_node, + switch_delay); + } + + return; +} + +/* Constrain a path within a Switch block, + * If this indicates a metal wire, we constraint to be 0 delay + */ +void verilog_generate_sdc_constrain_one_cb_path(FILE* fp, + t_cb* cur_cb_info, + t_rr_node* src_rr_node, + t_rr_node* des_rr_node, + int des_rr_node_grid_side, + float tmax) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ((INC_DIRECTION == src_rr_node->direction) + ||(DEC_DIRECTION == src_rr_node->direction)); + assert ((CHANX == src_rr_node->type) + ||(CHANY == src_rr_node->type)); + assert (IPIN == des_rr_node->type); + + fprintf(fp, "set_max_delay"); + + fprintf(fp, " -from "); + fprintf(fp, "%s/", + gen_verilog_one_cb_instance_name(cur_cb_info)); + fprintf(fp, "%s", + gen_verilog_routing_channel_one_midout_name( cur_cb_info, + src_rr_node->ptc_num)); + + fprintf(fp, " -to "); + + fprintf(fp, "%s/", + gen_verilog_one_cb_instance_name(cur_cb_info)); + + dump_verilog_grid_side_pin_with_given_index(fp, IPIN, /* This is an output of a connection box */ + des_rr_node->ptc_num, + des_rr_node_grid_side, + des_rr_node->xlow, + des_rr_node->ylow, + FALSE); + + /* If src_node == des_node, this is a metal wire */ + fprintf(fp, " %.2g", tmax); + + fprintf(fp, "\n"); + + return; +} + + +/* Constrain the inputs and outputs of SBs, with the Switch delays */ +void verilog_generate_sdc_constrain_sbs(t_sram_orgz_info* cur_sram_orgz_info, + t_sdc_opts sdc_opts, + int LL_nx, int LL_ny, + int num_switch, + t_switch_inf* switches, + t_spice* spice) { + FILE* fp = NULL; + int ix, iy; + int side, itrack; + t_sb* cur_sb_info = NULL; + char* fname = my_strcat(sdc_opts.sdc_dir, sdc_constrain_sb_file_name); + + vpr_printf(TIO_MESSAGE_INFO, + "Generating SDC for constraining Switch Blocks in P&R flow: %s ...\n", + fname); + + /* Print the muxes netlist*/ + fp = fopen(fname, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, fname); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_sdc_file_header(fp, "Constrain Switch Blocks for PnR"); + + + /* We start from a SB[x][y] */ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 0; iy < (LL_ny + 1); iy++) { + cur_sb_info = &(sb_info[ix][iy]); + for (side = 0; side < cur_sb_info->num_sides; side++) { + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + assert((CHANX == cur_sb_info->chan_rr_node[side][itrack]->type) + ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); + /* We only care the output port and it should indicate a SB mux */ + if (OUT_PORT != cur_sb_info->chan_rr_node_direction[side][itrack]) { + continue; + } + /* Constrain thru wires */ + if (FALSE != check_drive_rr_node_imply_short(*cur_sb_info, cur_sb_info->chan_rr_node[side][itrack], side)) { + /* Set the max, min delay to 0? */ + verilog_generate_sdc_constrain_one_sb_path(fp, cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack], + cur_sb_info->chan_rr_node[side][itrack], + 0.); + continue; + } + /* This is a MUX, constrain all the paths from an input to an output */ + verilog_generate_sdc_constrain_one_sb_mux(fp, cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack]); + } + } + } + } + + /* Close the file*/ + fclose(fp); + + /* Free strings */ + my_free(fname); + + return; +} + +void verilog_generate_sdc_constrain_one_cb(FILE* fp, + t_cb* cur_cb_info) { + int side, side_cnt; + int inode, iedge, switch_id; + float switch_delay = 0.; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + side_cnt = 0; + /* Print the ports of grids*/ + /* only check ipin_rr_nodes of cur_cb_info */ + for (side = 0; side < cur_cb_info->num_sides; side++) { + /* Bypass side with zero IPINs*/ + if (0 == cur_cb_info->num_ipin_rr_nodes[side]) { + continue; + } + side_cnt++; + assert(0 < cur_cb_info->num_ipin_rr_nodes[side]); + assert(NULL != cur_cb_info->ipin_rr_node[side]); + for (inode = 0; inode < cur_cb_info->num_ipin_rr_nodes[side]; inode++) { + for (iedge = 0; iedge < cur_cb_info->ipin_rr_node[side][inode]->num_drive_rr_nodes; iedge++) { + /* Get the switch delay */ + switch_id = cur_cb_info->ipin_rr_node[side][inode]->drive_switches[iedge]; + switch_delay = get_switch_sdc_tmax (&(switch_inf[switch_id])); + + /* Print each INPUT Pins of a grid */ + verilog_generate_sdc_constrain_one_cb_path(fp, cur_cb_info, + cur_cb_info->ipin_rr_node[side][inode]->drive_rr_nodes[iedge], + cur_cb_info->ipin_rr_node[side][inode], + cur_cb_info->ipin_rr_node_grid_side[side][inode], + switch_delay); + } + } + } + /* Make sure only 2 sides of IPINs are printed */ + assert((1 == side_cnt)||(2 == side_cnt)); + + return; +} + +/* Constrain the inputs and outputs of Connection Blocks, with the Switch delays */ +void verilog_generate_sdc_constrain_cbs(t_sram_orgz_info* cur_sram_orgz_info, + t_sdc_opts sdc_opts, + int LL_nx, int LL_ny, + int num_switch, + t_switch_inf* switches, + t_spice* spice) { + FILE* fp = NULL; + int ix, iy; + char* fname = my_strcat(sdc_opts.sdc_dir, sdc_constrain_cb_file_name); + + vpr_printf(TIO_MESSAGE_INFO, + "Generating SDC for constraining Connection Blocks in P&R flow: %s ...\n", + fname); + + /* Print the muxes netlist*/ + fp = fopen(fname, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, fname); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_sdc_file_header(fp, "Constrain Connection Blocks for PnR"); + + /* Connection Boxes */ + /* X - channels [1...nx][0..ny]*/ + for (iy = 0; iy < (LL_ny + 1); iy++) { + for (ix = 1; ix < (LL_nx + 1); ix++) { + if ((TRUE == is_cb_exist(CHANX, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) { + verilog_generate_sdc_constrain_one_cb(fp, &(cbx_info[ix][iy])); + } + } + } + /* Y - channels [1...ny][0..nx]*/ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 1; iy < (LL_ny + 1); iy++) { + if ((TRUE == is_cb_exist(CHANY, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) { + verilog_generate_sdc_constrain_one_cb(fp, &(cby_info[ix][iy])); + } + } + } + + /* Close the file*/ + fclose(fp); + + /* Free strings */ + my_free(fname); + + return; +} + +void verilog_generate_sdc_constrain_one_chan(FILE* fp, + t_rr_type chan_type, + int x, int y, + t_arch arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data) { + int chan_width = 0; + t_rr_node** chan_rr_nodes = NULL; + int cost_index, iseg, itrack; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Collect rr_nodes for Tracks for chanx[ix][iy] */ + chan_rr_nodes = get_chan_rr_nodes(&chan_width, chan_type, x, y, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + + for (itrack = 0; itrack < chan_width; itrack++) { + fprintf(fp, "set_max_delay"); + fprintf(fp, " -from "); + + fprintf(fp, "%s/in%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + + fprintf(fp, " -to "); + + fprintf(fp, "%s/out%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + /* Find the segment delay ! */ + cost_index = chan_rr_nodes[itrack]->cost_index; + iseg = LL_rr_indexed_data[cost_index].seg_index; + /* Check */ + assert((!(iseg < 0))&&(iseg < arch.num_segments)); + fprintf(fp, " %.2g", get_routing_seg_sdc_tmax(&(arch.Segments[iseg]))); + fprintf(fp, "\n"); + + fprintf(fp, "set_max_delay"); + fprintf(fp, " -from "); + + fprintf(fp, "%s/in%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + + fprintf(fp, " -to "); + + fprintf(fp, "%s/mid_out%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + /* Check */ + fprintf(fp, " %.2g", get_routing_seg_sdc_tmax(&(arch.Segments[iseg]))); + fprintf(fp, "\n"); + + } + + /* Free */ + my_free(chan_rr_nodes); + + return; +} + +void verilog_generate_sdc_disable_one_unused_chan(FILE* fp, + t_rr_type chan_type, + int x, int y, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data) { + int chan_width = 0; + t_rr_node** chan_rr_nodes = NULL; + int itrack; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Disable Timing for an %s[%d][%d] ###\n", + convert_chan_type_to_string(chan_type), + x, y); + fprintf(fp, + "##################################################\n"); + + /* Collect rr_nodes for Tracks for chanx[ix][iy] */ + chan_rr_nodes = get_chan_rr_nodes(&chan_width, chan_type, x, y, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + + for (itrack = 0; itrack < chan_width; itrack++) { + /* We disable the timing of the input and output of a routing track, + * when it is not mapped to a net or it is a parasitic net + */ + if (FALSE == is_rr_node_to_be_disable_for_analysis(chan_rr_nodes[itrack])) { + continue; + } + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/in%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + fprintf(fp, "\n"); + + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/out%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + fprintf(fp, "\n"); + + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/mid_out%d", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y), + itrack); + fprintf(fp, "\n"); + } + + /* Free */ + my_free(chan_rr_nodes); + + return; +} + + +/* Constrain the inputs and outputs of Connection Blocks, with the Switch delays */ +void verilog_generate_sdc_constrain_routing_channels(t_sram_orgz_info* cur_sram_orgz_info, + t_sdc_opts sdc_opts, + t_arch arch, + int LL_nx, int LL_ny, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + t_spice* spice) { + FILE* fp = NULL; + int ix, iy; + char* fname = my_strcat(sdc_opts.sdc_dir, sdc_constrain_routing_chan_file_name); + + vpr_printf(TIO_MESSAGE_INFO, + "Generating SDC for constraining Routing Channels in P&R flow: %s ...\n", + fname); + + /* Print the muxes netlist*/ + fp = fopen(fname, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, fname); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_sdc_file_header(fp, "Constrain Routing Channels for PnR"); + + /* Routing channels */ + /* X - channels [1...nx][0..ny]*/ + for (iy = 0; iy < (LL_ny + 1); iy++) { + for (ix = 1; ix < (LL_nx + 1); ix++) { + verilog_generate_sdc_constrain_one_chan(fp, CHANX, ix, iy, arch, + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, LL_rr_indexed_data); + } + } + /* Y - channels [1...ny][0..nx]*/ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 1; iy < (LL_ny + 1); iy++) { + verilog_generate_sdc_constrain_one_chan(fp, CHANY, ix, iy, arch, + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, LL_rr_indexed_data); + } + } + + /* Close the file*/ + fclose(fp); + + /* Free strings */ + my_free(fname); + + return; +} + +/* Disable the timing for all the global port + * Except the clock ports + */ +void verilog_generate_sdc_disable_global_ports(FILE* fp) { + t_llist* temp = global_ports_head; + t_spice_model_port* cur_port = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Disable Timing for global ports ###\n"); + fprintf(fp, + "##################################################\n"); + + while (NULL != temp) { + /* Get the port */ + cur_port = (t_spice_model_port*)(temp->dptr); + /* Only focus on the non-clock ports */ + if ( (SPICE_MODEL_PORT_CLOCK == cur_port->type) + && (FALSE == cur_port->is_prog) ) { + /* Go to the next */ + temp = temp->next; + continue; + } + /* Output disable timing command */ + fprintf(fp, + "set_disable_timing %s\n", + cur_port->prefix); + /* Go to the next */ + temp = temp->next; + } + + return; +} + +/* Disable the timing for SRAM outputs */ +void verilog_generate_sdc_disable_sram_orgz(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Disable Timing for configuration memories ###\n"); + fprintf(fp, + "##################################################\n"); + + verilog_generate_sdc_break_loop_sram(fp, cur_sram_orgz_info); + + return; +} + +void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp, int LL_nx, int LL_ny) { + +int ix, iy, side, itrack, imux; +t_rr_node* cur_rr_node; +t_sb* cur_sb_info; + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 0; iy < (LL_ny + 1); iy++) { + cur_sb_info = &(sb_info[ix][iy]); + /* Print comments */ + fprintf(fp, + "########################################################\n"); + fprintf(fp, + "### Disable Timing for MUXES in Switch block[%d][%d] ###\n", + ix, iy); + fprintf(fp, + "########################################################\n"); + for (side = 0; side < cur_sb_info->num_sides; side++) { + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + if (OUT_PORT == cur_sb_info->chan_rr_node_direction[side][itrack]) { + cur_rr_node = cur_sb_info->chan_rr_node[side][itrack]; + for (imux = 0 ; imux < cur_rr_node-> fan_in; imux++) { + if (imux == cur_rr_node->id_path) { + fprintf(fp, "#"); // comments out if the node is active + } +//if(cur_rr_node->name_mux == NULL) assert (NULL != cur_rr_node->name_mux); + fprintf(fp, "set_disable_timing %s[%d]\n", + cur_rr_node->name_mux, imux); + } + } + } + } + } + } +return; +} + +void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp) { + + int ix, iy, iside, inode, imux; + t_cb* cur_cb_info; + t_rr_node* cur_rr_node; + + for (iy = 0; iy < (ny + 1); iy++) { + for (ix = 1; ix < (nx + 1); ix++) { + if (0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy])) { + cur_cb_info = &(cbx_info[ix][iy]); + /* Print comments */ + fprintf(fp, + "##############################################################\n"); + fprintf(fp, + "### Disable Timing for MUXES in Connection block X[%d][%d] ###\n", + ix, iy); + fprintf(fp, + "##############################################################\n"); + + for (iside = 0; iside < cur_cb_info->num_sides; iside++) { + for (inode = 0; inode < cur_cb_info->num_ipin_rr_nodes[iside]; inode++) { + cur_rr_node = cur_cb_info->ipin_rr_node[iside][inode]; + for (imux = 0 ; imux < cur_rr_node-> fan_in; imux++) { + if (imux == cur_rr_node->id_path) { + fprintf(fp, "#"); // comments out if the node is active + } + fprintf(fp, "set_disable_timing %s[%d]\n", + cur_rr_node->name_mux, imux); + } + } + } + } + } + } + for (iy = 1; iy < (ny + 1); iy++) { + for (ix = 0; ix < (nx + 1); ix++) { + if (0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy])) { + cur_cb_info = &(cby_info[ix][iy]); + /* Print comments */ + fprintf(fp, + "##############################################################\n"); + fprintf(fp, + "### Disable Timing for MUXES in Connection block Y[%d][%d] ###\n", + ix, iy); + fprintf(fp, + "##############################################################\n"); + for (iside = 0; iside < cur_cb_info->num_sides; iside++) { + for (inode = 0; inode < cur_cb_info->num_ipin_rr_nodes[iside]; inode++) { + cur_rr_node = cur_cb_info->ipin_rr_node[iside][inode]; + for (imux = 0 ; imux < cur_rr_node-> fan_in; imux++) { + if (imux == cur_rr_node->id_path) { + fprintf(fp, "#"); // comments out if the node is active + } + fprintf(fp, "set_disable_timing %s[%d]\n", + cur_rr_node->name_mux, imux); + } + } + } + } + } + } + + return; +} + +void verilog_generate_sdc_disable_unused_sbs(FILE* fp, + int LL_nx, int LL_ny, + int num_switch, + t_switch_inf* switches, + t_spice* spice) { + int ix, iy; + int side, itrack, inode; + t_sb* cur_sb_info = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* We start from a SB[x][y] */ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 0; iy < (LL_ny + 1); iy++) { + cur_sb_info = &(sb_info[ix][iy]); + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Disable Timing for an Switch block[%d][%d] ###\n", + ix, iy); + fprintf(fp, + "##################################################\n"); + for (side = 0; side < cur_sb_info->num_sides; side++) { + /* Disable Channel inputs and outputs*/ + for (itrack = 0; itrack < cur_sb_info->chan_width[side]; itrack++) { + assert((CHANX == cur_sb_info->chan_rr_node[side][itrack]->type) + ||(CHANY == cur_sb_info->chan_rr_node[side][itrack]->type)); + if (FALSE == is_rr_node_to_be_disable_for_analysis(cur_sb_info->chan_rr_node[side][itrack])) { + continue; + } + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + dump_verilog_one_sb_chan_pin(fp, cur_sb_info, + cur_sb_info->chan_rr_node[side][itrack], + cur_sb_info->chan_rr_node_direction[side][itrack]); + fprintf(fp, "\n"); + } + /* Disable OPINs*/ + for (inode = 0; inode < cur_sb_info->num_opin_rr_nodes[side]; inode++) { + assert (OPIN == cur_sb_info->opin_rr_node[side][inode]->type); + if (FALSE == is_rr_node_to_be_disable_for_analysis(cur_sb_info->opin_rr_node[side][inode])) { + continue; + } + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + dump_verilog_one_sb_routing_pin(fp, cur_sb_info, + cur_sb_info->opin_rr_node[side][inode]); + fprintf(fp, "\n"); + } + } + } + } + + return; +} + + +void verilog_generate_sdc_disable_one_unused_cb(FILE* fp, + t_cb* cur_cb_info) { + int side, side_cnt; + int inode; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Disable Timing for an %s[%d][%d] ###\n", + convert_cb_type_to_string(cur_cb_info->type), + cur_cb_info->x, cur_cb_info->y); + fprintf(fp, + "##################################################\n"); + + side_cnt = 0; + /* Print the ports of grids*/ + /* only check ipin_rr_nodes of cur_cb_info */ + for (side = 0; side < cur_cb_info->num_sides; side++) { + /* Bypass side with zero IPINs*/ + if (0 == cur_cb_info->num_ipin_rr_nodes[side]) { + continue; + } + side_cnt++; + assert(0 < cur_cb_info->num_ipin_rr_nodes[side]); + assert(NULL != cur_cb_info->ipin_rr_node[side]); + for (inode = 0; inode < cur_cb_info->num_ipin_rr_nodes[side]; inode++) { + if (FALSE == is_rr_node_to_be_disable_for_analysis(cur_cb_info->ipin_rr_node[side][inode])) { + continue; + } + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/", + gen_verilog_one_cb_instance_name(cur_cb_info)); + dump_verilog_grid_side_pin_with_given_index(fp, IPIN, + cur_cb_info->ipin_rr_node[side][inode]->ptc_num, + cur_cb_info->ipin_rr_node_grid_side[side][inode], + cur_cb_info->ipin_rr_node[side][inode]->xlow, + cur_cb_info->ipin_rr_node[side][inode]->ylow, + FALSE); /* Do not specify direction of port */ + fprintf(fp, "\n"); + } + } + + return; +} + +void verilog_generate_sdc_disable_unused_cbs(FILE* fp, + int LL_nx, int LL_ny, + int num_switch, + t_switch_inf* switches, + t_spice* spice) { + int ix, iy; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Connection Boxes */ + /* X - channels [1...nx][0..ny]*/ + for (iy = 0; iy < (LL_ny + 1); iy++) { + for (ix = 1; ix < (LL_nx + 1); ix++) { + if ((TRUE == is_cb_exist(CHANX, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) { + verilog_generate_sdc_disable_one_unused_cb(fp, &(cbx_info[ix][iy])); + } + } + } + /* Y - channels [1...ny][0..nx]*/ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 1; iy < (LL_ny + 1); iy++) { + if ((TRUE == is_cb_exist(CHANY, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) { + verilog_generate_sdc_disable_one_unused_cb(fp, &(cby_info[ix][iy])); + } + } + } + + return; +} + +/* Constrain the inputs and outputs of Connection Blocks, with the Switch delays */ +void verilog_generate_sdc_disable_unused_routing_channels(FILE* fp, + t_arch arch, + int LL_nx, int LL_ny, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data) { + int ix, iy; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Routing channels */ + /* X - channels [1...nx][0..ny]*/ + for (iy = 0; iy < (LL_ny + 1); iy++) { + for (ix = 1; ix < (LL_nx + 1); ix++) { + verilog_generate_sdc_disable_one_unused_chan(fp, CHANX, ix, iy, + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, LL_rr_indexed_data); + } + } + /* Y - channels [1...ny][0..nx]*/ + for (ix = 0; ix < (LL_nx + 1); ix++) { + for (iy = 1; iy < (LL_ny + 1); iy++) { + verilog_generate_sdc_disable_one_unused_chan(fp, CHANY, ix, iy, + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, LL_rr_indexed_data); + } + } + + return; +} + +/* Go recursively in the hierarchy + * and disable all the pb_types + */ +void rec_verilog_generate_sdc_disable_unused_pb_types(FILE* fp, + char* prefix, + t_pb_type* cur_pb_type) { + int ipb; + int mode_index; + char* pass_on_prefix = NULL; + + /* Skip print the level for the top-level pb_type, + * it has been printed outside + */ + if (NULL == cur_pb_type->parent_mode) { + pass_on_prefix = my_strdup(prefix); + } else { + /* Special prefix for primitive node*/ + /* generate pass_on_prefix */ + pass_on_prefix = (char*) my_malloc(sizeof(char) * + ( strlen(prefix) + 1 + + strlen(cur_pb_type->name) + 1 + 1)); + sprintf(pass_on_prefix, "%s/%s*", + prefix, cur_pb_type->name); + + /* Disable everything in this pb_type + * Use the spice_model_name of current pb_type + */ + fprintf(fp, "set_disable_timing "); + /* Print top-level hierarchy */ + fprintf(fp, "%s/*", + pass_on_prefix); + fprintf(fp, "\n"); + } + + /* Return if this is the primitive pb_type */ + if (TRUE == is_primitive_pb_type(cur_pb_type)) { + return; + } + + /* Go recursively */ + mode_index = find_pb_type_physical_mode_index(*cur_pb_type); + for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + rec_verilog_generate_sdc_disable_unused_pb_types(fp, pass_on_prefix, + &(cur_pb_type->modes[mode_index].pb_type_children[ipb])); + } + + /* Free */ + my_free(pass_on_prefix); + + return; +} + +/* This block is totally unused. + * We just go through each pb_type and disable all the ports using wildcards + */ +void verilog_generate_sdc_disable_one_unused_grid(FILE* fp, + t_type_ptr cur_grid_type, + int block_x, int block_y, + int block_z) { + char* prefix = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Build prefix, which is the top-level hierarchy */ + prefix = (char*) my_malloc(sizeof(char) * + ( strlen(gen_verilog_one_grid_instance_name(block_x, block_y)) + + 1 + + strlen(gen_verilog_one_phy_block_instance_name(cur_grid_type, block_z)) + + 2)); + sprintf(prefix, "%s/%s", + gen_verilog_one_grid_instance_name(block_x, block_y), + gen_verilog_one_phy_block_instance_name(cur_grid_type, block_z)); + + /* Print comments */ + fprintf(fp, + "####################################################\n"); + fprintf(fp, + "### Disable Timing for an unused Grid[%d][%d][%d] ###\n", + block_x, block_y, block_z); + fprintf(fp, + "#####################################################\n"); + + /* Disable everything under this level */ + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/*", prefix); + fprintf(fp, "\n"); + + /* Go recursively in the pb_type hierarchy */ + rec_verilog_generate_sdc_disable_unused_pb_types(fp, prefix, + cur_grid_type->pb_type); + + /* Free */ + my_free(prefix); + + return; +} + +/* The block is used for mapping logic circuits + * But typically, only part of the logic resources are used. + * This function will search the local_rr_graph of a phy_pb of the block + * And disable the unused resources in a SDC format + */ +void verilog_generate_sdc_disable_one_unused_block(FILE* fp, + t_block* cur_block) { + int inode; + t_phy_pb* cur_phy_pb = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Get the phy_pb */ + cur_phy_pb = (t_phy_pb*)(cur_block->phy_pb); + + /* Print comments */ + fprintf(fp, + "####################################################\n"); + fprintf(fp, + "### Disable Timing for a mapped Grid[%d][%d][%d] ###\n", + cur_block->x, cur_block->y, cur_block->z); + fprintf(fp, + "####################################################\n"); + + /* Search every nodes in the local_rr_graph */ + for (inode = 0; inode < cur_phy_pb->rr_graph->num_rr_nodes; inode++) { + /* Focus on the SOURCE and SINK rr_nodes */ + if ((SOURCE != cur_phy_pb->rr_graph->rr_node[inode].type) + && (SINK != cur_phy_pb->rr_graph->rr_node[inode].type)) { + continue; + } + /* Identify if the rr_node is usused */ + if (FALSE == is_rr_node_to_be_disable_for_analysis(&(cur_phy_pb->rr_graph->rr_node[inode]))) { + continue; + } + /* Get the pb_graph_pin */ + assert (NULL != cur_phy_pb->rr_graph->rr_node[inode].pb_graph_pin); + /* Disable the timing of this node */ + fprintf(fp, "set_disable_timing "); + /* Print top-level hierarchy */ + fprintf(fp, "%s/", + gen_verilog_one_grid_instance_name(cur_block->x, cur_block->y)); + fprintf(fp, "%s/", + gen_verilog_one_phy_block_instance_name(cur_block->type, cur_block->z)); + fprintf(fp, "%s", + gen_verilog_one_pb_graph_pin_full_name_in_hierarchy(cur_phy_pb->rr_graph->rr_node[inode].pb_graph_pin)); + fprintf(fp, "\n"); + } + + return; +} + +void verilog_generate_sdc_disable_unused_grids(FILE* fp, + int LL_nx, int LL_ny, + t_grid_tile** LL_grid, + t_block* LL_block) { + int ix, iy, iblk; + int blk_id; + t_type_ptr type = NULL; + boolean* grid_usage = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + for (ix = 0; ix < (LL_nx + 2); ix++) { + for (iy = 0; iy < (LL_ny + 2); iy++) { + type = LL_grid[ix][iy].type; + /* bypass EMPTY type */ + if ((NULL == type) || (EMPTY_TYPE == type)) { + continue; + } + /* Allocate usage and initialize to unused */ + grid_usage = (boolean*) my_calloc(type->capacity, sizeof(boolean)); + for (iblk = 0; iblk < type->capacity; iblk++) { + grid_usage[iblk] = FALSE; + } + /* Print comments */ + fprintf(fp, + "#######################################\n"); + fprintf(fp, + "### Disable Timing for Grid[%d][%d] ###\n", + ix, iy); + fprintf(fp, + "#######################################\n"); + /* For used grid, find the unused rr_node in the local rr_graph and disable the pb_graph_pin */ + for (iblk = 0; iblk < LL_grid[ix][iy].usage; iblk++) { + blk_id = LL_grid[ix][iy].blocks[iblk]; + assert( (OPEN < LL_block[blk_id].z) && (LL_block[blk_id].z < type->capacity) ); + /* Label the grid_usage */ + grid_usage[LL_block[blk_id].z] = TRUE; + verilog_generate_sdc_disable_one_unused_block(fp, + &(LL_block[blk_id])); + } + /* For unused grid, disable all the pins in the physical_pb_type */ + for (iblk = 0; iblk < type->capacity; iblk++) { + /* Bypass used blocks */ + if (TRUE == grid_usage[iblk]) { + continue; + } + verilog_generate_sdc_disable_one_unused_grid(fp, + LL_grid[ix][iy].type, + ix, iy, + iblk); + continue; + } + } + } + + /* Free */ + my_free(grid_usage); + + return; +} + +void verilog_generate_sdc_disable_unused_grids_muxs(FILE* fp, + int LL_nx, int LL_ny, + t_grid_tile** LL_grid, + t_block* LL_block) { + + int ix, iy, iblk, itype, i_num_rr_nodes, i_fan_in; + int blk_id; + t_type_ptr type; + t_phy_pb* cur_phy_pb; + t_rr_graph* cur_rr_graph; + t_rr_node* cur_rr_node; + char* grid_instance_name=NULL; + char* grid_sub_instance_name=NULL; + char* grid_prefix=NULL; + + + + for (ix = 1; ix < (LL_nx + 1); ix++) { + for (iy = 1; iy < (LL_ny + 1); iy++) { + type = LL_grid[ix][iy].type; + /* Print comments */ + fprintf(fp, + "###########################################\n"); + fprintf(fp, + "### Disable Timing for Grid[%d][%d] MUXES ###\n", + ix, iy); + fprintf(fp, + "###########################################\n"); + + grid_instance_name = (char *) my_malloc(sizeof(char) * strlen(gen_verilog_one_grid_instance_name(ix, iy)) + 1); + grid_instance_name = gen_verilog_one_grid_instance_name(ix, iy); + for (iblk = 0; iblk < LL_grid[ix][iy].usage; iblk++) { + blk_id = LL_grid[ix][iy].blocks[iblk]; + grid_sub_instance_name = gen_verilog_one_phy_block_instance_name(type, LL_block[blk_id].z); + grid_prefix = (char *) my_malloc(sizeof(char) * (strlen(grid_instance_name) + 1 + strlen(grid_sub_instance_name) + 1)); + sprintf (grid_prefix, "%s/%s", grid_instance_name, grid_sub_instance_name); + cur_phy_pb = (t_phy_pb*) LL_block[blk_id].phy_pb; + if (NULL != cur_phy_pb) { + cur_rr_graph = cur_phy_pb->rr_graph; + for (itype = 0; itype < num_types; itype++){ + if (FILL_TYPE == &type_descriptors[itype]){ + dump_sdc_one_clb_muxes(fp, grid_prefix, cur_rr_graph, type_descriptors[itype].pb_graph_head); + } + } + } + my_free(grid_sub_instance_name); + my_free(grid_prefix); + } + my_free(grid_instance_name); + } + } + return; +} + +/* Head function of the recursive generation of the sdc constraints + * on the muxes inside of the CLBs */ +void dump_sdc_one_clb_muxes(FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_node* pb_graph_head) { + + /* Give head of the pb_graph to the recursive function*/ + dump_sdc_rec_one_pb_muxes(fp, grid_instance_name, rr_graph, pb_graph_head); + + return; +} + +/* Recursive function going to the leaf nodes of the graph and dumping + * the sdc constraints for the current node. We use the id present inside + * of the rr_graph to comment the active path and the fan_in and name + * inside of the pb_graph to dump the name of the port we need to disable*/ +void dump_sdc_rec_one_pb_muxes(FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_node* cur_pb_graph_node) { + + int mode_index; + int ipb, jpb, child_mode_index; + t_pb_type* cur_pb_type = NULL; + + cur_pb_type = cur_pb_graph_node->pb_type; + + if (TRUE == is_primitive_pb_type(cur_pb_type )) { + return; + } + mode_index = find_pb_type_physical_mode_index(*cur_pb_type); + for(ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for(jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++) { + dump_sdc_rec_one_pb_muxes(fp, grid_instance_name, rr_graph, + &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb])); + } + } + dump_sdc_pb_graph_node_muxes(fp, grid_instance_name, rr_graph, + cur_pb_graph_node); + + return; +} + +void dump_sdc_pb_graph_node_muxes (FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_node* pb_graph_node) { + int i_pin, i_port; + // Input pins + for (i_port = 0; i_port< pb_graph_node->num_input_ports; i_port++) { + for (i_pin = 0; i_pin < pb_graph_node->num_input_pins[i_port]; i_pin++) { + dump_sdc_pb_graph_pin_muxes (fp, grid_instance_name, rr_graph, pb_graph_node->input_pins[i_port][i_pin]); + } + } + // Output pins + for (i_port = 0; i_port< pb_graph_node->num_output_ports; i_port++) { + for (i_pin = 0; i_pin < pb_graph_node->num_output_pins[i_port]; i_pin++) { + dump_sdc_pb_graph_pin_muxes (fp, grid_instance_name, rr_graph, pb_graph_node->output_pins[i_port][i_pin]); + } + } + // Clock pins + for (i_port = 0; i_port< pb_graph_node->num_clock_ports; i_port++) { + for (i_pin = 0; i_pin < pb_graph_node->num_clock_pins[i_port]; i_pin++) { + dump_sdc_pb_graph_pin_muxes (fp, grid_instance_name, rr_graph, pb_graph_node->clock_pins[i_port][i_pin]); + } + } + return; +} + +void dump_sdc_pb_graph_pin_muxes (FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_pin pb_graph_pin) { + int i_fan_in, datapath_id, fan_in; + int level_changing = 0; + int mode_index; + int num_mux_input; + t_spice_model* mux_spice_model; + t_rr_node cur_node = rr_graph->rr_node[pb_graph_pin.rr_node_index_physical_pb]; + t_pb_type* cur_pb_type = pb_graph_pin.parent_node->pb_type; + int cur_mode_index = find_pb_type_physical_mode_index(*cur_pb_type); + t_mode* cur_mode = cur_pb_type->modes; + t_interconnect* cur_interc; + + /* There are three types of interconnection: same level, going down a level, going up a level + * Since we check the fan_in, we need to get the right input edge mode */ + if (0 == pb_graph_pin.num_input_edges || 0 == pb_graph_pin.num_output_edges) { + return; + } + if (pb_graph_pin.input_edges[cur_mode_index]->interconnect->parent_mode != pb_graph_pin.output_edges[cur_mode_index]->interconnect->parent_mode) { + if (pb_graph_pin.input_edges[cur_mode_index]->interconnect->parent_mode != cur_mode) { + cur_mode = pb_graph_pin.input_edges[cur_mode_index]->interconnect->parent_mode; + level_changing = 1; + } + } + + find_interc_fan_in_des_pb_graph_pin(&pb_graph_pin, cur_mode, &cur_interc, &fan_in); + + if (0 == fan_in || 1 == fan_in) { + return; /* Returns if there is no mux */ + } + /* Handle DEFAULT PATH ID */ + datapath_id = cur_node.id_path; + if (DEFAULT_PATH_ID == datapath_id) { + mux_spice_model = cur_interc->spice_model; + datapath_id = get_mux_default_path_id(mux_spice_model, fan_in, datapath_id); + /* Either the default is the last pin or the num 0. If fan_in was 0, we wouldn't be here + * so if the next condition works, datapath_id is actually 1 too far */ + if (fan_in == datapath_id) { + datapath_id --; + } + } else { + assert((DEFAULT_PATH_ID < datapath_id)&&(datapath_id < fan_in)); + } + for (i_fan_in=0 ; i_fan_in < fan_in ; i_fan_in++) { + if (i_fan_in == datapath_id) { + fprintf(fp, "#"); + } + if (0 == level_changing) { + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/%s%s/in[%d]\n", grid_instance_name, + gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_node.pb_graph_pin), + pb_graph_pin.name_mux, i_fan_in); + } + if (1 == level_changing) { + fprintf(fp, "set_disable_timing "); + fprintf(fp, "%s/%s%s/in[%d]\n", grid_instance_name, + gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_grand_parent_node(cur_node.pb_graph_pin), + pb_graph_pin.name_mux, i_fan_in); + } + // Hierarchical dumping. Might be broken if extending the software hence going through a more direct method. + //fprintf(fp, "set_disable_timing [get_pins -filter \"hierarchical_name ="); + //fprintf(fp, "~ *%s/in[%d]\" -of_objects [get_cells -hier -filter ", + // pb_graph_pin->name_mux, i_fan_in); + //printf("%s", pb_graph_pin->name_mux); + + //fprintf(fp, "\"hierarchical_name =~ %s*\"]]", + // grid_instance_name); + // Might need to comment here the name of the verilog pin connected to ease the debugging + //fprintf(fp, "\n"); + } + return; +} + +/* Generate SDC constaints for inputs and outputs + * We consider the top module in formal verification purpose here + * which is easier + */ +void verilog_generate_sdc_input_output_delays(FILE* fp, + char* circuit_name, + float critical_path_delay) { + int iopad_idx, iblock, iport; + int found_mapped_inpad; + char* port_name = NULL; + int num_clock_ports = 0; + t_spice_model_port** clock_port = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Get clock port from the global port */ + get_fpga_x2p_global_op_clock_ports(global_ports_head, &num_clock_ports, &clock_port); + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Create clock #\n"); + fprintf(fp, + "##################################################\n"); + + /* Create a clock */ + for (iport = 0; iport < num_clock_ports; iport++) { + fprintf(fp, "create_clock "); + fprintf(fp, "%s -period %.4g -waveform {0 %.4g}\n", + clock_port[iport]->prefix, + critical_path_delay, critical_path_delay/2); + } + + /* Print comments */ + fprintf(fp, + "##################################################\n"); + fprintf(fp, + "### Create input and output delays #\n"); + fprintf(fp, + "##################################################\n"); + + fprintf(fp, "set input_pins \"\"\n"); + fprintf(fp, "set output_pins \"\"\n"); + assert(NULL != iopad_verilog_model); + for (iopad_idx = 0; iopad_idx < iopad_verilog_model->cnt; iopad_idx++) { + /* Find if this inpad is mapped to a logical block */ + found_mapped_inpad = 0; + /* Malloc and assign port_name */ + port_name = gen_verilog_top_module_io_port_prefix(gio_inout_prefix, iopad_verilog_model->prefix); + /* Find the linked logical block */ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* Bypass OUTPAD: donot put any voltage stimuli */ + /* Make sure We find the correct logical block !*/ + if ((iopad_verilog_model == logical_block[iblock].mapped_spice_model) + &&(iopad_idx == logical_block[iblock].mapped_spice_model_index)) { + /* Output PAD only need a short connection */ + if (VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, "set_output_delay "); + fprintf(fp, "-clock "); + /*for (iport = 0; iport < num_clock_ports; iport++) { + fprintf(fp, "%s ", + clock_port[iport]->prefix); + }*/ + fprintf(fp, "[get_clocks] "); + fprintf(fp, "-max %.4g ", + critical_path_delay); + dump_verilog_generic_port_no_repeat(fp, VERILOG_PORT_CONKT, + port_name, + iopad_idx, iopad_idx); + fprintf(fp, "\n"); + found_mapped_inpad = 1; + fprintf(fp, "append output_pins \"%s[%d] \"\n",port_name ,iopad_idx); + break; + } + /* Input PAD may drive a clock net or a constant generator */ + assert(VPACK_INPAD == logical_block[iblock].type); + /* clock net or constant generator should be disabled in timing analysis */ + if (TRUE == logical_block[iblock].is_clock) { + break; + } + fprintf(fp, "set_input_delay "); + fprintf(fp, "-clock "); + /*for (iport = 0; iport < num_clock_ports; iport++) { + fprintf(fp, "%s ", + clock_port[iport]->prefix); + }*/ + fprintf(fp, "[get_clocks] "); + fprintf(fp, "-max 0 "); + dump_verilog_generic_port_no_repeat(fp, VERILOG_PORT_CONKT, + port_name, + iopad_idx, iopad_idx); + fprintf(fp, "\n"); + found_mapped_inpad = 1; + fprintf(fp, "append input_pins \"%s[%d] \"\n",port_name ,iopad_idx); + + } + } + assert((0 == found_mapped_inpad)||(1 == found_mapped_inpad)); + /* If we find one iopad already, we finished in this round here */ + if (1 == found_mapped_inpad) { + /* Free */ + my_free(port_name); + continue; + } + /* if we cannot find any mapped inpad from tech.-mapped netlist, set the disable timing! */ + fprintf(fp, "set_disable_timing "); + dump_verilog_generic_port_no_repeat(fp, VERILOG_PORT_CONKT, + port_name, + iopad_idx, iopad_idx); + fprintf(fp, "\n"); + /* Free */ + my_free(port_name); + } + + /* Free */ + my_free(clock_port); + + return; +} + +void verilog_generate_sdc_pnr(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + int LL_nx, int LL_ny, t_grid_tile** LL_grid, + t_syn_verilog_opts fpga_verilog_opts) { + t_sdc_opts sdc_opts; + + /* Initialize */ + sdc_opts.sdc_dir = my_strdup(sdc_dir); + sdc_opts.constrain_pbs = TRUE; + sdc_opts.constrain_routing_channels = TRUE; + sdc_opts.constrain_sbs = TRUE; + sdc_opts.constrain_cbs = TRUE; + sdc_opts.break_loops = TRUE; + sdc_opts.break_loops_mux = FALSE; /* By default, we turn it off to avoid a overkill */ + + /* Part 1. Constrain clock cycles */ + verilog_generate_sdc_clock_period(sdc_opts, arch.spice->spice_params.stimulate_params.vpr_crit_path_delay); + + /* Part 2. Output Design Constraints for breaking loops */ + if (TRUE == sdc_opts.break_loops) { + verilog_generate_sdc_break_loops(cur_sram_orgz_info, sdc_opts, + LL_nx, LL_ny, + routing_arch->num_switch, switch_inf, + arch.spice, + routing_arch); + } + + /* Part 3. Output routing constraints for Switch Blocks */ + if (TRUE == sdc_opts.constrain_sbs) { + verilog_generate_sdc_constrain_sbs(cur_sram_orgz_info, sdc_opts, + LL_nx, LL_ny, + routing_arch->num_switch, switch_inf, + arch.spice); + } + + /* Part 4. Output routing constraints for Connection Blocks */ + if (TRUE == sdc_opts.constrain_cbs) { + verilog_generate_sdc_constrain_cbs(cur_sram_orgz_info, sdc_opts, + LL_nx, LL_ny, + routing_arch->num_switch, switch_inf, + arch.spice); + } + + /* Part 5. Output routing constraints for Connection Blocks */ + if (TRUE == sdc_opts.constrain_routing_channels) { + verilog_generate_sdc_constrain_routing_channels(cur_sram_orgz_info, sdc_opts, arch, + LL_nx, LL_ny, + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, LL_rr_indexed_data, + arch.spice); + } + + /* Part 6. Output routing constraints for Programmable blocks */ + if (TRUE == sdc_opts.constrain_pbs) { + verilog_generate_sdc_constrain_pb_types(cur_sram_orgz_info, + sdc_dir); + } + + return; +} + +/* Output a SDC file to constrain a FPGA mapped with a benchmark */ +void verilog_generate_sdc_analysis(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir, + char* circuit_name, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + int LL_nx, int LL_ny, t_grid_tile** LL_grid, + t_block* LL_block, + t_syn_verilog_opts fpga_verilog_opts) { + FILE* fp = NULL; + char* fname = my_strcat(sdc_dir, sdc_analysis_file_name); + + vpr_printf(TIO_MESSAGE_INFO, + "Generating SDC for Timing/Power analysis on the mapped FPGA: %s ...\n", + fname); + + /* Create file handler */ + fp = fopen(fname, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create SDC constraints %s", + __FILE__, __LINE__, fname); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_sdc_file_header(fp, "Constrain for Timing/Power analysis on the mapped FPGA"); + + /* Create clock and set input/output delays */ + verilog_generate_sdc_input_output_delays(fp, circuit_name, + arch.spice->spice_params.stimulate_params.vpr_crit_path_delay); + + /* Disable the timing for global ports */ + verilog_generate_sdc_disable_global_ports(fp); + + /* Disable the timing for configuration cells */ + verilog_generate_sdc_disable_sram_orgz(fp, cur_sram_orgz_info); + + /* Disable timing for un-used resources */ + /* Apply to Routing Channels */ + verilog_generate_sdc_disable_unused_routing_channels(fp, arch, LL_nx, LL_ny, + LL_num_rr_nodes, LL_rr_node, + LL_rr_node_indices, LL_rr_indexed_data); + + /* Apply to Connection blocks */ + verilog_generate_sdc_disable_unused_cbs(fp, LL_nx, LL_ny, + routing_arch->num_switch, switch_inf, + arch.spice); + verilog_generate_sdc_disable_unused_cbs_muxs(fp); + + /* Apply to Switch blocks */ + verilog_generate_sdc_disable_unused_sbs(fp, LL_nx, LL_ny, + routing_arch->num_switch, switch_inf, + arch.spice); + + verilog_generate_sdc_disable_unused_sbs_muxs(fp, LL_nx, LL_ny); + + /* Apply to Grids */ + verilog_generate_sdc_disable_unused_grids(fp, LL_nx, LL_ny, LL_grid, LL_block); + verilog_generate_sdc_disable_unused_grids_muxs(fp, LL_nx, LL_ny, LL_grid, LL_block); + + /* Close the file*/ + fclose(fp); + + /* Free strings */ + my_free(fname); + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.h new file mode 100644 index 000000000..e3a369713 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.h @@ -0,0 +1,53 @@ + +void verilog_generate_sdc_pnr(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + int LL_nx, int LL_ny, t_grid_tile** LL_grid, + t_syn_verilog_opts fpga_verilog_opts); + +void verilog_generate_sdc_analysis(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir, + char* circuit_name, + t_arch arch, + t_det_routing_arch* routing_arch, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices, + t_rr_indexed_data* LL_rr_indexed_data, + int LL_nx, int LL_ny, t_grid_tile** LL_grid, + t_block* LL_block, + t_syn_verilog_opts fpga_verilog_opts); + +void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp, int LL_nx, int LL_ny); + +void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp); + +void verilog_generate_sdc_disable_unused_grids_muxs(FILE* fp, + int LL_nx, int LL_ny, + t_grid_tile** LL_grid, + t_block* LL_block); + +void dump_sdc_one_clb_muxes(FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_node* pb_graph_head); + + +void dump_sdc_rec_one_pb_muxes(FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_node* cur_pb_graph_node); + +void dump_sdc_pb_graph_node_muxes(FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_node* cur_pb_graph_node); + +void dump_sdc_pb_graph_pin_muxes (FILE* fp, + char* grid_instance_name, + t_rr_graph* rr_graph, + t_pb_graph_pin pb_graph_pin); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.c new file mode 100644 index 000000000..d1d5b9e17 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.c @@ -0,0 +1,519 @@ +/***********************************/ +/* SDC Generation dumping */ +/* Xifan TANG, EPFL/LSI */ +/* Baudouin Chauviere LNIS */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "path_delay.h" +#include "stats.h" +#include "route_common.h" + +/* Include FPGA-SPICE utils */ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" + +/* Include SynVerilog headers */ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_submodules.h" +#include "verilog_pbtypes.h" +#include "verilog_routing.h" +#include "verilog_compact_netlist.h" +#include "verilog_top_testbench.h" +#include "verilog_autocheck_top_testbench.h" +#include "verilog_verification_top_netlist.h" +#include "verilog_modelsim_autodeck.h" +#include "verilog_report_timing.h" +#include "verilog_sdc.h" +#include "verilog_formality_autodeck.h" +#include "verilog_sdc_pb_types.h" + + +void sdc_dump_annotation(char* from_path, // includes the cell + char* to_path, + FILE* fp, + t_interconnect interconnect){ + //char* min_value = NULL; + float max_value = NULL; + int i,j; + + // Find in the annotations the min and max + + for (i=0; i < interconnect.num_annotations; i++) { + if (E_ANNOT_PIN_TO_PIN_DELAY == interconnect.annotations[i].type) { + for (j=0; j < interconnect.annotations[i].num_value_prop_pairs; j++) { + /* if (E_ANNOT_PIN_TO_PIN_DELAY_MIN == interconnect.annotations[i].prop[j]) { + min_value = interconnect.annotations[i].value[j]; + }*/ + if(E_ANNOT_PIN_TO_PIN_DELAY_MAX == interconnect.annotations[i].prop[j]) { + max_value = atof(interconnect.annotations[i].value[j]); + max_value = max_value*pow(10,9); /* converts sec in ns */ + } + } + } + } + + + // Dump the annotation + // If no annotation was found, dump 0 + + /* fprintf (fp, "set_min_delay -from %s -to %s ", from_path,to_path); + if (NULL != min_value) { + fprintf(fp, "%s\n", min_value); + } else { + fprintf(fp, "0\n"); + } */ + + /*fprintf (fp, "set_max_delay -from %s -to %s ", from_path, to_path); + if (max_value != NULL){ + fprintf (fp,"%s\n",max_value); + } else { + fprintf (fp,"0\n"); + }*/ + if (max_value != NULL){ + fprintf (fp, "set_max_delay -from %s -to %s ", from_path, to_path); + fprintf (fp,"%f\n", max_value); + } +return; +} + + +void dump_sdc_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, + t_pb_graph_pin* des_pb_graph_pin, + t_mode* cur_mode, + char* instance_name) { + int iedge, ipin; + int fan_in = 0; + t_interconnect* cur_interc = NULL; + enum e_interconnect verilog_interc_type = DIRECT_INTERC; + + t_pb_graph_pin* src_pb_graph_pin = NULL; + t_pb_graph_node* src_pb_graph_node = NULL; + t_pb_type* src_pb_type = NULL; + + t_pb_graph_node* des_pb_graph_node = NULL; + + char* from_path_int = NULL; + char* to_path_int = NULL; + char* from_path = NULL; + char* to_path = NULL; + boolean interc_is_disabled = FALSE; + + char* set_disable_path; + t_pb_graph_pin* cur_pin_disable; + char* input_buffer_path; + char* input_buffer_name; + char* input_buffer_in; + char* input_buffer_out; + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf (TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* 1. identify pin interconnection type, + * 2. Identify the number of fan-in (Consider interconnection edges of only selected mode) + * 3. Select and print the SPICE netlist + */ + fan_in = 0; + cur_interc = NULL; + find_interc_fan_in_des_pb_graph_pin (des_pb_graph_pin, cur_mode, &cur_interc, &fan_in); + if ((NULL == cur_interc) || (0 == fan_in)) { + /* No interconnection matched */ + /* Connect this pin to GND for better convergence */ + /* TODO: find the correct pin name!!!*/ + /* + dump_verilog_dangling_des_pb_graph_pin_interc(fp, des_pb_graph_pin, cur_mode, pin2pin_interc_type, + formatted_parent_pin_prefix); + */ + return; + } + /* Initialize the interconnection type that will be implemented in SPICE netlist*/ + verilog_interc_type = determine_actual_pb_interc_type (cur_interc, fan_in); + /* This time, (2nd round), we print the subckt, according to interc type*/ + switch (verilog_interc_type) { + case DIRECT_INTERC: + /* Check : + * 1. Direct interc has only one fan-in! + */ + assert (1 == fan_in); + //assert(1 == des_pb_graph_pin->num_input_edges); + /* For more than one mode defined, the direct interc has more than one input_edge , + * We need to find which edge is connected the pin we want + */ + for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { + if (cur_interc == des_pb_graph_pin->input_edges[iedge]->interconnect) { + break; + } + } + assert (iedge < des_pb_graph_pin->num_input_edges); + /* 2. spice_model is a wire */ + assert (NULL != cur_interc->spice_model); + assert (SPICE_MODEL_WIRE == cur_interc->spice_model->type); + assert (NULL != cur_interc->spice_model->wire_param); + /* Initialize*/ + /* Source pin, node, pb_type*/ + src_pb_graph_pin = des_pb_graph_pin->input_edges[iedge]->input_pins[0]; + src_pb_graph_node = src_pb_graph_pin->parent_node; + src_pb_type = src_pb_graph_node->pb_type; + /* Des pin, node, pb_type */ + des_pb_graph_node = des_pb_graph_pin->parent_node; + + /* if clock, clock tree synthesis will take care of the timings */ + if (TRUE == src_pb_graph_pin->port->is_clock || + TRUE == des_pb_graph_pin->port->is_clock) { + return; + } + // Generation of the paths for the dumping of the annotations + from_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin)) + 1)); + sprintf (from_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin)); + to_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin)) + 1)); + sprintf (to_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin)); + + // Dumping of the annotations + sdc_dump_annotation (from_path, to_path, fp, cur_interc[0]); + break; + case COMPLETE_INTERC: + case MUX_INTERC: + /* Check : + * MUX should have at least 2 fan_in + */ + assert ((2 == fan_in) || (2 < fan_in)); + /* 2. spice_model is a wire */ + assert (NULL != cur_interc->spice_model); + assert (SPICE_MODEL_MUX == cur_interc->spice_model->type); + ipin = 0; + for (iedge = 0; iedge < des_pb_graph_pin->num_input_edges; iedge++) { + if (cur_mode != des_pb_graph_pin->input_edges[iedge]->interconnect->parent_mode) { + continue; + } + check_pb_graph_edge(*(des_pb_graph_pin->input_edges[iedge])); + /* Initialize*/ + /* Source pin, node, pb_type*/ + src_pb_graph_pin = des_pb_graph_pin->input_edges[iedge]->input_pins[0]; + src_pb_graph_node = src_pb_graph_pin->parent_node; + src_pb_type = src_pb_graph_node->pb_type; + /* Des pin, node, pb_type */ + des_pb_graph_node = des_pb_graph_pin->parent_node; + + /* If the pin is disabled, the dumping is different. We need to use the + * input and output of the inverter of the mux */ + if (TRUE == des_pb_graph_pin->input_edges[iedge]->is_disabled) { + /* We need to find the highest node between src and des */ + if (src_pb_graph_node->parent_pb_graph_node == des_pb_graph_node->parent_pb_graph_node) { + cur_pin_disable = src_pb_graph_pin->parent_node->parent_pb_graph_node->input_pins[0]; + } + else if (src_pb_graph_node->parent_pb_graph_node == des_pb_graph_node) { + cur_pin_disable = des_pb_graph_pin; + } + else { + cur_pin_disable = src_pb_graph_pin; + } + if (cur_interc->spice_model->input_buffer == NULL) { + vpr_printf (TIO_MESSAGE_ERROR, + "The loop_breaker annotation can only be applied when there is an input buffer"); + } + input_buffer_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + + strlen (gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable)) + 1 + + strlen (cur_interc->spice_model->name) + 5 + strlen(my_itoa(cur_interc->fan_in)) + 1 + + strlen (my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_mux)) + 1 + 1)); + if (0 == strcmp("",gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable))) { + sprintf (input_buffer_path, "%s/%s_size%d_%d_",instance_name, + cur_interc->spice_model->name, cur_interc->fan_in, + des_pb_graph_pin->input_edges[iedge]->nb_mux); + } + else { + sprintf (input_buffer_path, "%s/%s%s_size%d_%d_",instance_name, + gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable), + cur_interc->spice_model->name, cur_interc->fan_in , + des_pb_graph_pin->input_edges[iedge]->nb_mux); + } + input_buffer_name = cur_interc ->spice_model->input_buffer->spice_model_name; + input_buffer_in = cur_interc ->spice_model->input_buffer->spice_model->ports[0].lib_name; + input_buffer_out = cur_interc ->spice_model->input_buffer->spice_model->ports[1].lib_name; + set_disable_path = (char*) my_malloc(sizeof(char)*(strlen(input_buffer_path) + 1 + strlen(input_buffer_name) + + 1 + strlen(my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_pin)))); + sprintf(set_disable_path, "%s/%s_%d_", input_buffer_path, input_buffer_name, + des_pb_graph_pin->input_edges[iedge]->nb_pin); + + fprintf (fp, "set_disable_timing -from %s -to %s %s \n", input_buffer_in, input_buffer_out, set_disable_path); + free(input_buffer_path); + free(set_disable_path); + } + else { + // Generation of the paths for the dumping of the annotations + from_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin)) + 1)); + sprintf (from_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin)); + to_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin)) + 1)); + sprintf (to_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin)); + // Dumping of the annotations + sdc_dump_annotation (from_path, to_path, fp, cur_interc[0]); + } + } + break; + + + default: + vpr_printf (TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid interconnection type for %s (Arch[LINE%d])!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + + return; +} + + +/* Print the SPICE interconnections of a port defined in pb_graph */ +void dump_sdc_pb_graph_port_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + enum e_spice_pb_port_type pb_port_type, + t_mode* cur_mode, + char* instance_name) { + int iport, ipin; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf (TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + switch (pb_port_type) { + case SPICE_PB_PORT_INPUT: + for (iport = 0; iport < cur_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_input_pins[iport]; ipin++) { + /* If this is a idle block, we set 0 to the selected edge*/ + /* Get the selected edge of current pin*/ + dump_sdc_pb_graph_pin_interc (cur_sram_orgz_info, + fp, + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->input_pins[iport][ipin]), + cur_mode, + instance_name); + } + } + break; + case SPICE_PB_PORT_OUTPUT: + for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) { + dump_sdc_pb_graph_pin_interc(cur_sram_orgz_info, + fp, + OUTPUT2OUTPUT_INTERC, + &(cur_pb_graph_node->output_pins[iport][ipin]), + cur_mode, + instance_name); + } + } + break; + case SPICE_PB_PORT_CLOCK: + for (iport = 0; iport < cur_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < cur_pb_graph_node->num_clock_pins[iport]; ipin++) { + dump_sdc_pb_graph_pin_interc(cur_sram_orgz_info, + fp, + INPUT2INPUT_INTERC, + &(cur_pb_graph_node->clock_pins[iport][ipin]), + cur_mode, + instance_name); + } + } + break; + default: + vpr_printf (TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid pb port type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +void sdc_dump_cur_node_constraints(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + int select_mode_index, + char* instance_name) { + int ipb, jpb; + t_mode* cur_mode = NULL; + t_pb_type* cur_pb_type = cur_pb_graph_node->pb_type; + t_pb_graph_node* child_pb_graph_node = NULL; + + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf (TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + /* Check cur_pb_type*/ + if (NULL == cur_pb_type) { + vpr_printf (TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_type.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Assign current mode */ + cur_mode = &(cur_pb_graph_node->pb_type->modes[select_mode_index]); + + /* We check output_pins of cur_pb_graph_node and its the input_edges + * Built the interconnections between outputs of cur_pb_graph_node and outputs of child_pb_graph_node + * child_pb_graph_node.output_pins -----------------> cur_pb_graph_node.outpins + * /|\ + * | + * input_pins, edges, output_pins + */ + dump_sdc_pb_graph_port_interc(cur_sram_orgz_info, fp, + cur_pb_graph_node, + SPICE_PB_PORT_OUTPUT, + cur_mode, + instance_name); + + /* We check input_pins of child_pb_graph_node and its the input_edges + * Built the interconnections between inputs of cur_pb_graph_node and inputs of child_pb_graph_node + * cur_pb_graph_node.input_pins -----------------> child_pb_graph_node.input_pins + * /|\ + * | + * input_pins, edges, output_pins + */ + for (ipb = 0; ipb < cur_pb_type->modes[select_mode_index].num_pb_type_children; ipb++) { + for (jpb = 0; jpb < cur_pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) { + child_pb_graph_node = &(cur_pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]); + /* For each child_pb_graph_node input pins*/ + dump_sdc_pb_graph_port_interc(cur_sram_orgz_info, fp, + child_pb_graph_node, + SPICE_PB_PORT_INPUT, + cur_mode, + instance_name); + /* TODO: for clock pins, we should do the same work */ + dump_sdc_pb_graph_port_interc(cur_sram_orgz_info, fp, + child_pb_graph_node, + SPICE_PB_PORT_CLOCK, + cur_mode, + instance_name); + } + } + return; +} + +void sdc_rec_dump_child_pb_graph_node(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + char* instance_name) { + + int mode_index, ipb, jpb, child_mode_index; + t_pb_type* cur_pb_type = NULL; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",__FILE__, __LINE__); + exit(1); + } +/* Check current node */ + if (NULL == cur_pb_graph_node) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid cur_pb_graph_node.\n",__FILE__, __LINE__); + exit(1); + } + cur_pb_type = cur_pb_graph_node->pb_type; + +/* First we only go through the graph through the physical nodes. The other modes don't have sdc constraints. We then check all the children nodes and repeat the operation until arriving to the leaf nodes. + * Once at the leaf, all the edges are dumped with a default set_min/max_delay of 0 if non is user-defined. + * Contrary to the verilog, because the interconnections can get tricky through shift registers, carry-chains and all, we do not use wild cards or instantiation to be sure to completely constrain our design. + */ +/* Recursively finish all the child pb types */ + if (FALSE == is_primitive_pb_type(cur_pb_type)) { + /* Find the mode that defines the physical mode*/ + mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); + for(ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { + for(jpb = 0; jpb < cur_pb_type->modes[mode_index].pb_type_children[ipb].num_pb; jpb++){ + /* Contrary to the verilog, we do not need to keep the prefix + * We go done to every child node to dump the constraints now*/ + sdc_rec_dump_child_pb_graph_node(cur_sram_orgz_info, fp, &(cur_pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]), instance_name); + } + } + sdc_dump_cur_node_constraints(cur_sram_orgz_info, fp, cur_pb_graph_node, mode_index, instance_name); // graph_head only has one pb_type + } + +return; +} + +void sdc_dump_all_pb_graph_nodes(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int type_descriptors_mode, + char* instance_name){ + + // Give head of the pb_graph to the recursive function + sdc_rec_dump_child_pb_graph_node (cur_sram_orgz_info, fp, type_descriptors[type_descriptors_mode].pb_graph_head, instance_name); + +return; +} + +void dump_sdc_physical_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_path, + int type_descriptor_mode, + char* instance_name) { + + FILE* fp; + + /* Check if the path exists*/ + fp = fopen (sdc_path,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in creating SDC for constraining Primitive Blocks %s!",__FILE__, __LINE__, sdc_path); + exit(1); +} + + vpr_printf (TIO_MESSAGE_INFO, "Generating SDC for constraining Primitive Blocks in P&R flow: (%s)...\n", + sdc_path); + + + // Launch a recursive function to visit all the nodes of the correct mode + sdc_dump_all_pb_graph_nodes(fp, cur_sram_orgz_info, type_descriptor_mode, instance_name); + + +/* close file */ + fclose(fp); + +return; +} + + +void verilog_generate_sdc_constrain_pb_types(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir) { + + int itype; + char* sdc_path; + char* instance_name; + + sdc_path = my_strcat (sdc_dir, sdc_constrain_pb_type_file_name); // Global var + + for (itype = 0; itype < num_types; itype++){ + if (FILL_TYPE == &type_descriptors[itype]){ + instance_name = gen_verilog_one_phy_block_instance_name(&type_descriptors[itype],0); /* it is 0 because the CLBs only have 1 block.*/ + dump_sdc_physical_blocks(cur_sram_orgz_info, sdc_path, itype, instance_name); + } + } +return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.h new file mode 100644 index 000000000..528e2ad5d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc_pb_types.h @@ -0,0 +1,43 @@ + +void sdc_dump_annotation(char* from_path, // includes the cell + char* to_path, + FILE* fp, + t_interconnect interconnect); + +void dump_sdc_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_spice_pin2pin_interc_type pin2pin_interc_type, + t_pb_graph_pin* des_pb_graph_pin, + t_mode* cur_mode, + char* instance_name); + +void dump_sdc_pb_graph_port_interc(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + enum e_spice_pb_port_type pb_port_type, + t_mode* cur_mode, + char* instance_name); + +void sdc_dump_cur_node_constraints(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + int select_mode_index, + char* instance_name); + +void sdc_rec_dump_child_pb_graph_node(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_pb_graph_node* cur_pb_graph_node, + char* instance_name); + +void sdc_dump_all_pb_graph_nodes(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int type_descriptor_mode, + char* instance_name); + +void dump_sdc_physical_blocks(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_path, + int type_descriptor_mode, + char* instance_name); + +void verilog_generate_sdc_constrain_pb_types(t_sram_orgz_info* cur_sram_orgz_info, + char* sdc_dir); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c similarity index 56% rename from vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c index 38198c4eb..5db4558c6 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_submodules.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c @@ -23,14 +23,18 @@ /* Include FPGA-SPICE utils */ #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "spice_mux.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_bitstream_utils.h" /* Include verilog utils */ #include "verilog_global.h" #include "verilog_utils.h" #include "verilog_pbtypes.h" +#include "verilog_decoder.h" + +/***** Subroutines *****/ void dump_verilog_submodule_timing(FILE* fp, t_spice_model* cur_spice_model) { @@ -57,7 +61,7 @@ void dump_verilog_submodule_timing(FILE* fp, exit(1); } - fprintf(fp, "\n`ifdef %s\n", verilog_timing_preproc_flag); + fprintf(fp, "`ifdef %s\n", verilog_timing_preproc_flag); fprintf(fp, " //------ BEGIN Pin-to-pin Timing constraints -----\n"); fprintf(fp, " specify\n"); /* Give pin-to-pin delays */ @@ -65,9 +69,9 @@ void dump_verilog_submodule_timing(FILE* fp, for (iport = 0; iport < num_input_port; iport++) { for (ipin = 0; ipin < input_port[iport]->size; ipin++) { for (iedge = 0; iedge < input_port[iport]->num_tedges[ipin]; iedge++) { - fprintf(fp, " (%s[%d] => %s[%d]) = (%.2g, %.2g);\n", - input_port[iport]->prefix, ipin, - input_port[iport]->tedge[ipin][iedge]->to_port->prefix, + fprintf(fp, "(%s[%d] => %s[%d]) = (%.2g, %.2g);\n", + input_port[iport]->lib_name, ipin, + input_port[iport]->tedge[ipin][iedge]->to_port->lib_name, input_port[iport]->tedge[ipin][iedge]->to_port_pin_number, input_port[iport]->tedge[ipin][iedge]->trise / verilog_sim_timescale, input_port[iport]->tedge[ipin][iedge]->tfall / verilog_sim_timescale); @@ -81,12 +85,11 @@ void dump_verilog_submodule_timing(FILE* fp, return; } -void dump_verilog_submodule_init_sim(FILE* fp, - t_spice_model* cur_spice_model) { +void dump_verilog_submodule_signal_init(FILE* fp, + t_spice_model* cur_spice_model) { int iport, ipin; int num_input_port; t_spice_model_port** input_port= NULL; - input_port = find_spice_model_ports(cur_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); /* Ensure a valid file handler*/ @@ -96,17 +99,16 @@ void dump_verilog_submodule_init_sim(FILE* fp, exit(1); } - fprintf(fp, "\n`ifdef %s\n", verilog_init_sim_preproc_flag); + fprintf(fp, "\n`ifdef %s\n", verilog_signal_init_preproc_flag); fprintf(fp, " //------ BEGIN driver initialization -----\n"); fprintf(fp, "initial begin\n"); - + fprintf(fp, "`ifdef %s\n #0.001\n`endif\n", + icarus_simulator_flag); for (iport = 0; iport < num_input_port; iport++) { - fprintf(fp, " $signal_force(\"%s\", %d, 0, 1, , 1);\n", - input_port[iport]->prefix, - input_port[iport]->default_val); + fprintf(fp, " $deposit(%s, $random);\n", + input_port[iport]->lib_name); } fprintf(fp, "end\n"); - fprintf(fp, " //------ END driver initialization -----\n"); fprintf(fp, "`endif\n"); @@ -114,12 +116,9 @@ void dump_verilog_submodule_init_sim(FILE* fp, } -/***** Subroutines *****/ /* Dump a module of inverter or buffer or tapered buffer */ void dump_verilog_invbuf_module(FILE* fp, - t_spice_model* invbuf_spice_model, - boolean include_timing, - boolean init_sim) { + t_spice_model* invbuf_spice_model) { int ipin, iport, port_cnt; int num_input_port = 0; int num_output_port = 0; @@ -166,13 +165,13 @@ void dump_verilog_invbuf_module(FILE* fp, fprintf(fp, "module %s (\n", invbuf_spice_model->name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, invbuf_spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_lib_global_ports(fp, invbuf_spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Dump ports */ - fprintf(fp, " input [0:0] %s,\n", input_port[0]->prefix); - fprintf(fp, " output [0:0] %s\n", output_port[0]->prefix); - fprintf(fp, " );\n"); + fprintf(fp, "input [0:0] %s,\n", input_port[0]->lib_name); + fprintf(fp, "output [0:0] %s\n", output_port[0]->lib_name); + fprintf(fp, ");\n"); /* Finish dumping ports */ /* Assign logics : depending on topology */ @@ -180,14 +179,14 @@ void dump_verilog_invbuf_module(FILE* fp, case SPICE_MODEL_BUF_INV: if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { /* Create a sensitive list */ - fprintf(fp, "reg %s_reg;\n", output_port[0]->prefix); + fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name); fprintf(fp, "always @("); /* Power-gate port first*/ for (iport = 0; iport < num_powergate_port; iport++) { - fprintf(fp, "%s,", powergate_port[iport]->prefix); + fprintf(fp, "%s,", powergate_port[iport]->lib_name); } fprintf(fp, "%s) begin\n", - input_port[0]->prefix); + input_port[0]->lib_name); /* Dump the case of power-gated */ fprintf(fp, " if ("); port_cnt = 0; /* Initialize the counter: decide if we need to put down '&&' */ @@ -201,7 +200,7 @@ void dump_verilog_invbuf_module(FILE* fp, * Therefore, we need to reverse them here */ fprintf(fp, "(~%s[%d])", - powergate_port[iport]->prefix, + powergate_port[iport]->lib_name, ipin); port_cnt++; /* Update port counter*/ } @@ -215,7 +214,7 @@ void dump_verilog_invbuf_module(FILE* fp, * Therefore, we need to reverse them here */ fprintf(fp, "(%s[%d])", - powergate_port[iport]->prefix, + powergate_port[iport]->lib_name, ipin); port_cnt++; /* Update port counter*/ } @@ -223,33 +222,33 @@ void dump_verilog_invbuf_module(FILE* fp, } fprintf(fp, ") begin\n"); fprintf(fp, "\t\tassign %s_reg = ~%s;\n", - output_port[0]->prefix, - input_port[0]->prefix); + output_port[0]->lib_name, + input_port[0]->lib_name); fprintf(fp, "\tend else begin\n"); fprintf(fp, "\t\tassign %s_reg = 1'bz;\n", - output_port[0]->prefix); + output_port[0]->lib_name); fprintf(fp, "\tend\n"); fprintf(fp, "end\n"); fprintf(fp, "assign %s = %s_reg;\n", - output_port[0]->prefix, - output_port[0]->prefix); + output_port[0]->lib_name, + output_port[0]->lib_name); } else { fprintf(fp, "assign %s = ~%s;\n", - output_port[0]->prefix, - input_port[0]->prefix); + output_port[0]->lib_name, + input_port[0]->lib_name); } break; case SPICE_MODEL_BUF_BUF: if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { /* Create a sensitive list */ - fprintf(fp, "reg %s_reg;\n", output_port[0]->prefix); + fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name); fprintf(fp, "always @("); /* Power-gate port first*/ for (iport = 0; iport < num_powergate_port; iport++) { - fprintf(fp, "%s,", powergate_port[iport]->prefix); + fprintf(fp, "%s,", powergate_port[iport]->lib_name); } fprintf(fp, "%s) begin\n", - input_port[0]->prefix); + input_port[0]->lib_name); /* Dump the case of power-gated */ fprintf(fp, " if ("); port_cnt = 0; /* Initialize the counter: decide if we need to put down '&&' */ @@ -263,7 +262,7 @@ void dump_verilog_invbuf_module(FILE* fp, * Therefore, we need to reverse them here */ fprintf(fp, "(~%s[%d])", - powergate_port[iport]->prefix, + powergate_port[iport]->lib_name, ipin); port_cnt++; /* Update port counter*/ } @@ -277,7 +276,7 @@ void dump_verilog_invbuf_module(FILE* fp, * Therefore, we need to reverse them here */ fprintf(fp, "(%s[%d])", - powergate_port[iport]->prefix, + powergate_port[iport]->lib_name, ipin); port_cnt++; /* Update port counter*/ } @@ -285,31 +284,31 @@ void dump_verilog_invbuf_module(FILE* fp, } fprintf(fp, ") begin\n"); fprintf(fp, "\t\tassign %s_reg = %s;\n", - output_port[0]->prefix, - input_port[0]->prefix); + output_port[0]->lib_name, + input_port[0]->lib_name); fprintf(fp, "\tend else begin\n"); fprintf(fp, "\t\tassign %s_reg = 1'bz;\n", - output_port[0]->prefix); + output_port[0]->lib_name); fprintf(fp, "\tend\n"); fprintf(fp, "end\n"); fprintf(fp, "assign %s = %s_reg;\n", - output_port[0]->prefix, - output_port[0]->prefix); + output_port[0]->lib_name, + output_port[0]->lib_name); } else if (FALSE == invbuf_spice_model->design_tech_info.buffer_info->tapered_buf) { fprintf(fp, "assign %s = %s;\n", - output_port[0]->prefix, - input_port[0]->prefix); + output_port[0]->lib_name, + input_port[0]->lib_name); } else { assert (TRUE == invbuf_spice_model->design_tech_info.buffer_info->tapered_buf); fprintf(fp, "assign %s = ", - output_port[0]->prefix); + output_port[0]->lib_name); /* depend on the stage, we may invert the output */ if (1 == invbuf_spice_model->design_tech_info.buffer_info->tap_buf_level % 2) { fprintf(fp, "~"); } fprintf(fp, "%s;\n", - input_port[0]->prefix); + input_port[0]->lib_name); } break; default: @@ -319,14 +318,9 @@ void dump_verilog_invbuf_module(FILE* fp, } /* Print timing info */ - if (TRUE == include_timing) { - dump_verilog_submodule_timing(fp, invbuf_spice_model); - } + dump_verilog_submodule_timing(fp, invbuf_spice_model); - /* Print simulation initialization info */ - if (TRUE == init_sim) { - dump_verilog_submodule_init_sim(fp, invbuf_spice_model); - } + dump_verilog_submodule_signal_init(fp, invbuf_spice_model); fprintf(fp, "endmodule\n"); @@ -341,8 +335,7 @@ void dump_verilog_invbuf_module(FILE* fp, /* Dump a module of pass-gate logic */ void dump_verilog_passgate_module(FILE* fp, - t_spice_model* passgate_spice_model, - boolean include_timing) { + t_spice_model* passgate_spice_model) { int iport; int num_input_port = 0; int num_output_port = 0; @@ -374,6 +367,11 @@ void dump_verilog_passgate_module(FILE* fp, fprintf(fp, "module %s (\n", passgate_spice_model->name); + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_lib_global_ports(fp, passgate_spice_model, TRUE, FALSE, FALSE)) { + fprintf(fp, ",\n"); + } + /* Assign ports : depending on topology */ switch (passgate_spice_model->design_tech_info.pass_gate_info->type) { case SPICE_MODEL_PASS_GATE_TRANSMISSION: @@ -386,11 +384,11 @@ void dump_verilog_passgate_module(FILE* fp, assert(1 == input_port[iport]->size); } /* Dump ports */ - fprintf(fp, " input [0:0] in,\n"); - fprintf(fp, " input [0:0] sel,\n"); - fprintf(fp, " input [0:0] selb,\n"); - fprintf(fp, " output [0:0] %s\n", output_port[0]->prefix); - fprintf(fp, " );\n"); + fprintf(fp, "input [0:0] %s,\n", input_port[0]->lib_name); + fprintf(fp, "input [0:0] %s,\n", input_port[1]->lib_name); + fprintf(fp, "input [0:0] %s,\n", input_port[2]->lib_name); + fprintf(fp, "output [0:0] %s\n", output_port[0]->lib_name); + fprintf(fp, ");\n"); /* Finish dumping ports */ break; @@ -404,10 +402,10 @@ void dump_verilog_passgate_module(FILE* fp, assert(1 == input_port[iport]->size); } /* Dump ports */ - fprintf(fp, " input [0:0] in,\n"); - fprintf(fp, " input [0:0] sel,\n"); - fprintf(fp, " output [0:0] %s\n", output_port[0]->prefix); - fprintf(fp, " );\n"); + fprintf(fp, "input [0:0] %s,\n", input_port[0]->lib_name); + fprintf(fp, "input [0:0] %s,\n", input_port[1]->lib_name); + fprintf(fp, "output [0:0] %s\n", output_port[0]->lib_name); + fprintf(fp, ");\n"); /* Finish dumping ports */ break; default: @@ -417,13 +415,16 @@ void dump_verilog_passgate_module(FILE* fp, } /* Dump logics */ - fprintf(fp, "assign %s = sel? in : 1'bz;\n", - output_port[0]->prefix); + fprintf(fp, "assign %s = %s? %s : 1'bz;\n", + output_port[0]->lib_name, + input_port[1]->lib_name, + input_port[0]->lib_name); /* Print timing info */ - if (TRUE == include_timing) { - dump_verilog_submodule_timing(fp, passgate_spice_model); - } + dump_verilog_submodule_timing(fp, passgate_spice_model); + + /* Print signal initialization */ + dump_verilog_submodule_signal_init(fp, passgate_spice_model); fprintf(fp, "endmodule\n"); @@ -436,16 +437,131 @@ void dump_verilog_passgate_module(FILE* fp, return; } +/* Dump a module of pass-gate logic */ +void dump_verilog_gate_module(FILE* fp, + t_spice_model* gate_spice_model) { + int iport, ipin, jport, jpin; + int num_input_port = 0; + int num_output_port = 0; + t_spice_model_port** input_port = NULL; + t_spice_model_port** output_port = NULL; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Find the input port, output port*/ + input_port = find_spice_model_ports(gate_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_port = find_spice_model_ports(gate_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + + /* Make sure: + * There is only 1 output port, + * each size of which is 1 + */ + assert(1 == num_output_port); + assert(1 == output_port[0]->size); + + assert(0 < num_input_port); + + fprintf(fp, "//----- Verilog module for %s -----\n", + gate_spice_model->name); + + /* dump module body */ + fprintf(fp, "module %s (\n", + gate_spice_model->name); + + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_lib_global_ports(fp, gate_spice_model, TRUE, FALSE, FALSE)) { + fprintf(fp, ",\n"); + } + + /* Dump ports */ + for (iport = 0; iport < num_input_port; iport++) { + fprintf(fp, "input [0:%d] %s,\n", + input_port[iport]->size - 1, input_port[iport]->lib_name); + } + for (iport = 0; iport < num_output_port; iport++) { + fprintf(fp, "output [0:%d] %s\n", + output_port[iport]->size - 1, output_port[iport]->lib_name); + } + fprintf(fp, ");\n"); + + /* Dump logics */ + switch (gate_spice_model->design_tech_info.gate_info->type) { + case SPICE_MODEL_GATE_AND: + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + fprintf(fp, "assign %s[%d] = ", + output_port[iport]->lib_name, ipin); + for (jport = 0; jport < num_input_port; jport++) { + for (jpin = 0; jpin < input_port[jport]->size; jpin++) { + fprintf(fp, "%s[%d]", + input_port[jport]->lib_name, jpin); + if ((jport == num_input_port - 1) && (jpin == input_port[jport]->size - 1)) { + continue; /* Stop output AND sign for the last element in the loop */ + } + fprintf(fp, " & "); + } + } + fprintf(fp, ";\n"); + } + } + break; + case SPICE_MODEL_GATE_OR: + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + fprintf(fp, "assign %s[%d] = ", + output_port[iport]->lib_name, ipin); + for (jport = 0; jport < num_input_port; jport++) { + for (jpin = 0; jpin < input_port[jport]->size; jpin++) { + fprintf(fp, "%s[%d]", + input_port[jport]->lib_name, jpin); + if ((jport == num_input_port - 1) && (jpin == input_port[jport]->size - 1)) { + continue; /* Stop output AND sign for the last element in the loop */ + } + fprintf(fp, " | "); + } + } + fprintf(fp, ";\n"); + } + } + + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid topology for spice model (%s)!\n", + __FILE__, __LINE__, gate_spice_model->name); + exit(1); + } + + + /* Print timing info */ + dump_verilog_submodule_timing(fp, gate_spice_model); + + /* Print signal initialization */ + dump_verilog_submodule_signal_init(fp, gate_spice_model); + + fprintf(fp, "endmodule\n"); + + fprintf(fp, "\n"); + + /* Free */ + my_free(input_port); + my_free(output_port); + + return; +} /* Dump Essential modules: * 1. inverters * 2. buffers * 3. pass-gate logics */ -void dump_verilog_submodule_essentials(char* submodule_dir, +void dump_verilog_submodule_essentials(char* verilog_dir, char* submodule_dir, int num_spice_model, t_spice_model* spice_models, - boolean include_timing, - boolean init_sim) { + t_syn_verilog_opts fpga_verilog_opts) { int imodel; char* verilog_name = my_strcat(submodule_dir, essentials_verilog_file_name); FILE* fp = NULL; @@ -457,9 +573,9 @@ void dump_verilog_submodule_essentials(char* submodule_dir, __FILE__, __LINE__, essentials_verilog_file_name); exit(1); } - dump_verilog_file_header(fp,"Essential gates"); + dump_verilog_file_header(fp,"Essential gates"); - dump_verilog_preproc(fp, include_timing); + verilog_include_defines_preproc_file(fp, verilog_dir); /* Output essential models*/ for (imodel = 0; imodel < num_spice_model; imodel++) { @@ -468,18 +584,21 @@ void dump_verilog_submodule_essentials(char* submodule_dir, continue; } if (SPICE_MODEL_INVBUF == spice_models[imodel].type) { - dump_verilog_invbuf_module(fp, &(spice_models[imodel]), include_timing, init_sim); + dump_verilog_invbuf_module(fp, &(spice_models[imodel])); } if (SPICE_MODEL_PASSGATE == spice_models[imodel].type) { - dump_verilog_passgate_module(fp, &(spice_models[imodel]), include_timing); + dump_verilog_passgate_module(fp, &(spice_models[imodel])); + } + if (SPICE_MODEL_GATE == spice_models[imodel].type) { + dump_verilog_gate_module(fp, &(spice_models[imodel])); } } /* Close file handler*/ - fclose(fp); + fclose(fp); /* Add fname to the linked list */ - submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); /* Free */ @@ -513,15 +632,15 @@ void dump_verilog_cmos_mux_one_basis_module(FILE* fp, /* Print the port list and definition */ fprintf(fp, "module %s (\n", mux_basis_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Port list */ - fprintf(fp, " input [0:%d] in,\n", num_input_basis_subckt - 1); - fprintf(fp, " output out,\n"); - fprintf(fp, " input [0:%d] mem,\n", + fprintf(fp, "input [0:%d] in,\n", num_input_basis_subckt - 1); + fprintf(fp, "output out,\n"); + fprintf(fp, "input [0:%d] mem,\n", num_mem - 1); - fprintf(fp, " input [0:%d] mem_inv);\n", + fprintf(fp, "input [0:%d] mem_inv);\n", num_mem - 1); /* Verilog Behavior description for a MUX */ fprintf(fp, "//---- Behavior-level description -----\n"); @@ -590,6 +709,11 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp, int num_mem = num_input_basis_subckt; /* Get the tgate module name */ char* tgate_module_name = cur_spice_model->pass_gate_logic->spice_model_name; + t_spice_model* tgate_spice_model = cur_spice_model->pass_gate_logic->spice_model; + int num_input_port = 0; + int num_output_port = 0; + t_spice_model_port** input_port = NULL; + t_spice_model_port** output_port = NULL; assert(TRUE == cur_spice_model->dump_structural_verilog); @@ -598,6 +722,20 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp, vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); exit(1); } + + /* Find the input port, output port, and sram port*/ + assert ( NULL != tgate_spice_model); + input_port = find_spice_model_ports(tgate_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); + output_port = find_spice_model_ports(tgate_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); + + /* Check */ + assert ((3 == num_input_port)); + for (i = 0; i < num_input_port; i++) { + assert ( 1 == input_port[i]->size ); + } + assert ((1 == num_output_port) + && (1 == output_port[0]->size)); + /* Determine the number of memory bit * The function considers a special case : * 2-input basis in tree-like MUX only requires 1 memory bit */ @@ -609,15 +747,15 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp, /* Print the port list and definition */ fprintf(fp, "module %s (\n", mux_basis_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Port list */ - fprintf(fp, " input [0:%d] in,\n", num_input_basis_subckt - 1); - fprintf(fp, " output out,\n"); - fprintf(fp, " input [0:%d] mem,\n", + fprintf(fp, "input [0:%d] in,\n", num_input_basis_subckt - 1); + fprintf(fp, "output out,\n"); + fprintf(fp, "input [0:%d] mem,\n", num_mem - 1); - fprintf(fp, " input [0:%d] mem_inv);\n", + fprintf(fp, "input [0:%d] mem_inv);\n", num_mem - 1); /* Verilog Behavior description for a MUX */ fprintf(fp, "//---- Structure-level description -----\n"); @@ -627,19 +765,50 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp, */ if (1 == num_mem) { /* Transmission gates are connected to each input and also the output*/ - fprintf(fp, " %s %s_0 (in[0], mem[0], mem_inv[0], out);\n", + fprintf(fp, " %s %s_0 ", tgate_module_name, tgate_module_name); - fprintf(fp, " %s %s_1 (in[1], mem_inv[0], mem[0], out);\n", + /* Dump explicit port map if required */ + if (TRUE == tgate_spice_model->dump_explicit_port_map) { + fprintf(fp, " (.%s(in[0]), .%s(mem[0]), .%s(mem_inv[0]), .%s(out));\n", + input_port[0]->lib_name, + input_port[1]->lib_name, + input_port[2]->lib_name, + output_port[0]->lib_name); + } else { + fprintf(fp, " (in[0], mem[0], mem_inv[0], out);\n"); + } + fprintf(fp, " %s %s_1 ", tgate_module_name, tgate_module_name); + /* Dump explicit port map if required */ + if (TRUE == tgate_spice_model->dump_explicit_port_map) { + fprintf(fp, " (.%s(in[1]), .%s(mem_inv[0]), .%s(mem[0]), .%s(out));\n", + input_port[0]->lib_name, + input_port[1]->lib_name, + input_port[2]->lib_name, + output_port[0]->lib_name); + } else { + fprintf(fp, " (in[1], mem_inv[0], mem[0], out);\n"); + } + } else { /* Other cases, we need to follow the rules: * When mem[k] is enabled, switch on input[k] * Only one memory bit is enabled! */ for (i = 0; i < num_mem; i++) { - fprintf(fp, " %s %s_%d (in[%d], mem[%d], mem_inv[%d], out);\n", - tgate_module_name, tgate_module_name, i, - i, i, i); + fprintf(fp, " %s %s_%d ", + tgate_module_name, tgate_module_name, i); + /* Dump explicit port map if required */ + if (TRUE == tgate_spice_model->dump_explicit_port_map) { + fprintf(fp, " (.%s(in[%d]), .%s(mem[%d]), .%s(mem_inv[%d]), .%s(out));\n", + input_port[0]->lib_name, i, + input_port[1]->lib_name, i, + input_port[2]->lib_name, i, + output_port[0]->lib_name); + } else { + fprintf(fp, " (in[%d], mem[%d], mem_inv[%d], out);\n", + i, i, i); + } } } @@ -681,15 +850,15 @@ void dump_verilog_rram_mux_one_basis_module_structural(FILE* fp, /* Print the port list and definition */ fprintf(fp, "module %s (\n", mux_basis_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Port list */ - fprintf(fp, " input wire [0:%d] in,\n", num_input_basis_subckt - 1); - fprintf(fp, " output wire out,\n"); - fprintf(fp, " input wire [0:%d] bl,\n", + fprintf(fp, "input wire [0:%d] in,\n", num_input_basis_subckt - 1); + fprintf(fp, "output wire out,\n"); + fprintf(fp, "input wire [0:%d] bl,\n", num_mem - 1); - fprintf(fp, " input wire [0:%d] wl);\n", + fprintf(fp, "input wire [0:%d] wl);\n", num_mem - 1); /* Print internal structure of 4T1R programming structures @@ -746,15 +915,15 @@ void dump_verilog_rram_mux_one_basis_module(FILE* fp, /* Print the port list and definition */ fprintf(fp, "module %s (\n", mux_basis_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Port list */ - fprintf(fp, " input wire [0:%d] in,\n", num_input_basis_subckt - 1); - fprintf(fp, " output wire out,\n"); - fprintf(fp, " input wire [0:%d] bl,\n", + fprintf(fp, "input wire [0:%d] in,\n", num_input_basis_subckt - 1); + fprintf(fp, "output wire out,\n"); + fprintf(fp, "input wire [0:%d] bl,\n", num_mem - 1); - fprintf(fp, " input wire [0:%d] wl);\n", + fprintf(fp, "input wire [0:%d] wl);\n", num_mem - 1); /* Print the internal logics: @@ -918,7 +1087,9 @@ void dump_verilog_mux_basis_module(FILE* fp, /* Generate the spice_mux_arch */ spice_mux_model->spice_mux_arch = (t_spice_mux_arch*)my_malloc(sizeof(t_spice_mux_arch)); - init_spice_mux_arch(spice_mux_model->spice_model, spice_mux_model->spice_mux_arch, spice_mux_model->size); + init_spice_mux_arch(spice_mux_model->spice_model, + spice_mux_model->spice_mux_arch, + spice_mux_model->size); /* Corner case: Error out MUX_SIZE = 2, automatcially give a one-level structure */ /* @@ -931,15 +1102,9 @@ void dump_verilog_mux_basis_module(FILE* fp, /* Prepare the basis subckt name: */ - mux_basis_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_mux_model->spice_model->name) + 5 - + strlen(my_itoa(spice_mux_model->size)) + strlen(verilog_mux_basis_posfix) + 1)); - sprintf(mux_basis_subckt_name, "%s_size%d%s", - spice_mux_model->spice_model->name, spice_mux_model->size, verilog_mux_basis_posfix); + mux_basis_subckt_name = generate_verilog_mux_subckt_name(spice_mux_model->spice_model, spice_mux_model->size, verilog_mux_basis_posfix); - special_basis_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_mux_model->spice_model->name) + 5 - + strlen(my_itoa(spice_mux_model->size)) + strlen(verilog_mux_special_basis_posfix) + 1)); - sprintf(special_basis_subckt_name, "%s_size%d%s", - spice_mux_model->spice_model->name, spice_mux_model->size, verilog_mux_special_basis_posfix); + special_basis_subckt_name = generate_verilog_mux_subckt_name(spice_mux_model->spice_model, spice_mux_model->size, verilog_mux_special_basis_posfix); /* deteremine the number of inputs of basis subckt */ num_input_basis_subckt = spice_mux_model->spice_mux_arch->num_input_basis; @@ -949,7 +1114,7 @@ void dump_verilog_mux_basis_module(FILE* fp, num_input_basis_subckt, spice_mux_model->spice_model, FALSE); /* See if we need a special basis */ - switch (spice_mux_model->spice_model->design_tech_info.structure) { + switch (spice_mux_model->spice_model->design_tech_info.mux_info->structure) { case SPICE_MODEL_STRUCTURE_TREE: case SPICE_MODEL_STRUCTURE_ONELEVEL: break; @@ -983,12 +1148,42 @@ void dump_verilog_cmos_mux_tree_structure(FILE* fp, int nextj, out_idx; int mux_basis_cnt = 0; + int num_buf_input_port = 0; + int num_buf_output_port = 0; + + t_spice_model_port** buf_input_port = NULL; + t_spice_model_port** buf_output_port = NULL; + + boolean* inter_buf_loc = NULL; + /* Make sure we have a valid file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); exit(1); } + /* Intermediate buffer location map */ + inter_buf_loc = (boolean*)my_calloc(spice_mux_arch.num_level + 1, sizeof(boolean)); + for (i = 0; i < spice_mux_arch.num_level + 1; i++) { + inter_buf_loc[i] = FALSE; + } + if (NULL != spice_model.lut_intermediate_buffer->location_map) { + assert (spice_mux_arch.num_level - 1 == strlen(spice_model.lut_intermediate_buffer->location_map)); + /* For intermediate buffers */ + for (i = 0; i < spice_mux_arch.num_level - 1; i++) { + if ('1' == spice_model.lut_intermediate_buffer->location_map[i]) { + inter_buf_loc[spice_mux_arch.num_level - i - 1] = TRUE; + } + } + } + /* + printf("inter_buf_loc[]="); + for (i = 0; i < spice_mux_arch.num_level + 1; i++) { + printf("%d", inter_buf_loc[i]); + } + printf("\n"); + */ + mux_basis_cnt = 0; for (i = 0; i < spice_mux_arch.num_level; i++) { level = spice_mux_arch.num_level - i; @@ -998,6 +1193,12 @@ void dump_verilog_cmos_mux_tree_structure(FILE* fp, fprintf(fp, "wire [%d:%d] mux2_l%d_in; \n", 0, spice_mux_arch.num_input_per_level[nextlevel] -1, /* input0 input1 */ level); + /* For intermediate buffers */ + if (TRUE == inter_buf_loc[level]) { + fprintf(fp, "wire [%d:%d] mux2_l%d_in_buf; \n", + 0, spice_mux_arch.num_input_per_level[nextlevel] -1, /* input0 input1 */ + level); + } } fprintf(fp, "wire [%d:%d] mux2_l%d_in; \n", 0, 0, 0); @@ -1014,12 +1215,62 @@ void dump_verilog_cmos_mux_tree_structure(FILE* fp, /* Each basis mux2to1: svdd sgnd */ fprintf(fp, "%s mux_basis_no%d (", mux_basis_subckt_name, mux_basis_cnt); /* given_name */ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } - fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, nextj); /* input0 input1 */ + /* For intermediate buffers */ + if (TRUE == inter_buf_loc[level]) { + fprintf(fp, "mux2_l%d_in_buf[%d:%d], ", level, j, nextj); /* input0 input1 */ + } else { + fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, nextj); /* input0 input1 */ + } fprintf(fp, "mux2_l%d_in[%d], ", nextlevel, out_idx); /* output */ fprintf(fp, "%s[%d], %s_inv[%d]);\n", sram_port[0]->prefix, i, sram_port[0]->prefix, i); /* sram sram_inv */ + /* For intermediate buffers */ + if (TRUE == inter_buf_loc[nextlevel]) { + /* Find the input port, output port, and sram port*/ + buf_input_port = find_spice_model_ports(spice_model.lut_intermediate_buffer->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(spice_model.lut_intermediate_buffer->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert ( (1 == num_buf_input_port) + &&(1 == buf_input_port[0]->size)); + assert ( (1 == num_buf_output_port) + &&(1 == buf_output_port[0]->size)); + + /* TODO: what about tapered buffer, can we support? */ + /* Each buf: svdd sgnd size=param*/ + fprintf(fp, "%s %s_%d_%d (", + spice_model.lut_intermediate_buffer->spice_model_name, + spice_model.lut_intermediate_buffer->spice_model_name, + nextlevel, out_idx); /* Given name*/ + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.lut_intermediate_buffer->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); + } + /* Dump explicit port map if required */ + if ( TRUE == spice_model.lut_intermediate_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); + } + fprintf(fp, "mux2_l%d_in[%d] ", nextlevel, out_idx); /* output */ + if ( TRUE == spice_model.lut_intermediate_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + /* Dump explicit port map if required */ + if ( TRUE == spice_model.lut_intermediate_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "mux2_l%d_in_buf[%d] ", nextlevel, out_idx); /* output */ + if ( TRUE == spice_model.lut_intermediate_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); + } /* Update the counter */ j = nextj; mux_basis_cnt++; @@ -1030,6 +1281,9 @@ void dump_verilog_cmos_mux_tree_structure(FILE* fp, assert(0 == out_idx); assert(mux_basis_cnt == spice_mux_arch.num_input - 1); + /* Free */ + my_free(inter_buf_loc); + return; } @@ -1073,9 +1327,9 @@ void dump_verilog_cmos_mux_multilevel_structure(FILE* fp, /* Check */ assert(nextlevel > -1); /* Print basis muxQto1 for each level*/ - for (j = 0; j < spice_mux_arch.num_input_per_level[nextlevel]; j = j+cur_num_input_basis) { + for (j = 0; j < spice_mux_arch.num_input_per_level[nextlevel]; j = j + cur_num_input_basis) { /* output index */ - out_idx = j/spice_mux_arch.num_input_basis; + out_idx = j / spice_mux_arch.num_input_basis; /* Determine the number of input of this basis */ cur_num_input_basis = spice_mux_arch.num_input_basis; if ((j + cur_num_input_basis) > spice_mux_arch.num_input_per_level[nextlevel]) { @@ -1084,7 +1338,7 @@ void dump_verilog_cmos_mux_multilevel_structure(FILE* fp, /* Print the special basis */ fprintf(fp, "%s special_basis(", mux_special_basis_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, j + cur_num_input_basis - 1); /* input0 input1 */ @@ -1101,7 +1355,7 @@ void dump_verilog_cmos_mux_multilevel_structure(FILE* fp, fprintf(fp, "%s ", mux_basis_subckt_name); /* subckt_name */ fprintf(fp, "mux_basis_no%d (", mux_basis_cnt); /* given_name */ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, j + cur_num_input_basis - 1); /* input0 input1 */ @@ -1143,7 +1397,7 @@ void dump_verilog_cmos_mux_onelevel_structure(FILE* fp, fprintf(fp, "%s mux_basis (\n", mux_basis_subckt_name); /* given_name */ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "//----- MUX inputs -----\n"); @@ -1171,7 +1425,7 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, int mux_size, t_spice_model spice_model, t_spice_mux_arch spice_mux_arch) { - int i, num_conf_bits; + int i, num_conf_bits, iport, ipin, num_mode_bits; int num_input_port = 0; int num_output_port = 0; int num_sram_port = 0; @@ -1179,23 +1433,22 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, t_spice_model_port** output_port = NULL; t_spice_model_port** sram_port = NULL; + int num_buf_input_port = 0; + int num_buf_output_port = 0; + + t_spice_model_port** buf_input_port = NULL; + t_spice_model_port** buf_output_port = NULL; + enum e_spice_model_structure cur_mux_structure; /* Find the basis subckt*/ char* mux_basis_subckt_name = NULL; char* mux_special_basis_subckt_name = NULL; - mux_basis_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model.name) + 5 - + strlen(my_itoa(mux_size)) + strlen(verilog_mux_basis_posfix) + 1)); - sprintf(mux_basis_subckt_name, "%s_size%d%s", - spice_model.name, mux_size, verilog_mux_basis_posfix); - - mux_special_basis_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model.name) + 5 - + strlen(my_itoa(spice_mux_arch.num_input)) - + strlen(verilog_mux_special_basis_posfix) + 1)); - sprintf(mux_special_basis_subckt_name, "%s_size%d%s", - spice_model.name, spice_mux_arch.num_input, verilog_mux_special_basis_posfix); + mux_basis_subckt_name = generate_verilog_mux_subckt_name(&spice_model, mux_size, verilog_mux_basis_posfix); + mux_special_basis_subckt_name = generate_verilog_mux_subckt_name(&spice_model, mux_size, verilog_mux_special_basis_posfix); + /* Make sure we have a valid file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); @@ -1214,31 +1467,61 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, sram_port = find_spice_model_ports(&spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); /* Asserts*/ - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - assert(1 == output_port[0]->size); + if ((SPICE_MODEL_MUX == spice_model.type) + || ((SPICE_MODEL_LUT == spice_model.type) + && (FALSE == spice_model.design_tech_info.lut_info->frac_lut))) { + assert(1 == num_input_port); + assert(1 == num_output_port); + assert(1 == num_sram_port); + assert(1 == output_port[0]->size); + } else { + assert((SPICE_MODEL_LUT == spice_model.type) + && (TRUE == spice_model.design_tech_info.lut_info->frac_lut)); + assert(1 == num_input_port); + assert(2 == num_sram_port); + for (iport = 0; iport < num_output_port; iport++) { + assert(0 < output_port[iport]->size); + } + } + + /* Setup a reasonable frac_out level for the output port*/ + for (iport = 0; iport < num_output_port; iport++) { + /* We always initialize the lut_frac_level when there is only 1 output! + * It should be pointed the last level! + */ + if ((OPEN == output_port[iport]->lut_frac_level) + || (1 == num_output_port)) { + output_port[iport]->lut_frac_level = spice_mux_arch.num_level; + } + } + + /* Add Fracturable LUT outputs */ /* We have two types of naming rules in terms of the usage of MUXes: * 1. MUXes, the naming rule is __size * 2. LUTs, the naming rule is _mux_size */ num_conf_bits = count_num_sram_bits_one_spice_model(&spice_model, - /* sram_verilog_orgz_info->type, */ mux_size); + num_mode_bits = count_num_mode_bits_one_spice_model(&spice_model); + /* Knock out the SRAM bits for the mode selection, they are separated dealed */ + num_conf_bits = num_conf_bits - num_mode_bits; + if (SPICE_MODEL_LUT == spice_model.type) { /* Special for LUT MUX */ - fprintf(fp, "//------ CMOS MUX info: spice_model_name= %s_MUX, size=%d -----\n", spice_model.name, mux_size); + fprintf(fp, "//------ CMOS MUX info: spice_model_name= %s_MUX, size=%d -----\n", + spice_model.name, mux_size); fprintf(fp, "module %s_mux(\n", spice_model.name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Print input ports*/ - assert(mux_size == num_conf_bits); fprintf(fp, "input wire [0:%d] %s,\n", num_conf_bits - 1, input_port[0]->prefix); /* Print output ports*/ - fprintf(fp, "output wire %s,\n", output_port[0]->prefix); + for (iport = 0; iport < num_output_port; iport++) { + fprintf(fp, "output wire [0:%d] %s,\n", output_port[iport]->size - 1, output_port[iport]->prefix); + } /* Print configuration ports*/ /* The configuration port in MUX context is the input port in LUT context ! */ fprintf(fp, "input wire [0:%d] %s,\n", @@ -1247,12 +1530,13 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, input_port[0]->size - 1, sram_port[0]->prefix); } else { fprintf(fp, "//----- CMOS MUX info: spice_model_name=%s, size=%d, structure: %s -----\n", - spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.structure)); - fprintf(fp, "module %s_size%d (", spice_model.name, mux_size); + spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.mux_info->structure)); + fprintf(fp, "module %s (", + gen_verilog_one_mux_module_name(&spice_model, mux_size)); /* Print input ports*/ fprintf(fp, "input wire [0:%d] %s,\n", mux_size - 1, input_port[0]->prefix); /* Print output ports*/ - fprintf(fp, "output wire %s,\n", output_port[0]->prefix); + fprintf(fp, "output wire [0:%d] %s,\n", output_port[0]->size - 1, output_port[0]->prefix); /* Print configuration ports*/ fprintf(fp, "input wire [0:%d] %s,\n", num_conf_bits - 1, sram_port[0]->prefix); @@ -1264,8 +1548,8 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, fprintf(fp, ");"); fprintf(fp, "\n"); - /* Handle the corner case: input size = 2 */ - cur_mux_structure = spice_model.design_tech_info.structure; + /* Handle the corner case: input size = 2 */ + cur_mux_structure = spice_model.design_tech_info.mux_info->structure; if (2 == spice_mux_arch.num_input) { cur_mux_structure = SPICE_MODEL_STRUCTURE_ONELEVEL; } @@ -1293,37 +1577,47 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, /* To connect the input ports*/ for (i = 0; i < mux_size; i++) { if (1 == spice_model.input_buffer->exist) { - switch (spice_model.input_buffer->type) { - case SPICE_MODEL_BUF_INV: - /* Each inv: svdd sgnd size=param*/ - fprintf(fp, "%s inv%d (", - spice_model.input_buffer->spice_model_name, i); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "%s[%d], ", input_port[0]->prefix, i); /* input port */ - fprintf(fp, "mux2_l%d_in[%d]); ", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ - fprintf(fp, "\n"); - break; - case SPICE_MODEL_BUF_BUF: - /* TODO: what about tapered buffer, can we support? */ - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "%s buf%d (", - spice_model.input_buffer->spice_model_name, i); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "%s[%d], ", input_port[0]->prefix, i); /* input port */ - fprintf(fp, "mux2_l%d_in[%d]); ", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type for spice_model_buffer.\n", - __FILE__, __LINE__); - exit(1); + /* Find the input port, output port, and sram port*/ + buf_input_port = find_spice_model_ports(spice_model.input_buffer->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(spice_model.input_buffer->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert ( (1 == num_buf_input_port) + &&(1 == buf_input_port[0]->size)); + assert ( (1 == num_buf_output_port) + &&(1 == buf_output_port[0]->size)); + + /* TODO: what about tapered buffer, can we support? */ + /* Each buf: svdd sgnd size=param*/ + fprintf(fp, "%s %s_%d_ (", + spice_model.input_buffer->spice_model_name, + spice_model.input_buffer->spice_model_name, i); /* Given name*/ + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); } + /* Dump explicit port map if required */ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); + } + fprintf(fp, "%s[%d]", input_port[0]->prefix, i); /* input port */ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + /* Dump explicit port map if required */ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "mux2_l%d_in[%d] ", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); } else { /* There is no buffer, I create a zero resisitance between*/ /* Resistance R 0*/ @@ -1332,64 +1626,82 @@ void dump_verilog_cmos_mux_submodule(FILE* fp, spice_mux_arch.input_offset[i]); } } + /* Special: for the last inputs, we connect to VDD|GND + * TODO: create an option to select the connection VDD or GND + */ + if ((SPICE_MODEL_MUX == spice_model.type) + && (TRUE == spice_model.design_tech_info.mux_info->add_const_input)) { + assert ( (0 == spice_model.design_tech_info.mux_info->const_input_val) + || (1 == spice_model.design_tech_info.mux_info->const_input_val) ); + fprintf(fp, "assign mux2_l%d_in[%d] = 1'b%d;\n", + spice_mux_arch.input_level[spice_mux_arch.num_input - 1], + spice_mux_arch.input_offset[spice_mux_arch.num_input - 1], + spice_model.design_tech_info.mux_info->const_input_val); + } /* Output buffer*/ - if (1 == spice_model.output_buffer->exist) { - switch (spice_model.output_buffer->type) { - case SPICE_MODEL_BUF_INV: - if (TRUE == spice_model.output_buffer->tapered_buf) { - break; + for (iport = 0; iport < num_output_port; iport++) { + for (ipin = 0; ipin < output_port[iport]->size; ipin++) { + if (1 == spice_model.output_buffer->exist) { + /* Find the input port, output port, and sram port*/ + buf_input_port = find_spice_model_ports(spice_model.input_buffer->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(spice_model.input_buffer->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert ( (1 == num_buf_input_port) + &&(1 == buf_input_port[0]->size)); + assert ( (1 == num_buf_output_port) + &&(1 == buf_output_port[0]->size)); + + /* Each buf: svdd sgnd size=param*/ + fprintf(fp, "%s %s_out_%d_%d (", + spice_model.output_buffer->spice_model_name, + spice_model.output_buffer->spice_model_name, + iport, ipin); /* subckt name */ + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); + } + /* check */ + assert ( -1 < spice_mux_arch.num_level - output_port[iport]->lut_frac_level ); + /* Dump explicit port map if required */ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); + } + fprintf(fp, "mux2_l%d_in[%d]", + spice_mux_arch.num_level - output_port[iport]->lut_frac_level, + output_port[iport]->lut_output_mask[ipin]); /* input port */ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + /* Dump explicit port map if required */ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "%s[%d]", output_port[iport]->prefix, ipin); /* Output port*/ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); + } else { + /* check */ + assert ( -1 < spice_mux_arch.num_level - output_port[iport]->lut_frac_level ); + /* There is no buffer, I create a zero resisitance between*/ + /* Resistance R 0*/ + fprintf(fp, "assign mux2_l%d_in[%d] = %s[%d];\n", + spice_mux_arch.num_level - output_port[iport]->lut_frac_level, + output_port[iport]->lut_output_mask[ipin], + output_port[iport]->prefix, ipin); } - /* Each inv: svdd sgnd size=param*/ - fprintf(fp, "%s inv_out (", - spice_model.output_buffer->spice_model_name); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "mux2_l%d_in[%d], ", 0, 0); /* input port */ - fprintf(fp, "%s );", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "\n"); - break; - case SPICE_MODEL_BUF_BUF: - if (TRUE == spice_model.output_buffer->tapered_buf) { - break; - } - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "%s buf_out (", - spice_model.output_buffer->spice_model_name); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "mux2_l%d_in[%d], ", 0, 0); /* input port */ - fprintf(fp, "%s );", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type for spice_model_buffer.\n", - __FILE__, __LINE__); - exit(1); } - /* Tapered buffer support */ - if (TRUE == spice_model.output_buffer->tapered_buf) { - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "%s buf_out (", - spice_model.output_buffer->spice_model_name); /* subckt name */ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "mux2_l%d_in[%d], ", 0, 0); /* input port */ - fprintf(fp, "%s );", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "\n"); - } - } else { - /* There is no buffer, I create a zero resisitance between*/ - /* Resistance R 0*/ - fprintf(fp, "assign mux2_l0_in[0] = %s;\n",output_port[0]->prefix); } - + + fprintf(fp, "endmodule\n"); fprintf(fp, "//----- END CMOS MUX info: spice_model_name=%s, size=%d -----\n\n", spice_model.name, mux_size); fprintf(fp, "\n"); @@ -1456,7 +1768,7 @@ void dump_verilog_rram_mux_tree_structure(FILE* fp, /* Each basis mux2to1: svdd sgnd */ fprintf(fp, "%s mux_basis_no%d (", mux_basis_subckt_name, mux_basis_cnt); /* given_name */ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, nextj); /* input0 input1 */ @@ -1536,7 +1848,7 @@ void dump_verilog_rram_mux_multilevel_structure(FILE* fp, /* Print the special basis */ fprintf(fp, "%s special_basis(\n", mux_special_basis_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, j + cur_num_input_basis - 1); /* inputs */ @@ -1554,7 +1866,7 @@ void dump_verilog_rram_mux_multilevel_structure(FILE* fp, fprintf(fp, "%s ", mux_basis_subckt_name); /* subckt_name */ fprintf(fp, "mux_basis_no%d (", mux_basis_cnt); /* given_name */ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "mux2_l%d_in[%d:%d], ", level, j, j + cur_num_input_basis - 1); /* input0 input1 */ @@ -1599,7 +1911,7 @@ void dump_verilog_rram_mux_onelevel_structure(FILE* fp, fprintf(fp, "%s mux_basis (\n", mux_basis_subckt_name); /* given_name */ /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "//----- MUX inputs -----\n"); @@ -1607,7 +1919,6 @@ void dump_verilog_rram_mux_onelevel_structure(FILE* fp, fprintf(fp, "mux2_l%d_in[%d],\n", 0, 0); /* output */ fprintf(fp, "//----- SRAM ports -----\n"); num_conf_bits = count_num_sram_bits_one_spice_model(&spice_model, - /* sram_verilog_orgz_info->type,*/ spice_mux_arch.num_input); fprintf(fp, "%s[0:%d], %s_inv[0:%d]", sram_port[0]->prefix, num_conf_bits - 1, @@ -1630,21 +1941,20 @@ void dump_verilog_rram_mux_submodule(FILE* fp, t_spice_model_port** output_port = NULL; t_spice_model_port** sram_port = NULL; + int num_buf_input_port = 0; + int num_buf_output_port = 0; + + t_spice_model_port** buf_input_port = NULL; + t_spice_model_port** buf_output_port = NULL; + /* Find the basis subckt*/ char* mux_basis_subckt_name = NULL; char* mux_special_basis_subckt_name = NULL; - mux_basis_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model.name) + 5 - + strlen(my_itoa(mux_size)) + strlen(verilog_mux_basis_posfix) + 1)); - sprintf(mux_basis_subckt_name, "%s_size%d%s", - spice_model.name, mux_size, verilog_mux_basis_posfix); - - mux_special_basis_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model.name) + 5 - + strlen(my_itoa(spice_mux_arch.num_input)) - + strlen(verilog_mux_special_basis_posfix) + 1)); - sprintf(mux_special_basis_subckt_name, "%s_size%d%s", - spice_model.name, spice_mux_arch.num_input, verilog_mux_special_basis_posfix); + mux_basis_subckt_name = generate_verilog_mux_subckt_name(&spice_model, mux_size, verilog_mux_basis_posfix); + mux_special_basis_subckt_name = generate_verilog_mux_subckt_name(&spice_model, mux_size, verilog_mux_special_basis_posfix); + /* Make sure we have a valid file handler*/ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); @@ -1679,11 +1989,12 @@ void dump_verilog_rram_mux_submodule(FILE* fp, */ } else { fprintf(fp, "//----- RRAM MUX info: spice_model_name=%s, size=%d, structure: %s -----\n", - spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.structure)); - fprintf(fp, "module %s_size%d( \n", spice_model.name, mux_size); + spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.mux_info->structure)); + fprintf(fp, "module %s ( \n", + gen_verilog_one_mux_module_name(&spice_model, mux_size)); } /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Print input ports*/ @@ -1692,7 +2003,6 @@ void dump_verilog_rram_mux_submodule(FILE* fp, fprintf(fp, "output wire %s,\n ", output_port[0]->prefix); /* Print configuration ports */ num_conf_bits = count_num_sram_bits_one_spice_model(&spice_model, - /* sram_verilog_orgz_info->type,*/ mux_size); fprintf(fp, "input wire [0:%d] %s,\n", num_conf_bits - 1, sram_port[0]->prefix); @@ -1704,7 +2014,7 @@ void dump_verilog_rram_mux_submodule(FILE* fp, /* Print internal architecture*/ /* RRAM MUX is optimal in terms of area, delay and power for one-level structure. */ - switch (spice_model.design_tech_info.structure) { + switch (spice_model.design_tech_info.mux_info->structure) { case SPICE_MODEL_STRUCTURE_TREE: dump_verilog_rram_mux_tree_structure(fp, mux_basis_subckt_name, spice_model, spice_mux_arch, num_sram_port, sram_port); @@ -1726,37 +2036,47 @@ void dump_verilog_rram_mux_submodule(FILE* fp, /* To connect the input ports*/ for (i = 0; i < mux_size; i++) { if (1 == spice_model.input_buffer->exist) { - switch (spice_model.input_buffer->type) { - case SPICE_MODEL_BUF_INV: - /* Each inv: svdd sgnd size=param*/ - fprintf(fp, "%s inv%d (", - spice_model.input_buffer->spice_model_name, i); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "%s[%d], ", input_port[0]->prefix, i); /* input port */ - fprintf(fp, "mux2_l%d_in[%d]);", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ - fprintf(fp, "\n"); - break; - case SPICE_MODEL_BUF_BUF: - /* TODO: what about tapered buffer, can we support? */ - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "%s buf%d (", - spice_model.input_buffer->spice_model_name, i); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "%s[%d], ", input_port[0]->prefix, i); /* input port */ - fprintf(fp, "mux2_l%d_in[%d)];", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type for spice_model_buffer.\n", - __FILE__, __LINE__); - exit(1); + /* Find the input port, output port, and sram port*/ + buf_input_port = find_spice_model_ports(spice_model.input_buffer->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(spice_model.input_buffer->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert ( (1 == num_buf_input_port) + &&(1 == buf_input_port[0]->size)); + assert ( (1 == num_buf_output_port) + &&(1 == buf_output_port[0]->size)); + + /* Each inv: svdd sgnd size=param*/ + fprintf(fp, "%s %s%d (", + spice_model.input_buffer->spice_model_name, + spice_model.input_buffer->spice_model_name, i); /* Given name*/ + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.input_buffer->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); } + /* Dump explicit port map if required */ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); + } + fprintf(fp, "%s[%d], ", input_port[0]->prefix, i); /* input port */ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + + /* Dump explicit port map if required */ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "mux2_l%d_in[%d]);", spice_mux_arch.input_level[i], spice_mux_arch.input_offset[i]); /* output port*/ + if ( TRUE == spice_model.input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); } else { /* There is no buffer, I create a zero resisitance between*/ /* Resistance R 0*/ @@ -1766,61 +2086,64 @@ void dump_verilog_rram_mux_submodule(FILE* fp, } } + /* Special: for the last inputs, we connect to VDD|GND + * TODO: create an option to select the connection VDD or GND + */ + if ((SPICE_MODEL_MUX == spice_model.type) + && (TRUE == spice_model.design_tech_info.mux_info->add_const_input)) { + assert ( (0 == spice_model.design_tech_info.mux_info->const_input_val) + || (1 == spice_model.design_tech_info.mux_info->const_input_val) ); + fprintf(fp, "assign mux2_l%d_in[%d] = 1'b%d;\n", + spice_mux_arch.input_level[spice_mux_arch.num_input], + spice_mux_arch.input_offset[spice_mux_arch.num_input], spice_model.design_tech_info.mux_info->const_input_val); + } + /* Output buffer*/ if (1 == spice_model.output_buffer->exist) { - switch (spice_model.output_buffer->type) { - case SPICE_MODEL_BUF_INV: - if (TRUE == spice_model.output_buffer->tapered_buf) { - break; - } - /* Each inv: svdd sgnd size=param*/ - fprintf(fp, "%s inv_out (", - spice_model.output_buffer->spice_model_name); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "mux2_l%d_in[%d], ", 0, 0); /* input port */ - fprintf(fp, "%s );", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "\n"); - break; - case SPICE_MODEL_BUF_BUF: - if (TRUE == spice_model.output_buffer->tapered_buf) { - break; - } - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "%s buf_out (", - spice_model.output_buffer->spice_model_name); /* Given name*/ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "mux2_l%d_in[%d], ", 0, 0); /* input port */ - fprintf(fp, "%s );", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "\n"); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type for spice_model_buffer.\n", - __FILE__, __LINE__); - exit(1); + /* Find the input port, output port, and sram port*/ + buf_input_port = find_spice_model_ports(spice_model.output_buffer->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(spice_model.output_buffer->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert ( (1 == num_buf_input_port) + &&(1 == buf_input_port[0]->size)); + assert ( (1 == num_buf_output_port) + &&(1 == buf_output_port[0]->size)); + /* Each buf: svdd sgnd size=param*/ + fprintf(fp, "%s %s_out (", + spice_model.output_buffer->spice_model_name, + spice_model.output_buffer->spice_model_name); /* subckt name */ + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); } - /* Tapered buffer support */ - if (TRUE == spice_model.output_buffer->tapered_buf) { - /* Each buf: svdd sgnd size=param*/ - fprintf(fp, "%s buf_out (", - spice_model.output_buffer->spice_model_name); /* subckt name */ - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, spice_model.output_buffer->spice_model, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - fprintf(fp, "mux2_l%d_in[%d], ", 0 , 0); /* input port */ - fprintf(fp, "%s );", output_port[0]->prefix); /* Output port*/ - fprintf(fp, "\n"); + /* Dump explicit port map if required */ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); } + fprintf(fp, "mux2_l%d_in[%d]", 0 , 0); /* input port */ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + + /* Dump explicit port map if required */ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "%s", output_port[0]->prefix); /* Output port*/ + if ( TRUE == spice_model.output_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); } else { /* There is no buffer, I create a zero resisitance between*/ /* Resistance R 0*/ - fprintf(fp, "assign mux2_l0_in[0] %s;\n",output_port[0]->prefix); + fprintf(fp, "assign mux2_l0_in[0] %s;\n", output_port[0]->prefix); } fprintf(fp, "endmodule\n"); @@ -1837,6 +2160,140 @@ void dump_verilog_rram_mux_submodule(FILE* fp, return; } +/* Dump a memory submodule for the MUX */ +void dump_verilog_cmos_mux_mem_submodule(FILE* fp, + int mux_size, + t_spice_model spice_model, + t_spice_mux_arch spice_mux_arch) { + int i, num_conf_bits; + + int num_sram_port = 0; + t_spice_model_port** sram_port = NULL; + + /* Find the basis subckt*/ + char* mux_mem_subckt_name = NULL; + t_spice_model* mem_model = NULL; + + /* Make sure we have a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); + exit(1); + } + + /* We only do this for MUX not LUT + * LUT memory block added at top-level + */ + assert((SPICE_MODEL_MUX == spice_model.type)||(SPICE_MODEL_LUT == spice_model.type)); + if (SPICE_MODEL_LUT == spice_model.type) { + return; + } + + /* Ensure we have a CMOS MUX */ + assert(SPICE_MODEL_DESIGN_CMOS == spice_model.design_tech); + + /* Generate subckt name */ + mux_mem_subckt_name = generate_verilog_mux_subckt_name(&spice_model, mux_size, verilog_mem_posfix); + + /* Get SRAM port */ + sram_port = find_spice_model_ports(&spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + + /* Asserts*/ + assert ((1 == num_sram_port) && (NULL != sram_port)); + assert (NULL != sram_port[0]->spice_model); + assert ((SPICE_MODEL_SCFF == sram_port[0]->spice_model->type) + || (SPICE_MODEL_SRAM == sram_port[0]->spice_model->type)); + + /* Get the memory model */ + mem_model = sram_port[0]->spice_model; + + /* We have two types of naming rules in terms of the usage of MUXes: + * 1. MUXes, the naming rule is __size + * 2. LUTs, the naming rule is _mux_size + */ + num_conf_bits = count_num_sram_bits_one_spice_model(&spice_model, + mux_size); + + fprintf(fp, "//----- CMOS MUX info: spice_model_name=%s, size=%d, structure: %s -----\n", + spice_model.name, mux_size, gen_str_spice_model_structure(spice_model.design_tech_info.mux_info->structure)); + fprintf(fp, "module %s (", mux_mem_subckt_name); + /* Here we force the sequence of ports: of a memory subumodule: + * 1. Global ports + * 2. input ports + * 3. output ports + * 4. bl/wl ports + */ + dump_verilog_mem_module_port_map(fp, mem_model, TRUE, 0, num_conf_bits, FALSE); + fprintf(fp, ");\n"); + + /* Dump all the submodules */ + for (i = 0 ; i < num_conf_bits; i++) { + fprintf(fp, "%s %s_%d_ ( ", + mem_model->name, mem_model->prefix, i); + dump_verilog_mem_module_port_map(fp, mem_model, FALSE, i, 1, + mem_model->dump_explicit_port_map); + fprintf(fp, ");\n"); + } + + /* END of this submodule */ + fprintf(fp, "endmodule\n"); + + /* Free */ + my_free(mux_mem_subckt_name); + + return; +} + +/** Dump a verilog module for a MUX + * We always dump a basis submodule for a MUX + * whatever structure it is: one-level, two-level or multi-level + */ +void dump_verilog_mux_mem_module(FILE* fp, + t_spice_mux_model* spice_mux_model) { + /* Make sure we have a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); + exit(1); + } + /* Make sure we have a valid spice_model*/ + if (NULL == spice_mux_model) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid spice_mux_model!\n",__FILE__, __LINE__); + exit(1); + } + /* Make sure we have a valid spice_model*/ + if (NULL == spice_mux_model->spice_model) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid spice_model!\n",__FILE__, __LINE__); + exit(1); + } + + /* Check the mux size */ + if (spice_mux_model->size < 2) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid MUX size(=%d)! Should be at least 2.\n", + __FILE__, __LINE__, spice_mux_model->size); + exit(1); + } + + /* Print the definition of subckt*/ + /* Check the design technology*/ + switch (spice_mux_model->spice_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + dump_verilog_cmos_mux_mem_submodule(fp, spice_mux_model->size, + *(spice_mux_model->spice_model), + *(spice_mux_model->spice_mux_arch)); + break; + case SPICE_MODEL_DESIGN_RRAM: + /* We do not need a memory submodule for RRAM MUX, + * RRAM are embedded in the datapath + */ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid design_technology of MUX(name: %s)\n", + __FILE__, __LINE__, spice_mux_model->spice_model->name); + exit(1); + } + + return; +} + /** Dump a verilog module for a MUX * We always dump a basis submodule for a MUX * whatever structure it is: one-level, two-level or multi-level @@ -1897,13 +2354,13 @@ void dump_verilog_mux_module(FILE* fp, return; } - /*** Top-level function *****/ /* We should count how many multiplexers with different sizes are needed */ -/**/ -void dump_verilog_submodule_muxes(char* submodule_dir, +void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* submodule_dir, int num_switch, t_switch_inf* switches, t_spice* spice, @@ -1942,6 +2399,8 @@ void dump_verilog_submodule_muxes(char* submodule_dir, /* Generate the descriptions*/ dump_verilog_file_header(fp,"MUXes used in FPGA"); + verilog_include_defines_preproc_file(fp, verilog_dir); + /* Print mux netlist one by one*/ temp = muxes_head; while(temp) { @@ -1962,11 +2421,11 @@ void dump_verilog_submodule_muxes(char* submodule_dir, } /* Check the SRAM port size */ num_input_basis = determine_num_input_basis_multilevel_mux(cur_spice_mux_model->size, - cur_spice_mux_model->spice_model->design_tech_info.mux_num_level); - if ((num_input_basis * cur_spice_mux_model->spice_model->design_tech_info.mux_num_level) != sram_ports[0]->size) { + cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level); + if ((num_input_basis * cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level) != sram_ports[0]->size) { vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])User-defined MUX SPICE MODEL(%s) SRAM size(%d) unmatch with the num of level(%d)!\n", - __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, sram_ports[0]->size, cur_spice_mux_model->spice_model->design_tech_info.mux_num_level*num_input_basis); + __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, sram_ports[0]->size, cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level*num_input_basis); exit(1); } /* Move on to the next*/ @@ -2001,7 +2460,7 @@ void dump_verilog_submodule_muxes(char* submodule_dir, /* Determine reserved Bit/Word Lines if a memory bank is specified, * At least 1 BL/WL should be reserved! */ - try_update_sram_orgz_info_reserved_blwl(sram_verilog_orgz_info, + try_update_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, max_routing_mux_size, max_routing_mux_size); vpr_printf(TIO_MESSAGE_INFO,"Generated %d Multiplexer submodules.\n", @@ -2012,16 +2471,16 @@ void dump_verilog_submodule_muxes(char* submodule_dir, min_mux_size); /* Add fname to the linked list */ - submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + + /* Close the file*/ + fclose(fp); /* remember to free the linked list*/ free_muxes_llist(muxes_head); /* Free strings */ free(verilog_name); - /* Close the file*/ - fclose(fp); - return; } @@ -2058,7 +2517,7 @@ void dump_verilog_wire_module(FILE* fp, /* Add an output at middle point for connecting CB inputs */ fprintf(fp, "module %s (\n", wire_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &verilog_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &verilog_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "input wire %s, output wire %s, output wire mid_out);\n", @@ -2071,7 +2530,7 @@ void dump_verilog_wire_module(FILE* fp, fprintf(fp, "module %s (\n", wire_subckt_name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, &verilog_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, &verilog_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "input wire %s, output wire %s);\n", @@ -2095,8 +2554,7 @@ void dump_verilog_wire_module(FILE* fp, /* Dump one module of a LUT */ void dump_verilog_submodule_one_lut(FILE* fp, - t_spice_model* verilog_model, - boolean include_timing) { + t_spice_model* verilog_model) { int num_input_port = 0; int num_output_port = 0; int num_sram_port = 0; @@ -2104,19 +2562,39 @@ void dump_verilog_submodule_one_lut(FILE* fp, t_spice_model_port** output_port = NULL; t_spice_model_port** sram_port = NULL; int iport, ipin, iedge; + int sram_port_index = OPEN; + int mode_port_index = OPEN; + int mode_lsb = 0; + int num_dumped_port = 0; + char* mode_inport_postfix = "_mode"; + int num_buf_input_port = 0; + int num_buf_output_port = 0; + t_spice_model_port** buf_input_port = NULL; + t_spice_model_port** buf_output_port = NULL; + + int jport, jpin, pin_cnt; + int modegate_num_input_port = 0; + int modegate_num_input_pins = 0; + int modegate_num_output_port = 0; + t_spice_model_port** modegate_input_port = NULL; + t_spice_model_port** modegate_output_port = NULL; + char* required_gate_type = NULL; + enum e_spice_model_gate_type required_gate_model_type; + /* Check */ if (NULL == fp) { vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler.\n", __FILE__, __LINE__); - exit(1);} + exit(1); + } assert(SPICE_MODEL_LUT == verilog_model->type); /* Print module name */ fprintf(fp, "//-----LUT module, verilog_model_name=%s -----\n", verilog_model->name); fprintf(fp, "module %s (", verilog_model->name); /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, FALSE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, TRUE, FALSE, FALSE)) { fprintf(fp, ",\n"); } /* Print module port list */ @@ -2126,45 +2604,337 @@ void dump_verilog_submodule_one_lut(FILE* fp, sram_port = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); /* Asserts*/ - assert(1 == num_input_port); - assert(1 == num_output_port); - assert(1 == num_sram_port); - assert(1 == output_port[0]->size); + if (FALSE == verilog_model->design_tech_info.lut_info->frac_lut) { + /* when fracturable LUT is considered + * More than 1 output is allowed + * Only two SRAM ports are allowed + */ + assert(1 == num_input_port); + assert(1 == num_output_port); + assert(1 == num_sram_port); + } else { + assert (TRUE == verilog_model->design_tech_info.lut_info->frac_lut); + /* when fracturable LUT is considered + * More than 1 output is allowed + * Only two SRAM ports are allowed + */ + assert(1 == num_input_port); + for (iport = 0; iport < num_output_port; iport++) { + assert(0 < output_port[iport]->size); + } + assert(2 == num_sram_port); + } /* input port */ fprintf(fp, "input wire [0:%d] %s,\n", input_port[0]->size - 1, input_port[0]->prefix); /* Print output ports*/ - fprintf(fp, "output wire [0:%d] %s,\n", - output_port[0]->size - 1, output_port[0]->prefix); + for (iport = 0; iport < num_output_port; iport++) { + fprintf(fp, "output wire [0:%d] %s,\n", + output_port[iport]->size - 1, output_port[iport]->prefix); + } /* Print configuration ports*/ - fprintf(fp, "input wire [0:%d] %s_out,\n", - sram_port[0]->size - 1, sram_port[0]->prefix); - /* Inverted configuration port is not connected to any internal signal of a LUT */ - fprintf(fp, "input wire [0:%d] %s_outb\n", - sram_port[0]->size - 1, sram_port[0]->prefix); + num_dumped_port = 0; + for (iport = 0; iport < num_sram_port; iport++) { + /* By pass mode select ports */ + if (TRUE == sram_port[iport]->mode_select) { + continue; + } + assert(FALSE == sram_port[iport]->mode_select); + fprintf(fp, "input wire [0:%d] %s_out,\n", + sram_port[iport]->size - 1, sram_port[iport]->prefix); + /* Inverted configuration port is not connected to any internal signal of a LUT */ + fprintf(fp, "input wire [0:%d] %s_outb\n", + sram_port[iport]->size - 1, sram_port[iport]->prefix); + sram_port_index = iport; + num_dumped_port++; + } + assert(1 == num_dumped_port); + /* Print mode configuration ports*/ + num_dumped_port = 0; + for (iport = 0; iport < num_sram_port; iport++) { + /* By pass mode select ports */ + if (FALSE == sram_port[iport]->mode_select) { + continue; + } + fprintf(fp, ",\n"); + assert(TRUE == sram_port[iport]->mode_select); + fprintf(fp, "input wire [0:%d] %s_out,\n", + sram_port[iport]->size - 1, sram_port[iport]->prefix); + /* Inverted configuration port is not connected to any internal signal of a LUT */ + fprintf(fp, "input wire [0:%d] %s_outb\n", + sram_port[iport]->size - 1, sram_port[iport]->prefix); + mode_port_index = iport; + num_dumped_port++; + } + /* Check if all required SRAMs ports*/ + if (TRUE == verilog_model->design_tech_info.lut_info->frac_lut) { + if (1 != num_dumped_port) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d]) Fracturable LUT (spice_model_name=%s) must have 1 mode port!\n", + __FILE__, __LINE__, verilog_model->name); + exit(1); + } + } /* End of port list */ fprintf(fp, ");\n"); - /* Create inverted input port */ + /* Add mode selector */ + fprintf(fp, " wire [0:%d] %s%s;\n", + input_port[0]->size - 1, input_port[0]->prefix, mode_inport_postfix); fprintf(fp, " wire [0:%d] %s_b;\n", input_port[0]->size - 1, input_port[0]->prefix); - /* Create inverters between input port and its inversion */ - fprintf(fp, " assign %s_b = ~ %s;\n", - input_port[0]->prefix, input_port[0]->prefix); + fprintf(fp, " wire [0:%d] %s_buf;\n", + input_port[0]->size - 1, input_port[0]->prefix); + + /* Regular ports */ + if (FALSE == verilog_model->design_tech_info.lut_info->frac_lut) { + /* Wire the mode ports to regular inputs */ + for (ipin = 0; ipin < input_port[0]->size; ipin++) { + fprintf(fp, " assign %s%s[%d] = %s[%d];\n", + input_port[0]->prefix, mode_inport_postfix, ipin, + input_port[0]->prefix, ipin); + } + } else { + assert (TRUE == verilog_model->design_tech_info.lut_info->frac_lut); + assert( NULL != input_port[0]->tri_state_map ); + /* Create inverters between input port and its inversion */ + mode_lsb = 0; + for (ipin = 0; ipin < input_port[0]->size; ipin++) { + /* Set up checking flags */ + if ('0' == input_port[0]->tri_state_map[ipin]) { + required_gate_type = "AND"; + required_gate_model_type = SPICE_MODEL_GATE_AND; + } + if ('1' == input_port[0]->tri_state_map[ipin]) { + required_gate_type = "OR"; + required_gate_model_type = SPICE_MODEL_GATE_OR; + } + switch (input_port[0]->tri_state_map[ipin]) { + case '-': + fprintf(fp, " assign %s%s[%d] = %s[%d];\n", + input_port[0]->prefix, mode_inport_postfix, ipin, + input_port[0]->prefix, ipin); + break; + case '0': + case '1': + /* Check: we must have an AND2/OR2 gate */ + if (NULL == input_port[0]->spice_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) is not defined!\n", + __FILE__, __LINE__, required_gate_type, + input_port[0]->prefix, verilog_model->name); + exit(1); + } + if ((SPICE_MODEL_GATE != input_port[0]->spice_model->type) + || (required_gate_model_type != input_port[0]->spice_model->design_tech_info.gate_info->type)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) is not defined as a AND logic gate!\n", + __FILE__, __LINE__, required_gate_type, + input_port[0]->prefix, verilog_model->name); + exit(1); + } + /* Check input ports */ + modegate_input_port = find_spice_model_ports(input_port[0]->spice_model, SPICE_MODEL_PORT_INPUT, &modegate_num_input_port, TRUE); + modegate_num_input_pins = 0; + for (jport = 0; jport < modegate_num_input_port; jport++) { + modegate_num_input_pins += modegate_input_port[jport]->size; + } + if (2 != modegate_num_input_pins) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) should have only 2 input pins!\n", + __FILE__, __LINE__, required_gate_type, + input_port[0]->prefix, verilog_model->name); + exit(1); + } + /* Check output ports */ + modegate_output_port = find_spice_model_ports(input_port[0]->spice_model, SPICE_MODEL_PORT_OUTPUT, &modegate_num_output_port, TRUE); + if ( (1 != modegate_num_output_port) + || (1 != modegate_output_port[0]->size)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE: %s, [LINE%d]) %s gate for the input port (name=%s) of spice model (name=%s) should have only 1 output!\n", + __FILE__, __LINE__, required_gate_type, + input_port[0]->prefix, verilog_model->name); + exit(1); + } + /* Instance the AND2/OR2 gate */ + fprintf(fp, " %s %s_%s_%d_(", + input_port[0]->spice_model->name, + input_port[0]->spice_model->prefix, + input_port[0]->prefix, ipin); + pin_cnt = 0; + for (jport = 0; jport < modegate_num_input_port; jport++) { + if (0 < jport) { + fprintf(fp, ","); + } + for (jpin = 0; jpin < modegate_input_port[jport]->size; jpin++) { + if (0 < jpin) { + fprintf(fp, ","); + } + if (0 == pin_cnt) { + /* Dump explicit port map if required */ + if (TRUE == input_port[0]->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + modegate_input_port[jport]->lib_name); + } + fprintf(fp, "%s[%d]", + input_port[0]->prefix, ipin); + if (TRUE == input_port[0]->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + } else if (1 == pin_cnt) { + /* Dump explicit port map if required */ + if (TRUE == input_port[0]->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + modegate_input_port[jport]->lib_name); + } + fprintf(fp, " %s_out[%d]", + sram_port[mode_port_index]->prefix, mode_lsb); + if (TRUE == input_port[0]->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + } + pin_cnt++; + } + } + assert(2 == pin_cnt); + fprintf(fp, ", "); + /* Dump explicit port map if required */ + if (TRUE == input_port[0]->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + modegate_output_port[0]->lib_name); + } + fprintf(fp, " %s%s[%d]", + input_port[0]->prefix, mode_inport_postfix, ipin); + if (TRUE == input_port[0]->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + mode_lsb++; + /* Free ports */ + my_free(modegate_input_port); + my_free(modegate_output_port); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d]) Invalid LUT tri_state_map = %s ", + __FILE__, __LINE__, input_port[0]->tri_state_map); + exit(1); + } + } + if (mode_lsb != sram_port[mode_port_index]->size) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d]) SPICE model LUT (name=%s) has a unmatched tri-state map (%s) implied by mode_port size(%d)!\n", + __FILE__, __LINE__, verilog_model->name, input_port[0]->tri_state_map[ipin], input_port[0]->size); + exit(1); + } + } + + + /* Find the ports for input_inverter */ + buf_input_port = find_spice_model_ports(verilog_model->lut_input_buffer->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(verilog_model->lut_input_buffer->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert(1 == num_buf_input_port); + assert(1 == num_buf_output_port); + + /* Create buffer input port */ + for (ipin = 0; ipin < input_port[0]->size; ipin++) { + fprintf(fp, "%s %s_%s_%d_ ( ", + verilog_model->lut_input_buffer->spice_model->name, + verilog_model->lut_input_buffer->spice_model->name, + input_port[0]->prefix, ipin); + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model->lut_input_buffer->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); + } + /* Dump explicit port map if required */ + if (TRUE == verilog_model->lut_input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); + } + fprintf(fp, "%s%s[%d]", + input_port[0]->prefix, mode_inport_postfix, ipin); + if (TRUE == verilog_model->lut_input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + /* Dump explicit port map if required */ + if (TRUE == verilog_model->lut_input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "%s_buf[%d]", + input_port[0]->prefix, ipin); + if (TRUE == verilog_model->lut_input_buffer->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + } + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); + + /* Find the ports for input_inverter */ + buf_input_port = find_spice_model_ports(verilog_model->lut_input_inverter->spice_model, SPICE_MODEL_PORT_INPUT, &num_buf_input_port, TRUE); + buf_output_port = find_spice_model_ports(verilog_model->lut_input_inverter->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_buf_output_port, TRUE); + /* Check */ + assert(1 == num_buf_input_port); + assert(1 == num_buf_output_port); + + /* Create inverted input port */ + for (ipin = 0; ipin < input_port[0]->size; ipin++) { + fprintf(fp, "%s %s_%s_%d_ ( ", + verilog_model->lut_input_inverter->spice_model->name, + verilog_model->lut_input_inverter->spice_model->name, + input_port[0]->prefix, ipin); + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model->lut_input_inverter->spice_model, FALSE, FALSE, TRUE)) { + fprintf(fp, ",\n"); + } + /* Dump explicit port map if required */ + if (TRUE == verilog_model->lut_input_inverter->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_input_port[0]->lib_name); + } + fprintf(fp, "%s%s[%d]", + input_port[0]->prefix, mode_inport_postfix, ipin); + if (TRUE == verilog_model->lut_input_inverter->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ", "); + /* Dump explicit port map if required */ + if (TRUE == verilog_model->lut_input_inverter->spice_model->dump_explicit_port_map) { + fprintf(fp, ".%s(", + buf_output_port[0]->lib_name); + } + fprintf(fp, "%s_b[%d]", + input_port[0]->prefix, ipin); + if (TRUE == verilog_model->lut_input_inverter->spice_model->dump_explicit_port_map) { + fprintf(fp, ")"); + } + fprintf(fp, ");\n"); + } + /* Free */ + my_free(buf_input_port); + my_free(buf_output_port); + /* Internal structure of a LUT */ /* Call the LUT MUX */ fprintf(fp, " %s_mux %s_mux_0_ (", verilog_model->name, verilog_model->name); /* Connect MUX inputs to LUT configuration port */ + assert(FALSE == sram_port[sram_port_index]->mode_select); fprintf(fp, " %s_out,", - sram_port[0]->prefix); + sram_port[sram_port_index]->prefix); /* Connect MUX output to LUT output */ - fprintf(fp, " %s,", - output_port[0]->prefix); + for (iport = 0; iport < num_output_port; iport++) { + fprintf(fp, " %s,", + output_port[iport]->prefix); + } /* Connect MUX configuration port to LUT inputs */ - fprintf(fp, " %s,", + fprintf(fp, " %s_buf,", input_port[0]->prefix); /* Connect MUX inverted configuration port to inverted LUT inputs */ fprintf(fp, " %s_b", @@ -2172,26 +2942,105 @@ void dump_verilog_submodule_one_lut(FILE* fp, /* End of call LUT MUX */ fprintf(fp, ");\n"); - /* Give timing information */ - if (TRUE == include_timing) { - dump_verilog_submodule_timing(fp, verilog_model); - } - + /* Print timing info */ + dump_verilog_submodule_timing(fp, verilog_model); + /* Print signal initialization */ + dump_verilog_submodule_signal_init(fp, verilog_model); /* Print end of module */ fprintf(fp, "endmodule\n"); fprintf(fp, "//-----END LUT module, verilog_model_name=%s -----\n", verilog_model->name); fprintf(fp, "\n"); + /* Free */ + my_free(input_port); + my_free(output_port); + my_free(sram_port); + return; } +/* Dump one module of a LUT */ +void dump_verilog_submodule_one_mem(FILE* fp, + t_spice_model* verilog_model) { + int iport, ipin, pin_index; + int num_conf_bits; + + int num_sram_port = 0; + t_spice_model_port** sram_port = NULL; + t_spice_model* mem_model = NULL; + + /* Find the basis subckt*/ + char* mem_subckt_name = NULL; + + /* Make sure we have a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!\n",__FILE__, __LINE__); + exit(1); + } + + sram_port = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE); + + /* Return if there is no sram port */ + if (0 == num_sram_port) { + return; + } + + + /* Currently, Only support one mem_model for each SPICE MODEL */ + for (iport = 0; iport < num_sram_port; iport++) { + if (NULL == mem_model) { + mem_model = sram_port[iport]->spice_model; + continue; + } + if ( mem_model != sram_port[iport]->spice_model ) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d]) Different memory model has been found for a spice_model %s! Currently only support unified memory model\n", + __FILE__, __LINE__, verilog_model->name); + exit(1); + } + } + + /* Generate subckt name */ + mem_subckt_name = generate_verilog_mem_subckt_name(verilog_model, mem_model, verilog_mem_posfix); + + num_conf_bits = count_num_sram_bits_one_spice_model(verilog_model, -1); + + fprintf(fp, "//----- CMOS Mem info: spice_model_name=%s -----\n", + verilog_model->name); + fprintf(fp, "module %s (", mem_subckt_name); + dump_verilog_mem_module_port_map(fp, mem_model, TRUE, 0, num_conf_bits, FALSE); + fprintf(fp, ");\n"); + + /* For each SRAM port we generate mem subckt */ + pin_index = 0; + /* Dump all the submodules */ + for (ipin = 0 ; ipin < num_conf_bits; ipin++) { + fprintf(fp, "%s %s_%d_ ( ", + mem_model->name, mem_model->prefix, ipin); + dump_verilog_mem_module_port_map(fp, mem_model, FALSE, pin_index, 1, + mem_model->dump_explicit_port_map); + fprintf(fp, ");\n"); + pin_index++; + } + + /* END of this submodule */ + fprintf(fp, "endmodule\n"); + + /* Free */ + my_free(mem_subckt_name); + + +} + /* Dump verilog top-level module for LUTs */ -void dump_verilog_submodule_luts(char* submodule_dir, +void dump_verilog_submodule_luts(char* verilog_dir, + char* submodule_dir, int num_spice_model, t_spice_model* spice_models, - boolean include_timing) { + boolean include_timing, + boolean include_signal_init) { FILE* fp = NULL; char* verilog_name = my_strcat(submodule_dir, luts_verilog_file_name); int imodel; @@ -2204,7 +3053,7 @@ void dump_verilog_submodule_luts(char* submodule_dir, } dump_verilog_file_header(fp,"Look-Up Tables"); - dump_verilog_preproc(fp, include_timing); + verilog_include_defines_preproc_file(fp, verilog_dir); /* Search for each LUT spice model */ for (imodel = 0; imodel < num_spice_model; imodel++) { @@ -2213,7 +3062,7 @@ void dump_verilog_submodule_luts(char* submodule_dir, continue; } if (SPICE_MODEL_LUT == spice_models[imodel].type) { - dump_verilog_submodule_one_lut(fp, &(spice_models[imodel]), include_timing); + dump_verilog_submodule_one_lut(fp, &(spice_models[imodel])); } } @@ -2221,7 +3070,7 @@ void dump_verilog_submodule_luts(char* submodule_dir, fclose(fp); /* Add fname to the linked list */ - submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); return; } @@ -2290,7 +3139,8 @@ void dump_verilog_hard_wired_gnd(FILE* fp, return; } -void dump_verilog_submodule_wires(char* subckt_dir, +void dump_verilog_submodule_wires(char* verilog_dir, + char* subckt_dir, int num_segments, t_segment_inf* segments, int num_spice_model, @@ -2307,6 +3157,9 @@ void dump_verilog_submodule_wires(char* subckt_dir, exit(1); } dump_verilog_file_header(fp,"Wires"); + + verilog_include_defines_preproc_file(fp, verilog_dir); + /* Output wire models*/ for (imodel = 0; imodel < num_spice_model; imodel++) { /* Bypass user-defined spice models */ @@ -2344,6 +3197,7 @@ void dump_verilog_submodule_wires(char* subckt_dir, } /* Create module for hard-wired VDD and GND */ + /* for (imodel = 0; imodel < num_spice_model; imodel++) { if (SPICE_MODEL_VDD == spice_models[imodel].type) { dump_verilog_hard_wired_vdd(fp, spice_models[imodel]); @@ -2351,12 +3205,13 @@ void dump_verilog_submodule_wires(char* subckt_dir, dump_verilog_hard_wired_gnd(fp, spice_models[imodel]); } } + */ /* Close the file handler */ fclose(fp); /* Add fname to the linked list */ - submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); /*Free*/ my_free(seg_index_str); @@ -2365,43 +3220,295 @@ void dump_verilog_submodule_wires(char* subckt_dir, return; } +void dump_verilog_submodule_memories(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* submodule_dir, + int num_switch, + t_switch_inf* switches, + t_spice* spice, + t_det_routing_arch* routing_arch) { + + /* Statisitcs for input sizes and structures of MUXes + * used in FPGA architecture + */ + /* We have linked list whichs stores spice model information of multiplexer*/ + t_llist* muxes_head = NULL; + t_llist* temp = NULL; + FILE* fp = NULL; + char* verilog_name = my_strcat(submodule_dir, memories_verilog_file_name); + int num_input_ports = 0; + t_spice_model_port** input_ports = NULL; + int num_sram_ports = 0; + t_spice_model_port** sram_ports = NULL; + + int num_input_basis = 0; + t_spice_mux_model* cur_spice_mux_model = NULL; + + int imodel; + + /* Alloc the muxes*/ + muxes_head = stats_spice_muxes(num_switch, switches, spice, routing_arch); + + /* Print the muxes netlist*/ + fp = fopen(verilog_name, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create subckt SPICE netlist %s", + __FILE__, __LINE__, verilog_name); + exit(1); + } + /* Generate the descriptions*/ + dump_verilog_file_header(fp,"Memories used in FPGA"); + + verilog_include_defines_preproc_file(fp, verilog_dir); + + /* Print mux netlist one by one*/ + temp = muxes_head; + while(temp) { + assert(NULL != temp->dptr); + cur_spice_mux_model = (t_spice_mux_model*)(temp->dptr); + /* Bypass the spice models who has a user-defined subckt */ + if (NULL != cur_spice_mux_model->spice_model->verilog_netlist) { + input_ports = find_spice_model_ports(cur_spice_mux_model->spice_model, SPICE_MODEL_PORT_INPUT, &num_input_ports, TRUE); + sram_ports = find_spice_model_ports(cur_spice_mux_model->spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_ports, TRUE); + assert(0 != num_input_ports); + assert(0 != num_sram_ports); + /* Check the Input port size */ + if (cur_spice_mux_model->size != input_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])User-defined MUX SPICE MODEL(%s) size(%d) unmatch with the architecture needs(%d)!\n", + __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, input_ports[0]->size,cur_spice_mux_model->size); + exit(1); + } + /* Check the SRAM port size */ + num_input_basis = determine_num_input_basis_multilevel_mux(cur_spice_mux_model->size, + cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level); + if ((num_input_basis * cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level) != sram_ports[0]->size) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d])User-defined MUX SPICE MODEL(%s) SRAM size(%d) unmatch with the num of level(%d)!\n", + __FILE__, __LINE__, cur_spice_mux_model->spice_model->name, sram_ports[0]->size, + cur_spice_mux_model->spice_model->design_tech_info.mux_info->mux_num_level * num_input_basis); + exit(1); + } + /* Move on to the next*/ + temp = temp->next; + /* Free */ + my_free(input_ports); + my_free(sram_ports); + continue; + } + /* Generate the spice_mux_arch */ + cur_spice_mux_model->spice_mux_arch = (t_spice_mux_arch*)my_malloc(sizeof(t_spice_mux_arch)); + init_spice_mux_arch(cur_spice_mux_model->spice_model, cur_spice_mux_model->spice_mux_arch, cur_spice_mux_model->size); + /* Print the mux mem subckt */ + dump_verilog_mux_mem_module(fp, cur_spice_mux_model); + /* Update the statistics*/ + /* Move on to the next*/ + temp = temp->next; + } + + /* Search all the other SPICE models and create memory module */ + for (imodel = 0; imodel < spice->num_spice_model; imodel++) { + /* Bypass MUX */ + if (SPICE_MODEL_MUX == spice->spice_models[imodel].type) { + continue; + } + /* We only care those with SRAM ports */ + sram_ports = find_spice_model_ports(&(spice->spice_models[imodel]), SPICE_MODEL_PORT_SRAM, &num_sram_ports, TRUE); + if (0 == num_sram_ports) { + continue; + } + /* Create a memory submodule */ + dump_verilog_submodule_one_mem(fp, &(spice->spice_models[imodel])); + } + + /* Close the file*/ + fclose(fp); + + /* Add fname to the linked list */ + submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); + + /* remember to free the linked list*/ + free_muxes_llist(muxes_head); + + /* Free strings */ + free(verilog_name); + + return; +} + + +/* Print a non-global port for the template */ +void dump_one_verilog_template_module_one_port(FILE* fp, int* cnt, + t_spice_model* cur_spice_model, + enum e_spice_model_port_type port_type) { + int iport; + int num_port_to_dump= 0; + t_spice_model_port** port_to_dump = NULL; + + port_to_dump = find_spice_model_ports(cur_spice_model, port_type, &num_port_to_dump, TRUE); + for (iport = 0; iport < num_port_to_dump; iport++) { + if (0 < *cnt) { + fprintf(fp, ",\n"); + } + dump_verilog_generic_port(fp, + convert_spice_model_port_type_to_verilog_port_type(port_to_dump[iport]->type), + port_to_dump[iport]->lib_name, + port_to_dump[iport]->size - 1, 0); + (*cnt)++; + } + + /* Free */ + my_free(port_to_dump); + + return; +} + +/* Give a template for a user-defined module */ +void dump_one_verilog_template_module(FILE* fp, + t_spice_model* cur_spice_model) { + int iport; + int cnt = 0; + + /* Ensure a valid file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler.\n", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "//----- Template Verilog module for %s -----\n", + cur_spice_model->name); + + /* dump module body */ + fprintf(fp, "module %s (\n", + cur_spice_model->name); + + /* Dump ports */ + for (iport = 0; iport < cur_spice_model->num_port; iport++) { + if (0 < cnt) { + fprintf(fp, ",\n"); + } + dump_verilog_generic_port(fp, + convert_spice_model_port_type_to_verilog_port_type(cur_spice_model->ports[iport].type), + cur_spice_model->ports[iport].lib_name, + cur_spice_model->ports[iport].size - 1, 0); + cnt++; + /* if there is an inv_prefix, we will dump the paired port */ + if (NULL == cur_spice_model->ports[iport].inv_prefix) { + continue; + } + if (0 < cnt) { + fprintf(fp, ",\n"); + } + dump_verilog_generic_port(fp, + convert_spice_model_port_type_to_verilog_port_type(cur_spice_model->ports[iport].type), + cur_spice_model->ports[iport].inv_prefix, + cur_spice_model->ports[iport].size - 1, 0); + cnt++; + } + + fprintf(fp, ");\n"); + + fprintf(fp, "\n//------ User-defined Verilog netlist model should start from here! -----\n"); + + + fprintf(fp, "endmodule\n"); + + fprintf(fp, "\n"); + + return; +} + +/* Give a template of all the submodules that are user-defined */ +void dump_verilog_submodule_templates(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* submodule_dir, + int num_spice_model, + t_spice_model* spice_models) { + int imodel; + char* verilog_name = my_strcat(submodule_dir, user_defined_template_verilog_file_name); + FILE* fp = NULL; + + /* Create file */ + fp = fopen(verilog_name, "w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create Verilog netlist %s", + __FILE__, __LINE__, user_defined_template_verilog_file_name); + exit(1); + } + dump_verilog_file_header(fp,"User-defined netlists template"); + + /* Output essential models*/ + for (imodel = 0; imodel < num_spice_model; imodel++) { + /* Focus on user-defined modules */ + if (NULL == spice_models[imodel].verilog_netlist) { + continue; + } + /* Create the port template */ + dump_one_verilog_template_module(fp, &spice_models[imodel]); + } + + /* close file */ + fclose(fp); + + /* Free */ + my_free(verilog_name); + + return; +} /* Dump verilog files of submodules to be used in FPGA components : * 1. MUXes */ -void dump_verilog_submodules(char* submodule_dir, +void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* submodule_dir, t_arch Arch, t_det_routing_arch* routing_arch, - boolean include_timing, - boolean init_sim) { + t_syn_verilog_opts fpga_verilog_opts) { /* 0. basic units: inverter, buffers and pass-gate logics, */ vpr_printf(TIO_MESSAGE_INFO, "Generating essential modules...\n"); - dump_verilog_submodule_essentials(submodule_dir, + dump_verilog_submodule_essentials(verilog_dir, submodule_dir, Arch.spice->num_spice_model, Arch.spice->spice_models, - include_timing, - init_sim); + fpga_verilog_opts); /* 1. MUXes */ vpr_printf(TIO_MESSAGE_INFO, "Generating modules of multiplexers...\n"); - dump_verilog_submodule_muxes(submodule_dir, routing_arch->num_switch, + dump_verilog_submodule_muxes(cur_sram_orgz_info, verilog_dir, submodule_dir, routing_arch->num_switch, switch_inf, Arch.spice, routing_arch); /* 2. LUTes */ vpr_printf(TIO_MESSAGE_INFO, "Generating modules of LUTs...\n"); - dump_verilog_submodule_luts(submodule_dir, + dump_verilog_submodule_luts(verilog_dir, submodule_dir, Arch.spice->num_spice_model, Arch.spice->spice_models, - include_timing); + fpga_verilog_opts.include_timing, + fpga_verilog_opts.include_signal_init); /* 3. Hardwires */ vpr_printf(TIO_MESSAGE_INFO, "Generating modules of hardwires...\n"); - dump_verilog_submodule_wires(submodule_dir, Arch.num_segments, Arch.Segments, + dump_verilog_submodule_wires(verilog_dir, submodule_dir, Arch.num_segments, Arch.Segments, Arch.spice->num_spice_model, Arch.spice->spice_models); + /* 4. Memories */ + vpr_printf(TIO_MESSAGE_INFO, "Generating modules of memories...\n"); + dump_verilog_submodule_memories(cur_sram_orgz_info, verilog_dir, submodule_dir, routing_arch->num_switch, + switch_inf, Arch.spice, routing_arch); - /*Create a header file to include all the subckts */ + /* 5. Dump decoder modules only when memory bank is required */ + dump_verilog_config_peripherals(cur_sram_orgz_info, verilog_dir, submodule_dir); + /* 6. Dump template for all the modules */ + if (TRUE == fpga_verilog_opts.print_user_defined_template) { + dump_verilog_submodule_templates(cur_sram_orgz_info, + verilog_dir, + submodule_dir, + Arch.spice->num_spice_model, + Arch.spice->spice_models); + } + + /* Create a header file to include all the subckts */ vpr_printf(TIO_MESSAGE_INFO,"Generating header file for basic submodules...\n"); dump_verilog_subckt_header_file(submodule_verilog_subckt_file_path_head, submodule_dir, diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.h new file mode 100644 index 000000000..155c87543 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.h @@ -0,0 +1,7 @@ + +void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info, + char* verilog_dir, + char* submodule_dir, + t_arch Arch, + t_det_routing_arch* routing_arch, + t_syn_verilog_opts fpga_verilog_opts); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.c new file mode 100644 index 000000000..c6ec4742e --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.c @@ -0,0 +1,404 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph_util.h" +#include "rr_graph.h" +#include "rr_graph2.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_rr_graph_utils.h" +#include "fpga_x2p_globals.h" + +/* Include Verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" + +/***** Subroutine Functions *****/ +void dump_verilog_sdc_file_header(FILE* fp, + char* usage) { + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d]) FileHandle is NULL!\n",__FILE__,__LINE__); + exit(1); + } + fprintf(fp,"#############################################\n"); + fprintf(fp,"# Synopsys Design Constraints (SDC) # \n"); + fprintf(fp,"# FPGA Synthesizable Verilog Netlist # \n"); + fprintf(fp,"# Description: %s \n",usage); + fprintf(fp,"# Author: Xifan TANG # \n"); + fprintf(fp,"# Organization: EPFL/IC/LSI # \n"); + fprintf(fp,"# Date: %s \n", my_gettime()); + fprintf(fp,"#############################################\n"); + fprintf(fp,"\n"); + + return; +} + + +void dump_verilog_one_sb_chan_pin(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* cur_rr_node, + enum PORTS port_type) { + int track_idx, side; + int x_start, y_start; + t_rr_type chan_rr_type; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert ((CHANX == cur_rr_node->type) + ||(CHANY == cur_rr_node->type)); + /* Get the coordinate of chanx or chany*/ + /* Find the coordinate of the cur_rr_node */ + get_rr_node_side_and_index_in_sb_info(cur_rr_node, + *cur_sb_info, + port_type, &side, &track_idx); + get_chan_rr_node_coorindate_in_sb_info(*cur_sb_info, side, + &(chan_rr_type), + &x_start, &y_start); + assert (chan_rr_type == cur_rr_node->type); + /* Print the pin of the cur_rr_node */ + fprintf(fp, "%s", + gen_verilog_routing_channel_one_pin_name(cur_rr_node, + x_start, y_start, track_idx, + port_type)); + return; +} + +/* Output the pin name of a routing wire in a SB */ +void dump_verilog_one_sb_routing_pin(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* cur_rr_node) { + int side; + + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + /* Get the top-level pin name and print it out */ + /* Depends on the type of node */ + switch (cur_rr_node->type) { + case OPIN: + /* Identify the side of OPIN on a grid */ + side = get_grid_pin_side(cur_rr_node->xlow, cur_rr_node->ylow, cur_rr_node->ptc_num); + assert (OPEN != side); + dump_verilog_grid_side_pin_with_given_index(fp, OPIN, + cur_rr_node->ptc_num, + side, + cur_rr_node->xlow, + cur_rr_node->ylow, + FALSE); /* Do not specify direction of port */ + break; + case CHANX: + case CHANY: + dump_verilog_one_sb_chan_pin(fp, cur_sb_info, cur_rr_node, IN_PORT); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of ending point rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + + return; +} + +/** Given a starting rr_node (CHANX or CHANY) + * and a ending rr_node (IPIN) + * return the cb contains both (the ending CB of the routing wire) + */ +t_cb* get_chan_rr_node_ending_cb(t_rr_node* src_rr_node, + t_rr_node* end_rr_node) { + int num_ipin_sides = 2; + int* ipin_side = (int*)my_calloc(num_ipin_sides, sizeof(int)); + int num_chan_sides = 2; + int* chan_side = (int*)my_calloc(num_chan_sides, sizeof(int)); + int iside, next_cb_x, next_cb_y; + int node_exist; + t_cb* next_cb = NULL; + + /* Type of connection block depends on the src_rr_node */ + switch (src_rr_node->type) { + case CHANX: + /* the x of CB is same as end_rr_node, + * the y of CB should be same as src_rr_node + */ + assert (end_rr_node->xlow == end_rr_node->xhigh); + next_cb_x = end_rr_node->xlow; + assert (src_rr_node->ylow == src_rr_node->yhigh); + next_cb_y = src_rr_node->ylow; + /* Side will be either on TOP or BOTTOM */ + ipin_side[0] = TOP; + ipin_side[1] = BOTTOM; + chan_side[0] = RIGHT; + chan_side[1] = LEFT; + next_cb = &(cbx_info[next_cb_x][next_cb_y]); + break; + case CHANY: + /* the x of CB is same as src_rr_node, + * the y of CB should be same as end_rr_node + */ + assert (src_rr_node->xlow == src_rr_node->xhigh); + next_cb_x = src_rr_node->xlow; + assert (end_rr_node->ylow == end_rr_node->yhigh); + next_cb_y = end_rr_node->ylow; + /* Side will be either on RIGHT or LEFT */ + ipin_side[0] = LEFT; + ipin_side[1] = RIGHT; + chan_side[0] = BOTTOM; + chan_side[1] = TOP; + next_cb = &(cby_info[next_cb_x][next_cb_y]); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File: %s [LINE%d]) Invalid type of src_rr_node!\n", + __FILE__, __LINE__); + + exit(1); + } + + /* Double check if src_rr_node is in the IN_PORT list */ + node_exist = 0; + for (iside = 0; iside < num_chan_sides; iside++) { + if (OPEN != get_rr_node_index_in_cb_info( src_rr_node, + *next_cb, + chan_side[iside], IN_PORT)) { + node_exist++; + } + } + assert (0 < node_exist); + + /* Double check if end_rr_node is in the OUT_PORT list */ + node_exist = 0; + for (iside = 0; iside < num_ipin_sides; iside++) { + if (OPEN != get_rr_node_index_in_cb_info( end_rr_node, + *next_cb, + ipin_side[iside], OUT_PORT)) { + node_exist++; + } + } + assert (0 < node_exist); + + return next_cb; +} + +/** Given a starting rr_node (CHANX or CHANY) + * and a ending rr_node (IPIN) + * return the sb contains both (the ending CB of the routing wire) + */ +t_sb* get_chan_rr_node_ending_sb(t_rr_node* src_rr_node, + t_rr_node* end_rr_node) { + int side; + int x_start, y_start; + int x_end, y_end; + int next_sb_x, next_sb_y; + int node_exist; + t_sb* next_sb = NULL; + + get_chan_rr_node_start_coordinate(src_rr_node, &x_start, &y_start); + get_chan_rr_node_start_coordinate(end_rr_node, &x_end, &y_end); + + /* Case 1: + * end_rr_node(chany[x][y+1]) + * /|\ + * | + * --------- + * | | + * src_rr_node ------>| next_sb |-------> end_rr_node + * (chanx[x][y]) | [x][y] | (chanx[x+1][y] + * --------- + * | + * \|/ + * end_rr_node(chany[x][y]) + */ + /* Case 2 + * end_rr_node(chany[x][y+1]) + * /|\ + * | + * --------- + * | | + * end_rr_node <------| next_sb |<-------- src_rr_node + * (chanx[x][y]) | [x][y] | (chanx[x+1][y] + * --------- + * | + * \|/ + * end_rr_node(chany[x][y]) + */ + /* Case 3 + * end_rr_node(chany[x][y+1]) + * /|\ + * | + * --------- + * | | + * end_rr_node <------| next_sb |-------> src_rr_node + * (chanx[x][y]) | [x][y] | (chanx[x+1][y] + * --------- + * /|\ + * | + * src_rr_node(chany[x][y]) + */ + /* Case 4 + * src_rr_node(chany[x][y+1]) + * | + * \|/ + * --------- + * | | + * end_rr_node <------| next_sb |--------> end_rr_node + * (chanx[x][y]) | [x][y] | (chanx[x+1][y] + * --------- + * | + * \|/ + * end_rr_node(chany[x][y]) + */ + + + /* Try the xlow, ylow of ending rr_node */ + switch (src_rr_node->type) { + case CHANX: + next_sb_x = x_end; + next_sb_y = y_start; + break; + case CHANY: + next_sb_x = x_start; + next_sb_y = y_end; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of rr_node!\n", + __FILE__, __LINE__); + exit(1); + } + + switch (src_rr_node->direction) { + case INC_DIRECTION: + get_chan_rr_node_end_coordinate(src_rr_node, &x_end, &y_end); + if (next_sb_x > x_end) { + next_sb_x = x_end; + } + if (next_sb_y > y_end) { + next_sb_y = y_end; + } + break; + case DEC_DIRECTION: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of rr_node!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Double check if src_rr_node is in the list */ + node_exist = 0; + for (side = 0; side < 4; side++) { + if( OPEN != get_rr_node_index_in_sb_info(src_rr_node, + sb_info[next_sb_x][next_sb_y], + side, IN_PORT)) { + node_exist++; + } + } + assert (1 == node_exist); + + /* Double check if end_rr_node is in the list */ + node_exist = 0; + for (side = 0; side < 4; side++) { + if (OPEN != get_rr_node_index_in_sb_info(end_rr_node, + sb_info[next_sb_x][next_sb_y], + side, OUT_PORT)) { + node_exist++; + } + } + if (1 != node_exist) { + assert (1 == node_exist); + } + + /* Passing the check, assign ending sb */ + next_sb = &(sb_info[next_sb_x][next_sb_y]); + + return next_sb; +} + +/* Restore the disabled timing for the sb wire */ +void restore_disable_timing_one_sb_output(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + assert( ( CHANX == wire_rr_node->type ) + || ( CHANY == wire_rr_node->type )); + + /* Restore disabled timing for wire_rr_node as an SB output */ + fprintf(fp, "reset_disable_timing "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + dump_verilog_one_sb_chan_pin(fp, cur_sb_info, wire_rr_node, OUT_PORT); + fprintf(fp, "\n"); + + return; +} + +/* Restore the disabled timing for the sb wire */ +void set_disable_timing_one_sb_output(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node) { + /* Check the file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Invalid file handler for SDC generation", + __FILE__, __LINE__); + exit(1); + } + + assert( ( CHANX == wire_rr_node->type ) + || ( CHANY == wire_rr_node->type )); + + /* Restore disabled timing for wire_rr_node as an SB output */ + fprintf(fp, "set_disable_timing "); + /* output instance name */ + fprintf(fp, "%s/", + gen_verilog_one_sb_instance_name(cur_sb_info)); + dump_verilog_one_sb_chan_pin(fp, cur_sb_info, wire_rr_node, OUT_PORT); + fprintf(fp, "\n"); + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.h new file mode 100644 index 000000000..2a44f1ab2 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_tcl_utils.h @@ -0,0 +1,26 @@ + +void dump_verilog_sdc_file_header(FILE* fp, + char* usage); + +void dump_verilog_one_sb_chan_pin(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* cur_rr_node, + enum PORTS port_type); + +void dump_verilog_one_sb_routing_pin(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* cur_rr_node); + +t_cb* get_chan_rr_node_ending_cb(t_rr_node* src_rr_node, + t_rr_node* end_rr_node); + +t_sb* get_chan_rr_node_ending_sb(t_rr_node* src_rr_node, + t_rr_node* end_rr_node); + +void restore_disable_timing_one_sb_output(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node); + +void set_disable_timing_one_sb_output(FILE* fp, + t_sb* cur_sb_info, + t_rr_node* wire_rr_node); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.c new file mode 100644 index 000000000..bb1fc8ada --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.c @@ -0,0 +1,1543 @@ +/***********************************/ +/* Dump Synthesizable Veriolog */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include spice support headers*/ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" + +/* Include verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" +#include "verilog_pbtypes.h" +#include "verilog_decoder.h" +#include "verilog_top_netlist_utils.h" + +/* Local Subroutines declaration */ + +/******** Subroutines ***********/ + +/* Connect BLs and WLs to configuration bus in the top-level Verilog netlist*/ +static +void dump_verilog_top_netlist_memory_bank_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + t_spice_model* mem_model = NULL; + int num_bl, num_wl; + int num_array_bl, num_array_wl; + int num_reserved_bl, num_reserved_wl; + int bl_decoder_size, wl_decoder_size; + int num_blb_ports, num_wlb_ports; + t_spice_model_port** blb_port = NULL; + t_spice_model_port** wlb_port = NULL; + + /* Check */ + assert (cur_sram_orgz_info->type == SPICE_SRAM_MEMORY_BANK); + + /* A valid file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Depending on the memory technology*/ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + /* Get the total number of BLs and WLs */ + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &num_bl, &num_wl); + /* Get the reserved BLs and WLs */ + get_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, &num_reserved_bl, &num_reserved_wl); + + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + /* Get BLB and WLB ports */ + find_blb_wlb_ports_spice_model(mem_model, &num_blb_ports, &blb_port, + &num_wlb_ports, &wlb_port); + /* Get inverter spice_model */ + + /* Important!!!: + * BL/WL should always start from LSB to MSB! + * In order to follow this convention in primitive nodes. + */ + /* No. of BLs and WLs in the array */ + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_bl_port_name, 0, num_array_bl - 1); + fprintf(fp, "; //--- Array Bit lines bus \n"); + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_wl_port_name, 0, num_array_wl - 1); + fprintf(fp, "; //--- Array Bit lines bus \n"); + if (1 == num_blb_ports) { + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_blb_port_name, 0, num_array_bl - 1); + fprintf(fp, "; //--- Inverted Array Bit lines bus \n"); + } + if (1 == num_wlb_ports) { + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_array_wlb_port_name, 0, num_array_wl - 1); + fprintf(fp, "; //--- Inverted Array Word lines bus \n"); + } + fprintf(fp, "\n"); + + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + assert( 0 == num_reserved_bl ); + assert( 0 == num_reserved_wl ); + /* SRAMs are place in an array + * BLs of SRAMs in the same column are connected to a common BL + * BLs of SRAMs in the same row are connected to a common WL + */ + /* Declare wires */ + fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Bit lines \n", + 0, num_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); + fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Word lines \n", + 0, num_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); + /* Declare inverted wires if needed */ + if (1 == num_blb_ports) { + fprintf(fp, " wire [%d:%d] %s%s; //---- Inverted Normal Bit lines \n", + 0, num_bl - 1, mem_model->prefix, top_netlist_normal_blb_port_postfix); + } + if (1 == num_wlb_ports) { + fprintf(fp, " wire [%d:%d] %s%s; //---- Inverted Normal Word lines \n", + 0, num_wl - 1, mem_model->prefix, top_netlist_normal_wlb_port_postfix); + } + /* Dump ports only visible during formal verification*/ + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + 0, get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info) - 1, + VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + fprintf(fp, "`endif\n"); + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Check: there should be reserved BLs and WLs */ + assert( 0 < num_reserved_bl ); + assert( 0 < num_reserved_wl ); + /* Declare reserved and normal conf_bits ports */ + fprintf(fp, " wire [0:%d] %s%s; //---- Reserved Bit lines \n", + num_reserved_bl - 1, mem_model->prefix, top_netlist_reserved_bl_port_postfix); + fprintf(fp, " wire [0:%d] %s%s; //---- Reserved Word lines \n", + num_reserved_wl - 1, mem_model->prefix, top_netlist_reserved_wl_port_postfix); + fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Bit lines \n", + num_reserved_bl, num_array_bl - 1, mem_model->prefix, top_netlist_normal_bl_port_postfix); + fprintf(fp, " wire [%d:%d] %s%s; //---- Normal Word lines \n", + num_reserved_wl, num_array_wl - 1, mem_model->prefix, top_netlist_normal_wl_port_postfix); + /* TODO: Dump ports only visible during formal verification*/ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Delcare primary inputs/outputs for scan-chains in the top-level netlists + */ +static +void dump_verilog_top_netlist_scan_chain_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_dump_verilog_port_type dump_port_type) { + /* Only accept two types of dump_port_type here! */ + assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); + + /* Check */ + assert (cur_sram_orgz_info->type == SPICE_SRAM_SCAN_CHAIN); + + /* A valid file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Only the head of scan-chain will be the primary input in the top-level netlist + * TODO: we may have multiple scan-chains, their heads will be the primary outputs + */ + dump_verilog_generic_port(fp, dump_port_type, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, " //---- Scan-chain head \n"); + + return; +} + +/* Connect scan-chain flip-flops in the top-level netlist */ +static +void dump_verilog_top_netlist_scan_chain_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + t_spice_model* scff_mem_model = NULL; + int num_scffs; + + /* A valid file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + num_scffs = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &scff_mem_model); + /* Check */ + assert( SPICE_MODEL_SCFF == scff_mem_model->type ); + + /* Delcare local wires */ + fprintf(fp, " wire [0:%d] %s_scff_in_local_bus;\n", + num_scffs - 1, scff_mem_model->prefix); + + fprintf(fp, " wire [0:%d] %s_scff_out_local_bus;\n", + num_scffs - 1, scff_mem_model->prefix); + + /* Dump ports only visible during formal verification*/ + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, " "); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + 0, num_scffs - 1, + VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + fprintf(fp, "`endif\n"); + + + /* Exception for head: connect to primary inputs */ + /* + fprintf(fp, " assign %s_scff_in[%d] = %s;\n", + scff_mem_model->prefix, 0, + top_netlist_scan_chain_head_prefix); + */ + /* Connected the scan-chain flip-flops */ + /* Ensure we are in the correct range */ + /* + fprintf(fp, " genvar i;\n"); + fprintf(fp, " generate\n"); + fprintf(fp, " for (i = %d; i < %d; i = i + 1) begin\n", + 1, num_scffs - 1); + fprintf(fp, "assign %s_scff_in[i] = %s_scff_out[i - 1];\n", + scff_mem_model->prefix, + scff_mem_model->prefix); + fprintf(fp, " end\n"); + fprintf(fp, " endgenerate;\n"); + */ + + return; +} + + +/* Dump ports for the top-level module in Verilog netlist */ +void dump_verilog_top_module_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_dump_verilog_port_type dump_port_type) { + char* port_name = NULL; + char split_sign; + enum e_dump_verilog_port_type actual_dump_port_type; + boolean dump_global_port_type = FALSE; + + split_sign = determine_verilog_generic_port_split_sign(dump_port_type); + + /* Only accept two types of dump_port_type here! */ + assert((VERILOG_PORT_INPUT == dump_port_type)||(VERILOG_PORT_CONKT == dump_port_type)); + + if (VERILOG_PORT_INPUT == dump_port_type) { + dump_global_port_type = TRUE; + } + + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, dump_global_port_type)) { + fprintf(fp, "%c\n", split_sign); + } + /* Inputs and outputs of I/O pads */ + /* Inout Pads */ + assert(NULL != iopad_verilog_model); + if ((NULL == iopad_verilog_model) + ||(iopad_verilog_model->cnt > 0)) { + actual_dump_port_type = VERILOG_PORT_CONKT; + if (VERILOG_PORT_INPUT == dump_port_type) { + actual_dump_port_type = VERILOG_PORT_INOUT; + } + /* Malloc and assign port_name */ + port_name = gen_verilog_top_module_io_port_prefix(gio_inout_prefix, iopad_verilog_model->prefix); + /* Dump a register port */ + dump_verilog_generic_port(fp, actual_dump_port_type, + port_name, iopad_verilog_model->cnt - 1, 0); + fprintf(fp, "%c //---FPGA inouts \n", split_sign); + /* Free port_name */ + my_free(port_name); + } + + /* Configuration ports depend on the organization of SRAMs */ + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + dump_verilog_generic_port(fp, dump_port_type, + sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); + fprintf(fp, " //--- SRAM outputs \n"); + /* Definition ends */ + break; + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_top_netlist_scan_chain_ports(cur_sram_orgz_info, fp, dump_port_type); + /* Definition ends */ + break; + case SPICE_SRAM_MEMORY_BANK: + dump_verilog_decoder_memory_bank_ports(cur_sram_orgz_info, fp, dump_port_type); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + + +/* Dump ports for the top-level Verilog netlist */ +void dump_verilog_top_netlist_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int num_clocks, + char* circuit_name, + t_spice verilog) { + /* + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + char* port_name = NULL; + */ + + /* A valid file handler */ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "//----- Top-level Verilog Module -----\n"); + fprintf(fp, "module %s_top (\n", circuit_name); + fprintf(fp, "\n"); + + dump_verilog_top_module_ports(cur_sram_orgz_info, fp, VERILOG_PORT_INPUT); + + fprintf(fp, ");\n"); + + return; +} + +void dump_verilog_top_netlist_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + /* Configuration ports depend on the organization of SRAMs */ + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + /* Definition ends */ + break; + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_top_netlist_scan_chain_internal_wires(cur_sram_orgz_info, fp); + /* Definition ends */ + break; + case SPICE_SRAM_MEMORY_BANK: + dump_verilog_top_netlist_memory_bank_internal_wires(cur_sram_orgz_info, fp); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + + + + + +static +void dump_verilog_defined_one_grid(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int ix, int iy) { + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + if ((NULL == grid[ix][iy].type) + || (EMPTY_TYPE == grid[ix][iy].type) + ||(0 != grid[ix][iy].offset)) { + return; + } + + /* Comment lines */ + fprintf(fp, "//----- BEGIN Call Grid[%d][%d] module -----\n", ix, iy); + /* Print the Grid module */ + fprintf(fp, "grid_%d__%d_ ", ix, iy); /* Call the name of subckt */ + fprintf(fp, "grid_%d__%d__0_ ", ix, iy); + fprintf(fp, "("); + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + + if (IO_TYPE == grid[ix][iy].type) { + dump_verilog_io_grid_pins(fp, ix, iy, TRUE, FALSE, FALSE); + } else { + dump_verilog_grid_pins(fp, ix, iy, TRUE, FALSE, FALSE); + } + + /* IO PAD */ + dump_verilog_grid_common_port(fp, iopad_verilog_model, gio_inout_prefix, + iopad_verilog_model->grid_index_low[ix][iy], + iopad_verilog_model->grid_index_high[ix][iy] - 1, + VERILOG_PORT_CONKT); + + /* Print configuration ports */ + /* Reserved configuration ports */ + if (0 < cur_sram_orgz_info->grid_reserved_conf_bits[ix][iy]) { + fprintf(fp, ",\n"); + } + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, + cur_sram_orgz_info->grid_reserved_conf_bits[ix][iy] - 1, + VERILOG_PORT_CONKT); + /* Normal configuration ports */ + if (0 < (cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] + - cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy])) { + fprintf(fp, ",\n"); + } + dump_verilog_sram_ports(fp, cur_sram_orgz_info, + cur_sram_orgz_info->grid_conf_bits_lsb[ix][iy], + cur_sram_orgz_info->grid_conf_bits_msb[ix][iy] - 1, + VERILOG_PORT_CONKT); + fprintf(fp, ");\n"); + /* Comment lines */ + fprintf(fp, "//----- END call Grid[%d][%d] module -----\n\n", ix, iy); + + return; +} + +/* Call defined channels. + * Ensure the port name here is co-herent to other sub-circuits(SB,CB,grid)!!! + */ +static +void dump_verilog_defined_one_channel(FILE* fp, + t_rr_type chan_type, int x, int y, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int itrack; + int chan_width = 0; + t_rr_node** chan_rr_nodes = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert((CHANX == chan_type)||(CHANY == chan_type)); + /* check x*/ + assert((!(0 > x))&&(x < (nx + 1))); + /* check y*/ + assert((!(0 > y))&&(y < (ny + 1))); + + /* Collect rr_nodes for Tracks for chanx[ix][iy] */ + chan_rr_nodes = get_chan_rr_nodes(&chan_width, chan_type, x, y, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + + /* Comment lines */ + switch (chan_type) { + case CHANX: + fprintf(fp, "//----- BEGIN Call Channel-X [%d][%d] module -----\n", x, y); + break; + case CHANY: + fprintf(fp, "//----- BEGIN call Channel-Y [%d][%d] module -----\n\n", x, y); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid Channel Type!\n", __FILE__, __LINE__); + exit(1); + } + + /* Call the define sub-circuit */ + fprintf(fp, "%s ", + gen_verilog_one_routing_channel_module_name(chan_type, x, y)); + fprintf(fp, "%s ", + gen_verilog_one_routing_channel_instance_name(chan_type, x, y)); + fprintf(fp, "("); + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + + /* LEFT/BOTTOM side port of CHANX/CHANY */ + /* We apply an opposite port naming rule than function: fprint_routing_chan_subckt + * In top-level netlists, we follow the same port name as switch blocks and connection blocks + * When a track is in INC_DIRECTION, the LEFT/BOTTOM port would be an output of a switch block + * When a track is in DEC_DIRECTION, the LEFT/BOTTOM port would be an input of a switch block + */ + for (itrack = 0; itrack < chan_width; itrack++) { + switch (chan_rr_nodes[itrack]->direction) { + case INC_DIRECTION: + fprintf(fp, "%s, ", + gen_verilog_routing_channel_one_pin_name(chan_rr_nodes[itrack], + x, y, itrack, OUT_PORT)); + fprintf(fp, "\n"); + break; + case DEC_DIRECTION: + fprintf(fp, "%s, ", + gen_verilog_routing_channel_one_pin_name(chan_rr_nodes[itrack], + x, y, itrack, IN_PORT)); + fprintf(fp, "\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of %s[%d][%d]_track[%d]!\n", + __FILE__, __LINE__, + convert_chan_type_to_string(chan_type), + x, y, itrack); + exit(1); + } + } + /* RIGHT/TOP side port of CHANX/CHANY */ + /* We apply an opposite port naming rule than function: fprint_routing_chan_subckt + * In top-level netlists, we follow the same port name as switch blocks and connection blocks + * When a track is in INC_DIRECTION, the RIGHT/TOP port would be an input of a switch block + * When a track is in DEC_DIRECTION, the RIGHT/TOP port would be an output of a switch block + */ + for (itrack = 0; itrack < chan_width; itrack++) { + switch (chan_rr_nodes[itrack]->direction) { + case INC_DIRECTION: + fprintf(fp, "%s, ", + gen_verilog_routing_channel_one_pin_name(chan_rr_nodes[itrack], + x, y, itrack, IN_PORT)); + fprintf(fp, "\n"); + break; + case DEC_DIRECTION: + fprintf(fp, "%s, ", + gen_verilog_routing_channel_one_pin_name(chan_rr_nodes[itrack], + x, y, itrack, OUT_PORT)); + fprintf(fp, "\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of %s[%d][%d]_track[%d]!\n", + __FILE__, __LINE__, + convert_chan_type_to_string(chan_type), + x, y, itrack); + exit(1); + } + } + + /* output at middle point */ + for (itrack = 0; itrack < chan_width; itrack++) { + fprintf(fp, "%s_%d__%d__midout_%d_ ", + convert_chan_type_to_string(chan_type), + x, y, itrack); + if (itrack < chan_width - 1) { + fprintf(fp, ","); + } + fprintf(fp, "\n"); + } + fprintf(fp, ");\n"); + + /* Comment lines */ + switch (chan_type) { + case CHANX: + fprintf(fp, "//----- END Call Channel-X [%d][%d] module -----\n", x, y); + break; + case CHANY: + fprintf(fp, "//----- END call Channel-Y [%d][%d] module -----\n\n", x, y); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid Channel Type!\n", __FILE__, __LINE__); + exit(1); + } + + /* Free */ + my_free(chan_rr_nodes); + + return; +} + +/* Call the sub-circuits for channels : Channel X and Channel Y*/ +void dump_verilog_defined_channels(FILE* fp, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices) { + int ix, iy; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid File Handler!\n", __FILE__, __LINE__); + exit(1); + } + + /* Channel X */ + for (iy = 0; iy < (ny + 1); iy++) { + for (ix = 1; ix < (nx + 1); ix++) { + dump_verilog_defined_one_channel(fp, CHANX, ix, iy, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + } + + /* Channel Y */ + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + dump_verilog_defined_one_channel(fp, CHANY, ix, iy, + LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices); + } + } + + return; +} + +/* Call the defined sub-circuit of connection box + * TODO: actually most of this function is copied from + * spice_routing.c : dump_verilog_conneciton_box_interc + * Should be more clever to use the original function + */ +static +void dump_verilog_defined_one_connection_box(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_cb cur_cb_info) { + int itrack, inode, side, x, y; + int side_cnt = 0; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + /* Check */ + assert((!(0 > cur_cb_info.x))&&(!(cur_cb_info.x > (nx + 1)))); + assert((!(0 > cur_cb_info.y))&&(!(cur_cb_info.y > (ny + 1)))); + + x = cur_cb_info.x; + y = cur_cb_info.y; + + /* Comment lines */ + fprintf(fp, + "//----- BEGIN Call Connection Box for %s direction [%d][%d] module -----\n", + convert_chan_type_to_string(cur_cb_info.type), + x, y); + + /* Print module */ + fprintf(fp, "%s ", gen_verilog_one_cb_module_name(&cur_cb_info)); + fprintf(fp, "%s ", gen_verilog_one_cb_instance_name(&cur_cb_info)); + + fprintf(fp, "("); + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + + /* Print the ports of channels*/ + /* connect to the mid point of a track*/ + side_cnt = 0; + for (side = 0; side < cur_cb_info.num_sides; side++) { + /* Bypass side with zero channel width */ + if (0 == cur_cb_info.chan_width[side]) { + continue; + } + assert (0 < cur_cb_info.chan_width[side]); + side_cnt++; + fprintf(fp, "//----- %s side inputs: channel track middle outputs -----\n", convert_side_index_to_string(side)); + for (itrack = 0; itrack < cur_cb_info.chan_width[side]; itrack++) { + fprintf(fp, "%s, ", + gen_verilog_routing_channel_one_midout_name(&cur_cb_info, itrack)); + fprintf(fp, "\n"); + } + } + /*check side_cnt */ + assert(1 == side_cnt); + + side_cnt = 0; + /* Print the ports of grids*/ + for (side = 0; side < cur_cb_info.num_sides; side++) { + /* Bypass side with zero IPINs*/ + if (0 == cur_cb_info.num_ipin_rr_nodes[side]) { + continue; + } + side_cnt++; + assert(0 < cur_cb_info.num_ipin_rr_nodes[side]); + assert(NULL != cur_cb_info.ipin_rr_node[side]); + fprintf(fp, "//----- %s side outputs: CLB input pins -----\n", convert_side_index_to_string(side)); + for (inode = 0; inode < cur_cb_info.num_ipin_rr_nodes[side]; inode++) { + /* Print each INPUT Pins of a grid */ + dump_verilog_grid_side_pin_with_given_index(fp, OPIN, + cur_cb_info.ipin_rr_node[side][inode]->ptc_num, + cur_cb_info.ipin_rr_node_grid_side[side][inode], + cur_cb_info.ipin_rr_node[side][inode]->xlow, + cur_cb_info.ipin_rr_node[side][inode]->ylow, + FALSE); /* Do not specify direction of port */ + fprintf(fp, ", \n"); + } + } + /* Make sure only 2 sides of IPINs are printed */ + assert((1 == side_cnt)||(2 == side_cnt)); + + /* Configuration ports */ + /* Reserved sram ports */ + if (0 < (cur_cb_info.num_reserved_conf_bits)) { + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, cur_cb_info.num_reserved_conf_bits - 1, + VERILOG_PORT_CONKT); + fprintf(fp, ",\n"); + } + /* Normal sram ports */ + if (0 < (cur_cb_info.conf_bits_msb - cur_cb_info.conf_bits_lsb)) { + dump_verilog_sram_local_ports(fp, cur_sram_orgz_info, + cur_cb_info.conf_bits_lsb, cur_cb_info.conf_bits_msb - 1, + VERILOG_PORT_CONKT); + } + /* Dump ports only visible during formal verification*/ + if (0 < (cur_cb_info.conf_bits_msb - 1 - cur_cb_info.conf_bits_lsb)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_cb_info.conf_bits_lsb, + cur_cb_info.conf_bits_msb - 1, + VERILOG_PORT_CONKT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + fprintf(fp, ");\n"); + + /* Comment lines */ + switch(cur_cb_info.type) { + case CHANX: + fprintf(fp, "//----- END call Connection Box-X direction [%d][%d] module -----\n\n", x, y); + break; + case CHANY: + fprintf(fp, "//----- END call Connection Box-Y direction [%d][%d] module -----\n\n", x, y); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert((1 == side_cnt)||(2 == side_cnt)); + + return; +} + +/* Call the sub-circuits for connection boxes */ +void dump_verilog_defined_connection_boxes(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int ix, iy; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* X - channels [1...nx][0..ny]*/ + for (iy = 0; iy < (ny + 1); iy++) { + for (ix = 1; ix < (nx + 1); ix++) { + if ((TRUE == is_cb_exist(CHANX, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) { + dump_verilog_defined_one_connection_box(cur_sram_orgz_info, fp, cbx_info[ix][iy]); + } + } + } + /* Y - channels [1...ny][0..nx]*/ + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 1; iy < (ny + 1); iy++) { + if ((TRUE == is_cb_exist(CHANY, ix, iy)) + &&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) { + dump_verilog_defined_one_connection_box(cur_sram_orgz_info, fp, cby_info[ix][iy]); + } + } + } + + return; +} + +/* Call the defined switch box sub-circuit + * TODO: This function is also copied from + * spice_routing.c : dump_verilog_routing_switch_box_subckt + */ +static +void dump_verilog_defined_one_switch_box(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_sb cur_sb_info) { + int ix, iy, side, itrack, x, y, inode; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert((!(0 > cur_sb_info.x))&&(!(cur_sb_info.x > (nx + 1)))); + assert((!(0 > cur_sb_info.y))&&(!(cur_sb_info.y > (ny + 1)))); + + x = cur_sb_info.x; + y = cur_sb_info.y; + + /* Comment lines */ + fprintf(fp, "//----- BEGIN call module Switch blocks [%d][%d] -----\n", + cur_sb_info.x, cur_sb_info.y); + /* Print module*/ + fprintf(fp, "%s ", gen_verilog_one_sb_module_name(&cur_sb_info)); + fprintf(fp, "%s ", gen_verilog_one_sb_instance_name(&cur_sb_info)); + fprintf(fp, "("); + + fprintf(fp, "\n"); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + + for (side = 0; side < cur_sb_info.num_sides; side++) { + determine_sb_port_coordinator(cur_sb_info, side, &ix, &iy); + + fprintf(fp, "//----- %s side channel ports-----\n", convert_side_index_to_string(side)); + for (itrack = 0; itrack < cur_sb_info.chan_width[side]; itrack++) { + fprintf(fp, "%s,\n", + gen_verilog_routing_channel_one_pin_name(cur_sb_info.chan_rr_node[side][itrack], + ix, iy, itrack, + cur_sb_info.chan_rr_node_direction[side][itrack])); + } + fprintf(fp, "//----- %s side inputs: CLB output pins -----\n", convert_side_index_to_string(side)); + /* Dump OPINs of adjacent CLBs */ + for (inode = 0; inode < cur_sb_info.num_opin_rr_nodes[side]; inode++) { + dump_verilog_grid_side_pin_with_given_index(fp, IPIN, + cur_sb_info.opin_rr_node[side][inode]->ptc_num, + cur_sb_info.opin_rr_node_grid_side[side][inode], + cur_sb_info.opin_rr_node[side][inode]->xlow, + cur_sb_info.opin_rr_node[side][inode]->ylow, + FALSE); /* Do not specify the direction of port */ + fprintf(fp, ", "); + } + fprintf(fp, "\n"); + } + + /* Configuration ports */ + /* output of each configuration bit */ + /* Reserved sram ports */ + if (0 < (cur_sb_info.num_reserved_conf_bits)) { + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, cur_sb_info.num_reserved_conf_bits - 1, + VERILOG_PORT_CONKT); + fprintf(fp, ",\n"); + } + /* Normal sram ports */ + if (0 < (cur_sb_info.conf_bits_msb - cur_sb_info.conf_bits_lsb)) { + dump_verilog_sram_local_ports(fp, cur_sram_orgz_info, + cur_sb_info.conf_bits_lsb, + cur_sb_info.conf_bits_msb - 1, + VERILOG_PORT_CONKT); + } + + /* Dump ports only visible during formal verification*/ + if (0 < (cur_sb_info.conf_bits_msb - 1 - cur_sb_info.conf_bits_lsb)) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_sb_info.conf_bits_lsb, + cur_sb_info.conf_bits_msb - 1, + VERILOG_PORT_CONKT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + fprintf(fp, ");\n"); + + /* Comment lines */ + fprintf(fp, "//----- END call module Switch blocks [%d][%d] -----\n\n", x, y); + + /* Free */ + + return; +} + +void dump_verilog_defined_switch_boxes(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int ix, iy; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 0; iy < (ny + 1); iy++) { + dump_verilog_defined_one_switch_box(cur_sram_orgz_info, fp, sb_info[ix][iy]); + } + } + + return; +} + +/* Apply a CLB to CLB direct connection to a SPICE netlist + */ +static +void dump_verilog_one_clb2clb_direct(FILE* fp, + int from_grid_x, int from_grid_y, + int to_grid_x, int to_grid_y, + t_clb_to_clb_directs* cur_direct) { + int ipin, cur_from_clb_pin_index, cur_to_clb_pin_index; + int cur_from_clb_pin_side, cur_to_clb_pin_side; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check bandwidth match between from_clb and to_clb pins */ + if (0 != (cur_direct->from_clb_pin_end_index - cur_direct->from_clb_pin_start_index + - cur_direct->to_clb_pin_end_index - cur_direct->to_clb_pin_start_index)) { + vpr_printf(TIO_MESSAGE_ERROR, "(%s, [LINE%d]) Unmatch pin bandwidth in direct connection (name=%s)!\n", + __FILE__, __LINE__, cur_direct->name); + exit(1); + } + + for (ipin = 0; ipin < cur_direct->from_clb_pin_end_index - cur_direct->from_clb_pin_start_index; ipin++) { + /* Update pin index and get the side of the pins on grids */ + cur_from_clb_pin_index = cur_direct->from_clb_pin_start_index + ipin; + cur_to_clb_pin_index = cur_direct->to_clb_pin_start_index + ipin; + cur_from_clb_pin_side = get_grid_pin_side(from_grid_x, from_grid_y, cur_from_clb_pin_index); + cur_to_clb_pin_side = get_grid_pin_side(to_grid_x, to_grid_y, cur_to_clb_pin_index); + /* Call the subckt that has already been defined before */ + fprintf(fp, "%s ", cur_direct->spice_model->name); + fprintf(fp, "%s_%d_ (", cur_direct->spice_model->prefix, cur_direct->spice_model->cnt); + /* Dump global ports */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_direct->spice_model, FALSE, FALSE, FALSE)) { + fprintf(fp, ",\n"); + } + /* Input: Print the source grid pin */ + dump_verilog_toplevel_one_grid_side_pin_with_given_index(fp, OPIN, + cur_from_clb_pin_index, + cur_from_clb_pin_side, + from_grid_x, from_grid_y, + FALSE); + fprintf(fp, ", "); + /* Output: Print the destination grid pin */ + dump_verilog_toplevel_one_grid_side_pin_with_given_index(fp, IPIN, + cur_to_clb_pin_index, + cur_to_clb_pin_side, + to_grid_x, from_grid_y, + FALSE); + fprintf(fp, ");\n"); + + /* Stats the number of spice_model used*/ + cur_direct->spice_model->cnt++; + } + + return; +} + +/* Apply CLB to CLB direct connections to a Verilog netlist + */ +void dump_verilog_clb2clb_directs(FILE* fp, + int num_directs, t_clb_to_clb_directs* direct) { + int ix, iy, idirect; + int to_clb_x, to_clb_y; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "//----- BEGIN CLB to CLB Direct Connections -----\n"); + + /* Scan the grid, visit each grid and apply direct connections */ + for (ix = 0; ix < (nx + 1); ix++) { + for (iy = 0; iy < (ny + 1); iy++) { + /* Bypass EMPTY_TYPE*/ + if ((NULL == grid[ix][iy].type) + || (EMPTY_TYPE == grid[ix][iy].type)) { + continue; + } + /* Check each clb2clb directs, + * see if a match to the type + */ + for (idirect = 0; idirect < num_directs; idirect++) { + /* Bypass unmatch types */ + if (grid[ix][iy].type != direct[idirect].from_clb_type) { + continue; + } + /* Apply x/y_offset */ + to_clb_x = ix + direct[idirect].x_offset; + to_clb_y = iy + direct[idirect].y_offset; + /* see if the destination CLB is in the bound */ + if ((FALSE == is_grid_coordinate_in_range(0, nx, to_clb_x)) + ||(FALSE == is_grid_coordinate_in_range(0, ny, to_clb_y))) { + continue; + } + /* Check if capacity (z_offset) is in the range + if (FALSE == is_grid_coordinate_in_range(0, grid[ix][iy].type->capacity, grid[ix][iy].type->z + direct[idirect].z_offset)) { + continue; + } + */ + /* Check if the to_clb_type matches */ + if (grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) { + continue; + } + /* Bypass x/y_offset = 1 + * since it may be addressed in Connection blocks + if (1 == (x_offset + y_offset)) { + continue; + } + */ + /* Now we can print a direct connection with the spice models */ + dump_verilog_one_clb2clb_direct(fp, + ix, iy, + to_clb_x, to_clb_y, + &direct[idirect]); + } + } + } + + fprintf(fp, "//----- END CLB to CLB Direct Connections -----\n"); + + return; + +} + +/** Dump Standalone SRAMs + */ +static +void dump_verilog_configuration_circuits_standalone_srams(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int num_mem_bits = 0; + + /* Check */ + assert(SPICE_SRAM_STANDALONE == cur_sram_orgz_info->type); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler!",__FILE__, __LINE__); + exit(1); + } + + /* Get the total memory bits */ + num_mem_bits = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Dump each SRAM */ + fprintf(fp, "//------ Standalone SRAMs -----\n"); + fprintf(fp, "%s %s_0_ (\n", + verilog_config_peripheral_prefix, + verilog_config_peripheral_prefix); + fprintf(fp, "%s_in[%d:%d],\n", + sram_verilog_model->prefix, + 0, num_mem_bits - 1); + fprintf(fp, "%s_out[%d:%d],\n", + sram_verilog_model->prefix, + 0, num_mem_bits - 1); + fprintf(fp, "%s_outb[%d:%d]);\n", + sram_verilog_model->prefix, + 0, num_mem_bits - 1); + fprintf(fp, "//------ END Standalone SRAMs -----\n"); + + return; +} + +/** Dump scan-chains + */ +static +void dump_verilog_configuration_circuits_scan_chains(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int num_mem_bits = 0; + + /* Check */ + assert(SPICE_SRAM_SCAN_CHAIN == cur_sram_orgz_info->type); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); + exit(1); + } + + /* Get the total memory bits */ + num_mem_bits = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); + + /* Dump each Scan-chain FF */ + fprintf(fp, "//------ Configuration peripheral for Scan-chain FFs -----\n"); + fprintf(fp, "%s %s_0_ (\n", + verilog_config_peripheral_prefix, + verilog_config_peripheral_prefix); + /* Scan-chain input*/ + dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, ",\n"); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 1, -1, VERILOG_PORT_CONKT); + fprintf(fp, ",\n"); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 1, 0, VERILOG_PORT_CONKT); + fprintf(fp, ");\n"); + fprintf(fp, "//------ END Configuration peripheral Scan-chain FFs -----\n"); + + return; +} + +/* Dump a memory bank to configure all the Bit lines and Word lines */ +static +void dump_verilog_configuration_circuits_memory_bank(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info) { + int num_bl, num_wl; + int num_reserved_bl, num_reserved_wl; + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + t_spice_model* mem_model = NULL; + int num_blb_ports, num_wlb_ports; + t_spice_model_port** blb_port = NULL; + t_spice_model_port** wlb_port = NULL; + + /* Check */ + assert(SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type); + assert(NULL != cur_sram_orgz_info->mem_bank_info); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); + exit(1); + } + + /* Get the total number of BLs and WLs */ + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &num_bl, &num_wl); + /* Get the reserved BLs and WLs */ + get_sram_orgz_info_reserved_blwl(cur_sram_orgz_info, &num_reserved_bl, &num_reserved_wl); + + /* Get memory model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + /* Get BLB and WLB ports */ + find_blb_wlb_ports_spice_model(mem_model, &num_blb_ports, &blb_port, + &num_wlb_ports, &wlb_port); + + /* Comment lines */ + fprintf(fp, "//------ BEGIN Configuration peripheral for Memory-bank -----\n"); + fprintf(fp, "%s %s_0_ (\n", + verilog_config_peripheral_prefix, + verilog_config_peripheral_prefix); + /* Ports for memory decoders */ + dump_verilog_decoder_memory_bank_ports(cur_sram_orgz_info, fp, VERILOG_PORT_CONKT); + fprintf(fp, ","); + /* Ports for all the SRAM cells */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + assert( 0 == num_reserved_bl ); + assert( 0 == num_reserved_wl ); + /* Declare normal BL / WL inputs */ + fprintf(fp, " %s%s[%d:%d],", + mem_model->prefix, top_netlist_normal_bl_port_postfix, + 0, num_bl - 1); + fprintf(fp, " %s%s[%d:%d]", + mem_model->prefix, top_netlist_normal_wl_port_postfix, + 0, num_wl - 1); + /* Declare inverted wires if needed */ + if (1 == num_blb_ports) { + fprintf(fp, ", "); + fprintf(fp, "%s%s[%d:%d]", + mem_model->prefix, top_netlist_normal_blb_port_postfix, + 0, num_bl - 1); + } + if (1 == num_wlb_ports) { + fprintf(fp, ", "); + fprintf(fp, "%s%s[%d:%d]", + mem_model->prefix, top_netlist_normal_wlb_port_postfix, + 0, num_wl - 1); + } + + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Check: there should be reserved BLs and WLs */ + assert( 0 < num_reserved_bl ); + assert( 0 < num_reserved_wl ); + /* Declare reserved and normal conf_bits ports */ + fprintf(fp, " %s%s[0:%d],", + mem_model->prefix, top_netlist_reserved_bl_port_postfix, + num_reserved_bl - 1); + fprintf(fp, " %s%s[0:%d],", + mem_model->prefix, top_netlist_reserved_wl_port_postfix, + num_reserved_wl - 1); + fprintf(fp, " %s%s[%d:%d],", + mem_model->prefix, top_netlist_normal_bl_port_postfix, + num_reserved_bl, num_array_bl - 1); + fprintf(fp, " %s%s[%d:%d]", + mem_model->prefix, top_netlist_normal_wl_port_postfix, + num_reserved_wl, num_array_wl - 1); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, ");\n"); + fprintf(fp, "//------ END Configuration peripheral for Memory-bank -----\n"); + + return; +} + +/* Dump the configuration circuits in verilog according to user-specification + * Supported styles of configuration circuits: + * 1. Scan-chains + * 2. Memory banks + * 3. Standalone SRAMs + */ +void dump_verilog_configuration_circuits(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + dump_verilog_configuration_circuits_standalone_srams(cur_sram_orgz_info, fp); + break; + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_configuration_circuits_scan_chains(cur_sram_orgz_info, fp); + break; + case SPICE_SRAM_MEMORY_BANK: + dump_verilog_configuration_circuits_memory_bank(fp, cur_sram_orgz_info); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + return; +} + +/* Create a fake (x, y) coorindate for a I/O block on the border side */ +void verilog_compact_generate_fake_xy_for_io_border_side(int border_side, + int* ix, int* iy) { + switch (border_side) { + case 0: /* TOP*/ + (*ix) = 1; + (*iy) = ny + 1; + break; + case 1: /*RIGHT */ + (*ix) = nx + 1; + (*iy) = 1; + break; + case 2: /*BOTTOM */ + (*ix) = 1; + (*iy) = 0; + break; + case 3: /* LEFT */ + (*ix) = 0; + (*iy) = 1; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d]) Invalid border_side(%d) for I/O grid!\n", + __FILE__, __LINE__, border_side); + exit(1); + } + + return; +} + +/* We print all the pins of a type descriptor in the following sequence + * TOP, RIGHT, BOTTOM, LEFT + */ +void dump_compact_verilog_grid_pins(FILE* fp, + t_type_ptr grid_type_descriptor, + boolean dump_port_type, + boolean dump_last_comma) { + int iheight, side, ipin, class_id; + int side_pin_index; + int num_dumped_port = 0; + int first_dump = 1; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert(NULL != grid_type_descriptor); + assert(0 < grid_type_descriptor->capacity); + + for (side = 0; side < 4; side++) { + /* Count the number of pins */ + side_pin_index = 0; + //for (iz = 0; iz < grid_type_descriptor->capacity; iz++) { + for (iheight = 0; iheight < grid_type_descriptor->height; iheight++) { + for (ipin = 0; ipin < grid_type_descriptor->num_pins; ipin++) { + if (1 == grid_type_descriptor->pinloc[iheight][side][ipin]) { + /* Add comma if needed */ + if (1 == first_dump) { + first_dump = 0; + } else { + if (TRUE == dump_port_type) { + fprintf(fp, ",\n"); + } else { + fprintf(fp, ",\n"); + } + } + if (TRUE == dump_port_type) { + /* Determine this pin is an input or output */ + class_id = grid_type_descriptor->pin_class[ipin]; + switch (grid_type_descriptor->class_inf[class_id].type) { + case RECEIVER: + fprintf(fp, "input "); + break; + case DRIVER: + fprintf(fp, "output "); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid pin_class_type!\n", + __FILE__, __LINE__); + exit(1); + } + } + /* This pin appear at this side! */ + fprintf(fp, " %s_height_%d__pin_%d_", + convert_side_index_to_string(side), iheight, ipin); + /* Update counter */ + num_dumped_port++; + side_pin_index++; + } + } + } + //} + } + + if ((0 < num_dumped_port)&&(TRUE == dump_last_comma)) { + if (TRUE == dump_port_type) { + fprintf(fp, ",\n"); + } else { + fprintf(fp, ",\n"); + } + } + + return; +} + +/* Special for I/O grid, we need only part of the ports + * i.e., grid[0][0..ny] only need the right side ports. + */ +/* We print all the pins of a type descriptor in the following sequence + * TOP, RIGHT, BOTTOM, LEFT + */ +void dump_compact_verilog_io_grid_pins(FILE* fp, + t_type_ptr grid_type_descriptor, + int border_side, + boolean dump_port_type, + boolean dump_last_comma) { + int iheight, ipin; + int side_pin_index; + int class_id = -1; + int num_dumped_port = 0; + int first_dump = 1; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Check */ + assert( (-1 < border_side) && (border_side < 4)); + /* Make sure this is IO */ + assert(NULL != grid_type_descriptor); + assert(IO_TYPE == grid_type_descriptor); + + /* Count the number of pins */ + side_pin_index = 0; + //for (iz = 0; iz < capacity; iz++) { + for (iheight = 0; iheight < grid_type_descriptor->height; iheight++) { + for (ipin = 0; ipin < grid_type_descriptor->num_pins; ipin++) { + if (1 == grid_type_descriptor->pinloc[iheight][border_side][ipin]) { + /* Add comma if needed */ + if (1 == first_dump) { + first_dump = 0; + } else { + if (TRUE == dump_port_type) { + fprintf(fp, ",\n"); + } else { + fprintf(fp, ",\n"); + } + } + /* Determine this pin is an input or output */ + if (TRUE == dump_port_type) { + class_id = grid_type_descriptor->pin_class[ipin]; + switch (grid_type_descriptor->class_inf[class_id].type) { + case RECEIVER: + fprintf(fp, "input "); + break; + case DRIVER: + fprintf(fp, "output "); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid pin_class_type!\n", + __FILE__, __LINE__); + exit(1); + } + } + /* This pin appear at this side! */ + fprintf(fp, " %s_height_%d__pin_%d_", + convert_side_index_to_string(border_side), iheight, ipin); + /* Update counter */ + num_dumped_port++; + side_pin_index++; + } + } + } + //} + + if ((0 < num_dumped_port)&&(TRUE == dump_last_comma)) { + if (TRUE == dump_port_type) { + fprintf(fp, ",\n"); + } else { + fprintf(fp, ",\n"); + } + } + + return; +} + +/* Physical mode subckt name */ +char* compact_verilog_get_grid_phy_block_subckt_name(t_type_ptr grid_type_descriptor, + int z, + char* subckt_prefix) { + char* ret = NULL; + char* formatted_subckt_prefix = format_verilog_node_prefix(subckt_prefix); + int phy_mode_index = 0; + + /* Check */ + assert(NULL != grid_type_descriptor); + + /* This a NULL logic block... Find the idle mode*/ + phy_mode_index = find_pb_type_physical_mode_index(*(grid_type_descriptor->pb_type)); + assert(-1 < phy_mode_index); + + ret = (char*)my_malloc(sizeof(char)* + (strlen(formatted_subckt_prefix) + strlen(grid_type_descriptor->name) + + 6 + strlen(grid_type_descriptor->pb_type->modes[phy_mode_index].name) + 1 + 1)); + sprintf(ret, "%s%s_mode_%s_", formatted_subckt_prefix, + grid_type_descriptor->name, grid_type_descriptor->pb_type->modes[phy_mode_index].name); + + return ret; +} + +/* Print the pins of grid subblocks */ +void dump_compact_verilog_io_grid_block_subckt_pins(FILE* fp, + t_type_ptr grid_type_descriptor, + int border_side, + int z) { + int iport, ipin, dump_pin_cnt; + int grid_pin_index, pin_height, side_pin_index; + t_pb_graph_node* top_pb_graph_node = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + /* Check */ + assert(NULL != grid_type_descriptor); + top_pb_graph_node = grid_type_descriptor->pb_graph_head; + assert(NULL != top_pb_graph_node); + + /* Make sure this is IO */ + assert(IO_TYPE == grid_type_descriptor); + + /* identify the location of IO grid and + * decide which side of ports we need + */ + + dump_pin_cnt = 0; + + for (iport = 0; iport < top_pb_graph_node->num_input_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_input_pins[iport]; ipin++) { + grid_pin_index = top_pb_graph_node->input_pins[iport][ipin].pin_count_in_cluster + + z * grid_type_descriptor->num_pins / grid_type_descriptor->capacity; + /* num_pins/capacity = the number of pins that each type_descriptor has. + * Capacity defines the number of type_descriptors in each grid + * so the pin index at grid level = pin_index_in_type_descriptor + * + type_descriptor_index_in_capacity * num_pins_per_type_descriptor + */ + pin_height = grid_type_descriptor->pin_height[grid_pin_index]; + if (1 == grid_type_descriptor->pinloc[pin_height][border_side][grid_pin_index]) { + /* This pin appear at this side! */ + if (0 < dump_pin_cnt) { + fprintf(fp, ",\n"); + } + fprintf(fp, "%s_height_%d__pin_%d_", + convert_side_index_to_string(border_side), pin_height, grid_pin_index); + side_pin_index++; + dump_pin_cnt++; + } + } + } + + for (iport = 0; iport < top_pb_graph_node->num_output_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_output_pins[iport]; ipin++) { + grid_pin_index = top_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster + + z * grid_type_descriptor->num_pins / grid_type_descriptor->capacity; + /* num_pins/capacity = the number of pins that each type_descriptor has. + * Capacity defines the number of type_descriptors in each grid + * so the pin index at grid level = pin_index_in_type_descriptor + * + type_descriptor_index_in_capacity * num_pins_per_type_descriptor + */ + pin_height = grid_type_descriptor->pin_height[grid_pin_index]; + if (1 == grid_type_descriptor->pinloc[pin_height][border_side][grid_pin_index]) { + /* This pin appear at this side! */ + if (0 < dump_pin_cnt) { + fprintf(fp, ",\n"); + } + fprintf(fp, "%s_height_%d__pin_%d_", + convert_side_index_to_string(border_side), pin_height, grid_pin_index); + side_pin_index++; + dump_pin_cnt++; + } + } + } + + for (iport = 0; iport < top_pb_graph_node->num_clock_ports; iport++) { + for (ipin = 0; ipin < top_pb_graph_node->num_clock_pins[iport]; ipin++) { + grid_pin_index = top_pb_graph_node->clock_pins[iport][ipin].pin_count_in_cluster + + z * grid_type_descriptor->num_pins / grid_type_descriptor->capacity; + /* num_pins/capacity = the number of pins that each type_descriptor has. + * Capacity defines the number of type_descriptors in each grid + * so the pin index at grid level = pin_index_in_type_descriptor + * + type_descriptor_index_in_capacity * num_pins_per_type_descriptor + */ + pin_height = grid_type_descriptor->pin_height[grid_pin_index]; + if (1 == grid_type_descriptor->pinloc[pin_height][border_side][grid_pin_index]) { + /* This pin appear at this side! */ + if (0 < dump_pin_cnt) { + fprintf(fp, ",\n"); + } + fprintf(fp, "%s_height_%d__pin_%d_", + convert_side_index_to_string(border_side), pin_height, grid_pin_index); + side_pin_index++; + dump_pin_cnt++; + } + } + } + + return; +} + + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.h new file mode 100644 index 000000000..c25c42756 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_netlist_utils.h @@ -0,0 +1,54 @@ + +void dump_verilog_top_netlist_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int num_clocks, + char* circuit_name, + t_spice verilog); + +void dump_verilog_top_netlist_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp); + +void dump_verilog_defined_channels(FILE* fp, + int LL_num_rr_nodes, t_rr_node* LL_rr_node, + t_ivec*** LL_rr_node_indices); + +void dump_verilog_defined_connection_boxes(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp); + +void dump_verilog_defined_switch_boxes(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp); + +void dump_verilog_clb2clb_directs(FILE* fp, + int num_directs, t_clb_to_clb_directs* direct); + +void dump_verilog_configuration_circuits(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp); + +void dump_verilog_top_module_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + enum e_dump_verilog_port_type dump_port_type); + +void verilog_compact_generate_fake_xy_for_io_border_side(int border_side, + int* ix, int* iy) ; + +void dump_compact_verilog_grid_pins(FILE* fp, + t_type_ptr grid_type_descriptor, + boolean dump_port_type, + boolean dump_last_comma) ; + +void dump_compact_verilog_io_grid_pins(FILE* fp, + t_type_ptr grid_type_descriptor, + int border_side, + boolean dump_port_type, + boolean dump_last_comma) ; + +char* compact_verilog_get_grid_phy_block_subckt_name(t_type_ptr grid_type_descriptor, + int z, + char* subckt_prefix); + +void dump_compact_verilog_io_grid_block_subckt_pins(FILE* fp, + t_type_ptr grid_type_descriptor, + int border_side, + int z) ; + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.c new file mode 100644 index 000000000..f7a6f1300 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.c @@ -0,0 +1,1421 @@ +/***********************************/ +/* Dump Synthesizable Veriolog */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "route_common.h" +#include "vpr_utils.h" + +/* Include spice support headers*/ +#include "read_xml_spice_util.h" +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "fpga_x2p_globals.h" +#include "fpga_bitstream.h" + +/* Include verilog support headers*/ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_routing.h" +#include "verilog_pbtypes.h" +#include "verilog_decoder.h" +#include "verilog_top_netlist_utils.h" + +/* Dump all the global ports that are stored in the linked list */ +void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head, + enum e_dump_verilog_port_type dump_port_type) { + t_llist* temp = head; + t_spice_model_port* cur_global_port = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + } + + fprintf(fp, "//----- BEGIN Global ports -----\n"); + while(NULL != temp) { + cur_global_port = (t_spice_model_port*)(temp->dptr); + dump_verilog_generic_port(fp, dump_port_type, + cur_global_port->prefix, 0, cur_global_port->size - 1); + fprintf(fp, ";\n"); + /* Go to the next */ + temp = temp->next; + } + fprintf(fp, "//----- END Global ports -----\n"); + + return; +} + +/* Connect a global port to a voltage stimuli */ +static +void dump_verilog_top_testbench_wire_one_global_port_stimuli(FILE* fp, t_spice_model_port* cur_global_port, + char* voltage_stimuli_port_name) { + int ipin; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + assert(NULL != cur_global_port); + + for (ipin = 0; ipin < cur_global_port->size; ipin++) { + fprintf(fp, "assign %s[%d] = ", + cur_global_port->prefix, ipin); + assert((0 == cur_global_port->default_val)||(1 == cur_global_port->default_val)); + if (1 == cur_global_port->default_val) { + fprintf(fp, "~"); + } + fprintf(fp, "%s;\n", + voltage_stimuli_port_name); + } + + return; +} + +/* Print stimuli for global ports in top-level testbench */ +void dump_verilog_top_testbench_global_ports_stimuli(FILE* fp, t_llist* head) { + t_llist* temp = head; + t_spice_model_port* cur_global_port = NULL; + int ipin; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "//----- Connecting Global ports -----\n"); + while(NULL != temp) { + cur_global_port = (t_spice_model_port*)(temp->dptr); + /* Make sure this is a global port */ + assert(TRUE == cur_global_port->is_global); + /* If this is a clock signal, connect to op_clock signal */ + if (SPICE_MODEL_PORT_CLOCK == cur_global_port->type) { + /* Special for programming clock */ + if (TRUE == cur_global_port->is_prog) { + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_clock_port_name); + } else { + assert(FALSE == cur_global_port->is_prog); + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_op_clock_port_name); + } + /* If this is a config_enable signal, connect to config_done signal */ + } else if (TRUE == cur_global_port->is_config_enable) { + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_clock_port_name); + /* If this is a set/reset signal, connect to global reset and set signals */ + } else if (TRUE == cur_global_port->is_reset) { + /* Special for programming reset */ + if (TRUE == cur_global_port->is_prog) { + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_reset_port_name); + } else { + assert(FALSE == cur_global_port->is_prog); + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_reset_port_name); + } + /* If this is a set/reset signal, connect to global reset and set signals */ + } else if (TRUE == cur_global_port->is_set) { + /* Special for programming reset */ + if (TRUE == cur_global_port->is_prog) { + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_prog_set_port_name); + } else { + assert(FALSE == cur_global_port->is_prog); + dump_verilog_top_testbench_wire_one_global_port_stimuli(fp, cur_global_port, top_tb_set_port_name); + } + } else { + /* Other global signals stuck at the default values */ + for (ipin = 0; ipin < cur_global_port->size; ipin++) { + fprintf(fp, "assign %s[%d] = 1'b%d;\n", + cur_global_port->prefix, ipin, cur_global_port->default_val); + } + } + /* Go to the next */ + temp = temp->next; + } + fprintf(fp, "//----- End Connecting Global ports -----\n"); + + return; +} + + +static +void dump_verilog_top_testbench_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* circuit_name) { + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + int iblock, iopad_idx; + t_spice_model* mem_model = NULL; + char* port_name = NULL; + + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + fprintf(fp, "module %s_top_tb;\n", circuit_name); + /* Local wires */ + /* 1. reset, set, clock signals */ + /* 2. iopad signals */ + + /* Connect to defined signals */ + /* set and reset signals */ + fprintf(fp, "\n"); + dump_verilog_top_testbench_global_ports(fp, global_ports_head, VERILOG_PORT_WIRE); + fprintf(fp, "\n"); + + /* TODO: dump each global signal as reg here */ + + /* Inputs and outputs of I/O pads */ + /* Inout Pads */ + assert(NULL != iopad_verilog_model); + if ((NULL == iopad_verilog_model) + ||(iopad_verilog_model->cnt > 0)) { + /* Malloc and assign port_name */ + port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); + sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); + /* Dump a wired port */ + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + port_name, iopad_verilog_model->cnt - 1, 0); + fprintf(fp, "; //--- FPGA inouts \n"); + /* Free port_name */ + my_free(port_name); + /* Malloc and assign port_name */ + port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + strlen(top_tb_inout_reg_postfix) + 1)); + sprintf(port_name, "%s%s%s", gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix); + /* Dump a wired port */ + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + port_name, iopad_verilog_model->cnt - 1, 0); + fprintf(fp, "; //--- reg for FPGA inouts \n"); + /* Free port_name */ + my_free(port_name); + } + + /* Add a signal to identify the configuration phase is finished */ + fprintf(fp, "reg [0:0] %s;\n", top_tb_config_done_port_name); + /* Programming clock */ + fprintf(fp, "wire [0:0] %s;\n", top_tb_prog_clock_port_name); + fprintf(fp, "reg [0:0] %s%s;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); + /* Operation clock */ + fprintf(fp, "wire [0:0] %s;\n", top_tb_op_clock_port_name); + fprintf(fp, "reg [0:0] %s%s;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); + /* Programming set and reset */ + fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_reset_port_name); + fprintf(fp, "reg [0:0] %s;\n", top_tb_prog_set_port_name); + /* Global set and reset */ + fprintf(fp, "reg [0:0] %s;\n", top_tb_reset_port_name); + fprintf(fp, "reg [0:0] %s;\n", top_tb_set_port_name); + /* Generate stimuli for global ports or connect them to existed signals */ + dump_verilog_top_testbench_global_ports_stimuli(fp, global_ports_head); + + /* Configuration ports depend on the organization of SRAMs */ + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); + fprintf(fp, "; //---- SRAM outputs \n"); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* We put the head of scan-chains here + */ + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, "; //---- Scan-chain head \n"); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Get the number of array BLs/WLs, decoder sizes */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + fprintf(fp, " wire [0:0] %s;\n", + top_netlist_bl_enable_port_name + ); + fprintf(fp, " wire [0:0] %s;\n", + top_netlist_wl_enable_port_name + ); + /* Wire en_bl, en_wl to prog_clock */ + fprintf(fp, "assign %s[0:0] = %s[0:0];\n", + top_netlist_bl_enable_port_name, + top_tb_prog_clock_port_name); + fprintf(fp, "assign %s [0:0]= %s[0:0];\n", + top_netlist_wl_enable_port_name, + top_tb_prog_clock_port_name); + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); + fprintf(fp, "; //--- Address of bit lines \n"); + dump_verilog_generic_port(fp, VERILOG_PORT_REG, + top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); + fprintf(fp, "; //--- Address of word lines \n"); + /* data_in is only require by BL decoder of SRAM array + * As for RRAM array, the data_in signal will not be used + */ + if (SPICE_MODEL_DESIGN_CMOS == mem_model->design_tech) { + fprintf(fp, " reg [0:0] %s; // --- Data_in signal for BL decoder, only required by SRAM array \n", + top_netlist_bl_data_in_port_name); + } + /* I add all the Bit lines and Word lines here just for testbench usage + fprintf(fp, " input wire [%d:0] %s_out; //--- Bit lines \n", + sram_verilog_model->cnt - 1, sram_verilog_model->prefix); + fprintf(fp, " input wire [%d:0] %s_outb; //--- Word lines \n", + sram_verilog_model->cnt - 1, sram_verilog_model->prefix); + */ + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + /* Add signals from blif benchmark and short-wire them to FPGA I/O PADs + * This brings convenience to checking functionality + */ + fprintf(fp, "//-----Link Blif Benchmark inputs to FPGA IOPADs -----\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); + fprintf(fp, "//----- Blif Benchmark inout %s is mapped to FPGA IOPAD %s[%d] -----\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx); + fprintf(fp, "//----- name_tag: %s -----\n", + logical_block[iblock].pb->spice_name_tag); + fprintf(fp, "wire %s_%s_%d_;\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx); + fprintf(fp, "assign %s_%s_%d_ = %s%s[%d];\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx, + gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); + } + } + + return; +} + +void dump_verilog_top_testbench_call_top_module(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* circuit_name) { + /* + int iblock, iopad_idx; + */ + + /* Include defined top-level module */ + fprintf(fp, "//----- Device Under Test (DUT) ----\n"); + fprintf(fp, "//------Call defined Top-level Verilog Module -----\n"); + fprintf(fp, "%s_top U0 (\n", circuit_name); + + dump_verilog_top_module_ports(cur_sram_orgz_info, fp, VERILOG_PORT_CONKT); + + fprintf(fp, ");\n"); + return; +} + +/* Find the number of configuration clock cycles for a top-level testbench + * A valid configuration clock cycle is allocated for an element with + * (1) SRAM_val=1; + * (2) BL = 1 && WL = 1; + * (3) BL = 1 && WL = 0 with a paired conf_bit; + */ +static +int dump_verilog_top_testbench_find_num_config_clock_cycles(t_sram_orgz_info* cur_sram_orgz_info, + t_llist* head) { + int cnt = 0; + t_llist* temp = head; + t_conf_bit_info* temp_conf_bit_info = NULL; + + while (NULL != temp) { + /* Fetch the conf_bit_info */ + temp_conf_bit_info = (t_conf_bit_info*)(temp->dptr); + /* Check if conf_bit_info needs a clock cycle*/ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + cnt++; + temp_conf_bit_info->index_in_top_tb = cnt; + break; + case SPICE_SRAM_MEMORY_BANK: + cnt++; + temp_conf_bit_info->index_in_top_tb = cnt; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + /* Go to the next */ + temp = temp->next; + } + + return cnt; +} + + +/* Dump configuration bits of a SRAM memory bank + * The efficient sharing BLs/WLs force configuration to be done WL by WL + * (We always assume that Word Lines are the write/read enable signal for SRAMs) + * All the SRAMs controlled by the same WL will be configuration during one programming cycle + * by assign different BL values for each of them. + */ +static +void dump_verilog_top_testbench_sram_memory_bank_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_llist* cur_conf_bit) { + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + int** array_bit = NULL; + t_conf_bit_info*** array_conf_bit_info = NULL; + + int ibl, iwl, cur_wl, cur_bl; + char* wl_addr = NULL; + char* bl_addr = NULL; + + t_llist* temp = cur_conf_bit; + t_conf_bit_info* cur_conf_bit_info = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); + exit(1); + } + + /* Dump one configuring operation on BL and WL addresses */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + /* We will allocate the configuration bits to be written for each programming cycle */ + array_bit = (int**)my_malloc(sizeof(int*)*num_array_wl); + array_conf_bit_info = (t_conf_bit_info***)my_malloc(sizeof(t_conf_bit_info**)*num_array_wl); + /* Initialization */ + for (iwl = 0; iwl < num_array_wl; iwl++) { + array_bit[iwl] = (int*)my_malloc(sizeof(int)*num_array_bl); + array_conf_bit_info[iwl] = (t_conf_bit_info**)my_malloc(sizeof(t_conf_bit_info*)*num_array_bl); + for (ibl = 0; ibl < num_array_bl; ibl++) { + array_bit[iwl][ibl] = 0; + array_conf_bit_info[iwl][ibl] = NULL; + } + } + + /* Classify each configuration bit info to its assciated bl/wl codes + * The bl_addr and wl_addr recorded in the list is the absoluate address, + */ + while (NULL != temp) { + cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); + /* Memory bank requires the address to be given to the decoder*/ + assert( cur_conf_bit_info->bl->addr == cur_conf_bit_info->wl->addr ); + cur_wl = cur_conf_bit_info->bl->addr / num_array_bl; + cur_bl = cur_conf_bit_info->bl->addr % num_array_bl; + /* Update the SRAM bit array */ + array_bit[cur_wl][cur_bl] = cur_conf_bit_info->bl->val; + array_conf_bit_info[cur_wl][cur_bl] = cur_conf_bit_info; + /* Check if SRAM bit is valid */ + assert( (0 == array_bit[cur_wl][cur_bl]) || (1 == array_bit[cur_wl][cur_bl]) ); + /* Go to next */ + temp = temp->next; + } + + /* Dump decoder input for each programming cycle */ + for (iwl = 0; iwl < num_array_wl; iwl++) { + for (ibl = 0; ibl < num_array_bl; ibl++) { + /* Bypass configuration bit not available */ + if ( NULL == array_conf_bit_info[iwl][ibl]) { + continue; + } + /* Check */ + assert(( 1 == array_bit[iwl][ibl] )||( 0 == array_bit[iwl][ibl] )); + assert( NULL != array_conf_bit_info[iwl][ibl]); + /* If this WL is selected , we decode its index to address */ + bl_addr = (char*)my_calloc(bl_decoder_size + 1, sizeof(char)); + /* If this WL is selected , we decode its index to address */ + encode_decoder_addr(ibl, bl_decoder_size, bl_addr); + /* Word line address */ + wl_addr = (char*)my_calloc(wl_decoder_size + 1, sizeof(char)); + encode_decoder_addr(iwl, wl_decoder_size, wl_addr); + /* Get corresponding conf_bit */ + cur_conf_bit_info = array_conf_bit_info[iwl][ibl]; + /* One operation per clock cycle */ + /* Information about this configuration bit */ + fprintf(fp, " //--- Configuration bit No.: %d \n", cur_conf_bit_info->index); + fprintf(fp, " //--- Bit Line Address: %d, \n", cur_conf_bit_info->bl->addr); + fprintf(fp, " //--- Word Line Address: %d \n ", cur_conf_bit_info->wl->addr); + fprintf(fp, " //--- Bit Line index: %d, \n", ibl); + fprintf(fp, " //--- Word Line index: %d \n ", iwl); + fprintf(fp, " //--- Bit Line Value: %d, \n", cur_conf_bit_info->bl->val); + fprintf(fp, " //--- Word Line Value: %d \n ", cur_conf_bit_info->wl->val); + fprintf(fp, " //--- SPICE model name: %s \n", cur_conf_bit_info->parent_spice_model->name); + fprintf(fp, " //--- SPICE model index: %d \n", cur_conf_bit_info->parent_spice_model_index); + fprintf(fp, " prog_cycle_blwl(%d'b%s, %d'b%s, 1'b%d); //--- (BL_addr_code, WL_addr_code, bl_data_in) \n", + bl_decoder_size, bl_addr, wl_decoder_size, wl_addr, array_bit[iwl][ibl]); + fprintf(fp, "\n"); + } + } + + /* Free */ + for (iwl = 0; iwl < num_array_wl; iwl++) { + my_free(array_bit[iwl]); + my_free(array_conf_bit_info[iwl]); + } + my_free(array_bit); + my_free(array_conf_bit_info); + + return; +} + +static +void dump_verilog_top_testbench_rram_memory_bank_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_llist* cur_conf_bit) { + int num_bl, num_wl; + int bl_decoder_size, wl_decoder_size; + char* wl_addr = NULL; + char* bl_addr = NULL; + + t_llist* temp = cur_conf_bit; + t_conf_bit_info* cur_conf_bit_info = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); + exit(1); + } + + + /* Dump one configuring operation on BL and WL addresses */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_bl, &num_wl, &bl_decoder_size, &wl_decoder_size); + + while (NULL != temp) { + cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); + /* For memory bank, we do not care the sequence. + * To be easy to understand, we go from the first to the last + * IMPORTANT: sequence seems to be critical. + * Reversing the sequence leading to functional incorrect. + */ + /* Memory bank requires the address to be given to the decoder*/ + /* Decode address to BLs and WLs*/ + /* Encode addresses */ + /* Bit line address */ + /* If this WL is selected , we decode its index to address */ + bl_addr = (char*)my_calloc(bl_decoder_size + 1, sizeof(char)); + /* If this WL is selected , we decode its index to address */ + assert(NULL != cur_conf_bit_info->bl); + encode_decoder_addr(cur_conf_bit_info->bl->addr, bl_decoder_size, bl_addr); + /* Word line address */ + wl_addr = (char*)my_calloc(wl_decoder_size + 1, sizeof(char)); + encode_decoder_addr(cur_conf_bit_info->wl->addr, wl_decoder_size, wl_addr); + assert(NULL != cur_conf_bit_info->wl); + /* One operation per clock cycle */ + /* Information about this configuration bit */ + fprintf(fp, " //--- Configuration bit No.: %d \n", cur_conf_bit_info->index); + fprintf(fp, " //--- Bit Line: %d, \n", cur_conf_bit_info->bl->val); + fprintf(fp, " //--- Word Line: %d \n ", cur_conf_bit_info->wl->val); + fprintf(fp, " //--- SPICE model name: %s \n", cur_conf_bit_info->parent_spice_model->name); + fprintf(fp, " //--- SPICE model index: %d \n", cur_conf_bit_info->parent_spice_model_index); + fprintf(fp, " prog_cycle_blwl(%d'b%s, %d'b%s); //--- (BL_addr_code, WL_addr_code) \n", + bl_decoder_size, bl_addr, wl_decoder_size, wl_addr); + fprintf(fp, "\n"); + /* Free */ + my_free(wl_addr); + my_free(bl_addr); + /* Go to next */ + temp = temp->next; + } + + return; +} + +static +void dump_verilog_top_testbench_memory_bank_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_llist* cur_conf_bit) { + t_spice_model* mem_model = NULL; + + /* Depending on the memory technology*/ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + /* Check */ + assert(SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type); + + /* fork on the memory technology */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + dump_verilog_top_testbench_sram_memory_bank_conf_bits_serial(cur_sram_orgz_info, fp, cur_conf_bit); + break; + case SPICE_MODEL_DESIGN_RRAM: + dump_verilog_top_testbench_rram_memory_bank_conf_bits_serial(cur_sram_orgz_info, fp, cur_conf_bit); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for memory in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* For scan chain, the last bit should go first!*/ +/* The sequence of linked list is already reversed, we just need to output each bit */ +static +void dump_verilog_top_testbench_scan_chain_conf_bits_serial(FILE* fp, + t_llist* cur_conf_bit) { + t_llist* temp = cur_conf_bit; + t_conf_bit_info* cur_conf_bit_info = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!",__FILE__, __LINE__); + exit(1); + } + + /* Configuration phase: configure each SRAM or BL/WL */ + fprintf(fp, "//----- Configuration phase -----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- Scan_chain default input\n"); + /* Initial value should be the first configuration bits + * In the rest of programming cycles, + * configuration bits are fed at the falling edge of programming clock. + */ + /* We do not care the value of scan_chain head during the first programming cycle + * It is reset anyway + */ + fprintf(fp, " "); + dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, " = 1'b%d;\n", + 0 ); + fprintf(fp, "\n"); + /* Check we have a valid first bit */ + while (NULL != temp) { + cur_conf_bit_info = (t_conf_bit_info*)(temp->dptr); + /* Scan-chain only loads the SRAM values */ + fprintf(fp, "//---- Configuration bit No.: %d \n ", cur_conf_bit_info->index); + fprintf(fp, "//---- SRAM value: %d \n", cur_conf_bit_info->sram_bit->val); + fprintf(fp, "//---- SPICE model name: %s \n ", cur_conf_bit_info->parent_spice_model->name); + fprintf(fp, "//---- SPICE model index: %d \n", cur_conf_bit_info->parent_spice_model_index); + fprintf(fp, "\n"); + /* First bit is special */ + fprintf(fp, " prog_cycle_scan_chain(1'b%d); //--- (Scan_chain bits) \n", + cur_conf_bit_info->sram_bit->val); + fprintf(fp, "\n"); + /* Go to next */ + temp = temp->next; + } + fprintf(fp, " end\n"); + fprintf(fp, "//----- END of Configuration phase -----\n"); + + return; +} + +/* dump configuration bits which are stored in the linked list + * USE while LOOP !!! Recursive method causes memory corruptions! + * We start dump configuration bit from the tail of the linked list + * until the head of the linked list + */ +static +void dump_verilog_top_testbench_one_conf_bit_serial(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_llist* cur_conf_bit) { + + /* We already touch the tail, start dump */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_top_testbench_scan_chain_conf_bits_serial(fp, cur_conf_bit); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Should work differently depending on memory technology */ + dump_verilog_top_testbench_memory_bank_conf_bits_serial(cur_sram_orgz_info, fp, cur_conf_bit); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +static +void dump_verilog_top_testbench_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_llist* head) { + int num_bl, num_wl; + int bl_decoder_size, wl_decoder_size; + t_llist* new_head = head; + + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + /* For scan chain, the last bit should go first!*/ + /* We do not need to reverse the linked list HERE !!! + * Because, it is already arranged in the seqence of MSB to LSB + * Note that the first element in the linked list is the last bit now! + */ + /* For each element in linked list, generate a voltage stimuli */ + dump_verilog_top_testbench_one_conf_bit_serial(cur_sram_orgz_info, + fp, head); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Configuration bits are loaded differently depending on memory technology */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_bl, &num_wl, &bl_decoder_size, &wl_decoder_size); + /* Configuration phase: configure each SRAM or BL/WL */ + fprintf(fp, "//----- Configuration phase -----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- BL_WL_ADDR\n"); + fprintf(fp, " addr_bl = {%d {1'b0}};\n", bl_decoder_size); + fprintf(fp, " addr_wl = {%d {1'b0}};\n", wl_decoder_size); + /* For each element in linked list, generate a voltage stimuli */ + /* Reverse the linked list first !!! */ + new_head = reverse_llist(new_head); + dump_verilog_top_testbench_one_conf_bit_serial(cur_sram_orgz_info, fp, new_head); + /* Recover the sequence of linked list (reverse again) !!! */ + new_head = reverse_llist(new_head); + /* Check */ + assert(head == new_head); + fprintf(fp, " end\n"); + fprintf(fp, "//----- END of Configuration phase -----\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Print tasks, which is very useful in generating stimuli for each clock cycle + * For memory-bank manipulations only + */ +static +void dump_verilog_top_testbench_stimuli_serial_version_tasks_memory_bank(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + t_spice_model* mem_model = NULL; + + /* Check */ + assert (cur_sram_orgz_info->type == SPICE_SRAM_MEMORY_BANK); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Find the number of array BLs/WLs and decoder sizes */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + /* Depending on the memory technology*/ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + assert(NULL != mem_model); + + /* Depend on the memory technology */ + switch (mem_model->design_tech) { + case SPICE_MODEL_DESIGN_CMOS: + /* Declare two tasks: + * 1. assign BL/WL IO pads values during a programming clock cycle + * 2. assign BL/WL IO pads values during a operating clock cycle + */ + fprintf(fp, "\n"); + fprintf(fp, "//----- Task 1: input values during a programming clock cycle -----\n"); + fprintf(fp, "task prog_cycle_blwl;\n"); + fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); + fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); + fprintf(fp, " input [0:0] bl_data_in_val;\n"); + fprintf(fp, " begin\n"); + fprintf(fp, " @(posedge %s);\n", top_tb_prog_clock_port_name); + /* + fprintf(fp, " $display($time, \"Programming cycle: load BL address with \%h, load WL address with \%h\",\n"); + fprintf(fp, " bl_addr_val, wl_addr_val);\n"); + */ + fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); + fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); + fprintf(fp, " %s = bl_data_in_val;\n", top_netlist_bl_data_in_port_name); + fprintf(fp, " end\n"); + fprintf(fp, "endtask //---prog_cycle_stimuli\n"); + fprintf(fp, "\n"); + fprintf(fp, "//----- Task 2: input values during a operating clock cycle -----\n"); + fprintf(fp, "task op_cycle_blwl;\n"); + fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); + fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); + fprintf(fp, " input [0:0] bl_data_in_val;\n"); + fprintf(fp, " begin\n"); + fprintf(fp, " @(posedge %s);\n", top_tb_op_clock_port_name); + /* + fprintf(fp, " $display($time, \"Operating cycle: load BL address with \%h, load WL address with \%h\",\n"); + fprintf(fp, " bl_addr_val, wl_addr_val);\n"); + */ + fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); + fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); + fprintf(fp, " %s = bl_data_in_val;\n", top_netlist_bl_data_in_port_name); + fprintf(fp, " end\n"); + fprintf(fp, "endtask //---op_cycle_stimuli\n"); + fprintf(fp, "\n"); + break; + case SPICE_MODEL_DESIGN_RRAM: + /* Declare two tasks: + * 1. assign BL/WL IO pads values during a programming clock cycle + * 2. assign BL/WL IO pads values during a operating clock cycle + */ + fprintf(fp, "\n"); + fprintf(fp, "//----- Task 1: input values during a programming clock cycle -----\n"); + fprintf(fp, "task prog_cycle_blwl;\n"); + fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); + fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); + fprintf(fp, " begin\n"); + fprintf(fp, " @(posedge %s);\n", top_tb_prog_clock_port_name); + /* + fprintf(fp, " $display($time, \"Programming cycle: load BL address with \%h, load WL address with \%h\",\n"); + fprintf(fp, " bl_addr_val, wl_addr_val);\n"); + */ + fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); + fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); + fprintf(fp, " end\n"); + fprintf(fp, "endtask //---prog_cycle_stimuli\n"); + fprintf(fp, "\n"); + fprintf(fp, "//----- Task 2: input values during a operating clock cycle -----\n"); + fprintf(fp, "task op_cycle_blwl;\n"); + fprintf(fp, " input [%d:0] bl_addr_val;\n", bl_decoder_size - 1); + fprintf(fp, " input [%d:0] wl_addr_val;\n", wl_decoder_size - 1); + fprintf(fp, " begin\n"); + fprintf(fp, " @(posedge %s);\n", top_tb_op_clock_port_name); + /* + fprintf(fp, " $display($time, \"Operating cycle: load BL address with \%h, load WL address with \%h\",\n"); + fprintf(fp, " bl_addr_val, wl_addr_val);\n"); + */ + fprintf(fp, " %s = bl_addr_val;\n", top_netlist_addr_bl_port_name); + fprintf(fp, " %s = wl_addr_val;\n", top_netlist_addr_wl_port_name); + fprintf(fp, " end\n"); + fprintf(fp, "endtask //---op_cycle_stimuli\n"); + fprintf(fp, "\n"); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +/* Print tasks, which is very useful in generating stimuli for each clock cycle + * For scan-chain manipulation: + * During each programming cycle, we feed the input of scan chain with a memory bit + */ +static +void dump_verilog_top_testbench_stimuli_serial_version_tasks_scan_chain(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + + /* Check */ + assert ( SPICE_SRAM_SCAN_CHAIN == cur_sram_orgz_info->type); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Feed the scan-chain input at each falling edge of programming clock + * It aims at avoid racing the programming clock (scan-chain data changes at the rising edge). + */ + fprintf(fp, "\n"); + fprintf(fp, "//----- Task: input values during a programming clock cycle -----\n"); + fprintf(fp, "task prog_cycle_scan_chain;\n"); + fprintf(fp, " input %s_val;\n", + top_netlist_scan_chain_head_prefix); + fprintf(fp, " begin\n"); + fprintf(fp, " @(negedge %s);\n", top_tb_prog_clock_port_name); + fprintf(fp, " "); + dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, " = %s_val;\n", + top_netlist_scan_chain_head_prefix); + fprintf(fp, " end\n"); + fprintf(fp, "endtask //---prog_cycle_stimuli\n"); + fprintf(fp, "\n"); + + return; +} + +/* Print tasks, which is very useful in generating stimuli for each clock cycle */ +static +void dump_verilog_top_testbench_stimuli_serial_version_tasks(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + break; + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_top_testbench_stimuli_serial_version_tasks_scan_chain(cur_sram_orgz_info, fp); + break; + case SPICE_SRAM_MEMORY_BANK: + dump_verilog_top_testbench_stimuli_serial_version_tasks_memory_bank(cur_sram_orgz_info, fp); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + + +/* Print Stimulations for top-level netlist + * Test a complete configuration phase: + * configuration bits are programming in serial (one by one) + * Task list: + * 1. For clock signal, we should create voltage waveforms for two types of clock signals: + * a. operation clock + * b. programming clock + * 2. For Set/Reset, TODO: should we reset the chip after programming phase ends and before operation phase starts + * 3. For input/output clb nets (mapped to I/O grids), we should create voltage waveforms only after programming phase + */ +static +void dump_verilog_top_testbench_stimuli_serial_version(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int num_clock, + t_spice spice) { + int inet, iblock, iopad_idx; + int found_mapped_inpad = 0; + int num_config_clock_cycles = 0; + float prog_clock_period = (1./spice.spice_params.stimulate_params.prog_clock_freq); + float op_clock_period = (1./spice.spice_params.stimulate_params.op_clock_freq); + + /* Find Input Pad Spice model */ + t_spice_net_info* cur_spice_net_info = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Dump tasks */ + dump_verilog_top_testbench_stimuli_serial_version_tasks(cur_sram_orgz_info, fp); + + /* Estimate the number of configuration clock cycles + * by traversing the linked-list and count the number of SRAM=1 or BL=1&WL=1 in it. + * We plus 1 additional config clock cycle here because we need to reset everything during the first clock cycle + */ + num_config_clock_cycles = 1 + dump_verilog_top_testbench_find_num_config_clock_cycles(cur_sram_orgz_info, + cur_sram_orgz_info->conf_bit_head); + fprintf(fp, "//----- Number of clock cycles in configuration phase: %d -----\n", + num_config_clock_cycles); + + /* config_done signal: indicate when configuration is finished */ + fprintf(fp, "//----- %s ----\n", top_tb_config_done_port_name); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- CONFIG_DONE GENERATOR\n"); + fprintf(fp, " %s = 1'b0;\n", top_tb_config_done_port_name); + fprintf(fp, " //----- %s signal is enabled after %d configurating operations are done ----\n", + top_tb_config_done_port_name, num_config_clock_cycles); + fprintf(fp, " #%.2f %s = 1'b1;\n", + num_config_clock_cycles * prog_clock_period / verilog_sim_timescale, top_tb_config_done_port_name); + fprintf(fp, " end\n"); + fprintf(fp, "//----- END of %s ----\n", + top_tb_config_done_port_name); + fprintf(fp, "\n"); + + /* Generate stimilus of programming clock */ + fprintf(fp, "//----- Raw Programming clock ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- PROG_CLOCK INITIALIZATION\n"); + fprintf(fp, " %s%s = 1'b0;\n", top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); + fprintf(fp, " end\n"); + fprintf(fp, "always\n"); + fprintf(fp, " begin //--- PROG_CLOCK GENERATOR\n"); + fprintf(fp, " #%.2f %s%s = ~%s%s;\n", + 0.5*prog_clock_period / verilog_sim_timescale, + top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, + top_tb_prog_clock_port_name, top_tb_clock_reg_postfix); + fprintf(fp, " end\n"); + fprintf(fp, "//----- END of Programming clock ----\n"); + fprintf(fp, "\n"); + /* Programming clock should be only enabled during programming phase. + * When configuration is done (config_done is enabled), programming clock should be always zero. + */ + fprintf(fp, "//---- Actual programming clock is triggered only when %s and %s are disabled\n", + top_tb_config_done_port_name, + top_tb_prog_reset_port_name); + fprintf(fp, " assign %s = %s%s & (~%s) & (~%s);\n", + top_tb_prog_clock_port_name, + top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, + top_tb_config_done_port_name, + top_tb_prog_reset_port_name); + /* + fprintf(fp, " assign %s = %s%s & (~%s);\n", + top_tb_prog_clock_port_name, + top_tb_prog_clock_port_name, top_tb_clock_reg_postfix, + top_tb_config_done_port_name); + */ + fprintf(fp, "//----- END of Actual Programming clock ----\n"); + fprintf(fp, "\n"); + + /* Generate stimilus of programming clock */ + fprintf(fp, "//----- Raw Operation clock ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- OP_CLOCK INITIALIZATION\n"); + fprintf(fp, " %s%s = 1'b0;\n", top_tb_op_clock_port_name, top_tb_clock_reg_postfix); + fprintf(fp, " end\n"); + fprintf(fp, "always wait(~%s)\n", top_tb_reset_port_name); + fprintf(fp, " begin //--- OP_CLOCK GENERATOR\n"); + fprintf(fp, " #%.2f %s%s = ~%s%s;\n", + 0.5*op_clock_period / verilog_sim_timescale, + top_tb_op_clock_port_name, top_tb_clock_reg_postfix, + top_tb_op_clock_port_name, top_tb_clock_reg_postfix); + fprintf(fp, " end\n"); + fprintf(fp, "//----- END of Operation clock ----\n"); + /* Operation clock should be enabled after programming phase finishes. + * Before configuration is done (config_done is enabled), operation clock should be always zero. + */ + fprintf(fp, "//---- Actual operation clock is triggered only when %s is enabled \n", + top_tb_config_done_port_name); + fprintf(fp, " assign %s = %s%s & (%s);\n", + top_tb_op_clock_port_name, + top_tb_op_clock_port_name, top_tb_clock_reg_postfix, + top_tb_config_done_port_name); + fprintf(fp, "//----- END of Actual Operation clock ----\n"); + fprintf(fp, "\n"); + + /* Reset signal for configuration circuit : only enable during the first clock cycle in programming phase */ + fprintf(fp, "//----- Programming Reset Stimuli ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- PROGRAMMING RESET GENERATOR\n"); + fprintf(fp, " %s = 1'b1;\n", top_tb_prog_reset_port_name); + /* Reset is enabled until the first clock cycle in operation phase */ + fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in programming phase ----\n"); + fprintf(fp, "#%.2f %s = 1'b0;\n", + (1 * prog_clock_period) / verilog_sim_timescale, + top_tb_prog_reset_port_name); + fprintf(fp, "end\n"); + fprintf(fp, "\n"); + + /* Set signal for configuration circuit : only enable during the first clock cycle in programming phase */ + fprintf(fp, "//----- Programming set Stimuli ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- PROGRAMMING SET GENERATOR\n"); + fprintf(fp, "%s = 1'b0;\n", top_tb_prog_set_port_name); + fprintf(fp, "//----- Programming set signal is always disabled -----\n"); + fprintf(fp, "end\n"); + fprintf(fp, "\n"); + + /* reset signals: only enabled during the first clock cycle in operation phase */ + fprintf(fp, "//----- Reset Stimuli ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- RESET GENERATOR\n"); + fprintf(fp, " %s = 1'b1;\n", top_tb_reset_port_name); + /* Reset is enabled until the first clock cycle in operation phase */ + fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in operation phase ----\n"); + fprintf(fp, "wait(%s);\n", + top_tb_config_done_port_name); + fprintf(fp, "#%.2f %s = 1'b1;\n", + (1 * op_clock_period)/ verilog_sim_timescale, + top_tb_reset_port_name); + fprintf(fp, "#%.2f %s = 1'b0;\n", + (2 * op_clock_period) / verilog_sim_timescale, + top_tb_reset_port_name); + fprintf(fp, "end\n"); + fprintf(fp, "\n"); + + /* set signals */ + fprintf(fp, "//----- Set Stimuli ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- SET GENERATOR\n"); + fprintf(fp, "%s = 1'b0;\n", top_tb_set_port_name); + fprintf(fp, "//----- Set signal is always disabled -----\n"); + fprintf(fp, "end\n"); + fprintf(fp, "\n"); + + /* Inputs stimuli: BL/WL address lines */ + dump_verilog_top_testbench_conf_bits_serial(cur_sram_orgz_info, fp, cur_sram_orgz_info->conf_bit_head); + + /* For each input_signal + * TODO: this part is low-efficent for run-time concern... Need improve + */ + assert(NULL != iopad_verilog_model); + for (iopad_idx = 0; iopad_idx < iopad_verilog_model->cnt; iopad_idx++) { + /* Find if this inpad is mapped to a logical block */ + found_mapped_inpad = 0; + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* Bypass OUTPAD: donot put any voltage stimuli */ + /* Make sure We find the correct logical block !*/ + if ((iopad_verilog_model == logical_block[iblock].mapped_spice_model) + &&(iopad_idx == logical_block[iblock].mapped_spice_model_index)) { + /* Output PAD only need a short connection */ + if (VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, "//----- Output %s does not need a Stimuli ----\n", logical_block[iblock].name); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- Input %s[%d] GENERATOR\n", gio_inout_prefix, iopad_idx); + fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + verilog_default_signal_init_value); + fprintf(fp, "end\n"); + found_mapped_inpad = 1; + break; + } + /* Input PAD only need a short connection */ + assert(VPACK_INPAD == logical_block[iblock].type); + cur_spice_net_info = NULL; + for (inet = 0; inet < num_nets; inet++) { + if (0 == strcmp(clb_net[inet].name, logical_block[iblock].name)) { + cur_spice_net_info = clb_net[inet].spice_net_info; + break; + } + } + assert(NULL != cur_spice_net_info); + assert(!(0 > cur_spice_net_info->density)); + assert(!(1 < cur_spice_net_info->density)); + assert(!(0 > cur_spice_net_info->probability)); + assert(!(1 < cur_spice_net_info->probability)); + /* Connect the reg to inouts */ + fprintf(fp, "//----- Input %s Stimuli ----\n", logical_block[iblock].name); + fprintf(fp, "assign %s%s[%d] = %s%s%s[%d];\n", + gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx); + /* Get the net information */ + /* TODO: Give the net name in the blif file !*/ + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- Input %s GENERATOR\n", logical_block[iblock].name); + fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + cur_spice_net_info->init_val); + fprintf(fp, "end\n"); + fprintf(fp, "always wait (~%s)\n", top_tb_reset_port_name); + fprintf(fp, " begin \n"); + fprintf(fp, " %s%s%s[%d] = ~%s%s%s[%d];\n #%.2f;\n", + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + (((float)(int)((100 * op_clock_period) / verilog_sim_timescale) / 100) * ((int)(cur_spice_net_info->probability / cur_spice_net_info->density)+ iblock))); + fprintf(fp, " %s%s%s[%d] = ~%s%s%s[%d];\n #%.2f;\n", + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + (((float)(int)((100 * op_clock_period) / verilog_sim_timescale) / 100) * ((int)(cur_spice_net_info->density / cur_spice_net_info->probability) * 2.5 + iblock))); + fprintf(fp, " end \n"); + fprintf(fp, "\n"); + found_mapped_inpad++; + } + } + assert((0 == found_mapped_inpad)||(1 == found_mapped_inpad)); + /* If we find one iopad already, we finished in this round here */ + if (1 == found_mapped_inpad) { + continue; + } + /* TODO: identify if this iopad is set to input or output by default + * and see if it should be driven by a constant + */ + /* if we cannot find any mapped inpad from tech.-mapped netlist, give a default */ + /* Connect the reg to inouts */ + fprintf(fp, "//----- Input %s[%d] Stimuli ----\n", gio_inout_prefix, iopad_idx); + fprintf(fp, "assign %s%s[%d] = %s%s%s[%d];\n", + gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx); + /* TODO: Give the net name in the blif file !*/ + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- Input %s[%d] GENERATOR\n", gio_inout_prefix, iopad_idx); + fprintf(fp, " %s%s%s[%d] = 1'b%d;\n", + gio_inout_prefix, iopad_verilog_model->prefix, top_tb_inout_reg_postfix, iopad_idx, + verilog_default_signal_init_value); + fprintf(fp, "end\n"); + } + + /* Finish */ + + return; +} + +/* Generate the stimuli for the top-level testbench + * The simulation consists of two phases: configuration phase and operation phase + * We have two choices for the configuration phase: + * 1. Configuration bits are loaded serially. + * This is actually what we do for a physical FPGA + * 2. Configuration bits are loaded parallel. + * This is only feasible in simulation, which is convenient to check functionality. + */ +void dump_verilog_top_testbench_stimuli(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int num_clock, + t_syn_verilog_opts syn_verilog_opts, + t_spice verilog) { + + /* Only serial version is avaiable now */ + dump_verilog_top_testbench_stimuli_serial_version(cur_sram_orgz_info, fp, num_clock, verilog); + /* + if (TRUE == syn_verilog_opts.tb_serial_config_mode) { + } else { + dump_verilog_top_testbench_stimuli_parallel_version(fp, num_clock, verilog); + } + */ + + return; +} + +/* Dump the ports for input blif nestlist */ +static +void dump_verilog_input_blif_testbench_ports(FILE* fp, + char* circuit_name) { + int iblock; + + fprintf(fp, "module %s_blif_tb;\n", circuit_name); + + fprintf(fp, " reg %s;\n", top_tb_reset_port_name); + + /* Print all the inputs/outputs*/ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* Make sure We find the correct logical block !*/ + switch (logical_block[iblock].type) { + case VPACK_INPAD: + fprintf(fp, " reg %s;\n", logical_block[iblock].name); + break; + case VPACK_OUTPAD: + fprintf(fp, " wire %s;\n", logical_block[iblock].name); + break; + case VPACK_COMB: + case VPACK_LATCH: + case VPACK_EMPTY: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", + __FILE__, __LINE__, iblock); + exit(1); + } + } + + return; +} + +/* Dump the module to be tested for input blif nestlist */ +static +void dump_verilog_input_blif_testbench_call_top_module(FILE* fp, + char* circuit_name) { + int iblock, cnt; + /* Initialize a counter */ + cnt = 0; + + fprintf(fp, "%s uut (\n", circuit_name); + /* Print all the inputs/outputs*/ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* Make sure We find the correct logical block !*/ + switch (logical_block[iblock].type) { + case VPACK_INPAD: + case VPACK_OUTPAD: + /* Dump a comma only when needed*/ + if (0 < cnt) { + fprintf(fp, ",\n"); + } + /* Dump an input/output, avoid additional comma leading to wrong connections */ + fprintf(fp, "%s", logical_block[iblock].name); + /* Update counter */ + cnt++; + break; + case VPACK_COMB: + case VPACK_LATCH: + case VPACK_EMPTY: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", + __FILE__, __LINE__, iblock); + exit(1); + } + } + fprintf(fp, ");\n"); + fprintf(fp, "//---- End call module %s (%d inputs and outputs) -----\n", + circuit_name, cnt); + + return; +} + +/* Dump voltage stimuli for input blif nestlist */ +static +void dump_verilog_input_blif_testbench_stimuli(FILE* fp, + int num_clock, + t_syn_verilog_opts syn_verilog_opts, + t_spice spice) { + int iblock, inet; + t_spice_net_info* cur_spice_net_info = NULL; + float op_clock_period = 1./spice.spice_params.stimulate_params.op_clock_freq; + + fprintf(fp, "//----- Operation clock period: %.2g -----\n", op_clock_period); + + /* reset signals: only enabled during the first clock cycle in operation phase */ + fprintf(fp, "//----- Reset Stimuli ----\n"); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- RESET GENERATOR\n"); + fprintf(fp, " %s = 1'b1;\n", top_tb_reset_port_name); + /* Reset is enabled until the first clock cycle in operation phase */ + fprintf(fp, "//----- Reset signal is enabled until the first clock cycle in operation phase ----\n"); + fprintf(fp, "#%.2f %s = 1'b0;\n", + (1 * op_clock_period) / verilog_sim_timescale, + top_tb_reset_port_name); + fprintf(fp, "end\n"); + fprintf(fp, "\n"); + + /* Regular inputs */ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* Make sure We find the correct logical block !*/ + switch (logical_block[iblock].type) { + case VPACK_INPAD: + cur_spice_net_info = NULL; + for (inet = 0; inet < num_nets; inet++) { + if (0 == strcmp(clb_net[inet].name, logical_block[iblock].name)) { + cur_spice_net_info = clb_net[inet].spice_net_info; + break; + } + } + assert(NULL != cur_spice_net_info); + assert(!(0 > cur_spice_net_info->density)); + assert(!(1 < cur_spice_net_info->density)); + assert(!(0 > cur_spice_net_info->probability)); + assert(!(1 < cur_spice_net_info->probability)); + /* Get the net information */ + /* TODO: Give the net name in the blif file !*/ + fprintf(fp, "//----- Input %s Stimuli ----\n", logical_block[iblock].name); + fprintf(fp, "initial\n"); + fprintf(fp, " begin //--- Input %s GENERATOR\n", logical_block[iblock].name); + fprintf(fp, " %s = 1'b%d;\n", + logical_block[iblock].name, + cur_spice_net_info->init_val); + fprintf(fp, "end\n"); + fprintf(fp, "always wait (~%s)\n", top_tb_reset_port_name); + fprintf(fp, " begin \n"); + fprintf(fp, " #%.2f %s = ~%s;\n", + (op_clock_period * cur_spice_net_info->density * 2. / cur_spice_net_info->probability) / verilog_sim_timescale, + logical_block[iblock].name, + logical_block[iblock].name); + fprintf(fp, " end \n"); + fprintf(fp, "\n"); + break; + case VPACK_OUTPAD: + case VPACK_COMB: + case VPACK_LATCH: + case VPACK_EMPTY: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", + __FILE__, __LINE__, iblock); + exit(1); + } + } + + return; +} + +/** Top level function 1: Testbench for the top-level netlist + * This testbench includes a top-level module of a mapped FPGA and voltage pulses + */ +void dump_verilog_top_testbench(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog) { + FILE* fp = NULL; + char* title = my_strcat("FPGA Verilog Testbench for Top-level netlist of Design: ", circuit_name); + + /* Check if the path exists*/ + fp = fopen(top_netlist_name,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); + exit(1); + } + + vpr_printf(TIO_MESSAGE_INFO, "Writing Testbench for FPGA Top-level Verilog netlist for %s...\n", circuit_name); + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + /* Start of testbench */ + dump_verilog_top_testbench_ports(cur_sram_orgz_info, fp, circuit_name); + + /* Call defined top-level module */ + dump_verilog_top_testbench_call_top_module(cur_sram_orgz_info, fp, circuit_name); + + /* Add stimuli for reset, set, clock and iopad signals */ + dump_verilog_top_testbench_stimuli(cur_sram_orgz_info, fp, num_clock, fpga_verilog_opts, verilog); + + /* Testbench ends*/ + fprintf(fp, "endmodule\n"); + + /* Close the file*/ + fclose(fp); + + return; +} + +/** Top level function 2: Testbench for the top-level blif netlist (before FPGA mapping) + * This testbench includes a top-level module of a mapped FPGA and voltage pulses + */ +void dump_verilog_input_blif_testbench(char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts syn_verilog_opts, + t_spice verilog) { + FILE* fp = NULL; + char* title = my_strcat("FPGA Verilog Testbench for input blif netlist of Design: ", circuit_name); + + /* Check if the path exists*/ + fp = fopen(top_netlist_name,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); + exit(1); + } + + vpr_printf(TIO_MESSAGE_INFO, "Writing Testbench for blif netlist: %s...\n", circuit_name); + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + /* Start of testbench */ + dump_verilog_input_blif_testbench_ports(fp, circuit_name); + + /* Call defined top-level module */ + dump_verilog_input_blif_testbench_call_top_module(fp, circuit_name); + + /* Add stimuli for reset, set, clock and iopad signals */ + dump_verilog_input_blif_testbench_stimuli(fp, num_clock, syn_verilog_opts, verilog); + + /* Testbench ends*/ + fprintf(fp, "endmodule\n"); + + /* Close the file*/ + fclose(fp); + + return; +} + + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.h new file mode 100644 index 000000000..b52c60f5d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_top_testbench.h @@ -0,0 +1,30 @@ + +void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_top_testbench_global_ports_stimuli(FILE* fp, t_llist* head); + +void dump_verilog_top_testbench_call_top_module(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* circuit_name); + +void dump_verilog_top_testbench_stimuli(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + int num_clock, + t_syn_verilog_opts syn_verilog_opts, + t_spice verilog); + +void dump_verilog_top_testbench(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog); + +void dump_verilog_input_blif_testbench(char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts syn_verilog_opts, + t_spice verilog); diff --git a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c similarity index 54% rename from vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.c rename to vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c index be8dba272..5e1f476c7 100644 --- a/vpr7_x2p/vpr/SRC/fpga_spice/verilog/verilog_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.c @@ -22,12 +22,15 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "vpr_utils.h" +#include "route_common.h" /* FPGA-SPICE utils */ #include "read_xml_spice_util.h" #include "linkedlist.h" -#include "fpga_spice_utils.h" -#include "fpga_spice_globals.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_globals.h" /* syn_verilog globals */ #include "verilog_global.h" @@ -141,24 +144,6 @@ void dump_include_user_defined_verilog_netlists(FILE* fp, return; } -/* Dump preproc */ -void dump_verilog_preproc(FILE* fp, - boolean include_timing) { - - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d]) FileHandle is NULL!\n",__FILE__,__LINE__); - exit(1); - } - - /* To enable timing */ - if (TRUE == include_timing) { - fprintf(fp, "`define %s 1\n", verilog_timing_preproc_flag); - fprintf(fp, "\n"); - } - - return; -} - void dump_verilog_file_header(FILE* fp, char* usage) { if (NULL == fp) { @@ -170,7 +155,7 @@ void dump_verilog_file_header(FILE* fp, fprintf(fp,"// Description: %s \n",usage); fprintf(fp,"// Author: Xifan TANG \n"); fprintf(fp,"// Organization: EPFL/IC/LSI \n"); - fprintf(fp,"// Date: %s \n",my_gettime()); + fprintf(fp,"// Date: %s \n", my_gettime()); fprintf(fp,"//-------------------------------------------\n"); fprintf(fp,"//----- Time scale -----\n"); fprintf(fp,"`timescale 1ns / 1ps\n"); @@ -179,6 +164,187 @@ void dump_verilog_file_header(FILE* fp, return; } +/* Dump preproc */ +void dump_verilog_preproc(FILE* fp, + t_syn_verilog_opts fpga_verilog_opts, + enum e_verilog_tb_type verilog_tb_type) { + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d]) FileHandle is NULL!\n",__FILE__,__LINE__); + exit(1); + } + + /* To enable timing */ + if (TRUE == fpga_verilog_opts.include_timing) { + fprintf(fp, "`define %s 1\n", verilog_timing_preproc_flag); + fprintf(fp, "\n"); + } + + /* To enable timing */ + if (TRUE == fpga_verilog_opts.include_signal_init) { + fprintf(fp, "`define %s 1\n", verilog_signal_init_preproc_flag); + fprintf(fp, "\n"); + } + + /* To enable formal verfication flag */ + if (TRUE == fpga_verilog_opts.print_formal_verification_top_netlist) { + fprintf(fp, "`define %s 1\n", + verilog_formal_verification_preproc_flag); // the flag to enable formal verification during compilation + fprintf(fp, "\n"); + } + + /* To enable functional verfication with Icarus */ + if (TRUE == fpga_verilog_opts.include_icarus_simulator) { + fprintf(fp, "`define %s 1\n", + icarus_simulator_flag); // the flag to enable formal verification during compilation + fprintf(fp, "\n"); + } + + return; +} + +void dump_simulation_preproc(FILE* fp, + t_syn_verilog_opts fpga_verilog_opts, + enum e_verilog_tb_type verilog_tb_type) { + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s, LINE[%d]) FileHandle is NULL!\n",__FILE__,__LINE__); + exit(1); + } + + /* To enable manualy checked simulation */ + if (TRUE == fpga_verilog_opts.print_top_testbench) { + fprintf(fp, "`define %s 1\n", initial_simulation_flag); + fprintf(fp, "\n"); + } + + /* To enable auto-checked simulation */ + if (TRUE == fpga_verilog_opts.print_autocheck_top_testbench) { + fprintf(fp, "`define %s 1\n", autochecked_simulation_flag); + fprintf(fp, "\n"); + } + + /* To enable pre-configured FPGA simulation */ + if (TRUE == fpga_verilog_opts.print_formal_verification_top_netlist) { + fprintf(fp, "`define %s 1\n", formal_simulation_flag); + fprintf(fp, "\n"); + } + + return; +} + +void dump_verilog_simulation_preproc(char* subckt_dir, + t_syn_verilog_opts fpga_verilog_opts) { + /* Create a file handler */ + FILE* fp = NULL; + char* file_description = NULL; + char* fname = NULL; + + fname = my_strcat(subckt_dir, + defines_verilog_simulation_file_name); + + /* Create a file*/ + fp = fopen(fname, "w"); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create Verilog netlist %s", + __FILE__, __LINE__, fname); + exit(1); + } + + /* Generate the descriptions*/ + file_description = "Simulation Flags"; + dump_verilog_file_header(fp, file_description); + + /* Dump the defines preproc flags*/ + dump_simulation_preproc(fp, fpga_verilog_opts, VERILOG_TB_TOP); + + fclose(fp); + + /* Free */ + my_free(fname); + + return; +} + +void dump_verilog_defines_preproc(char* subckt_dir, + t_syn_verilog_opts fpga_verilog_opts) { + /* Create a file handler */ + FILE* fp = NULL; + char* file_description = NULL; + char* fname = NULL; + + fname = my_strcat(subckt_dir, + defines_verilog_file_name); + + /* Create a file*/ + fp = fopen(fname, "w"); + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s,LINE[%d])Failure in create Verilog netlist %s", + __FILE__, __LINE__, fname); + exit(1); + } + + /* Generate the descriptions*/ + file_description = "Preproc Flags"; + dump_verilog_file_header(fp, file_description); + + /* Dump the defines preproc flags*/ + dump_verilog_preproc(fp, fpga_verilog_opts, VERILOG_TB_TOP); + + fclose(fp); + + /* Free */ + my_free(fname); + + return; +} + +void verilog_include_defines_preproc_file(FILE* fp, + char* verilog_dir) { + char* temp_include_file_path = NULL; + char* formatted_verilog_dir = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "//------ Include defines: preproc flags -----\n"); + formatted_verilog_dir = format_dir_path(verilog_dir); + temp_include_file_path = my_strcat(formatted_verilog_dir, defines_verilog_file_name); + fprintf(fp, "`include \"%s\"\n", temp_include_file_path); + fprintf(fp, "//------ End Include defines: preproc flags -----\n"); + my_free(temp_include_file_path); + + return; +} + +void verilog_include_simulation_defines_file(FILE* fp, + char* verilog_dir) { + char* temp_include_file_path = NULL; + char* formatted_verilog_dir = NULL; + + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid file handler!", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, "//------ Include simulation defines -----\n"); + formatted_verilog_dir = format_dir_path(verilog_dir); + temp_include_file_path = my_strcat(formatted_verilog_dir, defines_verilog_simulation_file_name); + fprintf(fp, "`include \"%s\"\n", temp_include_file_path); + fprintf(fp, "//------ End Include simulation defines -----\n"); + my_free(temp_include_file_path); + + return; +} + /* Create a file handler for a subckt Verilog netlist */ FILE* verilog_create_one_subckt_file(char* subckt_dir, char* subckt_name_prefix, @@ -204,7 +370,7 @@ FILE* verilog_create_one_subckt_file(char* subckt_dir, /* Generate the descriptions*/ file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 2 + strlen(my_itoa(grid_x)) + 2 + strlen(my_itoa(grid_y)) - + 9)); + + 10)); sprintf(file_description, "%s [%d][%d] in FPGA", subckt_name_prefix, grid_x, grid_y); dump_verilog_file_header(fp, file_description); @@ -359,8 +525,8 @@ void dump_verilog_generic_port(FILE* fp, break; case VERILOG_PORT_CONKT: if (TRUE == dump_single_port) { - fprintf(fp,"%s ", - port_name); + fprintf(fp,"%s[%d] ", + port_name, port_lsb); } else { assert(FALSE == dump_single_port); fprintf(fp,"%s[%d:%d] ", @@ -377,278 +543,102 @@ void dump_verilog_generic_port(FILE* fp, return; } - - -/* Decode BL and WL bits for a SRAM - * SRAM could be - * 1. NV SRAM - * or - * 2. SRAM - */ -void decode_verilog_memory_bank_sram(t_spice_model* cur_sram_spice_model, int sram_bit, - int bl_len, int wl_len, int bl_offset, int wl_offset, - int* bl_conf_bits, int* wl_conf_bits) { - int i; +/* Dump a generic Verilog port */ +void dump_verilog_generic_port_no_repeat(FILE* fp, + enum e_dump_verilog_port_type dump_port_type, + char* port_name, int port_lsb, int port_msb) { + boolean dump_single_port = FALSE; + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } /* Check */ - assert(NULL != cur_sram_spice_model); - assert(NULL != bl_conf_bits); - assert(NULL != wl_conf_bits); - assert((1 == sram_bit)||(0 == sram_bit)); + assert((!(port_lsb < 0))&&(!(port_msb < 0))); + if (port_lsb == port_msb) { + dump_single_port = TRUE; + } + //dump_single_port = FALSE; /* Disable it for a clear synthesis */ - /* All the others should be zero */ - for (i = 0; i < bl_len; i++) { - bl_conf_bits[i] = 0; - } - for (i = 0; i < wl_len; i++) { - wl_conf_bits[i] = 0; - } - - /* Depending on the design technology of SRAM */ - switch (cur_sram_spice_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - /* CMOS SRAM */ - /* Make sure there is only 1 BL and 1 WL */ - assert((1 == bl_len)&&(1 == wl_len)); - /* We always assume that WL is a write-enable signal - * While BL contains what data will be written into SRAM - */ - bl_conf_bits[0] = sram_bit; - wl_conf_bits[0] = 1; - break; - case SPICE_MODEL_DESIGN_RRAM: - /* NV SRAM (RRAM-based) */ - /* We need at least 2 BLs and 2 WLs but no more than 3, See schematic in manual */ - /* Whatever the number of BLs and WLs, (RRAM0) - * when sram bit is 1, last bit of BL should be enabled - * while first bit of WL should be enabled at the same time - * when sram bit is 0, last bit of WL should be enabled - * while first bit of BL should be enabled at the same time - */ - assert((1 < bl_len)&&(bl_len < 4)); - assert((1 < wl_len)&&(wl_len < 4)); - assert((-1 < bl_offset)&&(bl_offset < bl_len)); - assert((-1 < wl_offset)&&(wl_offset < wl_len)); - /* In addition, we will may need two programing cycles. - * The first cycle is dedicated to programming RRAM0 - * The second cycle is dedicated to programming RRAM1 - */ - if (1 == sram_bit) { - bl_conf_bits[bl_len-1] = 1; - wl_conf_bits[0 + wl_offset] = 1; + switch (dump_port_type) { + case VERILOG_PORT_INPUT: + if (TRUE == dump_single_port) { + fprintf(fp,"input %s ", + port_name); } else { - assert(0 == sram_bit); - bl_conf_bits[0 + bl_offset] = 1; - wl_conf_bits[wl_len-1] = 1; - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for SRAM!\n", - __FILE__, __LINE__); - exit(1); - } - - return; -} - -/* Decode one SRAM bit for memory-bank-style configuration circuit, and add it to linked list */ -void -decode_and_add_verilog_sram_membank_conf_bit_to_llist(t_sram_orgz_info* cur_sram_orgz_info, - int mem_index, - int num_bl_per_sram, int num_wl_per_sram, - int cur_sram_bit) { - int j; - int* conf_bits_per_sram = NULL; - t_spice_model* mem_model = NULL; - - /* Check */ - assert( SPICE_SRAM_MEMORY_BANK == cur_sram_orgz_info->type ); - - /* Get memory model */ - get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); - assert(NULL != mem_model); - - /* Malloc/Calloc */ - conf_bits_per_sram = (int*)my_calloc(num_bl_per_sram + num_wl_per_sram, sizeof(int)); - - /* Depend on the memory technology, we have different configuration bits */ - switch (mem_model->design_tech) { - case SPICE_MODEL_DESIGN_CMOS: - /* Check */ - assert((1 == num_bl_per_sram) && (1 == num_wl_per_sram)); - /* For CMOS SRAM */ - decode_verilog_memory_bank_sram(mem_model, cur_sram_bit, - num_bl_per_sram, num_wl_per_sram, 0, 0, - conf_bits_per_sram, conf_bits_per_sram + num_bl_per_sram); - /* Use memory model here! Design technology of memory model determines the decoding strategy, instead of LUT model*/ - add_sram_conf_bits_to_llist(cur_sram_orgz_info, mem_index, - num_bl_per_sram + num_wl_per_sram, conf_bits_per_sram); - break; - case SPICE_MODEL_DESIGN_RRAM: - /* Decode the SRAM bits to BL/WL bits. - * first half part is BL, the other half part is WL - */ - /* Store the configuraion bit to linked-list */ - assert(num_bl_per_sram == num_wl_per_sram); - /* When the number of BL/WL is more than 1, we need multiple programming cycles to configure a SRAM */ - /* ONLY valid for NV SRAM !!!*/ - for (j = 0; j < num_bl_per_sram - 1; j++) { - if (0 == j) { - /* Store the configuraion bit to linked-list */ - decode_verilog_memory_bank_sram(mem_model, cur_sram_bit, - num_bl_per_sram, num_wl_per_sram, j, j, - conf_bits_per_sram, conf_bits_per_sram + num_bl_per_sram); - } else { - /* Store the configuraion bit to linked-list */ - decode_verilog_memory_bank_sram(mem_model, 1 - cur_sram_bit, - num_bl_per_sram, num_wl_per_sram, j, j, - conf_bits_per_sram, conf_bits_per_sram + num_bl_per_sram); - } - /* Use memory model here! Design technology of memory model determines the decoding strategy, instead of LUT model*/ - add_sram_conf_bits_to_llist(cur_sram_orgz_info, mem_index, - num_bl_per_sram + num_wl_per_sram, conf_bits_per_sram); + assert(FALSE == dump_single_port); + fprintf(fp,"input [%d:%d] %s ", + port_lsb, port_msb, + port_name); } - break; + break; + case VERILOG_PORT_OUTPUT: + if (TRUE == dump_single_port) { + fprintf(fp,"output %s ", + port_name); + } else { + assert(FALSE == dump_single_port); + fprintf(fp,"output [%d:%d] %s ", + port_lsb, port_msb, + port_name); + } + break; + case VERILOG_PORT_INOUT: + if (TRUE == dump_single_port) { + fprintf(fp,"inout %s ", + port_name); + } else { + assert(FALSE == dump_single_port); + fprintf(fp,"inout [%d:%d] %s ", + port_lsb, port_msb, + port_name); + } + break; + case VERILOG_PORT_WIRE: + if (TRUE == dump_single_port) { + fprintf(fp,"wire %s ", + port_name); + } else { + assert(FALSE == dump_single_port); + fprintf(fp,"wire [%d:%d] %s ", + port_lsb, port_msb, + port_name); + } + break; + case VERILOG_PORT_REG: + if (TRUE == dump_single_port) { + fprintf(fp,"reg %s ", + port_name); + } else { + assert(FALSE == dump_single_port); + fprintf(fp,"reg [%d:%d] %s ", + port_lsb, port_msb, + port_name); + } + break; + case VERILOG_PORT_CONKT: + if (TRUE == dump_single_port) { + fprintf(fp,"%s[%d] ", + port_name, port_lsb); + } else { + assert(FALSE == dump_single_port); + fprintf(fp,"%s[%d:%d] ", + port_name, + port_lsb, port_msb); + } + break; default: - vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid design technology!", + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of Verilog port to be dumped !\n", __FILE__, __LINE__); exit(1); } - /* Free */ - my_free(conf_bits_per_sram); - return; } - -/** Decode 1-level 4T1R MUX - */ -void decode_verilog_one_level_4t1r_mux(int path_id, - int bit_len, int* conf_bits) { - int i; - - /* Check */ - assert(0 < bit_len); - assert(NULL != conf_bits); - assert((-1 < path_id)&&((path_id < bit_len/2 - 1)||(path_id == bit_len/2 - 1))); - - /* All the others should be zero */ - for (i = 0; i < bit_len; i++) { - conf_bits[i] = 0; - } - - /* Last bit of WL should be 1 */ - conf_bits[bit_len-1] = 1; - /* determine which BL should be 1*/ - conf_bits[path_id] = 1; - - return; -} - -/** Decode multi-level 4T1R MUX - */ -void decode_verilog_multilevel_4t1r_mux(int num_level, int num_input_basis, - int mux_size, int path_id, - int bit_len, int* conf_bits) { - int i, active_basis_path_id; - - /* Check */ - assert(0 < bit_len); - assert(NULL != conf_bits); - /* assert((-1 < path_id)&&(path_id < bit_len/2 - 1)); */ - /* Start from first level to the last level */ - active_basis_path_id = path_id; - for (i = 0; i < num_level; i++) { - /* Treat each basis as a 1-level 4T1R MUX */ - active_basis_path_id = active_basis_path_id % num_input_basis; - /* Last bit of WL should be 1 */ - conf_bits[bit_len/2 + (num_input_basis+1)*(i+1) - 1] = 1; - /* determine which BL should be 1*/ - conf_bits[(num_input_basis+1)*i + active_basis_path_id] = 1; - } - - return; -} - -/** Decode the configuration bits for a 4T1R-based MUX - * Determine the number of configuration bits - * Configuration bits are decoded depending on the MUX structure: - * 1. 1-level; 2. multi-level (tree-like); - */ -void decode_verilog_rram_mux(t_spice_model* mux_spice_model, - int mux_size, int path_id, - int* bit_len, int** conf_bits, int* mux_level) { - int num_level, num_input_basis; - - /* Check */ - assert(NULL != mux_level); - assert(NULL != bit_len); - assert(NULL != conf_bits); - assert((-1 < path_id)&&(path_id < mux_size)); - assert(SPICE_MODEL_MUX == mux_spice_model->type); - assert(SPICE_MODEL_DESIGN_RRAM == mux_spice_model->design_tech); - - /* Initialization */ - (*mux_level) = 0; - (*bit_len) = 0; - (*conf_bits) = NULL; - - (*bit_len) = 2 * count_num_sram_bits_one_spice_model(mux_spice_model, mux_size); - - /* Switch cases: MUX structure */ - switch (mux_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_ONELEVEL: - /* Number of configuration bits is 2*(input_size+1) */ - num_level = 1; - break; - case SPICE_MODEL_STRUCTURE_TREE: - /* Number of configuration bits is num_level* 2*(basis+1) */ - num_level = determine_tree_mux_level(mux_size); - num_input_basis = 2; - break; - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - /* Number of configuration bits is num_level* 2*(basis+1) */ - num_level = mux_spice_model->design_tech_info.mux_num_level; - num_input_basis = determine_num_input_basis_multilevel_mux(mux_size, num_level); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid MUX structure!\n", - __FILE__, __LINE__); - exit(1); - } - - /* Malloc configuration bits */ - (*conf_bits) = (int*)my_calloc((*bit_len), sizeof(int)); - - /* Decode configuration bits : BL & WL*/ - /* Switch cases: MUX structure */ - switch (mux_spice_model->design_tech_info.structure) { - case SPICE_MODEL_STRUCTURE_ONELEVEL: - decode_verilog_one_level_4t1r_mux(path_id, (*bit_len), (*conf_bits)); - break; - case SPICE_MODEL_STRUCTURE_TREE: - case SPICE_MODEL_STRUCTURE_MULTILEVEL: - decode_verilog_multilevel_4t1r_mux(num_level, num_input_basis, mux_size, - path_id, (*bit_len), (*conf_bits)); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid MUX structure!\n", - __FILE__, __LINE__); - exit(1); - } - - (*mux_level) = num_level; - - return; -} - -/* Determine the size of input address of a decoder */ -int determine_decoder_size(int num_addr_out) { - return ceil(log(num_addr_out)/log(2.)); -} - -char* chomp_verilog_node_prefix(char* verilog_node_prefix) { +char* chomp_verilog_prefix(char* verilog_node_prefix) { int len = 0; char* ret = NULL; @@ -664,14 +654,12 @@ char* chomp_verilog_node_prefix(char* verilog_node_prefix) { my_free(ret); return NULL; } - strcpy(ret,verilog_node_prefix); /* If the path end up with "_" we should remove it*/ - /* - if ('_' == ret[len-1]) { + while ('_' == ret[len-1]) { ret[len-1] = ret[len]; + len--; } - */ return ret; } @@ -721,14 +709,18 @@ char* verilog_convert_port_type_to_string(enum e_spice_model_port_type port_type /* Dump all the global ports that are stored in the linked list * Return the number of ports that have been dumped */ -int rec_dump_verilog_spice_model_global_ports(FILE* fp, - t_spice_model* cur_spice_model, - boolean dump_port_type, boolean recursive) { - int iport, dumped_port_cnt, rec_dumped_port_cnt; +int rec_dump_verilog_spice_model_lib_global_ports(FILE* fp, + t_spice_model* cur_spice_model, + boolean dump_port_type, + boolean recursive, + boolean require_explicit_port_map) { + int dumped_port_cnt; boolean dump_comma = FALSE; + t_spice_model_port* cur_spice_model_port = NULL; + t_llist* spice_model_head = NULL; + t_llist* head = NULL; dumped_port_cnt = 0; - rec_dumped_port_cnt = 0; /* Check */ assert(NULL != cur_spice_model); @@ -742,72 +734,162 @@ int rec_dump_verilog_spice_model_global_ports(FILE* fp, __FILE__, __LINE__); } - for (iport = 0; iport < cur_spice_model->num_port; iport++) { - /* if this spice model requires customized netlist to be included, we do not go recursively */ - if (TRUE == recursive) { - /* GO recursively first, and meanwhile count the number of global ports */ - /* For the port that requires another spice_model, i.e., SRAM - * We need include any global port in that spice model - */ - if (NULL != cur_spice_model->ports[iport].spice_model) { - /* Check if we need to dump a comma */ - if (TRUE == dump_comma) { - fprintf(fp, ",\n"); - } - rec_dumped_port_cnt += - rec_dump_verilog_spice_model_global_ports(fp, cur_spice_model->ports[iport].spice_model, - dump_port_type, recursive); - /* Decide if we need a comma */ - if (0 < rec_dumped_port_cnt) { - dump_comma = TRUE; - } - /* Update counter */ - dumped_port_cnt += rec_dumped_port_cnt; - continue; - } - } - /* By pass non-global ports*/ - if (FALSE == cur_spice_model->ports[iport].is_global) { - continue; - } + rec_stats_spice_model_global_ports(cur_spice_model, + recursive, + &spice_model_head); + /* Traverse the linked list and dump the ports */ + head = spice_model_head; + while (head) { + /* Get the port to be dumped */ + cur_spice_model_port = (t_spice_model_port*)(head->dptr); /* We have some port to dump ! * Print a comment line */ - if (0 == dumped_port_cnt) { - fprintf(fp, "//----- BEGIN Global ports of SPICE_MODEL(%s) -----\n", - cur_spice_model->name); - } - /* Check if we need to dump a comma */ if (TRUE == dump_comma) { - fprintf(fp, ",\n"); + fprintf(fp, ", //----- Global port of SPICE_MODEL(%s) -----\n", + cur_spice_model->name); } if (TRUE == dump_port_type) { fprintf(fp, "%s [0:%d] %s", - verilog_convert_port_type_to_string(cur_spice_model->ports[iport].type), - cur_spice_model->ports[iport].size - 1, - cur_spice_model->ports[iport].prefix); + verilog_convert_port_type_to_string(cur_spice_model_port->type), + cur_spice_model_port->size - 1, + cur_spice_model_port->lib_name); } else { + /* Add explicit port mapping if required */ + if ((TRUE == require_explicit_port_map) + && (TRUE == cur_spice_model->dump_explicit_port_map)) { + fprintf(fp, ".%s(", + cur_spice_model_port->lib_name); + } fprintf(fp, "%s[0:%d]", - cur_spice_model->ports[iport].prefix, - cur_spice_model->ports[iport].size - 1); + cur_spice_model_port->lib_name, + cur_spice_model_port->size - 1); + if ((TRUE == require_explicit_port_map) + && (TRUE == cur_spice_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } } /* Decide if we need a comma */ dump_comma = TRUE; /* Update counter */ dumped_port_cnt++; + + /* Go to the next node */ + head = head->next; } - /* We have dumped some port! * Print another comment line */ if (0 < dumped_port_cnt) { fprintf(fp, "\n"); - fprintf(fp, "//----- END Global ports of SPICE_MODEL(%s)-----\n", + } + + /* Free linked list */ + head = spice_model_head; + while (head) { + head->dptr = NULL; + head = head->next; + } + free_llist(spice_model_head); + + return dumped_port_cnt; +} + + +/* Dump all the global ports that are stored in the linked list + * Return the number of ports that have been dumped + */ +int rec_dump_verilog_spice_model_global_ports(FILE* fp, + t_spice_model* cur_spice_model, + boolean dump_port_type, + boolean recursive, + boolean require_explicit_port_map) { + int dumped_port_cnt; + boolean dump_comma = FALSE; + t_spice_model_port* cur_spice_model_port = NULL; + t_llist* spice_model_head = NULL; + t_llist* head = NULL; + + dumped_port_cnt = 0; + + /* Check */ + assert(NULL != cur_spice_model); + if (0 < cur_spice_model->num_port) { + assert(NULL != cur_spice_model->ports); + } + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + } + + rec_stats_spice_model_global_ports(cur_spice_model, + recursive, + &spice_model_head); + + /* Traverse the linked list and dump the ports */ + head = spice_model_head; + if (NULL != head) { + fprintf(fp, "//----- Global port of SPICE_MODEL(%s) -----\n", cur_spice_model->name); } + while (head) { + /* Get the port to be dumped */ + cur_spice_model_port = (t_spice_model_port*)(head->dptr); + /* We have some port to dump ! + * Print a comment line + */ + /* Check if we need to dump a comma */ + if (TRUE == dump_comma) { + fprintf(fp, ",\n"); + } + if (TRUE == dump_port_type) { + fprintf(fp, "%s [0:%d] %s", + verilog_convert_port_type_to_string(cur_spice_model_port->type), + cur_spice_model_port->size - 1, + cur_spice_model_port->prefix); + } else { + /* Add explicit port mapping if required */ + if ((TRUE == require_explicit_port_map) + && (TRUE == cur_spice_model->dump_explicit_port_map)) { + fprintf(fp, ".%s(", + cur_spice_model_port->lib_name); + } + fprintf(fp, "%s[0:%d]", + cur_spice_model_port->prefix, + cur_spice_model_port->size - 1); + if ((TRUE == require_explicit_port_map) + && (TRUE == cur_spice_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } + } + /* Decide if we need a comma */ + dump_comma = TRUE; + /* Update counter */ + dumped_port_cnt++; + + /* Go to the next node */ + head = head->next; + } + + /* We have dumped some port! + * Print another comment line + */ + if (0 < dumped_port_cnt) { + fprintf(fp, "\n"); + } + + /* Free linked list */ + head = spice_model_head; + while (head) { + head->dptr = NULL; + head = head->next; + } + free_llist(spice_model_head); return dumped_port_cnt; } @@ -825,7 +907,7 @@ int dump_verilog_global_ports(FILE* fp, t_llist* head, __FILE__, __LINE__); } - fprintf(fp, "//----- BEGIN Global ports -----\n"); + /* fprintf(fp, "//----- BEGIN Global ports -----\n"); */ while(NULL != temp) { cur_global_port = (t_spice_model_port*)(temp->dptr); if (TRUE == dump_port_type) { @@ -840,15 +922,14 @@ int dump_verilog_global_ports(FILE* fp, t_llist* head, } /* if this is the tail, we do not dump a comma */ if (NULL != temp->next) { - fprintf(fp, ","); + fprintf(fp, ", //---- global port \n"); } - fprintf(fp, "\n"); /* Update counter */ dumped_port_cnt++; /* Go to the next */ temp = temp->next; } - fprintf(fp, "//----- END Global ports -----\n"); + /* fprintf(fp, "//----- END Global ports -----\n"); */ return dumped_port_cnt; } @@ -887,9 +968,11 @@ void dump_verilog_mux_sram_one_outport(FILE* fp, case SPICE_SRAM_SCAN_CHAIN: if (0 == port_type_index) { port_name = "out"; - } else { - assert(1 == port_type_index); + } else if (1 == port_type_index) { port_name = "outb"; + } else { + assert(-1 == port_type_index); + port_name = "in"; } break; case SPICE_SRAM_MEMORY_BANK: @@ -927,6 +1010,151 @@ void dump_verilog_mux_sram_one_outport(FILE* fp, return; } +/* Always dump the output ports of a SRAM in MUX */ +void dump_verilog_mux_sram_one_local_outport(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mux_spice_model, int mux_size, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type) { + t_spice_model* mem_model = NULL; + char* port_name = NULL; + char* port_full_name = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get memory_model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + /* Keep the branch as it is, in case thing may become more complicated*/ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + if (0 == port_type_index) { + port_name = "out_local_bus"; + } else { + assert(1 == port_type_index); + port_name = "outb_local_bus"; + } + break; + case SPICE_SRAM_SCAN_CHAIN: + if (0 == port_type_index) { + port_name = "out_local_bus"; + } else if (1 == port_type_index) { + port_name = "outb_local_bus"; + } else { + assert(-1 == port_type_index); + port_name = "in_local_bus"; + } + break; + case SPICE_SRAM_MEMORY_BANK: + if (0 == port_type_index) { + port_name = "out_local_bus"; + } else { + assert(1 == port_type_index); + port_name = "outb_local_bus"; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } + + /*Malloc and generate the full name of port */ + port_full_name = (char*)my_malloc(sizeof(char)* + (strlen(cur_mux_spice_model->prefix) + 5 + + strlen(my_itoa(mux_size)) + 1 + + strlen(my_itoa(cur_mux_spice_model->cnt)) + 1 + + strlen(mem_model->prefix) + 1 + + strlen(port_name) + 1)); + sprintf(port_full_name, "%s_size%d_%d_%s_%s", + cur_mux_spice_model->prefix, mux_size, + cur_mux_spice_model->cnt, + mem_model->prefix, port_name); + + dump_verilog_generic_port(fp, dump_port_type, port_full_name, sram_lsb, sram_msb); + + /* Free */ + /* Local variables such as port1_name and port2 name are automatically freed */ + my_free(port_full_name); + + return; +} + + +/* Always dump the output ports of a SRAM */ +void dump_verilog_sram_one_local_outport(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type) { + t_spice_model* mem_model = NULL; + char* port_name = NULL; + char* port_full_name = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get memory_model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + /* Keep the branch as it is, in case thing may become more complicated*/ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + if (0 == port_type_index) { + port_name = "out_local_bus"; + } else { + assert(1 == port_type_index); + port_name = "outb_local_bus"; + } + break; + case SPICE_SRAM_SCAN_CHAIN: + if (0 == port_type_index) { + port_name = "scff_out_local_bus"; + } else if (1 == port_type_index) { + port_name = "scff_outb_local_bus"; + } else { + assert(-1 == port_type_index); + port_name = "scff_in_local_bus"; + } + break; + case SPICE_SRAM_MEMORY_BANK: + if (0 == port_type_index) { + port_name = "out_local_bus"; + } else { + assert(1 == port_type_index); + port_name = "outb_local_bus"; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } + + /*Malloc and generate the full name of port */ + port_full_name = (char*)my_malloc(sizeof(char)*(strlen(mem_model->prefix) + strlen(port_name) + 1 + 1)); + sprintf(port_full_name, "%s_%s", mem_model->prefix, port_name); + + dump_verilog_generic_port(fp, dump_port_type, port_full_name, sram_lsb, sram_msb); + + /* Free */ + /* Local variables such as port1_name and port2 name are automatically freed */ + my_free(port_full_name); + + return; +} + + /* Always dump the output ports of a SRAM */ void dump_verilog_sram_one_outport(FILE* fp, @@ -961,9 +1189,11 @@ void dump_verilog_sram_one_outport(FILE* fp, case SPICE_SRAM_SCAN_CHAIN: if (0 == port_type_index) { port_name = "scff_out"; - } else { - assert(1 == port_type_index); + } else if (1 == port_type_index) { port_name = "scff_outb"; + } else { + assert(-1 == port_type_index); + port_name = "scff_in"; } break; case SPICE_SRAM_MEMORY_BANK: @@ -1028,6 +1258,59 @@ void dump_verilog_sram_outports(FILE* fp, return; } +/* Dump SRAM ports visible for formal verification purpose, + * which is supposed to be the last port in the port list */ +void dump_verilog_formal_verification_sram_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type) { + t_spice_model* mem_model = NULL; + char* port_name = NULL; + char* port_full_name = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + /* Get memory_model */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + mem_model = cur_sram_orgz_info->standalone_sram_info->mem_model; + port_name = "out_fm"; + break; + case SPICE_SRAM_SCAN_CHAIN: + mem_model = cur_sram_orgz_info->scff_info->mem_model; + port_name = "out_fm"; + break; + case SPICE_SRAM_MEMORY_BANK: + mem_model = cur_sram_orgz_info->mem_bank_info->mem_model; + port_name = "out_fm"; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } + + /*Malloc and generate the full name of port */ + port_full_name = (char*)my_malloc(sizeof(char)*(strlen(mem_model->prefix) + strlen(port_name) + 1 + 1)); + sprintf(port_full_name, "%s_%s", mem_model->prefix, port_name); + + dump_verilog_generic_port(fp, dump_port_type, port_full_name, sram_lsb, sram_msb); + + /* Free */ + /* Local variables such as port1_name and port2 name are automatically freed */ + my_free(port_full_name); + + return; +} + + void dump_verilog_sram_one_port(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, int sram_lsb, int sram_msb, @@ -1061,10 +1344,10 @@ void dump_verilog_sram_one_port(FILE* fp, case SPICE_SRAM_SCAN_CHAIN: mem_model = cur_sram_orgz_info->scff_info->mem_model; if (0 == port_type_index) { - port_name = "scff_in"; - } else { + port_name = "scff_head"; + } else if (1 == port_type_index) { assert(1 == port_type_index); - port_name = "scff_out"; + port_name = "scff_tail"; /* Special case: scan-chain ff output should be an output always */ if (VERILOG_PORT_INPUT == dump_port_type) { actual_dump_port_type = VERILOG_PORT_OUTPUT; @@ -1103,6 +1386,128 @@ void dump_verilog_sram_one_port(FILE* fp, return; } +/* Wire SRAM ports in formal verififcation purpose to regular SRAM ports */ +void dump_verilog_formal_verification_sram_ports_wiring(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb) { + fprintf(fp, "assign "); + + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 0, VERILOG_PORT_CONKT); + + fprintf(fp, " = "); + + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + + return; +} + +/* Wire SRAM ports in formal verififcation purpose to regular SRAM ports */ +void dump_verilog_formal_verification_mux_sram_ports_wiring(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mux_spice_model, int mux_size, + int sram_lsb, int sram_msb) { + fprintf(fp, "assign "); + + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + cur_mux_spice_model, mux_size, + sram_lsb, sram_msb, + 0, VERILOG_PORT_CONKT); + + fprintf(fp, " = "); + + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + + return; +} + +/* Dump SRAM ports, which is supposed to be the last port in the port list */ +void dump_verilog_sram_local_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type) { + /* Need to dump inverted BL/WL if needed */ + int num_blb_ports, num_wlb_ports; + t_spice_model_port** blb_port = NULL; + t_spice_model_port** wlb_port = NULL; + t_spice_model* cur_sram_verilog_model = NULL; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + if (0 > (sram_msb - sram_lsb)) { + return; + } + + if ((sram_lsb < 0)||(sram_msb < 0)) { + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid sram_lsb(%d) and sram_msb(%d)!\n", + __FILE__, __LINE__, sram_lsb, sram_msb); + return; + } + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_MEMORY_BANK: + /* Dump the first port: SRAM_out of CMOS MUX or BL of RRAM MUX */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 0, dump_port_type); + fprintf(fp, ",\n"); + /* Dump the first port: SRAM_outb of CMOS MUX or WL of RRAM MUX */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 1, dump_port_type); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* Dump the first port: SRAM_out of CMOS MUX or BL of RRAM MUX */ + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + sram_lsb, sram_lsb, + -1, dump_port_type); + fprintf(fp, ",\n"); + /* Dump the first port: SRAM_outb of CMOS MUX or WL of RRAM MUX */ + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + sram_msb, sram_msb, + 0, dump_port_type); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } + + /* Find the BLB and WLB port, if there is any */ + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_sram_verilog_model); + find_blb_wlb_ports_spice_model(cur_sram_verilog_model, + &num_blb_ports, &blb_port, &num_wlb_ports, &wlb_port); + /* BL inverted port */ + if (1 == num_blb_ports) { + fprintf(fp, ",\n"); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 2, dump_port_type); + } + /* WL inverted port */ + if (1 == num_wlb_ports) { + fprintf(fp, ",\n"); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 3, dump_port_type); + } + + return; +} + + /* Dump SRAM ports, which is supposed to be the last port in the port list */ void dump_verilog_sram_ports(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, @@ -1130,16 +1535,35 @@ void dump_verilog_sram_ports(FILE* fp, __FILE__, __LINE__, sram_lsb, sram_msb); return; } - - /* Dump the first port: SRAM_out of CMOS MUX or BL of RRAM MUX */ - dump_verilog_sram_one_port(fp, cur_sram_orgz_info, - sram_lsb, sram_msb, - 0, dump_port_type); - fprintf(fp, ",\n"); - /* Dump the first port: SRAM_outb of CMOS MUX or WL of RRAM MUX */ - dump_verilog_sram_one_port(fp, cur_sram_orgz_info, - sram_lsb, sram_msb, - 1, dump_port_type); + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_MEMORY_BANK: + /* Dump the first port: SRAM_out of CMOS MUX or BL of RRAM MUX */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 0, dump_port_type); + fprintf(fp, ",\n"); + /* Dump the first port: SRAM_outb of CMOS MUX or WL of RRAM MUX */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_msb, + 1, dump_port_type); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* Dump the first port: SRAM_out of CMOS MUX or BL of RRAM MUX */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_lsb, sram_lsb, + 0, dump_port_type); + fprintf(fp, ",\n"); + /* Dump the first port: SRAM_outb of CMOS MUX or WL of RRAM MUX */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + sram_msb, sram_msb, + 1, dump_port_type); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization !\n", + __FILE__, __LINE__); + exit(1); + } /* Find the BLB and WLB port, if there is any */ get_sram_orgz_info_mem_model(cur_sram_orgz_info, &cur_sram_verilog_model); @@ -1248,6 +1672,7 @@ void dump_verilog_reserved_sram_ports(FILE* fp, return; } + /* Dump a verilog submodule of SRAMs in MUX, according to SRAM organization type */ void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, t_spice_model* cur_mux_verilog_model, int mux_size, @@ -1305,7 +1730,7 @@ void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_i fprintf(fp, "%s %s_%d_ (", cur_sram_verilog_model->name, cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, @@ -1358,7 +1783,7 @@ void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_i fprintf(fp, "%s %s_%d_ (", cur_sram_verilog_model->name, cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "%s_out[%d], ", cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Input*/ @@ -1375,7 +1800,7 @@ void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_i fprintf(fp, "%s %s_%d_ (", cur_sram_verilog_model->name, cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } /* Input of Scan-chain DFF, should be connected to the output of its precedent */ @@ -1471,7 +1896,7 @@ void dump_verilog_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, fprintf(fp, "%s %s_%d_ (", cur_sram_verilog_model->name, cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "%s_out[%d], ", cur_sram_verilog_model->prefix, cur_num_sram); /* Input*/ @@ -1511,7 +1936,7 @@ void dump_verilog_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, fprintf(fp, "%s %s_%d_ (", cur_sram_verilog_model->name, cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } fprintf(fp, "%s_out[%d], ", cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Input*/ @@ -1528,7 +1953,7 @@ void dump_verilog_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, fprintf(fp, "%s %s_%d_ (", cur_sram_verilog_model->name, cur_sram_verilog_model->prefix, cur_sram_verilog_model->cnt); /* Only dump the global ports belonging to a spice_model */ - if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE)) { + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { fprintf(fp, ",\n"); } /* Input of Scan-chain DFF, should be connected to the output of its precedent */ @@ -1625,14 +2050,40 @@ void dump_verilog_mem_config_bus(FILE* fp, t_spice_model* mem_spice_model, case SPICE_SRAM_STANDALONE: break; case SPICE_SRAM_SCAN_CHAIN: - /* We do not need any configuration bus + /* We need to connect SCFF inputs and outputs in cacading * Scan-chain FF outputs are directly wired to SRAM inputs of MUXes - dump_verilog_scff_config_bus(fp, mem_spice_model, - cur_sram_orgz_info, - cur_num_sram, cur_num_sram + num_mem_conf_bits - 1, - VERILOG_PORT_WIRE); + */ + /* Connect first SCFF to the head */ + /* + fprintf(fp, "assign "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, cur_num_sram, cur_num_sram, -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, cur_num_sram, cur_num_sram, 0, VERILOG_PORT_CONKT); fprintf(fp, ";\n"); */ + /* Connect last SCFF to the tail */ + /* + fprintf(fp, "assign "); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, cur_num_sram + num_mem_conf_bits - 1, cur_num_sram + num_mem_conf_bits - 1, 1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, cur_num_sram + num_mem_conf_bits - 1, cur_num_sram + num_mem_conf_bits - 1, 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + */ + /* Connect SCFFs into chains */ + /* Cascade the SCFF between head and tail */ + /* + if (1 < num_mem_conf_bits) { + fprintf(fp, "assign "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram + 1, cur_num_sram + num_mem_conf_bits - 1, + -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram + num_mem_conf_bits - 2, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + } + */ break; case SPICE_SRAM_MEMORY_BANK: /* Find the BLB and WLB port, if there is any */ @@ -1762,11 +2213,65 @@ void dump_verilog_cmos_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, /* We do not need any configuration bus * Scan-chain FF outputs are directly wired to SRAM inputs of MUXes */ + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram, cur_num_sram + num_mux_conf_bits - 1, + -1, VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram, cur_num_sram + num_mux_conf_bits - 1, + 0, VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, mux_spice_model, mux_size, cur_num_sram, cur_num_sram + num_mux_conf_bits - 1, 1, VERILOG_PORT_WIRE); fprintf(fp, ";\n"); + /* We need to connect SCFF inputs and outputs in cacading + * Scan-chain FF outputs are directly wired to SRAM inputs of MUXes + */ + /* Connect first SCFF to the head */ + fprintf(fp, "assign "); + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram, cur_num_sram, + -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram, cur_num_sram, + -1, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + /* Connect last SCFF to the tail */ + fprintf(fp, "assign "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + cur_num_sram + num_mux_conf_bits - 1, cur_num_sram + num_mux_conf_bits - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram + num_mux_conf_bits - 1, cur_num_sram + num_mux_conf_bits - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + /* Connect SCFFs into chains */ + /* Connect the first SCFF (LSB) to the head */ + /* Connect the last SCFF (MSB) to the tail */ + /* Cascade the SCFF between head and tail */ + if (1 < num_mux_conf_bits) { + fprintf(fp, "assign "); + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram + 1, cur_num_sram + num_mux_conf_bits - 1, + -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram, cur_num_sram + num_mux_conf_bits - 2, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + } break; case SPICE_SRAM_MEMORY_BANK: /* configuration wire bus */ @@ -1957,9 +2462,10 @@ void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_m /* FOR Scan-chain, we need regular output of a scan-chain FF * We do not need a prefix implying MUX name, size and index */ - dump_verilog_sram_one_port(fp, cur_sram_orgz_info, - cur_num_sram, cur_num_sram + num_mux_conf_bits - 1, - 1, VERILOG_PORT_CONKT); + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + mux_spice_model, mux_size, + cur_num_sram, cur_num_sram + num_mux_conf_bits - 1, + 0, VERILOG_PORT_CONKT); fprintf(fp, ",\n"); dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, mux_spice_model, mux_size, @@ -2055,7 +2561,7 @@ void dump_verilog_grid_common_port(FILE* fp, t_spice_model* cur_verilog_model, } assert(NULL != cur_verilog_model); - if (0 > msb- lsb) { + if (0 > msb - lsb) { return; } @@ -2098,8 +2604,38 @@ void dump_verilog_sram_config_bus_internal_wires(FILE* fp, t_sram_orgz_info* cur case SPICE_SRAM_STANDALONE: break; case SPICE_SRAM_SCAN_CHAIN: - dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, lsb, msb, 1, VERILOG_PORT_WIRE); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, lsb, msb, -1, VERILOG_PORT_WIRE); fprintf(fp, ";\n"); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, lsb, msb, 0, VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, lsb, msb, 1, VERILOG_PORT_WIRE); + fprintf(fp, ";\n"); + /* Connect first SCFF to the head */ + fprintf(fp, "assign "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, lsb, lsb, -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, lsb, lsb, 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + /* Connect last SCFF to the tail */ + fprintf(fp, "assign "); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, msb, msb, 1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, msb, msb, 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + /* Connect SCFFs into chains */ + /* Cascade the SCFF between head and tail */ + if (1 < msb - lsb) { + fprintf(fp, "assign "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + lsb + 1, msb, + -1, VERILOG_PORT_CONKT); + fprintf(fp, " = "); + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + lsb, msb - 1, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ";\n"); + } + break; case SPICE_SRAM_MEMORY_BANK: dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, lsb, msb, 0, VERILOG_PORT_WIRE); @@ -2176,3 +2712,727 @@ void dump_verilog_toplevel_one_grid_side_pin_with_given_index(FILE* fp, t_rr_typ return; } +/* Generate the subckt name for a MUX module/submodule */ +char* generate_verilog_subckt_name(t_spice_model* spice_model, + char* postfix) { + char* subckt_name = NULL; + + subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model->name) + + strlen(postfix) + 1)); + sprintf(subckt_name, "%s%s", + spice_model->name, postfix); + + return subckt_name; +} + +/* Generate the subckt name for a MUX module/submodule */ +char* generate_verilog_mem_subckt_name(t_spice_model* spice_model, + t_spice_model* mem_model, + char* postfix) { + char* subckt_name = NULL; + + subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model->name) + + strlen(mem_model->name) + 1 + strlen(postfix) + 1)); + sprintf(subckt_name, "%s_%s%s", + spice_model->name, mem_model->name, postfix); + + return subckt_name; +} + + +/* Generate the subckt name for a MUX module/submodule */ +char* generate_verilog_mux_subckt_name(t_spice_model* spice_model, + int mux_size, char* postfix) { + char* mux_subckt_name = NULL; + + mux_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model->name) + 5 + + strlen(my_itoa(mux_size)) + strlen(postfix) + 1)); + sprintf(mux_subckt_name, "%s_size%d%s", + spice_model->name, mux_size, postfix); + + return mux_subckt_name; +} + +enum e_dump_verilog_port_type +convert_spice_model_port_type_to_verilog_port_type(enum e_spice_model_port_type spice_model_port_type) { + enum e_dump_verilog_port_type verilog_port_type; + + switch (spice_model_port_type) { + case SPICE_MODEL_PORT_INPUT: + verilog_port_type = VERILOG_PORT_INPUT; + break; + case SPICE_MODEL_PORT_OUTPUT: + verilog_port_type = VERILOG_PORT_OUTPUT; + break; + case SPICE_MODEL_PORT_INOUT: + verilog_port_type = VERILOG_PORT_INOUT; + break; + case SPICE_MODEL_PORT_CLOCK: + case SPICE_MODEL_PORT_SRAM: + case SPICE_MODEL_PORT_BL: + case SPICE_MODEL_PORT_BLB: + case SPICE_MODEL_PORT_WL: + case SPICE_MODEL_PORT_WLB: + verilog_port_type = VERILOG_PORT_INPUT; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of Verilog port to be dumped !\n", + __FILE__, __LINE__); + exit(1); + } + + return verilog_port_type; +} + +int dump_verilog_mem_module_one_port_map(FILE* fp, + t_spice_model* mem_model, + enum e_spice_model_port_type port_type_to_dump, + boolean dump_port_type, + int index, int num_mem, boolean dump_first_comma, + boolean require_explicit_port_map) { + int iport; + int cnt = 0; + enum e_dump_verilog_port_type verilog_port_type; + int lsb = 0; + + for (iport = 0; iport < mem_model->num_port; iport++) { + /* bypass global ports */ + if (TRUE == mem_model->ports[iport].is_global) { + continue; + } + /* bypass non-input ports */ + if (port_type_to_dump != mem_model->ports[iport].type) { + continue; + } + if (((0 == cnt) && (TRUE == dump_first_comma)) + || (0 < cnt)) { + fprintf(fp, ",\n"); + } + if (TRUE == dump_port_type) { + verilog_port_type = convert_spice_model_port_type_to_verilog_port_type(port_type_to_dump); + } else { + assert (FALSE == dump_port_type); + verilog_port_type = VERILOG_PORT_CONKT; + /* Dump explicit port mapping if needed */ + if ( (TRUE == require_explicit_port_map) + && (TRUE == mem_model->dump_explicit_port_map)) { + fprintf(fp, " .%s(", mem_model->ports[iport].lib_name); + } + } + /* The LSB depends on the port size */ + assert (-1 < index); + lsb = index * mem_model->ports[iport].size; + dump_verilog_generic_port(fp, verilog_port_type, + mem_model->ports[iport].prefix, lsb, lsb + num_mem * mem_model->ports[iport].size - 1); + if ( (FALSE == dump_port_type) + && (TRUE == require_explicit_port_map) + &&(TRUE == mem_model->dump_explicit_port_map)) { + fprintf(fp, ")"); + } + cnt++; + } + + return cnt; +} + +/* Output the ports of a SRAM MUX */ +void dump_verilog_mem_module_port_map(FILE* fp, + t_spice_model* mem_model, + boolean dump_port_type, + int lsb, int num_mem, + boolean require_explicit_port_map) { + boolean dump_first_comma = FALSE; + /* Here we force the sequence of ports: of a memory subumodule: + * 1. Global ports + * 2. input ports + * 3. output ports + * 4. bl ports + * 5. wl ports + * 6. blb ports + * 7. wlb ports + * Other ports are not accepted!!! + */ + /* 1. Global ports! */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, mem_model, dump_port_type, TRUE, require_explicit_port_map)) { + dump_first_comma = TRUE; + } + + /* 2. input ports */ + if (0 < dump_verilog_mem_module_one_port_map(fp, mem_model, SPICE_MODEL_PORT_INPUT, + dump_port_type, lsb, num_mem, dump_first_comma, + require_explicit_port_map)) { + dump_first_comma = TRUE; + } else { + dump_first_comma = FALSE; + } + + /* 3. output ports */ + if (0 < dump_verilog_mem_module_one_port_map(fp, mem_model, SPICE_MODEL_PORT_OUTPUT, + dump_port_type, lsb, num_mem, dump_first_comma, + require_explicit_port_map)) { + dump_first_comma = TRUE; + } else { + dump_first_comma = FALSE; + } + + /* 4. bl ports */ + if (0 < dump_verilog_mem_module_one_port_map(fp, mem_model, SPICE_MODEL_PORT_BL, + dump_port_type, lsb, num_mem, dump_first_comma, + require_explicit_port_map)) { + dump_first_comma = TRUE; + } else { + dump_first_comma = FALSE; + } + + /* 5. wl ports */ + if (0 < dump_verilog_mem_module_one_port_map(fp, mem_model, SPICE_MODEL_PORT_WL, + dump_port_type, lsb, num_mem, dump_first_comma, + require_explicit_port_map)) { + dump_first_comma = TRUE; + } else { + dump_first_comma = FALSE; + } + + /* 6. blb ports */ + if (0 < dump_verilog_mem_module_one_port_map(fp, mem_model, SPICE_MODEL_PORT_BLB, + dump_port_type, lsb, num_mem, dump_first_comma, + require_explicit_port_map)) { + dump_first_comma = TRUE; + } else { + dump_first_comma = FALSE; + } + + /* 7. wlb ports */ + if (0 < dump_verilog_mem_module_one_port_map(fp, mem_model, SPICE_MODEL_PORT_WLB, + dump_port_type, lsb, num_mem, dump_first_comma, + require_explicit_port_map)) { + dump_first_comma = TRUE; + } else { + dump_first_comma = FALSE; + } + + return; +} + +/* Dump a verilog submodule in the mem submodule (part of MUX, LUT and other ), according to SRAM organization type */ +void dump_verilog_mem_sram_submodule(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_verilog_model, int mux_size, + t_spice_model* cur_sram_verilog_model, + int lsb, int msb) { + int cur_bl, cur_wl; + int num_bl_ports, num_wl_ports; + t_spice_model_port** bl_port = NULL; + t_spice_model_port** wl_port = NULL; + int num_blb_ports, num_wlb_ports; + t_spice_model_port** blb_port = NULL; + t_spice_model_port** wlb_port = NULL; + + int num_bl_per_sram = 0; + int num_wl_per_sram = 0; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + exit(1); + } + + assert(NULL != cur_sram_orgz_info); + assert(NULL != cur_sram_verilog_model); + assert((SPICE_MODEL_SRAM == cur_sram_verilog_model->type) + || (SPICE_MODEL_SCFF == cur_sram_verilog_model->type)); + + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_MEMORY_BANK: + /* Detect the SRAM SPICE model linked to this SRAM port */ + find_bl_wl_ports_spice_model(cur_sram_verilog_model, + &num_bl_ports, &bl_port, &num_wl_ports, &wl_port); + assert(1 == num_bl_ports); + assert(1 == num_wl_ports); + num_bl_per_sram = bl_port[0]->size; + num_wl_per_sram = wl_port[0]->size; + /* Find the BLB and WLB port, if there is any */ + find_blb_wlb_ports_spice_model(cur_sram_verilog_model, + &num_blb_ports, &blb_port, &num_wlb_ports, &wlb_port); + if (1 == num_blb_ports) { + assert(num_bl_per_sram == blb_port[0]->size); + } else { + assert(0 == num_blb_ports); + } + if (1 == num_wlb_ports) { + assert(num_wl_per_sram == wlb_port[0]->size); + } else { + assert(0 == num_wlb_ports); + } + + /* Only dump the global ports belonging to a spice_model */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { + fprintf(fp, ",\n"); + } + + if (SPICE_MODEL_MUX == cur_verilog_model->type) { + fprintf(fp, "%s_size%d_%d_", + cur_verilog_model->name, mux_size, cur_verilog_model->cnt); + } + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + lsb, msb, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ","); + if (SPICE_MODEL_MUX == cur_verilog_model->type) { + fprintf(fp, "%s_size%d_%d_", + cur_verilog_model->name, mux_size, cur_verilog_model->cnt); + } + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + lsb, msb, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ","); + if (SPICE_MODEL_MUX == cur_verilog_model->type) { + fprintf(fp, "%s_size%d_%d_", + cur_verilog_model->name, mux_size, cur_verilog_model->cnt); + } + dump_verilog_sram_one_outport(fp, cur_sram_orgz_info, + lsb, msb, + 1, VERILOG_PORT_CONKT); + fprintf(fp, ","); + get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl); + /* Connect to Bit lines and Word lines, consider each conf_bit */ + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + lsb, msb, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ","); + + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + lsb, msb, + 1, VERILOG_PORT_CONKT); + /* If we have a BLB or WLB, we need to dump inverted config_bus */ + if (1 == num_blb_ports) { + fprintf(fp, ", "); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + lsb, msb, + 2, VERILOG_PORT_CONKT); + } + if (1 == num_wlb_ports) { + fprintf(fp, ", "); + dump_verilog_sram_one_port(fp, cur_sram_orgz_info, + lsb, msb, + 3, VERILOG_PORT_CONKT); + } + + break; + case SPICE_SRAM_STANDALONE: + /* SRAM subckts*/ + /* Only dump the global ports belonging to a spice_model */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { + fprintf(fp, ",\n"); + } + fprintf(fp, "%s_out[%d:%d], ", + cur_sram_verilog_model->prefix, lsb, msb); /* Input*/ + fprintf(fp, "%s_out[%d:%d], %s_outb[%d:%d] ", + cur_sram_verilog_model->prefix, lsb, msb, + cur_sram_verilog_model->prefix, lsb, msb); /* Outputs */ + break; + case SPICE_SRAM_SCAN_CHAIN: + /* Only dump the global ports belonging to a spice_model */ + if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) { + fprintf(fp, ",\n"); + } + if (SPICE_MODEL_MUX == cur_verilog_model->type) { + /* Input of Scan-chain DFF, should be connected to the output of its precedent */ + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + cur_verilog_model, mux_size, + lsb, msb, + -1, VERILOG_PORT_CONKT); + fprintf(fp, ", \n"); // + /* Output of Scan-chain DFF, should be connected to the output of its successor */ + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + cur_verilog_model, mux_size, + lsb, msb, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ", \n"); // + dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info, + cur_verilog_model, mux_size, + lsb, msb, + 1, VERILOG_PORT_CONKT); + break; + } + /* Input of Scan-chain DFF, should be connected to the output of its precedent */ + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + lsb, msb, + -1, VERILOG_PORT_CONKT); + fprintf(fp, ", \n"); // + /* Output of Scan-chain DFF, should be connected to the output of its successor */ + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + lsb, msb, + 0, VERILOG_PORT_CONKT); + fprintf(fp, ", \n"); // + dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, + lsb, msb, + 1, VERILOG_PORT_CONKT); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid SRAM organization type!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +char* gen_verilog_grid_one_pin_name(int x, int y, + int height, int side, int pin_index, + boolean for_top_netlist) { + char* ret = NULL; + + /* This pin appear at this side! */ + if (TRUE == for_top_netlist) { + ret = (char*) my_malloc(sizeof(char) * + (5 + strlen(my_itoa(x)) + 2 + strlen(my_itoa(y)) + + 6 + strlen(my_itoa(height)) + + 2 + strlen(my_itoa(side)) + + 2 + strlen(my_itoa(pin_index)) + + 2 )); + sprintf(ret, "grid_%d__%d__pin_%d__%d__%d_", + x, y, + height, side, pin_index); + } else { + assert(FALSE == for_top_netlist); + ret = (char*) my_malloc(sizeof(char) * + (strlen(convert_side_index_to_string(side)) + + 8 + strlen(my_itoa(height)) + + 6 + strlen(my_itoa(pin_index)) + + 2 )); + sprintf(ret, "%s_height_%d__pin_%d_", + convert_side_index_to_string(side), height, pin_index); + } + + return ret; +} + +char* gen_verilog_routing_channel_one_pin_name(t_rr_node* chan_rr_node, + int x, int y, int track_idx, + enum PORTS pin_direction) { + + char* ret = NULL; + + ret = (char*)my_malloc(strlen(convert_chan_type_to_string(chan_rr_node->type)) + + 1 + strlen(my_itoa(x)) + + 2 + strlen(my_itoa(y)) + + 6 + strlen(my_itoa(track_idx)) + + 2 + 1); + + switch (pin_direction) { + case OUT_PORT: + sprintf(ret, "%s_%d__%d__out_%d_", + convert_chan_type_to_string(chan_rr_node->type), + x, y, track_idx); + break; + case IN_PORT: + sprintf(ret, "%s_%d__%d__in_%d_", + convert_chan_type_to_string(chan_rr_node->type), + x, y, track_idx); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid direction of chan_rr_node!\n", + __FILE__, __LINE__); + exit(1); + } + + return ret; +} + +char* gen_verilog_routing_channel_one_midout_name(t_cb* cur_cb_info, + int track_idx) { + char* ret = NULL; + + ret = (char*)my_malloc(strlen(convert_chan_type_to_string(cur_cb_info->type)) + + 1 + strlen(my_itoa(cur_cb_info->x)) + + 2 + strlen(my_itoa(cur_cb_info->y)) + + 9 + strlen(my_itoa(track_idx)) + + 1 + 1); + + sprintf(ret, "%s_%d__%d__midout_%d_", + convert_chan_type_to_string(cur_cb_info->type), + cur_cb_info->x, cur_cb_info->y, track_idx); + + return ret; +} + +char* gen_verilog_one_cb_module_name(t_cb* cur_cb_info) { + char* ret = NULL; + + ret = (char*)my_malloc(strlen(convert_cb_type_to_string(cur_cb_info->type)) + + 1 + strlen(my_itoa(cur_cb_info->x)) + + 2 + strlen(my_itoa(cur_cb_info->y)) + + 1 + 1); + + sprintf(ret, "%s_%d__%d_", + convert_cb_type_to_string(cur_cb_info->type), + cur_cb_info->x, cur_cb_info->y); + + return ret; +} + +char* gen_verilog_one_cb_instance_name(t_cb* cur_cb_info) { + char* ret = NULL; + + ret = (char*)my_malloc(strlen(convert_cb_type_to_string(cur_cb_info->type)) + + 1 + strlen(my_itoa(cur_cb_info->x)) + + 2 + strlen(my_itoa(cur_cb_info->y)) + + 4 + 1); + + sprintf(ret, "%s_%d__%d__0_", + convert_cb_type_to_string(cur_cb_info->type), + cur_cb_info->x, cur_cb_info->y); + + return ret; +} + +char* gen_verilog_one_sb_module_name(t_sb* cur_sb_info) { + char* ret = NULL; + + ret = (char*)my_malloc(2 + 1 + strlen(my_itoa(cur_sb_info->x)) + + 2 + strlen(my_itoa(cur_sb_info->y)) + + 1 + 1); + + sprintf(ret, "sb_%d__%d_", + cur_sb_info->x, cur_sb_info->y); + + return ret; +} + +char* gen_verilog_one_sb_instance_name(t_sb* cur_sb_info) { + char* ret = NULL; + + ret = (char*)my_malloc(2 + 1 + strlen(my_itoa(cur_sb_info->x)) + + 2 + strlen(my_itoa(cur_sb_info->y)) + + 4 + 1); + + sprintf(ret, "sb_%d__%d__0_", + cur_sb_info->x, cur_sb_info->y); + + return ret; +} + +char* gen_verilog_one_routing_channel_module_name(t_rr_type chan_type, + int x, int y) { + char* ret = NULL; + + ret = (char*)my_malloc(strlen(convert_chan_type_to_string(chan_type)) + + 1 + strlen(my_itoa(x)) + + 2 + strlen(my_itoa(y)) + + 1 + 1); + + sprintf(ret, "%s_%d__%d_", + convert_chan_type_to_string(chan_type), + x, y); + + return ret; +} + +char* gen_verilog_one_routing_channel_instance_name(t_rr_type chan_type, + int x, int y) { + char* ret = NULL; + + ret = (char*)my_malloc(strlen(convert_chan_type_to_string(chan_type)) + + 1 + strlen(my_itoa(x)) + + 2 + strlen(my_itoa(y)) + + 1 + 1); + + sprintf(ret, "%s_%d__%d__0_", + convert_chan_type_to_string(chan_type), + x, y); + + return ret; +} + +/* Generate the subckt name for a MUX module/submodule */ +char* gen_verilog_one_mux_module_name(t_spice_model* spice_model, + int mux_size) { + char* mux_subckt_name = NULL; + + mux_subckt_name = (char*)my_malloc(sizeof(char)*(strlen(spice_model->name) + 5 + + strlen(my_itoa(mux_size)) + 1)); + sprintf(mux_subckt_name, "%s_size%d", + spice_model->name, mux_size); + + return mux_subckt_name; +} + +/* Generate the full path of a pb_graph_pin in the hierarchy of verilog netlists + * For example: grid____/grid__/.../__ + */ +char* gen_verilog_one_grid_instance_name(int grid_x, int grid_y) { + char* ret = NULL; + + ret = (char*)my_malloc(sizeof(char) * + ( 5 + strlen(my_itoa(grid_x)) + + 2 + strlen(my_itoa(grid_y)) + + 1 + 1)); + + sprintf(ret, "grid_%d__%d_", + grid_x, grid_y); + + return ret; +} + +char* gen_verilog_one_grid_module_name(int grid_x, int grid_y) { + return gen_verilog_one_grid_instance_name(grid_x, grid_y); +} + +char* gen_verilog_one_block_instance_name(int grid_x, int grid_y, int grid_z) { + char* ret = NULL; + + ret = (char*)my_malloc(sizeof(char) * + ( 5 + strlen(my_itoa(grid_x)) + + 2 + strlen(my_itoa(grid_y)) + + 2 + strlen(my_itoa(grid_z)) + + 1 + 1)); + + sprintf(ret, "grid_%d__%d__%d_", + grid_x, grid_y, grid_z); + + return ret; +} + +char* gen_verilog_one_phy_block_instance_name(t_type_ptr cur_type_ptr, + int block_z) { + char* ret = NULL; + + ret = (char*)my_malloc(sizeof(char) * + ( 5 + strlen(cur_type_ptr->name) + + 1 + strlen(my_itoa(block_z)) + + 1 + 1)); + + sprintf(ret, "grid_%s_%d_", + cur_type_ptr->name, block_z); + + return ret; +} + +char* gen_verilog_one_pb_graph_node_instance_name(t_pb_graph_node* cur_pb_graph_node) { + char* ret = NULL; + + ret = (char*)my_malloc(sizeof(char) * + ( strlen(cur_pb_graph_node->pb_type->name) + + 1 + strlen(my_itoa(cur_pb_graph_node->placement_index)) + + 1 + 1)); + + sprintf(ret, "%s_%d_", + cur_pb_graph_node->pb_type->name, cur_pb_graph_node->placement_index); + + return ret; +} + +char* gen_verilog_one_pb_type_pin_name(char* prefix, + t_port* cur_port, int pin_number) { + char* ret = NULL; + + ret = (char*)my_malloc(sizeof(char) * + (strlen(prefix) + 2 + + strlen(cur_port->name) + + 1 + strlen(my_itoa(pin_number)) + + 1 + 1)); + + sprintf(ret, "%s__%s_%d_", + prefix, cur_port->name, pin_number); + + return ret; +} + +/* Generate the full path of a pb_graph_pin in the hierarchy of verilog netlists + * For example: grid____/grid__/.../__ + */ +char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy(t_pb_graph_pin* cur_pb_graph_pin) { + char* full_name = NULL; + char* cur_name = NULL; + t_pb_graph_node* temp = cur_pb_graph_pin->parent_node; + + /* Give the pin name */ + full_name = gen_verilog_one_pb_type_pin_name(cur_pb_graph_pin->parent_node->pb_type->name, + cur_pb_graph_pin->port, + cur_pb_graph_pin->pin_number); + + /* The instance name of the top-level graph node is very special + * we output it in another function + */ + while (NULL != temp->parent_pb_graph_node) { + /* Generate the instance name of current pb_graph_node + * and add a slash to separate the upper level + */ + cur_name = gen_verilog_one_pb_graph_node_instance_name(temp); + cur_name = my_strcat(cur_name, "/"); + full_name = my_strcat(cur_name, full_name); + /* Go to upper level */ + temp = temp->parent_pb_graph_node; + my_free(cur_name); + } + + return full_name; +} + +char* gen_verilog_top_module_io_port_prefix(char* global_prefix, + char* io_port_prefix) { + char* port_name = NULL; + + port_name = (char*)my_malloc(sizeof(char)*(strlen(global_prefix) + strlen(io_port_prefix) + 1)); + sprintf(port_name, "%s%s", global_prefix, io_port_prefix); + + return port_name; +} + +char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(t_pb_graph_pin* cur_pb_graph_pin) { + char* full_name = NULL; + char* cur_name = NULL; + t_pb_graph_node* temp = cur_pb_graph_pin->parent_node; + //t_pb_graph_node* temp = cur_pb_graph_pin->parent_node->parent_pb_graph_node; + + full_name = ""; + /* The instance name of the top-level graph node is very special + * we output it in another function + */ + while (NULL != temp->parent_pb_graph_node) { + /* Generate the instance name of current pb_graph_node + * and add a slash to separate the upper level + */ + cur_name = gen_verilog_one_pb_graph_node_instance_name(temp); + cur_name = my_strcat(cur_name, "/"); + full_name = my_strcat(cur_name, full_name); + /* Go to upper level */ + temp = temp->parent_pb_graph_node; + my_free(cur_name); + } + + return full_name; +} + +char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_grand_parent_node(t_pb_graph_pin* cur_pb_graph_pin) { + char* full_name = ""; + char* cur_name = NULL; + t_pb_graph_node* temp = cur_pb_graph_pin->parent_node; + + if (NULL != temp->parent_pb_graph_node) { + temp = temp->parent_pb_graph_node; + } + else { + return full_name; + } + + /* The instance name of the top-level graph node is very special + * we output it in another function + */ + while (NULL != temp->parent_pb_graph_node) { + /* Generate the instance name of current pb_graph_node + * and add a slash to separate the upper level + */ + cur_name = gen_verilog_one_pb_graph_node_instance_name(temp); + cur_name = my_strcat(cur_name, "/"); + full_name = my_strcat(cur_name, full_name); + /* Go to upper level */ + temp = temp->parent_pb_graph_node; + my_free(cur_name); + } + + return full_name; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h new file mode 100644 index 000000000..9c552cfb0 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_utils.h @@ -0,0 +1,282 @@ + + +void init_list_include_verilog_netlists(t_spice* spice); + +void init_include_user_defined_verilog_netlists(t_spice spice); + +void dump_include_user_defined_verilog_netlists(FILE* fp, + t_spice spice); + +void dump_verilog_file_header(FILE* fp, + char* usage); + +void dump_verilog_preproc(FILE* fp, + t_syn_verilog_opts fpga_verilog_opts, + enum e_verilog_tb_type verilog_tb_type); + +void dump_simulation_preproc(FILE* fp, + t_syn_verilog_opts fpga_verilog_opts, + enum e_verilog_tb_type verilog_tb_type); + +void dump_verilog_simulation_preproc(char* subckt_dir, + t_syn_verilog_opts fpga_verilog_opts); + +void dump_verilog_defines_preproc(char* subckt_dir, + t_syn_verilog_opts fpga_verilog_opts); + +void verilog_include_simulation_defines_file(FILE* fp, + char* formatted_verilog_dir); + +void verilog_include_defines_preproc_file(FILE* fp, + char* formatted_verilog_dir); + +FILE* verilog_create_one_subckt_file(char* subckt_dir, + char* subckt_name_prefix, + char* verilog_subckt_file_name_prefix, + int grid_x, int grid_y, + char** verilog_fname); + +void dump_verilog_subckt_header_file(t_llist* subckt_llist_head, + char* subckt_dir, + char* header_file_name); + +char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_generic_port(FILE* fp, + enum e_dump_verilog_port_type dump_port_type, + char* port_name, int port_lsb, int port_msb); + +void dump_verilog_generic_port_no_repeat(FILE* fp, + enum e_dump_verilog_port_type dump_port_type, + char* port_name, int port_lsb, int port_msb); + + +char* chomp_verilog_prefix(char* verilog_node_prefix); + +char* format_verilog_node_prefix(char* verilog_node_prefix); + +char* verilog_convert_port_type_to_string(enum e_spice_model_port_type port_type); + +int rec_dump_verilog_spice_model_lib_global_ports(FILE* fp, + t_spice_model* cur_spice_model, + boolean dump_port_type, + boolean recursive, + boolean require_explicit_port_map); + +int rec_dump_verilog_spice_model_global_ports(FILE* fp, + t_spice_model* cur_spice_model, + boolean dump_port_type, + boolean recursive, + boolean require_explicit_port_map); + +int dump_verilog_global_ports(FILE* fp, t_llist* head, + boolean dump_port_type); + +void dump_verilog_mux_sram_one_outport(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mux_spice_model, int mux_size, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_one_outport(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_mux_sram_one_local_outport(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mux_spice_model, int mux_size, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_one_local_outport(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_outports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_formal_verification_sram_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_one_port(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_local_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_ports(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_reserved_sram_one_port(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + int port_type_index, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_formal_verification_sram_ports_wiring(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb); + +void dump_verilog_formal_verification_mux_sram_ports_wiring(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mux_spice_model, int mux_size, + int sram_lsb, int sram_msb); + +void dump_verilog_reserved_sram_ports(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + int sram_lsb, int sram_msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_mux_verilog_model, int mux_size, + t_spice_model* cur_sram_verilog_model); + +void dump_verilog_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* sram_verilog_model); + +void dump_verilog_scff_config_bus(FILE* fp, + t_spice_model* mem_spice_model, + t_sram_orgz_info* cur_sram_orgz_info, + int lsb, int msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_mem_config_bus(FILE* fp, t_spice_model* mem_spice_model, + t_sram_orgz_info* cur_sram_orgz_info, + int cur_num_sram, + int num_mem_reserved_conf_bits, + int num_mem_conf_bits); + +void dump_verilog_cmos_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, + t_sram_orgz_info* cur_sram_orgz_info, + int mux_size, int cur_num_sram, + int num_mux_reserved_conf_bits, + int num_mux_conf_bits); + +void dump_verilog_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, + t_sram_orgz_info* cur_sram_orgz_info, + int mux_size, int cur_num_sram, + int num_mux_reserved_conf_bits, + int num_mux_conf_bits); + +void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_model, + t_sram_orgz_info* cur_sram_orgz_info, + int mux_size, int cur_num_sram, + int num_mux_reserved_conf_bits, + int num_mux_conf_bits); + +void dump_verilog_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_model, + t_sram_orgz_info* cur_sram_orgz_info, + int mux_size, int cur_num_sram, + int num_mux_reserved_conf_bits, + int num_mux_conf_bits); + +void dump_verilog_grid_common_port(FILE* fp, t_spice_model* cur_verilog_model, + char* general_port_prefix, int lsb, int msb, + enum e_dump_verilog_port_type dump_port_type); + +void dump_verilog_sram_config_bus_internal_wires(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, + int lsb, int msb); + +void dump_verilog_toplevel_one_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, + int pin_index, int side, + int x, int y, + boolean dump_port_type); + +char* generate_verilog_subckt_name(t_spice_model* spice_model, + char* postfix); + +char* generate_verilog_mem_subckt_name(t_spice_model* spice_model, + t_spice_model* mem_model, + char* postfix); + +char* generate_verilog_mux_subckt_name(t_spice_model* spice_model, + int mux_size, char* postfix); + +enum e_dump_verilog_port_type +convert_spice_model_port_type_to_verilog_port_type(enum e_spice_model_port_type spice_model_port_type); + +int dump_verilog_mem_module_one_port_map(FILE* fp, + t_spice_model* mem_model, + enum e_spice_model_port_type port_type_to_dump, + boolean dump_port_type, + int index, int num_mem, boolean dump_first_comma, + boolean require_explicit_port_map); + +void dump_verilog_mem_module_port_map(FILE* fp, + t_spice_model* mem_model, + boolean dump_port_type, + int lsb, int num_mem, + boolean require_explicit_port_map); + +void dump_verilog_mem_sram_submodule(FILE* fp, + t_sram_orgz_info* cur_sram_orgz_info, + t_spice_model* cur_verilog_model, int mux_size, + t_spice_model* cur_sram_verilog_model, + int lsb, int msb); + +char* gen_verilog_grid_one_pin_name(int x, int y, + int height, int side, int pin_index, + boolean for_top_netlist); + +char* gen_verilog_routing_channel_one_pin_name(t_rr_node* chan_rr_node, + int x, int y, int track_idx, + enum PORTS pin_direction); + +char* gen_verilog_routing_channel_one_midout_name(t_cb* cur_cb_info, + int track_idx); + +char* gen_verilog_one_cb_module_name(t_cb* cur_cb_info); + +char* gen_verilog_one_cb_instance_name(t_cb* cur_cb_info); + +char* gen_verilog_one_sb_module_name(t_sb* cur_sb_info); + +char* gen_verilog_one_sb_instance_name(t_sb* cur_sb_info); + + +char* gen_verilog_one_routing_channel_module_name(t_rr_type chan_type, + int x, int y); + +char* gen_verilog_one_routing_channel_instance_name(t_rr_type chan_type, + int x, int y); + +char* gen_verilog_one_mux_module_name(t_spice_model* spice_model, + int mux_size); + +char* gen_verilog_one_grid_instance_name(int grid_x, int grid_y); + +char* gen_verilog_one_grid_module_name(int grid_x, int grid_y); + +char* gen_verilog_one_block_instance_name(int grid_x, int grid_y, int grid_z); + +char* gen_verilog_one_phy_block_instance_name(t_type_ptr cur_type_ptr, + int block_z); + +char* gen_verilog_one_pb_graph_node_instance_name(t_pb_graph_node* cur_pb_graph_node); + +char* gen_verilog_one_pb_type_pin_name(char* prefix, + t_port* cur_port, int pin_number); + +char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy(t_pb_graph_pin* cur_pb_graph_pin); +char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(t_pb_graph_pin* cur_pb_graph_pin); +char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_grand_parent_node(t_pb_graph_pin* cur_pb_graph_pin); + +char* gen_verilog_top_module_io_port_prefix(char* global_prefix, + char* io_port_prefix); + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.c new file mode 100644 index 000000000..9cba681d0 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.c @@ -0,0 +1,440 @@ +/***********************************/ +/* SPICE Modeling for VPR */ +/* Xifan TANG, EPFL/LSI */ +/***********************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "route_common.h" + +/* Include SPICE support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_mux_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "fpga_x2p_bitstream_utils.h" +#include "spice_mux.h" +#include "fpga_x2p_globals.h" + +/* Include Synthesizable Verilog headers */ +#include "verilog_global.h" +#include "verilog_utils.h" +#include "verilog_primitives.h" +#include "verilog_pbtypes.h" +#include "verilog_top_netlist_utils.h" +#include "verilog_top_testbench.h" + +static +void dump_verilog_formal_verification_top_netlist_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* circuit_name) { + int iblock, cnt; + char* port_name = NULL; + + fprintf(fp, "module %s%s(\n", + circuit_name, + formal_verification_top_module_postfix); + + cnt = 0; + + /* Print all the I/Os of the circuit implementation to be tested*/ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* Make sure We find the correct logical block !*/ + switch (logical_block[iblock].type) { + case VPACK_INPAD: + if (0 != cnt) { + fprintf(fp, ",\n"); + } + port_name = my_strdup(logical_block[iblock].name); + dump_verilog_generic_port(fp, VERILOG_PORT_INPUT, + my_strcat(port_name, formal_verification_top_module_port_postfix), + 0, 0); + my_free(port_name); + cnt++; + break; + case VPACK_OUTPAD: + if (0 != cnt) { + fprintf(fp, ",\n"); + } + port_name = my_strdup(logical_block[iblock].name); + dump_verilog_generic_port(fp, VERILOG_PORT_OUTPUT, + my_strcat(port_name, formal_verification_top_module_port_postfix), + 0, 0); + my_free(port_name); + cnt++; + break; + case VPACK_COMB: + case VPACK_LATCH: + case VPACK_EMPTY: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d]) Invalid type of logical block[%d]!\n", + __FILE__, __LINE__, iblock); + exit(1); + } + } + + fprintf(fp, ");\n"); + + return; +} + +static +void dump_verilog_formal_verification_top_netlist_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* circuit_name) { + char* port_name = NULL; + int num_array_bl, num_array_wl; + int bl_decoder_size, wl_decoder_size; + t_spice_model* mem_model = NULL; + + get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model); + + /* Print internal wires */ + /* Connect to defined signals */ + /* set and reset signals */ + fprintf(fp, "\n"); + dump_verilog_top_testbench_global_ports(fp, global_ports_head, VERILOG_PORT_WIRE); + fprintf(fp, "\n"); + + /* Inputs and outputs of I/O pads */ + /* Inout Pads */ + assert(NULL != iopad_verilog_model); + if ((NULL == iopad_verilog_model) + ||(iopad_verilog_model->cnt > 0)) { + /* Malloc and assign port_name */ + port_name = (char*)my_malloc(sizeof(char)*(strlen(gio_inout_prefix) + strlen(iopad_verilog_model->prefix) + 1)); + sprintf(port_name, "%s%s", gio_inout_prefix, iopad_verilog_model->prefix); + /* Dump a wired port */ + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + port_name, iopad_verilog_model->cnt - 1, 0); + fprintf(fp, "; //--- FPGA iopads \n"); + /* Free port_name */ + my_free(port_name); + } + + /* Programming Circuits inputs */ + /* Configuration ports depend on the organization of SRAMs */ + switch(cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + sram_verilog_model->prefix, sram_verilog_model->cnt - 1, 0); + fprintf(fp, "; //---- SRAM outputs \n"); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* We put the head of scan-chains here + */ + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_scan_chain_head_prefix, 0, 0); + fprintf(fp, "; //---- Scan-chain head \n"); + break; + case SPICE_SRAM_MEMORY_BANK: + /* Get the number of array BLs/WLs, decoder sizes */ + determine_blwl_decoder_size(cur_sram_orgz_info, + &num_array_bl, &num_array_wl, &bl_decoder_size, &wl_decoder_size); + + fprintf(fp, " wire [0:0] %s;\n", + top_netlist_bl_enable_port_name + ); + fprintf(fp, " wire [0:0] %s;\n", + top_netlist_wl_enable_port_name + ); + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_addr_bl_port_name, bl_decoder_size - 1, 0); + fprintf(fp, "; //--- Address of bit lines \n"); + dump_verilog_generic_port(fp, VERILOG_PORT_WIRE, + top_netlist_addr_wl_port_name, wl_decoder_size - 1, 0); + fprintf(fp, "; //--- Address of word lines \n"); + /* data_in is only require by BL decoder of SRAM array + * As for RRAM array, the data_in signal will not be used + */ + if (SPICE_MODEL_DESIGN_CMOS == mem_model->design_tech) { + fprintf(fp, " wire [0:0] %s; // --- Data_in signal for BL decoder, only required by SRAM array \n", + top_netlist_bl_data_in_port_name); + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +static +void dump_verilog_formal_verfication_top_netlist_call_top_module(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + char* circuit_name) { + /* Include defined top-level module */ + fprintf(fp, "//----- FPGA top-level module to be capsulated ----\n"); + fprintf(fp, "//------Call defined Top-level Verilog Module -----\n"); + fprintf(fp, "%s_top %s (\n", + circuit_name, + formal_verification_top_module_uut_name); + + dump_verilog_top_module_ports(cur_sram_orgz_info, fp, VERILOG_PORT_CONKT); + + fprintf(fp, ");\n"); + return; +} + +/* Connect global ports of FPGA top module to constants except: + * 1. operating clock + */ +static +void dump_verilog_formal_verification_top_netlist_connect_global_ports(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_llist* head) { + t_llist* temp = head; + t_spice_model_port* cur_global_port = NULL; + int ibit, iblock; + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + } + + fprintf(fp, "//----- Connect Global ports of FPGA top module -----\n"); + while(NULL != temp) { + cur_global_port = (t_spice_model_port*)(temp->dptr); + if ((SPICE_MODEL_PORT_CLOCK == cur_global_port->type) + && (FALSE == cur_global_port->is_prog)) { + /* Wire this port to the clock of benchmark */ + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* By pass non-input ports !*/ + if (VPACK_INPAD != logical_block[iblock].type) { + continue; + } + /* See if this is a clock net */ + if (FALSE == logical_block[iblock].is_clock) { + continue; + } + /* Reach here we have found a clock! */ + for (ibit = 0; ibit < cur_global_port->size; ibit++) { + fprintf(fp, "assign "); + dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, + cur_global_port->prefix, ibit, ibit); + fprintf(fp, " = %s%s;\n", + logical_block[iblock].name, formal_verification_top_module_port_postfix); + } + } + } else { + fprintf(fp, "assign "); + dump_verilog_generic_port(fp, VERILOG_PORT_CONKT, + cur_global_port->prefix, 0, cur_global_port->size - 1); + fprintf(fp, " = %d'b", cur_global_port->size); + for (ibit = 0; ibit < cur_global_port->size; ibit++) { + fprintf(fp, "%d", cur_global_port->default_val); + } + fprintf(fp, ";\n"); + } + /* Go to the next */ + temp = temp->next; + } + fprintf(fp, "//----- END Global ports -----\n"); + + return; +} + +/* Add stimuli for unused iopads and configuration memories */ +static +void dump_verilog_formal_verification_top_netlist_connect_ios(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + int iblock, jiopad, iopad_idx; + boolean* used_iopad = (boolean*) my_calloc (iopad_verilog_model->cnt, sizeof(boolean)); + + /* Check the file handler*/ + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n", + __FILE__, __LINE__); + } + + /* Initialize */ + for (jiopad = 0; jiopad < iopad_verilog_model->cnt - 1; jiopad++) { + used_iopad[jiopad] = FALSE; + } + + /* See if this IO should be wired to a benchmark input/output */ + /* Add signals from blif benchmark and short-wire them to FPGA I/O PADs + * This brings convenience to checking functionality + */ + fprintf(fp, "//-----Link Blif Benchmark inputs to FPGA IOPADs -----\n"); + for (iblock = 0; iblock < num_logical_blocks; iblock++) { + /* General INOUT*/ + if (iopad_verilog_model == logical_block[iblock].mapped_spice_model) { + iopad_idx = logical_block[iblock].mapped_spice_model_index; + /* Make sure We find the correct logical block !*/ + assert((VPACK_INPAD == logical_block[iblock].type)||(VPACK_OUTPAD == logical_block[iblock].type)); + fprintf(fp, "//----- Blif Benchmark inout %s is mapped to FPGA IOPAD %s[%d] -----\n", + logical_block[iblock].name, gio_inout_prefix, iopad_idx); + fprintf(fp, "//----- name_tag: %s -----\n", + logical_block[iblock].pb->spice_name_tag); + if (VPACK_INPAD == logical_block[iblock].type) { + fprintf(fp, "assign %s%s[%d] = %s%s;\n", + gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx, + logical_block[iblock].name, formal_verification_top_module_port_postfix); + } + if (VPACK_OUTPAD == logical_block[iblock].type) { + fprintf(fp, "assign %s%s = %s%s[%d];\n", + logical_block[iblock].name, formal_verification_top_module_port_postfix, + gio_inout_prefix, iopad_verilog_model->prefix, iopad_idx); + } + /* Mark this iopad has been used! */ + used_iopad[iopad_idx] = TRUE; + } + } + + /* Wire the unused iopads to a constant */ + for (jiopad = 0; jiopad < iopad_verilog_model->cnt - 1; jiopad++) { + /* Bypass used iopads */ + if (TRUE == used_iopad[jiopad]) { + continue; + } + /* TODO: identify if this iopad is set to input or output by default + * and see if it should be driven by a constant + */ + /* Wire to a contant */ + fprintf(fp, "assign %s%s[%d] = 1'b%d;\n", + gio_inout_prefix, iopad_verilog_model->prefix, jiopad, + verilog_default_signal_init_value); + } + + return; +} + +/* Impose the bitstream on the configuration memories */ +static +void dump_verilog_formal_verification_top_netlist_config_bitstream(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp) { + t_llist* head = cur_sram_orgz_info->conf_bit_head; + t_llist* temp = head; + t_conf_bit_info* cur_conf_bit = NULL; + + fprintf(fp, "//----- BEGIN load bitstream to configuration memories -----\n"); + + /* traverse the bitstream and assign values to configuration memories output ports */ + while (NULL != temp) { + /* Get conf bits */ + cur_conf_bit = (t_conf_bit_info*) (temp->dptr); + /* Assign */ + fprintf(fp, "assign %s.", formal_verification_top_module_uut_name); + /* According to the type, we allocate structs */ + switch (cur_sram_orgz_info->type) { + case SPICE_SRAM_STANDALONE: + case SPICE_SRAM_SCAN_CHAIN: + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_conf_bit->index, cur_conf_bit->index, + VERILOG_PORT_CONKT); + fprintf(fp, " = 1'b%d", + cur_conf_bit->sram_bit->val); + break; + case SPICE_SRAM_MEMORY_BANK: + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_conf_bit->bl->addr, cur_conf_bit->bl->addr, + VERILOG_PORT_CONKT); + fprintf(fp, " = 1'b%d", + cur_conf_bit->bl->val); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, "(File:%s,[LINE%d])Invalid type of SRAM organization!", + __FILE__, __LINE__); + exit(1); + } + + fprintf(fp, ";\n"); + /* Go to the next */ + temp = temp->next; + } + + fprintf(fp, "//----- END load bitstream to configuration memories -----\n"); + + return; +} + +/* Add stimuli for unused iopads and configuration memories */ +static +void dump_verilog_formal_verification_top_netlist_initialization(t_sram_orgz_info* cur_sram_orgz_info, + FILE* fp, + t_syn_verilog_opts syn_verilog_opts, + t_spice verilog) { + /* Connect FPGA top module global ports to constant or benchmark global signals! */ + dump_verilog_formal_verification_top_netlist_connect_global_ports(cur_sram_orgz_info, + fp, global_ports_head); + + /* Connect I/Os to benchmark I/Os or constant driver */ + dump_verilog_formal_verification_top_netlist_connect_ios(cur_sram_orgz_info, + fp); + + /* Assign FPGA internal SRAM/Memory ports to bitstream values */ + dump_verilog_formal_verification_top_netlist_config_bitstream(cur_sram_orgz_info, + fp); + + return; +} + +/** Top level function 2: the top-level netlist for formal verification purpose + * This testbench includes a top-level module and initialization for all the configuration memories + */ +void dump_verilog_formal_verification_top_netlist(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts fpga_verilog_opts, + t_spice verilog) { + FILE* fp = NULL; + char* title = my_strcat("FPGA Verilog Top-level netlist in formal verification purpose of Design: ", circuit_name); + + /* Check if the path exists*/ + fp = fopen(top_netlist_name,"w"); + if (NULL == fp) { + vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create top Verilog testbench %s!",__FILE__, __LINE__, top_netlist_name); + exit(1); + } + + vpr_printf(TIO_MESSAGE_INFO, "Writing FPGA Top-level Verilog netlist in formal verification purpose for design %s...\n", circuit_name); + + /* Print the title */ + dump_verilog_file_header(fp, title); + my_free(title); + + /* Print preprocessing flags */ + verilog_include_defines_preproc_file(fp, verilog_dir_path); + + /* Start with module declaration */ + dump_verilog_formal_verification_top_netlist_ports(cur_sram_orgz_info, fp, circuit_name); + + /* Define internal wires */ + dump_verilog_formal_verification_top_netlist_internal_wires(cur_sram_orgz_info, fp, circuit_name); + + /* Call defined top-level module */ + dump_verilog_formal_verfication_top_netlist_call_top_module(cur_sram_orgz_info, fp, circuit_name); + + /* Add stimuli for reset, set, clock and iopad signals */ + dump_verilog_formal_verification_top_netlist_initialization(cur_sram_orgz_info, fp, fpga_verilog_opts, verilog); + + /* Testbench ends*/ + fprintf(fp, "endmodule\n"); + + /* Close the file*/ + fclose(fp); + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.h new file mode 100644 index 000000000..5e4f5d7ee --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_verification_top_netlist.h @@ -0,0 +1,9 @@ + +void dump_verilog_formal_verification_top_netlist(t_sram_orgz_info* cur_sram_orgz_info, + char* circuit_name, + char* top_netlist_name, + char* verilog_dir_path, + int num_clock, + t_syn_verilog_opts syn_verilog_opts, + t_spice verilog); + diff --git a/vpr7_x2p/vpr/SRC/main.c b/vpr7_x2p/vpr/SRC/main.c index 637f30ade..41165e2ea 100644 --- a/vpr7_x2p/vpr/SRC/main.c +++ b/vpr7_x2p/vpr/SRC/main.c @@ -17,9 +17,6 @@ #include #include "vpr_api.h" -/* mrFPGA : Xifan TANG */ -#include "mrfpga_api.h" -/* END */ /** * VPR program @@ -34,53 +31,54 @@ * 4. Clean up */ int main(int argc, char **argv) { - t_options Options; - t_arch Arch; - t_vpr_setup vpr_setup; - clock_t entire_flow_begin,entire_flow_end; + t_options Options; + t_arch Arch; + t_vpr_setup vpr_setup; + clock_t entire_flow_begin,entire_flow_end; - entire_flow_begin = clock(); + entire_flow_begin = clock(); - /* Read options, architecture, and circuit netlist */ - vpr_init(argc, argv, &Options, &vpr_setup, &Arch); + /* Read options, architecture, and circuit netlist */ + vpr_init(argc, argv, &Options, &vpr_setup, &Arch); - /* If the user requests packing, do packing */ - if (vpr_setup.PackerOpts.doPacking) { - vpr_pack(vpr_setup, Arch); - } + /* If the user requests packing, do packing */ + if (vpr_setup.PackerOpts.doPacking) { + vpr_pack(vpr_setup, Arch); + } - if (vpr_setup.PlacerOpts.doPlacement || vpr_setup.RouterOpts.doRouting) { - vpr_init_pre_place_and_route(vpr_setup, Arch); - vpr_place_and_route(vpr_setup, Arch); + if (vpr_setup.PlacerOpts.doPlacement || vpr_setup.RouterOpts.doRouting) { + vpr_init_pre_place_and_route(vpr_setup, Arch); + vpr_place_and_route(vpr_setup, Arch); #if 0 - if(vpr_setup.RouterOpts.doRouting) { - vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture(&Arch); - } + if(vpr_setup.RouterOpts.doRouting) { + vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture(&Arch); + } #endif - } + } - if (vpr_setup.PowerOpts.do_power) { - vpr_power_estimation(vpr_setup, Arch); - } + if (vpr_setup.PowerOpts.do_power) { + vpr_power_estimation(vpr_setup, Arch); + } - /* Run FPGA-SPICE tool suites*/ - vpr_fpga_spice_tool_suites(vpr_setup, Arch); + /* Run FPGA-SPICE tool suites*/ + vpr_fpga_x2p_tool_suites(vpr_setup, Arch); - entire_flow_end = clock(); - - #ifdef CLOCKS_PER_SEC - vpr_printf(TIO_MESSAGE_INFO, "The entire flow of VPR took %g seconds.\n", (float)(entire_flow_end - entire_flow_begin) / CLOCKS_PER_SEC); - #else - vpr_printf(TIO_MESSAGE_INFO, "The entire flow of VPR took %g seconds.\n", (float)(entire_flow_end - entire_flow_begin) / CLK_PER_SEC); - #endif - - /* free data structures */ - vpr_free_all(Arch, Options, vpr_setup); + entire_flow_end = clock(); + + #ifdef CLOCKS_PER_SEC + vpr_printf(TIO_MESSAGE_INFO, "The entire flow of VPR took %g seconds.\n", (float)(entire_flow_end - entire_flow_begin) / CLOCKS_PER_SEC); + #else + vpr_printf(TIO_MESSAGE_INFO, "The entire flow of VPR took %g seconds.\n", (float)(entire_flow_end - entire_flow_begin) / CLK_PER_SEC); + #endif + + /* free data structures */ + vpr_free_all(Arch, Options, vpr_setup); - /* Return 0 to single success to scripts */ - return 0; + /* Return 0 to single success to scripts */ + return 0; } + diff --git a/vpr7_x2p/vpr/SRC/pack/cluster.c b/vpr7_x2p/vpr/SRC/pack/cluster.c index af2d3e110..ee95f08da 100755 --- a/vpr7_x2p/vpr/SRC/pack/cluster.c +++ b/vpr7_x2p/vpr/SRC/pack/cluster.c @@ -575,6 +575,7 @@ void do_clustering(const t_arch *arch, t_pack_molecule *molecule_head, check_clustering(num_clb, clb, is_clock); output_clustering(clb, num_clb, global_clocks, is_clock, out_fname, FALSE); + if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_POST_PACK_NETLIST)) { output_blif (clb, num_clb, global_clocks, is_clock, getEchoFileName(E_ECHO_POST_PACK_NETLIST), FALSE); @@ -1314,8 +1315,8 @@ static enum e_block_pack_status try_place_logical_block_rec( parent_pb->logical_block = OPEN; parent_pb->name = my_strdup(logical_block[ilogical_block].name); parent_pb->mode = pb_graph_node->pb_type->parent_mode->index; - set_pb_graph_mode(parent_pb->pb_graph_node, 0, 0); /* TODO: default mode is to use mode 0, document this! */ - set_pb_graph_mode(parent_pb->pb_graph_node, parent_pb->mode, 1); + /* set_pb_graph_mode(parent_pb->pb_graph_node, 0, 0); */ /* TODO: default mode is to use mode 0, document this! */ + set_pb_graph_mode(parent_pb->pb_graph_node, parent_pb->mode, 1); parent_pb->child_pbs = (t_pb **) my_calloc(parent_pb->pb_graph_node->pb_type->modes[parent_pb->mode].num_pb_type_children, sizeof(t_pb *)); for (i = 0; i < parent_pb->pb_graph_node->pb_type->modes[parent_pb->mode].num_pb_type_children; i++) { parent_pb->child_pbs[i] = (t_pb *) my_calloc(parent_pb->pb_graph_node->pb_type->modes[parent_pb->mode].pb_type_children[i].num_pb, sizeof(t_pb)); diff --git a/vpr7_x2p/vpr/SRC/pack/cluster_legality.c b/vpr7_x2p/vpr/SRC/pack/cluster_legality.c index 3fa702860..fb91fa2f5 100755 --- a/vpr7_x2p/vpr/SRC/pack/cluster_legality.c +++ b/vpr7_x2p/vpr/SRC/pack/cluster_legality.c @@ -410,6 +410,12 @@ void alloc_and_load_rr_graph_for_pb_graph_node( } for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) { + /* Xifan Tang: we DO NOT build the rr_graph for those modes are disabled in packing */ + /* + if (TRUE == pb_graph_node->pb_type->modes[i].disabled_in_packing) { + continue; + } + */ for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children; j++) { for (k = 0; @@ -580,7 +586,7 @@ void alloc_and_load_legalizer_for_cluster(INP t_block* clb, INP int clb_index, ipin++; } } - + alloc_and_load_rr_node_route_structs(); num_nets_in_cluster = 0; @@ -894,6 +900,14 @@ static void breadth_first_expand_neighbours_cluster(int inode, float pcost, num_edges = rr_node[inode].num_edges; for (iconn = 0; iconn < num_edges; iconn++) { to_node = rr_node[inode].edges[iconn]; + /* Xifan Tang: SHOULD BE FIXED THOROUGHLY!!! + * Here, I just bypass all the edges that belongs a mode that is disabled in packing + */ + if ( (NULL != rr_node[to_node].pb_graph_pin) + && (NULL != rr_node[to_node].pb_graph_pin->parent_node->pb_type->parent_mode) + && (TRUE == rr_node[to_node].pb_graph_pin->parent_node->pb_type->parent_mode->disabled_in_packing)) { + continue; + } /*if (first_time) { */ tot_cost = pcost + get_rr_cong_cost(to_node) * rr_node_intrinsic_cost(to_node); diff --git a/vpr7_x2p/vpr/SRC/pack/output_clustering.c b/vpr7_x2p/vpr/SRC/pack/output_clustering.c index db3a5fed9..9d08e66a0 100755 --- a/vpr7_x2p/vpr/SRC/pack/output_clustering.c +++ b/vpr7_x2p/vpr/SRC/pack/output_clustering.c @@ -117,6 +117,12 @@ static void print_interconnect(int inode, int *column, int num_tabs, rr_node[prev_node].pb_graph_pin->parent_node->placement_index, rr_node[prev_node].pb_graph_pin->port->name, rr_node[prev_node].pb_graph_pin->pin_number, name); + /* For debug + if (0 == strcmp("fle_phy", + rr_node[prev_node].pb_graph_pin->parent_node->pb_type->name)) { + printf("debugging point reached!\n"); + } + */ } else { len = strlen( diff --git a/vpr7_x2p/vpr/SRC/pack/pb_type_graph.c b/vpr7_x2p/vpr/SRC/pack/pb_type_graph.c index 20be15117..2c0e31870 100755 --- a/vpr7_x2p/vpr/SRC/pack/pb_type_graph.c +++ b/vpr7_x2p/vpr/SRC/pack/pb_type_graph.c @@ -37,7 +37,8 @@ static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, static void alloc_and_load_mode_interconnect( INOUTP t_pb_graph_node *pb_graph_parent_node, INOUTP t_pb_graph_node **pb_graph_children_nodes, - INP const t_mode * mode, boolean load_power_structures); + INP const t_mode * mode, boolean load_power_structures, + INP int index_mode); static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP int line_num, INP const t_pb_graph_node *pb_graph_parent_node, @@ -83,6 +84,12 @@ static void alloc_and_load_interconnect_pins(t_interconnect_pins * interc_pins, t_pb_graph_pin *** output_pins, int num_output_sets, int * num_output_pins); +static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num, + int index_mode, + t_pb_graph_pin*** input_pins, + int num_input_ports, + int* num_input_pins); + /** * Allocate memory into types and load the pb graph with interconnect edges */ @@ -239,7 +246,7 @@ static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, pb_graph_node->input_pins[i_input][j].pin_count_in_cluster = pin_count_in_cluster; pb_graph_node->input_pins[i_input][j].type = PB_PIN_NORMAL; - if (pb_graph_node->pb_type->blif_model != NULL ) { + if (pb_graph_node->pb_type->blif_model != NULL) { if (strcmp(pb_graph_node->pb_type->blif_model, ".output") == 0) { pb_graph_node->input_pins[i_input][j].type = @@ -273,7 +280,7 @@ static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, pb_graph_node->output_pins[i_output][j].pin_count_in_cluster = pin_count_in_cluster; pb_graph_node->output_pins[i_output][j].type = PB_PIN_NORMAL; - if (pb_graph_node->pb_type->blif_model != NULL ) { + if (pb_graph_node->pb_type->blif_model != NULL) { if (strcmp(pb_graph_node->pb_type->blif_model, ".input") == 0) { pb_graph_node->output_pins[i_output][j].type = @@ -310,7 +317,7 @@ static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, pb_graph_node->clock_pins[i_clockport][j].pin_count_in_cluster = pin_count_in_cluster; pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_NORMAL; - if (pb_graph_node->pb_type->blif_model != NULL ) { + if (pb_graph_node->pb_type->blif_model != NULL) { pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_CLOCK; } @@ -356,7 +363,7 @@ static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, /* Create interconnect for mode */ alloc_and_load_mode_interconnect(pb_graph_node, pb_graph_node->child_pb_graph_nodes[i], &pb_type->modes[i], - load_power_structures); + load_power_structures, i); } } @@ -461,7 +468,7 @@ static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node) { } free(pb_graph_node->child_pb_graph_nodes); - while (edges_head != NULL ) { + while (edges_head != NULL) { cur = edges_head; cur_num = num_edges_head; edges = (t_pb_graph_edge*) cur->data_vptr; @@ -621,7 +628,7 @@ static void alloc_and_load_interconnect_pins(t_interconnect_pins * interc_pins, num_ports = 0; for (set_idx = 0; set_idx < num_output_sets; set_idx++) { for (pin_idx = 0; pin_idx < num_output_pins[set_idx]; pin_idx++) { - interc_pins->output_pins[num_ports++][0] = + interc_pins->output_pins[num_ports++][0]= output_pins[set_idx][pin_idx]; } } @@ -640,7 +647,8 @@ static void alloc_and_load_interconnect_pins(t_interconnect_pins * interc_pins, static void alloc_and_load_mode_interconnect( INOUTP t_pb_graph_node *pb_graph_parent_node, INOUTP t_pb_graph_node **pb_graph_children_nodes, - INP const t_mode * mode, boolean load_power_structures) { + INP const t_mode * mode, boolean load_power_structures, + INP int index_mode) { int i, j; int *num_input_pb_graph_node_pins, *num_output_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */ int num_input_pb_graph_node_sets, num_output_pb_graph_node_sets; @@ -679,7 +687,7 @@ static void alloc_and_load_mode_interconnect( output_pb_graph_node_pins, num_output_pb_graph_node_sets, num_output_pb_graph_node_pins); } - + /* process the interconnect based on its type */ switch (mode->interconnect[i].type) { @@ -771,6 +779,17 @@ static void alloc_and_load_mode_interconnect( mode->interconnect[i].num_mux = num_mux; /* END */ + /* Baudouin Chauviere SDC generation: loop breaker */ + if (mode->interconnect[i].loop_breaker_string) { + map_loop_breaker_onto_edges(mode->interconnect[i].loop_breaker_string, + mode->interconnect[i].line_num, + index_mode, + input_pb_graph_node_pins, + num_input_pb_graph_node_sets, + num_input_pb_graph_node_pins); + } + /* END */ + for (j = 0; j < num_input_pb_graph_node_sets; j++) { free(input_pb_graph_node_pins[j]); } @@ -1233,7 +1252,7 @@ static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP int line_num, pb_lsb = pb_msb = 0; /* Internal representation of parent is always 0 */ } } else { - if (mode == NULL ) { + if (mode == NULL) { vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] pb_graph_parent_node %s failed\n", line_num, pb_graph_parent_node->pb_type->name); @@ -1386,7 +1405,7 @@ static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP int line_num, (*pb_graph_pins)[i * (abs(pin_msb - pin_lsb) + 1) + j] = get_pb_graph_pin_from_name(port_name, &pb_node_array[ipb], ipin); - if ((*pb_graph_pins)[i * (abs(pin_msb - pin_lsb) + 1) + j] == NULL ) { + if ((*pb_graph_pins)[i * (abs(pin_msb - pin_lsb) + 1) + j] == NULL) { vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Pin %s.%s[%d] cannot be found\n", line_num, pb_node_array[ipb].pb_type->name, port_name, ipin); @@ -1749,3 +1768,325 @@ static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports, } } +static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num, + int index_mode, + t_pb_graph_pin*** input_pins, + int num_input_ports, + int* num_input_pins) { + t_token * tokens; + int num_tokens; + int i_tokens, cur_port_index, cur_pin_index; + int i_index_mode; + t_mode* cur_mode; + t_pb_graph_node** cur_node; /* can have a family of nodes */ + int index_cur_node, i_index_cur_node; + t_pb_graph_node* tmp_node; + char* cur_pb_name; + char* cur_pin_name; + e_pb_graph_pin_type pin_type; + int lsb_pb, msb_pb; + int i_lsb_pb; + int lsb_pin, msb_pin, msb_pin_max; + int pb_name_found, pin_name_found; + int full_bus = 0; + int i_num_input_ports; + int i_num_output_edges; + int i_pb_type_in_mode, index_pb_type; + + // Get the tokens from the loop_breaker_string + num_tokens = 0; + tokens = GetTokensFromString(loop_breaker_string, &num_tokens); + + i_tokens = 0; + cur_node = (t_pb_graph_node**) my_malloc(sizeof(t_pb_graph_node*)); + *cur_node = (t_pb_graph_node*) my_malloc(sizeof(t_pb_graph_node)); + while (i_tokens < num_tokens) { + pb_name_found = 0; + pin_name_found = 0; + msb_pin = lsb_pin = msb_pb = lsb_pb = 0; + if (tokens[i_tokens].type != TOKEN_STRING) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: first element of a pair pb+pin should be a string\n", + line_num); + exit(1); + } + cur_pb_name = tokens[i_tokens].data; + *cur_node = (t_pb_graph_node*) my_realloc(*cur_node, sizeof(t_pb_graph_node)); + /* no distinction is made between children and parent nodes */ + for (i_num_input_ports = 0 ; i_num_input_ports < num_input_ports ; i_num_input_ports ++) { + if (0 == strcmp(cur_pb_name, input_pins[i_num_input_ports][0]->parent_node->pb_type->name)) { + pb_name_found = 1; + cur_node[0] = input_pins[i_num_input_ports][0]->parent_node; + break; + } + } + if (0 == pb_name_found) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Pb name not found in current interconnection\n", + line_num); + exit(1); + } + i_tokens++; + /* We deal with three cases: nothing, a wire, a bus */ + /* First, the bus/wire */ + tmp_node = cur_node[0]; + if( tokens[i_tokens].type == TOKEN_OPEN_SQUARE_BRACKET) { + i_tokens++; + if( tokens[i_tokens].type != TOKEN_INT) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Int expected inside of the pb bracket\n", + line_num); + exit(1); + } + msb_pb = my_atoi(tokens[i_tokens].data); + if (msb_pb > cur_node[0]->pb_type->num_pb) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: MSB pb larger than the number of pb\n", + line_num); + exit(1); + } + i_tokens++; + /* bus */ + if( tokens[i_tokens].type == TOKEN_COLON) { + i_tokens++; + if (tokens[i_tokens].type != TOKEN_INT) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Int expected inside of the pb bracket for LSB\n", + line_num); + exit(1); + } + lsb_pb = my_atoi(tokens[i_tokens].data); + if (lsb_pb > msb_pb) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: MSB supposed to be superior to LSB\n", + line_num); + exit(1); + } + i_tokens++; + if (tokens[i_tokens].type != TOKEN_CLOSE_SQUARE_BRACKET) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Expect closing bracket after the bus\n", + line_num); + exit(1); + } + i_tokens++; + } + /* wire */ + else if (tokens[i_tokens].type == TOKEN_CLOSE_SQUARE_BRACKET) { + lsb_pb = msb_pb; + } + else { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Expect closing bracket or colon after pin number\n", + line_num); + exit(1); + } + } + /* If no bracket was used, we use need to apply the loop breaker to all the pbs with that name */ + else { + msb_pb = cur_node[0]->pb_type->num_pb - 1; + lsb_pb = 0; + } + index_cur_node = 0; + *cur_node = (t_pb_graph_node*) my_realloc(*cur_node, sizeof(t_pb_graph_node) * (msb_pb + 1)); + if (tmp_node->parent_pb_graph_node == NULL) {/* if pb_graph_head */ + cur_node[0] = tmp_node; + } + else { + for (i_pb_type_in_mode = 0 ; + i_pb_type_in_mode < tmp_node->parent_pb_graph_node->pb_type->modes[index_mode].num_pb_type_children ; + i_pb_type_in_mode ++) { + if (cur_pb_name == + tmp_node->parent_pb_graph_node->child_pb_graph_nodes[index_mode][i_pb_type_in_mode][0].pb_type->name) { + index_pb_type = i_pb_type_in_mode; + break; + } + } + /* if previous conditions are respected, we should always find the index of the pb type */ + assert (index_pb_type != tmp_node->parent_pb_graph_node->pb_type->modes[index_mode].num_pb_type_children); + for ( i_lsb_pb = lsb_pb ; i_lsb_pb < msb_pb + 1 ; i_lsb_pb ++) { + cur_node[index_cur_node] = + &(tmp_node->parent_pb_graph_node->child_pb_graph_nodes[index_mode][index_pb_type][i_lsb_pb]); + index_cur_node++; + } + } + if (tokens[i_tokens].type != TOKEN_DOT) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Pb name should be followed by a dot\n", + line_num); + exit(1); + } + i_tokens++; + + /* Pin definition */ + if (tokens[i_tokens].type != TOKEN_STRING) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Pin name expected after dot\n", + line_num); + exit(1); + } + cur_pin_name = tokens[i_tokens].data; + i_tokens++; + /* We deal with three cases: nothing, a wire, a bus */ + /* First, the bus/wire */ + if( tokens[i_tokens].type == TOKEN_OPEN_SQUARE_BRACKET) { + i_tokens++; + if( tokens[i_tokens].type != TOKEN_INT) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Int expected inside of the pin bracket\n", + line_num); + exit(1); + } + msb_pin = my_atoi(tokens[i_tokens].data); + i_tokens++; + /* bus */ + if( tokens[i_tokens].type == TOKEN_COLON) { + i_tokens++; + if (tokens[i_tokens].type != TOKEN_INT) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Int expected inside of the bracket for LSB\n", + line_num); + exit(1); + } + lsb_pin = my_atoi(tokens[i_tokens].data); + if (lsb_pin > msb_pin) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: MSB supposed to be superior to LSB\n", + line_num); + exit(1); + } + i_tokens++; + if (tokens[i_tokens].type != TOKEN_CLOSE_SQUARE_BRACKET) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Expect closing bracket after the bus\n", + line_num); + exit(1); + } + i_tokens++; + } + /* wire */ + else if (tokens[i_tokens].type == TOKEN_CLOSE_SQUARE_BRACKET) { + lsb_pin = msb_pin; + } + else { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Expect closing bracket or colon after pin number\n", + line_num); + exit(1); + } + } + else { + /* With no bus/wire given, we take the full bus of the pin given*/ + full_bus =1; + } + /* Since we have the pin name, we find the right position of the pin + * in the associated node and check that msb is not superior to the + * number of pins we have. */ + /* Check inputs */ + for (cur_port_index = 0 ; cur_port_index < cur_node[0]->num_input_ports ; cur_port_index ++) { + if (0 == strcmp(cur_pin_name,cur_node[0]->input_pins[cur_port_index][0].port->name)) { + pin_name_found = 1; + pin_type = PB_PIN_INPUT; + msb_pin_max = cur_node[0]->num_input_pins[cur_port_index] - 1; + break; + } + } + /* Check outputs if not input */ + if (0 == pin_name_found) { + for (cur_port_index = 0 ; cur_port_index < cur_node[0]->num_output_ports ; cur_port_index ++) { + if (0 == strcmp(cur_pin_name,cur_node[0]->output_pins[cur_port_index][0].port->name)) { + pin_name_found = 1; + pin_type = PB_PIN_OUTPUT; + msb_pin_max = cur_node[0]->num_output_pins[cur_port_index] - 1; + break; + } + } + } + /* Check clocks */ + if (0 == pin_name_found) { + for (cur_port_index = 0 ; cur_port_index < cur_node[0]->num_clock_ports ; cur_port_index ++) { + if (0 == strcmp(cur_pin_name,cur_node[0]->clock_pins[cur_port_index][0].port->name)) { + pin_name_found = 1; + pin_type = PB_PIN_CLOCK; + msb_pin_max = cur_node[0]->num_clock_pins[cur_port_index] - 1; + break; + } + } + } + if (0 == pin_name_found) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Pin name not found in given pb\n", + line_num); + exit(1); + } + + if (1 == full_bus) { + switch(pin_type) { + case PB_PIN_INPUT: + msb_pin = cur_node[0]->num_input_pins[cur_port_index] - 1; + break; + case PB_PIN_OUTPUT: + msb_pin = cur_node[0]->num_output_pins[cur_port_index] - 1; + break; + case PB_PIN_CLOCK: + msb_pin = cur_node[0]->num_clock_pins[cur_port_index] - 1; + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] I) Pin was not found and this message should never be accessed in theory." + " Report it for a fix if it happens\n", + line_num); + exit(1); + } + msb_pin_max = msb_pin; + lsb_pin = 0; + } + /* Check that the pin number found in the string is valid */ + if (msb_pin < 0 || msb_pin > msb_pin_max) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Issue with MSB\n", + line_num); + exit(1); + } + if (lsb_pin < 0 || lsb_pin > msb_pin) { + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] loop_breaker: Issue with LSB\n", + line_num); + exit(1); + } + for (i_index_cur_node = 0 ; i_index_cur_node < index_cur_node ; i_index_cur_node ++) { + for (cur_pin_index = lsb_pin ; cur_pin_index < (msb_pin + 1) ; cur_pin_index++) { + switch(pin_type) { + case PB_PIN_INPUT: + for (i_num_output_edges = 0 ; + i_num_output_edges < cur_node[i_index_cur_node]->input_pins[cur_port_index][cur_pin_index].num_output_edges ; + i_num_output_edges ++) { + cur_node[i_index_cur_node]->input_pins[cur_port_index][cur_pin_index].output_edges[i_num_output_edges]->is_disabled = TRUE; + } + break; + case PB_PIN_OUTPUT: + for (i_num_output_edges = 0 ; + i_num_output_edges < cur_node[i_index_cur_node]->output_pins[cur_port_index][cur_pin_index].num_output_edges ; + i_num_output_edges ++) { + cur_node[i_index_cur_node]->output_pins[cur_port_index][cur_pin_index].output_edges[i_num_output_edges]->is_disabled = TRUE; + } + break; + case PB_PIN_CLOCK: + for (i_num_output_edges = 0 ; + i_num_output_edges < cur_node[i_index_cur_node]->clock_pins[cur_port_index][cur_pin_index].num_output_edges ; + i_num_output_edges ++) { + cur_node[i_index_cur_node]->clock_pins[cur_port_index][cur_pin_index].output_edges[i_num_output_edges]->is_disabled = TRUE; + } + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "[LINE %d] II) Pin was not found and this message should never be accessed in theory." + " Report it for a fix if it happens\n", + line_num); + exit(1); + } + } + } + } + return; +} diff --git a/vpr7_x2p/vpr/SRC/pack/pb_type_graph_annotations.c b/vpr7_x2p/vpr/SRC/pack/pb_type_graph_annotations.c index 83f631b03..090995f89 100755 --- a/vpr7_x2p/vpr/SRC/pack/pb_type_graph_annotations.c +++ b/vpr7_x2p/vpr/SRC/pack/pb_type_graph_annotations.c @@ -148,6 +148,14 @@ static void load_pack_pattern_annotations(INP int line_num, INOUTP t_pb_graph_no break; } } + /* Xifan Tang: bypass the edges that are disabled in packing */ + /* + if ((iedge != in_port[i][j]->num_output_edges) + && (TRUE == in_port[i][j]->output_edges[iedge]->interconnect->parent_mode->disabled_in_packing)) { + continue; + } + */ + /* END */ /* jluu Todo: This is inefficient, I know the interconnect so I know what edges exist can use this info to only annotate existing edges */ if (iedge != in_port[i][j]->num_output_edges) { diff --git a/vpr7_x2p/vpr/SRC/pack/prepack.c b/vpr7_x2p/vpr/SRC/pack/prepack.c index 51f201515..f4f43ad13 100644 --- a/vpr7_x2p/vpr/SRC/pack/prepack.c +++ b/vpr7_x2p/vpr/SRC/pack/prepack.c @@ -161,6 +161,13 @@ static void discover_pattern_names_in_pb_graph_node( for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) { hasPattern = FALSE; for (k = 0; k < pb_graph_node->input_pins[i][j].num_output_edges; k++) { + /* Xifan Tang: bypass pack_patterns whose parent mode is disabled_in_packing*/ + /* + if (TRUE == pb_graph_node->input_pins[i][j].output_edges[k]->interconnect->parent_mode->disabled_in_packing) { + continue; + } + */ + /* END */ for (m = 0; m < pb_graph_node->input_pins[i][j].output_edges[k]->num_pack_patterns; m++) { hasPattern = TRUE; index = add_pattern_name_to_hash(nhash, @@ -183,6 +190,13 @@ static void discover_pattern_names_in_pb_graph_node( for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) { hasPattern = FALSE; for (k = 0; k < pb_graph_node->output_pins[i][j].num_output_edges; k++) { + /* Xifan Tang: bypass pack_patterns whose parent mode is disabled_in_packing*/ + /* + if (TRUE == pb_graph_node->output_pins[i][j].output_edges[k]->interconnect->parent_mode->disabled_in_packing) { + continue; + } + */ + /* END */ for (m = 0; m < pb_graph_node->output_pins[i][j].output_edges[k]->num_pack_patterns; m++) { hasPattern = TRUE; index = add_pattern_name_to_hash(nhash, @@ -205,6 +219,13 @@ static void discover_pattern_names_in_pb_graph_node( for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) { hasPattern = FALSE; for (k = 0; k < pb_graph_node->clock_pins[i][j].num_output_edges; k++) { + /* Xifan Tang: bypass pack_patterns whose parent mode is disabled_in_packing*/ + /* + if (TRUE == pb_graph_node->clock_pins[i][j].output_edges[k]->interconnect->parent_mode->disabled_in_packing) { + continue; + } + */ + /* END */ for (m = 0; m < pb_graph_node->clock_pins[i][j].output_edges[k]->num_pack_patterns; m++) { hasPattern = TRUE; index = add_pattern_name_to_hash(nhash, @@ -637,6 +658,14 @@ t_pack_molecule *alloc_and_load_pack_molecules( is_used = (boolean*)my_calloc(num_packing_patterns, sizeof(boolean)); + /* Xifan Tang: initialize the pattern usage ! Mark used for patterns that belongs to modes disabled_in_packing*/ + for (i = 0; i < num_packing_patterns; i++) { + if (TRUE == list_of_pack_patterns[i].root_block->pb_type->parent_mode->disabled_in_packing) { + is_used[i] = TRUE; + } + } + /* END */ + cur_molecule = list_of_molecules_head = NULL; /* Find forced pack patterns */ @@ -651,6 +680,11 @@ t_pack_molecule *alloc_and_load_pack_molecules( best_pattern = j; } } + /* Xifan Tang: we may not found an usused pattern */ + if (TRUE == is_used[best_pattern]) { + continue; + } + /* END */ assert(is_used[best_pattern] == FALSE); is_used[best_pattern] = TRUE; for (j = 0; j < num_logical_blocks; j++) { diff --git a/vpr7_x2p/vpr/SRC/route/route_common.h b/vpr7_x2p/vpr/SRC/route/route_common.h index f7cc244fe..f3be76474 100755 --- a/vpr7_x2p/vpr/SRC/route/route_common.h +++ b/vpr7_x2p/vpr/SRC/route/route_common.h @@ -1,5 +1,6 @@ /************ Defines and types shared by all route files ********************/ +typedef struct s_heap t_heap; struct s_heap { int index; float cost; diff --git a/vpr7_x2p/vpr/SRC/shell_main.c b/vpr7_x2p/vpr/SRC/shell_main.c new file mode 100644 index 000000000..1ea5290ea --- /dev/null +++ b/vpr7_x2p/vpr/SRC/shell_main.c @@ -0,0 +1,19 @@ +/** + VPR is a CAD tool used to conduct FPGA architecture exploration. It takes, as input, a technology-mapped netlist and a description of the FPGA architecture being investigated. + VPR then generates a packed, placed, and routed FPGA (in .net, .place, and .route files respectively) that implements the input netlist. + + This file is where VPR starts execution. + + Key files in VPR: + 1. libarchfpga/physical_types.h - Data structures that define the properties of the FPGA architecture + 2. vpr_types.h - Very major file that defines the core data structures used in VPR. This includes detailed architecture information, user netlist data structures, and data structures that describe the mapping between those two. + 3. globals.h - Defines the global variables used by VPR. + */ + +#include + + +int main(int argc, char ** argv) { + + run_shell(argc, argv); +} diff --git a/vpr7_x2p/vpr/SRC/tags b/vpr7_x2p/vpr/SRC/tags new file mode 100644 index 000000000..2810be8f3 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/tags @@ -0,0 +1,6335 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.8 // +AAPACK_MAX_FEASIBLE_BLOCK_ARRAY_SIZE ./pack/cluster.c 35;" d file: +AAPACK_MAX_HIGH_FANOUT_EXPLORE ./pack/cluster.c 37;" d file: +AAPACK_MAX_NET_SINKS_IGNORE ./pack/cluster.c 36;" d file: +AAPACK_MAX_OVERUSE_LOOKAHEAD_PINS_CONST ./pack/cluster.c 33;" d file: +AAPACK_MAX_OVERUSE_LOOKAHEAD_PINS_FAC ./pack/cluster.c 32;" d file: +ABORTED ./place/place.c /^ REJECTED, ACCEPTED, ABORTED$/;" e enum:swap_result file: +ABSOLUTE ../../libarchfpga/include/physical_types.h /^ ABSOLUTE, FRACTIONAL$/;" e enum:e_Fc_type +ABS_DIFF ./place/place_stats.c 7;" d file: +ACCEPTED ./place/place.c /^ REJECTED, ACCEPTED, ABORTED$/;" e enum:swap_result file: +ACTIVITY_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 5;" d +ALLOW_SWITCH_OFF ./route/rr_graph2.c 16;" d file: +ALL_NETS ./base/draw.c /^ ALL_NETS, HIGHLIGHTED$/;" e enum:e_draw_net_type file: +ANALYSIS_CMD ./fpga_x2p/shell/shell_types.h /^ ANALYSIS_CMD,$/;" e enum:e_cmd_category +ANY ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +ANYBUT ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +ANYOF ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +ARCH_TYPES_H ../../libarchfpga/include/arch_types.h 9;" d +AUTO_SCHED ./base/vpr_types.h /^ AUTO_SCHED, USER_SCHED$/;" e enum:sched_type +ActFile ./base/ReadOptions.h /^ char *ActFile;$/;" m struct:s_options +ActFile ./base/vpr_types.h /^ char *ActFile;$/;" m struct:s_file_name_opts +AnnealSched ./base/vpr_types.h /^ struct s_annealing_sched AnnealSched; \/* Placement option annealing schedule *\/$/;" m struct:s_vpr_setup typeref:struct:s_vpr_setup::s_annealing_sched +ArchFile ./base/ReadOptions.h /^ char *ArchFile;$/;" m struct:s_options +ArchFile ./base/vpr_types.h /^ char *ArchFile;$/;" m struct:s_file_name_opts +Aspect ../../libarchfpga/include/physical_types.h /^ float Aspect;$/;" m struct:s_clb_grid +BACKCHAR ../../pcre/SRC/pcre.c 213;" d file: +BACKCHAR ../../pcre/SRC/pcre.c 290;" d file: +BASIC_CMD ./fpga_x2p/shell/shell_types.h /^ BASIC_CMD,$/;" e enum:e_cmd_category +BEST_CORNER ../../libarchfpga/fpga_spice_include/spice_types.h /^ BEST_CORNER,$/;" e enum:e_process_corner +BISQUE ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +BI_DIRECTION ./base/vpr_types.h /^ INC_DIRECTION = 0, DEC_DIRECTION = 1, BI_DIRECTION = 2$/;" e enum:e_direction +BI_DIRECTIONAL ../../libarchfpga/include/physical_types.h /^ UNI_DIRECTIONAL, BI_DIRECTIONAL$/;" e enum:e_directionality +BLACK ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +BLIF_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 1;" d +BLIF_LUT_KEYWORD ./fpga_x2p/base/fpga_x2p_types.h 18;" d +BLIF_TOKENS ./base/read_blif.c 235;" d file: +BLK_FAILED_FEASIBLE ./base/vpr_types.h /^ BLK_PASSED, BLK_FAILED_FEASIBLE, BLK_FAILED_ROUTE, BLK_STATUS_UNDEFINED$/;" e enum:e_block_pack_status +BLK_FAILED_ROUTE ./base/vpr_types.h /^ BLK_PASSED, BLK_FAILED_FEASIBLE, BLK_FAILED_ROUTE, BLK_STATUS_UNDEFINED$/;" e enum:e_block_pack_status +BLK_PASSED ./base/vpr_types.h /^ BLK_PASSED, BLK_FAILED_FEASIBLE, BLK_FAILED_ROUTE, BLK_STATUS_UNDEFINED$/;" e enum:e_block_pack_status +BLK_STATUS_UNDEFINED ./base/vpr_types.h /^ BLK_PASSED, BLK_FAILED_FEASIBLE, BLK_FAILED_ROUTE, BLK_STATUS_UNDEFINED$/;" e enum:e_block_pack_status +BLOCK_COUNT ./place/timing_place_lookup.c 52;" d file: +BLUE ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +BOL ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +BOOL ../../pcre/SRC/internal.h /^typedef int BOOL;$/;" t +BOTTOM ../../libarchfpga/include/physical_types.h /^ TOP = 0, RIGHT = 1, BOTTOM = 2, LEFT = 3$/;" e enum:e_side +BOUNDARY ../../libarchfpga/include/physical_types.h /^ BOUNDARY = 0, FILL, COL_REPEAT, COL_REL$/;" e enum:e_grid_loc_type +BOUNDING_BOX_PLACE ./base/vpr_types.h /^ BOUNDING_BOX_PLACE, NET_TIMING_DRIVEN_PLACE, PATH_TIMING_DRIVEN_PLACE$/;" e enum:e_place_algorithm +BRANCH ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +BRASTACK_SIZE ../../pcre/SRC/pcre.c 68;" d file: +BREADTH_FIRST ./base/vpr_types.h /^ BREADTH_FIRST, TIMING_DRIVEN, NO_TIMING$/;" e enum:e_router_algorithm +BUFFER_INSERTION_H ./mrfpga/buffer_insertion.h 2;" d +BUFSIZE ../../libarchfpga/include/util.h 23;" d +BUFSIZE ./base/graphics.c 184;" d file: +BUF_AND_PTRANS_FLAG ./route/check_rr_graph.c 16;" d file: +BUF_FLAG ./route/check_rr_graph.c 14;" d file: +BUTTON_POLY ./base/graphics.c /^ BUTTON_POLY,$/;" e enum:__anon3 file: +BUTTON_SEPARATOR ./base/graphics.c /^ BUTTON_SEPARATOR$/;" e enum:__anon3 file: +BUTTON_TEXT ./base/graphics.c /^ BUTTON_TEXT = 0,$/;" e enum:__anon3 file: +BUTTON_TEXT_LEN ./base/graphics.c 183;" d file: +BitstreamGenOpts ./base/vpr_types.h /^ t_bitstream_gen_opts BitstreamGenOpts; \/* Xifan Bitsteam Generator *\/$/;" m struct:s_fpga_spice_opts +BlifFile ./base/ReadOptions.h /^ char *BlifFile;$/;" m struct:s_options +BlifFile ./base/vpr_types.h /^ char *BlifFile;$/;" m struct:s_file_name_opts +ButtonsWND ./base/graphics.c /^ButtonsWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)$/;" f file: +C ../../libarchfpga/include/arch_types_mrfpga.h /^ float C; $/;" m struct:s_memristor_inf +C ../../libarchfpga/include/arch_types_mrfpga.h /^ float C;$/;" m struct:s_buffer_inf +C ../../libarchfpga/include/physical_types.h /^ float C;$/;" m union:s_port_power::__anon22 +C ./base/vpr_types.h /^ float C;$/;" m struct:s_rr_node +CAD_TYPES_H ../../libarchfpga/include/cad_types.h 5;" d +CAL_CAPACITANCE_H ./mrfpga/cal_capacitance.h 2;" d +CHANX ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +CHANX_COST_INDEX_START ./base/vpr_types.h /^ CHANX_COST_INDEX_START$/;" e enum:e_cost_indices +CHANY ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +CHECK ./place/place.c /^ NORMAL, CHECK$/;" e enum:cost_methods file: +CHECK_NETLIST_H ./base/check_netlist.h 2;" d +CHECK_RAND ../../libarchfpga/util.c 734;" d file: +CHECK_RR_GRAPH_H ./route/check_rr_graph.h 2;" d +CHUNK_SIZE ../../libarchfpga/util.c 208;" d file: +CLOCK_DENS ./power/power.h 37;" d +CLOCK_PROB ./power/power.h 36;" d +CLOSE ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +CLUSTER_FEASIBILITY_CHECK_H ./pack/cluster_feasibility_filter.h 23;" d +CLUSTER_LEGALITY_H ./pack/cluster_legality.h 2;" d +CLUSTER_PLACEMENT_H ./pack/cluster_placement.h 7;" d +CMOS_TECH_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 7;" d +COL_REL ../../libarchfpga/include/physical_types.h /^ BOUNDARY = 0, FILL, COL_REPEAT, COL_REL$/;" e enum:e_grid_loc_type +COL_REPEAT ../../libarchfpga/include/physical_types.h /^ BOUNDARY = 0, FILL, COL_REPEAT, COL_REL$/;" e enum:e_grid_loc_type +COMPLETE_INTERC ../../libarchfpga/include/physical_types.h /^ COMPLETE_INTERC = 1, DIRECT_INTERC = 2, MUX_INTERC = 3$/;" e enum:e_interconnect +CONV ../../libarchfpga/include/arch_types_mrfpga.h /^ CONV = 0, MONO, STTRAM, PCRAM_Xie, PCRAM_Pierre, NEM $/;" e enum:e_tech_comp +CONVERT_NM_PER_M ./power/power.c 50;" d file: +CONVERT_UM_PER_M ./power/power.c 51;" d file: +CORAL ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +CREATE_ERROR ./base/graphics.c 219;" d file: +CREF_RECURSE ../../pcre/SRC/internal.h 476;" d +CYAN ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +C_d ./power/power.h /^ float C_d;$/;" m struct:s_transistor_size_inf +C_downstream ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" m struct:s_buffer_plan file: +C_downstream ./route/route_tree_timing.h /^ float C_downstream;$/;" m struct:s_rt_node +C_downstream ./timing/net_delay_types.h /^ float C_downstream;$/;" m struct:s_rc_node +C_g ./power/power.h /^ float C_g;$/;" m struct:s_transistor_size_inf +C_internal ../../libarchfpga/include/physical_types.h /^ float C_internal; \/*Internal capacitance of the pb *\/$/;" m struct:s_pb_type_power +C_ipin_cblock ../../libarchfpga/include/physical_types.h /^ float C_ipin_cblock;$/;" m struct:s_arch +C_ipin_cblock ../../libarchfpga/include/physical_types.h /^ float C_ipin_cblock;$/;" m struct:s_timing_inf +C_load ./base/vpr_types.h /^ float C_load;$/;" m struct:s_rr_indexed_data +C_s ./power/power.h /^ float C_s;$/;" m struct:s_transistor_size_inf +C_tile_per_m ./base/vpr_types.h /^ float C_tile_per_m;$/;" m struct:s_rr_indexed_data +C_wire ../../libarchfpga/include/physical_types.h /^ float C_wire; \/* Wire capacitance (per meter) *\/$/;" m struct:s_clock_network +C_wire ../../libarchfpga/include/physical_types.h /^ float C_wire;$/;" m struct:s_pb_graph_pin_power +C_wire_local ../../libarchfpga/include/physical_types.h /^ float C_wire_local; \/* Capacitance of local interconnect (per meter) *\/$/;" m struct:s_power_arch +Chans ../../libarchfpga/include/physical_types.h /^ t_chan_width_dist Chans;$/;" m struct:s_arch +CheckArch ./base/CheckArch.c /^void CheckArch(INP t_arch Arch, INP boolean TimingEnabled) {$/;" f +CheckElement ../../libarchfpga/read_xml_util.c /^void CheckElement(INP ezxml_t Node, INP const char *Name) {$/;" f +CheckGrid ./base/SetupGrid.c /^static void CheckGrid() {$/;" f file: +CheckOptions ./base/CheckOptions.c /^void CheckOptions(INP t_options Options, INP boolean TimingEnabled) {$/;" f +CheckSegments ./base/CheckArch.c /^static void CheckSegments(INP t_arch Arch) {$/;" f file: +CheckSetup ./base/CheckSetup.c /^void CheckSetup(INP enum e_operation Operation,$/;" f +CheckSwitches ./base/CheckArch.c /^static void CheckSwitches(INP t_arch Arch, INP boolean TimingEnabled) {$/;" f file: +Cin ../../libarchfpga/include/physical_types.h /^ float Cin;$/;" m struct:s_switch_inf +CircuitName ./base/ReadOptions.h /^ char *CircuitName;$/;" m struct:s_options +CircuitName ./base/vpr_types.h /^ char *CircuitName;$/;" m struct:s_file_name_opts +Cmetal ../../libarchfpga/include/physical_types.h /^ float Cmetal;$/;" m struct:s_segment_inf +Cmetal ./base/vpr_types.h /^ float Cmetal;$/;" m struct:s_seg_details +Cmetal_per_m ./base/vpr_types.h /^ float Cmetal_per_m; \/* Used for power *\/$/;" m struct:s_seg_details +CmosTechFile ./base/ReadOptions.h /^ char *CmosTechFile;$/;" m struct:s_options +CmosTechFile ./base/vpr_types.h /^ char *CmosTechFile;$/;" m struct:s_file_name_opts +Count ./base/ReadOptions.h /^ int Count[OT_BASE_UNKNOWN];$/;" m struct:s_options +CountChildren ../../libarchfpga/read_xml_util.c /^extern int CountChildren(INP ezxml_t Node, INP const char *Name,$/;" f +CountTokens ../../libarchfpga/ReadLine.c /^int CountTokens(INP char **Tokens) {$/;" f +CountTokensInString ../../libarchfpga/read_xml_util.c /^extern void CountTokensInString(INP const char *Str, OUTP int *Num,$/;" f +Cout ../../libarchfpga/include/physical_types.h /^ float Cout;$/;" m struct:s_switch_inf +CreateEchoFile ./base/ReadOptions.h /^ boolean CreateEchoFile;$/;" m struct:s_options +CreateModelLibrary ../../libarchfpga/read_xml_arch_file.c /^static void CreateModelLibrary(OUTP struct s_arch *arch) {$/;" f file: +Cseg_global ../../libarchfpga/include/arch_types_mrfpga.h /^ float Cseg_global;$/;" m struct:s_arch_mrfpga +Cseg_global ./mrfpga/mrfpga_globals.c /^float Rseg_global, Cseg_global;$/;" v +DARKGREEN ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +DARKGREY ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +DARKKHAKI ./base/easygl_constants.h /^TURQUOISE, MEDIUMPURPLE, DARKSLATEBLUE, DARKKHAKI, NUM_COLOR};$/;" e enum:color_types +DARKSLATEBLUE ./base/easygl_constants.h /^TURQUOISE, MEDIUMPURPLE, DARKSLATEBLUE, DARKKHAKI, NUM_COLOR};$/;" e enum:color_types +DASHED ./base/easygl_constants.h /^enum line_types {SOLID, DASHED};$/;" e enum:line_types +DEBUG ./base/vpr_types.h 46;" d +DEBUG_TIMING_PLACE_LOOKUP ./place/timing_place_lookup.c 61;" d file: +DEC_DIRECTION ./base/vpr_types.h /^ INC_DIRECTION = 0, DEC_DIRECTION = 1, BI_DIRECTION = 2$/;" e enum:e_direction +DEFAULT_MUX_PATH_ID ./fpga_x2p/base/fpga_x2p_types.h 13;" d +DEFAULT_PATH_ID ./fpga_x2p/base/fpga_x2p_types.h 10;" d +DEFAULT_PREV_NODE ./fpga_x2p/base/fpga_x2p_types.h 7;" d +DEFAULT_SWITCH_ID ./fpga_x2p/base/fpga_x2p_types.h 4;" d +DEGTORAD ./base/graphics.c 228;" d file: +DELAY_NORMALIZED ./base/vpr_types.h /^ INTRINSIC_DELAY, DELAY_NORMALIZED, DEMAND_ONLY$/;" e enum:e_base_cost_type +DELETE_ERROR ./base/graphics.c 218;" d file: +DELTA ../../libarchfpga/include/physical_types.h /^ UNIFORM, GAUSSIAN, PULSE, DELTA$/;" e enum:e_stat +DEMAND_ONLY ./base/vpr_types.h /^ INTRINSIC_DELAY, DELAY_NORMALIZED, DEMAND_ONLY$/;" e enum:e_base_cost_type +DETAILED ./base/vpr_types.h /^ GLOBAL, DETAILED$/;" e enum:e_route_type +DIGIT ./timing/slre.c /^ STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT$/;" e enum:__anon19 file: +DIRECT_INTERC ../../libarchfpga/include/physical_types.h /^ COMPLETE_INTERC = 1, DIRECT_INTERC = 2, MUX_INTERC = 3$/;" e enum:e_interconnect +DISCOUNT_FUNCTION_BASE ./timing/path_delay.h 23;" d +DO_NOT_ANALYSE ./timing/path_delay.h 4;" d +DPRINTF ../../pcre/SRC/pcre.c 44;" d file: +DPRINTF ../../pcre/SRC/pcre.c 46;" d file: +DRAW_ALL_BUT_BUFFERS_RR ./base/draw.c /^ DRAW_ALL_BUT_BUFFERS_RR,$/;" e enum:e_draw_rr_toggle file: +DRAW_ALL_RR ./base/draw.c /^ DRAW_ALL_RR,$/;" e enum:e_draw_rr_toggle file: +DRAW_ERROR ./base/graphics.c 220;" d file: +DRAW_NODES_AND_SBOX_RR ./base/draw.c /^ DRAW_NODES_AND_SBOX_RR,$/;" e enum:e_draw_rr_toggle file: +DRAW_NODES_RR ./base/draw.c /^ DRAW_NODES_RR,$/;" e enum:e_draw_rr_toggle file: +DRAW_NORMAL ./base/graphics.h /^enum e_draw_mode {DRAW_NORMAL = 0, DRAW_XOR};$/;" e enum:e_draw_mode +DRAW_NO_RR ./base/draw.c /^ DRAW_NO_RR = 0,$/;" e enum:e_draw_rr_toggle file: +DRAW_RR_TOGGLE_MAX ./base/draw.c /^ DRAW_RR_TOGGLE_MAX$/;" e enum:e_draw_rr_toggle file: +DRAW_XOR ./base/graphics.h /^enum e_draw_mode {DRAW_NORMAL = 0, DRAW_XOR};$/;" e enum:e_draw_mode +DRIVER ../../libarchfpga/include/physical_types.h /^ OPEN = -1, DRIVER = 0, RECEIVER = 1$/;" e enum:e_pin_type +DUMPFILE ./place/timing_place_lookup.c 63;" d file: +Directs ../../libarchfpga/include/physical_types.h /^ t_direct_inf *Directs;$/;" m struct:s_arch +EASYGL_CONSTANTS_H ./base/easygl_constants.h 2;" d +EMPTY ./base/vpr_types.h 90;" d +EMPTY_TYPE ../../libarchfpga/read_xml_arch_file.c /^static t_type_ptr EMPTY_TYPE = NULL;$/;" v file: +EMPTY_TYPE ./base/globals.c /^t_type_ptr EMPTY_TYPE = NULL;$/;" v +EMPTY_TYPE_BACKUP ./place/timing_place_lookup.c /^static t_type_ptr EMPTY_TYPE_BACKUP;$/;" v file: +EMPTY_TYPE_INDEX ../../libarchfpga/include/read_xml_arch_file.h 15;" d +ENABLE_REVERSE ./route/rr_graph2.c 21;" d file: +END ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +EOL ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +EPSILON ./base/vpr_types.h 83;" d +ERR1 ../../pcre/SRC/internal.h 483;" d +ERR10 ../../pcre/SRC/internal.h 492;" d +ERR11 ../../pcre/SRC/internal.h 493;" d +ERR12 ../../pcre/SRC/internal.h 494;" d +ERR13 ../../pcre/SRC/internal.h 495;" d +ERR14 ../../pcre/SRC/internal.h 496;" d +ERR15 ../../pcre/SRC/internal.h 497;" d +ERR16 ../../pcre/SRC/internal.h 498;" d +ERR17 ../../pcre/SRC/internal.h 499;" d +ERR18 ../../pcre/SRC/internal.h 500;" d +ERR19 ../../pcre/SRC/internal.h 501;" d +ERR2 ../../pcre/SRC/internal.h 484;" d +ERR20 ../../pcre/SRC/internal.h 502;" d +ERR21 ../../pcre/SRC/internal.h 503;" d +ERR22 ../../pcre/SRC/internal.h 504;" d +ERR23 ../../pcre/SRC/internal.h 505;" d +ERR24 ../../pcre/SRC/internal.h 506;" d +ERR25 ../../pcre/SRC/internal.h 507;" d +ERR26 ../../pcre/SRC/internal.h 508;" d +ERR27 ../../pcre/SRC/internal.h 509;" d +ERR28 ../../pcre/SRC/internal.h 510;" d +ERR29 ../../pcre/SRC/internal.h 511;" d +ERR3 ../../pcre/SRC/internal.h 485;" d +ERR30 ../../pcre/SRC/internal.h 512;" d +ERR31 ../../pcre/SRC/internal.h 513;" d +ERR32 ../../pcre/SRC/internal.h 514;" d +ERR33 ../../pcre/SRC/internal.h 515;" d +ERR34 ../../pcre/SRC/internal.h 516;" d +ERR35 ../../pcre/SRC/internal.h 517;" d +ERR36 ../../pcre/SRC/internal.h 518;" d +ERR37 ../../pcre/SRC/internal.h 519;" d +ERR38 ../../pcre/SRC/internal.h 520;" d +ERR39 ../../pcre/SRC/internal.h 521;" d +ERR4 ../../pcre/SRC/internal.h 486;" d +ERR40 ../../pcre/SRC/internal.h 522;" d +ERR41 ../../pcre/SRC/internal.h 523;" d +ERR42 ../../pcre/SRC/internal.h 524;" d +ERR43 ../../pcre/SRC/internal.h 525;" d +ERR5 ../../pcre/SRC/internal.h 487;" d +ERR6 ../../pcre/SRC/internal.h 488;" d +ERR7 ../../pcre/SRC/internal.h 489;" d +ERR8 ../../pcre/SRC/internal.h 490;" d +ERR9 ../../pcre/SRC/internal.h 491;" d +ERROR_THRESHOLD ./base/check_netlist.c 15;" d file: +ERROR_TOL ./place/place.c 31;" d file: +ERROR_TOL ./route/route_timing.c 884;" d file: +ERRTAG ../../libarchfpga/include/util.h 26;" d +ERR_PORT ../../libarchfpga/include/logic_types.h /^ IN_PORT, OUT_PORT, INOUT_PORT, ERR_PORT$/;" e enum:PORTS +ESC_A ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_B ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_C ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_D ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_E ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_G ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_Q ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_REF ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_S ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_W ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_Z ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_b ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_d ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_dum1 ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_e ../../pcre/SRC/internal.h 235;" d +ESC_f ../../pcre/SRC/internal.h 239;" d +ESC_n ../../pcre/SRC/internal.h 243;" d +ESC_r ../../pcre/SRC/internal.h 247;" d +ESC_s ../../pcre/SRC/internal.h /^enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,$/;" e enum:__anon24 +ESC_t ../../pcre/SRC/internal.h 251;" d +ESC_w ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +ESC_z ../../pcre/SRC/internal.h /^ ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };$/;" e enum:__anon24 +EXACT ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +EXTRACT_BASIC_MAX ../../pcre/SRC/internal.h 472;" d +EZXML_BUFSIZE ../../libarchfpga/include/ezxml.h 37;" d +EZXML_DUP ../../libarchfpga/include/ezxml.h 40;" d +EZXML_ERRL ../../libarchfpga/include/ezxml.h 41;" d +EZXML_NAMEM ../../libarchfpga/include/ezxml.h 38;" d +EZXML_NIL ../../libarchfpga/ezxml.c /^char *EZXML_NIL[] = { NULL }; \/* empty, null terminated array of strings *\/$/;" v +EZXML_NOMMAP ../../libarchfpga/ezxml.c 26;" d file: +EZXML_TXTM ../../libarchfpga/include/ezxml.h 39;" d +EZXML_WS ../../libarchfpga/ezxml.c 64;" d file: +E_ANNOT_PIN_TO_PIN_CAPACITANCE ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_CAPACITANCE,$/;" e enum:e_pin_to_pin_annotation_type +E_ANNOT_PIN_TO_PIN_CAPACITANCE_C ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_CAPACITANCE_C = 0$/;" e enum:e_pin_to_pin_capacitance_annotations +E_ANNOT_PIN_TO_PIN_CONSTANT ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_MATRIX = 0, E_ANNOT_PIN_TO_PIN_CONSTANT$/;" e enum:e_pin_to_pin_annotation_format +E_ANNOT_PIN_TO_PIN_DELAY ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY = 0,$/;" e enum:e_pin_to_pin_annotation_type +E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX,$/;" e enum:e_pin_to_pin_delay_annotations +E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN,$/;" e enum:e_pin_to_pin_delay_annotations +E_ANNOT_PIN_TO_PIN_DELAY_MAX ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY_MAX,$/;" e enum:e_pin_to_pin_delay_annotations +E_ANNOT_PIN_TO_PIN_DELAY_MIN ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY_MIN = 0,$/;" e enum:e_pin_to_pin_delay_annotations +E_ANNOT_PIN_TO_PIN_DELAY_THOLD ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY_THOLD$/;" e enum:e_pin_to_pin_delay_annotations +E_ANNOT_PIN_TO_PIN_DELAY_TSETUP ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_DELAY_TSETUP,$/;" e enum:e_pin_to_pin_delay_annotations +E_ANNOT_PIN_TO_PIN_MATRIX ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_MATRIX = 0, E_ANNOT_PIN_TO_PIN_CONSTANT$/;" e enum:e_pin_to_pin_annotation_format +E_ANNOT_PIN_TO_PIN_MODE_SELECT ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_MODE_SELECT$/;" e enum:e_pin_to_pin_annotation_type +E_ANNOT_PIN_TO_PIN_MODE_SELECT_MODE_NAME ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_MODE_SELECT_MODE_NAME = 0$/;" e enum:e_pin_to_pin_mode_select_annotations +E_ANNOT_PIN_TO_PIN_PACK_PATTERN ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_PACK_PATTERN,$/;" e enum:e_pin_to_pin_annotation_type +E_ANNOT_PIN_TO_PIN_PACK_PATTERN_NAME ../../libarchfpga/include/physical_types.h /^ E_ANNOT_PIN_TO_PIN_PACK_PATTERN_NAME = 0$/;" e enum:e_pin_to_pin_pack_pattern_annotations +E_CRITICALITY_FILE ./base/ReadOptions.h /^ E_CRITICALITY_FILE,$/;" e enum:e_output_files +E_CRIT_PATH_FILE ./base/ReadOptions.h /^ E_CRIT_PATH_FILE,$/;" e enum:e_output_files +E_CUSTOM_PIN_DISTR ../../libarchfpga/include/physical_types.h /^ E_SPREAD_PIN_DISTR = 1, E_CUSTOM_PIN_DISTR = 2$/;" e enum:e_pin_location_distr +E_DETAILED_ROUTE_AT_END_ONLY ./pack/cluster.c /^ E_DETAILED_ROUTE_AT_END_ONLY = 0, E_DETAILED_ROUTE_FOR_EACH_ATOM, E_DETAILED_ROUTE_END$/;" e enum:e_detailed_routing_stages file: +E_DETAILED_ROUTE_END ./pack/cluster.c /^ E_DETAILED_ROUTE_AT_END_ONLY = 0, E_DETAILED_ROUTE_FOR_EACH_ATOM, E_DETAILED_ROUTE_END$/;" e enum:e_detailed_routing_stages file: +E_DETAILED_ROUTE_FOR_EACH_ATOM ./pack/cluster.c /^ E_DETAILED_ROUTE_AT_END_ONLY = 0, E_DETAILED_ROUTE_FOR_EACH_ATOM, E_DETAILED_ROUTE_END$/;" e enum:e_detailed_routing_stages file: +E_DIR_EXIST ./fpga_x2p/base/fpga_x2p_utils.c /^ E_DIR_EXIST$/;" e enum:e_dir_err file: +E_DIR_NOT_EXIST ./fpga_x2p/base/fpga_x2p_utils.c /^ E_DIR_NOT_EXIST,$/;" e enum:e_dir_err file: +E_ECHO_ARCH ./base/ReadOptions.h /^ E_ECHO_ARCH,$/;" e enum:e_echo_files +E_ECHO_BLIF_INPUT ./base/ReadOptions.h /^ E_ECHO_BLIF_INPUT,$/;" e enum:e_echo_files +E_ECHO_CLUSTERING_BLOCK_CRITICALITIES ./base/ReadOptions.h /^ E_ECHO_CLUSTERING_BLOCK_CRITICALITIES,$/;" e enum:e_echo_files +E_ECHO_CLUSTERING_TIMING_INFO ./base/ReadOptions.h /^ E_ECHO_CLUSTERING_TIMING_INFO,$/;" e enum:e_echo_files +E_ECHO_COMPLETE_NET_TRACE ./base/ReadOptions.h /^ E_ECHO_COMPLETE_NET_TRACE,$/;" e enum:e_echo_files +E_ECHO_CRITICALITY ./base/ReadOptions.h /^ E_ECHO_CRITICALITY,$/;" e enum:e_echo_files +E_ECHO_CRITICAL_PATH ./base/ReadOptions.h /^ E_ECHO_CRITICAL_PATH,$/;" e enum:e_echo_files +E_ECHO_END_CLB_PLACEMENT ./base/ReadOptions.h /^ E_ECHO_END_CLB_PLACEMENT,$/;" e enum:e_echo_files +E_ECHO_END_TOKEN ./base/ReadOptions.h /^ E_ECHO_END_TOKEN$/;" e enum:e_echo_files +E_ECHO_FINAL_PLACEMENT_CRITICALITY ./base/ReadOptions.h /^ E_ECHO_FINAL_PLACEMENT_CRITICALITY,$/;" e enum:e_echo_files +E_ECHO_FINAL_PLACEMENT_SLACK ./base/ReadOptions.h /^ E_ECHO_FINAL_PLACEMENT_SLACK,$/;" e enum:e_echo_files +E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH ./base/ReadOptions.h /^ E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH,$/;" e enum:e_echo_files +E_ECHO_INITIAL_CLB_PLACEMENT ./base/ReadOptions.h /^ E_ECHO_INITIAL_CLB_PLACEMENT = 0,$/;" e enum:e_echo_files +E_ECHO_INITIAL_PLACEMENT_CRITICALITY ./base/ReadOptions.h /^ E_ECHO_INITIAL_PLACEMENT_CRITICALITY,$/;" e enum:e_echo_files +E_ECHO_INITIAL_PLACEMENT_SLACK ./base/ReadOptions.h /^ E_ECHO_INITIAL_PLACEMENT_SLACK,$/;" e enum:e_echo_files +E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH ./base/ReadOptions.h /^ E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH,$/;" e enum:e_echo_files +E_ECHO_LUT_REMAPPING ./base/ReadOptions.h /^ E_ECHO_LUT_REMAPPING,$/;" e enum:e_echo_files +E_ECHO_MEM ./base/ReadOptions.h /^ E_ECHO_MEM,$/;" e enum:e_echo_files +E_ECHO_NET_DELAY ./base/ReadOptions.h /^ E_ECHO_NET_DELAY,$/;" e enum:e_echo_files +E_ECHO_PB_GRAPH ./base/ReadOptions.h /^ E_ECHO_PB_GRAPH,$/;" e enum:e_echo_files +E_ECHO_PLACEMENT_CRITICAL_PATH ./base/ReadOptions.h /^ E_ECHO_PLACEMENT_CRITICAL_PATH,$/;" e enum:e_echo_files +E_ECHO_PLACEMENT_CRIT_PATH ./base/ReadOptions.h /^ E_ECHO_PLACEMENT_CRIT_PATH,$/;" e enum:e_echo_files +E_ECHO_PLACEMENT_LOGIC_SINK_DELAYS ./base/ReadOptions.h /^ E_ECHO_PLACEMENT_LOGIC_SINK_DELAYS,$/;" e enum:e_echo_files +E_ECHO_PLACEMENT_LOWER_BOUND_SINK_DELAYS ./base/ReadOptions.h /^ E_ECHO_PLACEMENT_LOWER_BOUND_SINK_DELAYS,$/;" e enum:e_echo_files +E_ECHO_PLACEMENT_SINK_DELAYS ./base/ReadOptions.h /^ E_ECHO_PLACEMENT_SINK_DELAYS,$/;" e enum:e_echo_files +E_ECHO_POST_FLOW_TIMING_GRAPH ./base/ReadOptions.h /^ E_ECHO_POST_FLOW_TIMING_GRAPH,$/;" e enum:e_echo_files +E_ECHO_POST_PACK_NETLIST ./base/ReadOptions.h /^ E_ECHO_POST_PACK_NETLIST,$/;" e enum:e_echo_files +E_ECHO_PRE_PACKING_CRITICALITY ./base/ReadOptions.h /^ E_ECHO_PRE_PACKING_CRITICALITY,$/;" e enum:e_echo_files +E_ECHO_PRE_PACKING_MOLECULES_AND_PATTERNS ./base/ReadOptions.h /^ E_ECHO_PRE_PACKING_MOLECULES_AND_PATTERNS,$/;" e enum:e_echo_files +E_ECHO_PRE_PACKING_SLACK ./base/ReadOptions.h /^ E_ECHO_PRE_PACKING_SLACK,$/;" e enum:e_echo_files +E_ECHO_PRE_PACKING_TIMING_GRAPH ./base/ReadOptions.h /^ E_ECHO_PRE_PACKING_TIMING_GRAPH,$/;" e enum:e_echo_files +E_ECHO_PRE_PACKING_TIMING_GRAPH_AS_BLIF ./base/ReadOptions.h /^ E_ECHO_PRE_PACKING_TIMING_GRAPH_AS_BLIF,$/;" e enum:e_echo_files +E_ECHO_ROUTING_SINK_DELAYS ./base/ReadOptions.h /^ E_ECHO_ROUTING_SINK_DELAYS,$/;" e enum:e_echo_files +E_ECHO_RR_GRAPH ./base/ReadOptions.h /^ E_ECHO_RR_GRAPH,$/;" e enum:e_echo_files +E_ECHO_SEG_DETAILS ./base/ReadOptions.h /^ E_ECHO_SEG_DETAILS,$/;" e enum:e_echo_files +E_ECHO_SLACK ./base/ReadOptions.h /^ E_ECHO_SLACK,$/;" e enum:e_echo_files +E_ECHO_TIMING_CONSTRAINTS ./base/ReadOptions.h /^ E_ECHO_TIMING_CONSTRAINTS,$/;" e enum:e_echo_files +E_ECHO_TIMING_GRAPH ./base/ReadOptions.h /^ E_ECHO_TIMING_GRAPH,$/;" e enum:e_echo_files +E_EXIST_BUT_NOT_DIR ./fpga_x2p/base/fpga_x2p_utils.c /^ E_EXIST_BUT_NOT_DIR,$/;" e enum:e_dir_err file: +E_FILE_END_TOKEN ./base/ReadOptions.h /^ E_FILE_END_TOKEN$/;" e enum:e_output_files +E_SLACK_FILE ./base/ReadOptions.h /^ E_SLACK_FILE,$/;" e enum:e_output_files +E_SPREAD_PIN_DISTR ../../libarchfpga/include/physical_types.h /^ E_SPREAD_PIN_DISTR = 1, E_CUSTOM_PIN_DISTR = 2$/;" e enum:e_pin_location_distr +EchoArch ../../libarchfpga/read_xml_arch_file.c /^void EchoArch(INP const char *EchoFile, INP const t_type_descriptor * Types,$/;" f +EchoEnabled ./base/ReadOptions.c /^static boolean EchoEnabled;$/;" v file: +Enum ./base/vpr_types.h /^ int Enum;$/;" m struct:s_TokenPair +Error ./base/ReadOptions.c /^static void Error(INP const char *Token) {$/;" f file: +FALSE ../../libarchfpga/include/util.h /^ FALSE, TRUE$/;" e enum:__anon23 +FALSE ../../pcre/SRC/internal.h 227;" d +FALSE ./base/graphics.c 146;" d file: +FC_ABS ../../libarchfpga/read_xml_arch_file.c /^ FC_ABS, FC_FRAC, FC_FULL$/;" e enum:Fc_type file: +FC_FRAC ../../libarchfpga/read_xml_arch_file.c /^ FC_ABS, FC_FRAC, FC_FULL$/;" e enum:Fc_type file: +FC_FULL ../../libarchfpga/read_xml_arch_file.c /^ FC_ABS, FC_FRAC, FC_FULL$/;" e enum:Fc_type file: +FEASIBLE ./pack/cluster.c /^ FEASIBLE, INFEASIBLE$/;" e enum:e_feasibility file: +FF_FE ../../libarchfpga/fpga_spice_include/spice_types.h /^ FF_RE, FF_FE$/;" e enum:e_spice_ff_trigger_type +FF_RE ../../libarchfpga/fpga_spice_include/spice_types.h /^ FF_RE, FF_FE$/;" e enum:e_spice_ff_trigger_type +FF_size ../../libarchfpga/include/physical_types.h /^ float FF_size;$/;" m struct:s_power_arch +FILL ../../libarchfpga/include/physical_types.h /^ BOUNDARY = 0, FILL, COL_REPEAT, COL_REL$/;" e enum:e_grid_loc_type +FILL_TYPE ../../libarchfpga/read_xml_arch_file.c /^static t_type_ptr FILL_TYPE = NULL;$/;" v file: +FILL_TYPE ./base/globals.c /^t_type_ptr FILL_TYPE = NULL;$/;" v +FILL_TYPE_BACKUP ./place/timing_place_lookup.c /^static t_type_ptr FILL_TYPE_BACKUP;$/;" v file: +FINAL_DISCOUNT_FUNCTION_BASE ./timing/path_delay.h 28;" d +FIRST_ITER_WIRELENTH_LIMIT ./base/vpr_types.h 88;" d +FONTMAG ./base/graphics.c 229;" d file: +FPGA_SPICE_Opts ./base/vpr_types.h /^ t_fpga_spice_opts FPGA_SPICE_Opts; \/* Xifan TANG: FPGA-SPICE support *\/$/;" m struct:s_vpr_setup +FRACTIONAL ../../libarchfpga/include/physical_types.h /^ ABSOLUTE, FRACTIONAL$/;" e enum:e_Fc_type +FRAGMENT_THRESHOLD ../../libarchfpga/util.c 209;" d file: +FREE ./base/vpr_types.h /^ FREE, RANDOM, USER$/;" e enum:e_pad_loc_type +FROM_X_TO_Y ./base/draw.c /^ FROM_X_TO_Y, FROM_Y_TO_X$/;" e enum:e_edge_dir file: +FROM_Y_TO_X ./base/draw.c /^ FROM_X_TO_Y, FROM_Y_TO_X$/;" e enum:e_edge_dir file: +FULL ../../libarchfpga/include/physical_types.h /^ SUBSET, WILTON, UNIVERSAL, FULL$/;" e enum:e_switch_block_type +Fc ../../libarchfpga/include/physical_types.h /^ float *Fc; \/* [0..num_pins-1] *\/$/;" m struct:s_type_descriptor +Fc_type ../../libarchfpga/read_xml_arch_file.c /^enum Fc_type {$/;" g file: +FileNameOpts ./base/vpr_types.h /^ struct s_file_name_opts FileNameOpts; \/* File names *\/$/;" m struct:s_vpr_setup typeref:struct:s_vpr_setup::s_file_name_opts +FindElement ../../libarchfpga/read_xml_util.c /^ezxml_t FindElement(INP ezxml_t Parent, INP const char *Name,$/;" f +FindFirstElement ../../libarchfpga/read_xml_util.c /^ezxml_t FindFirstElement(INP ezxml_t Parent, INP const char *Name,$/;" f +FindProperty ../../libarchfpga/read_xml_util.c /^FindProperty(INP ezxml_t Parent, INP const char *Name, INP boolean Required) {$/;" f +FreeNode ../../libarchfpga/read_xml_util.c /^void FreeNode(INOUTP ezxml_t Node) {$/;" f +FreeSpice ../../libarchfpga/read_xml_spice_util.c /^void FreeSpice(t_spice* spice) {$/;" f +FreeSpiceMeasParams ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceMeasParams(t_spice_meas_params* meas_params) {$/;" f +FreeSpiceModel ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceModel(t_spice_model* spice_model) {$/;" f +FreeSpiceModelBuffer ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceModelBuffer(t_spice_model_buffer* spice_model_buffer) {$/;" f +FreeSpiceModelNetlist ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceModelNetlist(t_spice_model_netlist* spice_model_netlist) {$/;" f +FreeSpiceModelPassGateLogic ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceModelPassGateLogic(t_spice_model_pass_gate_logic* spice_model_pass_gate_logic) {$/;" f +FreeSpiceModelPort ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceModelPort(t_spice_model_port* spice_model_port) {$/;" f +FreeSpiceModelWireParam ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceModelWireParam(t_spice_model_wire_param* spice_model_wire_param) {$/;" f +FreeSpiceMonteCarloParams ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceMonteCarloParams(t_spice_mc_params* mc_params) {$/;" f +FreeSpiceMuxArch ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceMuxArch(t_spice_mux_arch* spice_mux_arch) {$/;" f +FreeSpiceParams ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceParams(t_spice_params* params) {$/;" f +FreeSpiceStimulateParams ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceStimulateParams(t_spice_stimulate_params* stimulate_params) {$/;" f +FreeSpiceVariationParams ../../libarchfpga/read_xml_spice_util.c /^void FreeSpiceVariationParams(t_spice_mc_variation_params* mc_variation_params) {$/;" f +FreeSramInf ../../libarchfpga/read_xml_spice_util.c /^void FreeSramInf(t_sram_inf* sram_inf) {$/;" f +FreeSramInfOrgz ../../libarchfpga/read_xml_spice_util.c /^void FreeSramInfOrgz(t_sram_inf_orgz* sram_inf_orgz) {$/;" f +FreeTokens ../../libarchfpga/ReadLine.c /^void FreeTokens(INOUTP char ***TokensPtr) {$/;" f +Fs ../../libarchfpga/include/physical_types.h /^ int Fs;$/;" m struct:s_arch +Fs ./base/vpr_types.h /^ int Fs;$/;" m struct:s_det_routing_arch +Fs_seed ./base/globals.c /^int Fs_seed = -1;$/;" v +GAIN ./pack/cluster.c /^ GAIN, NO_GAIN$/;" e enum:e_gain_update file: +GAUSSIAN ../../libarchfpga/include/physical_types.h /^ UNIFORM, GAUSSIAN, PULSE, DELTA$/;" e enum:e_stat +GET ../../pcre/SRC/internal.h 110;" d +GET ../../pcre/SRC/internal.h 124;" d +GET ../../pcre/SRC/internal.h 97;" d +GET2 ../../pcre/SRC/internal.h 148;" d +GETCHAR ../../pcre/SRC/pcre.c 209;" d file: +GETCHAR ../../pcre/SRC/pcre.c 220;" d file: +GETCHARINC ../../pcre/SRC/pcre.c 210;" d file: +GETCHARINC ../../pcre/SRC/pcre.c 238;" d file: +GETCHARINCTEST ../../pcre/SRC/pcre.c 211;" d file: +GETCHARINCTEST ../../pcre/SRC/pcre.c 254;" d file: +GETCHARLEN ../../pcre/SRC/pcre.c 212;" d file: +GETCHARLEN ../../pcre/SRC/pcre.c 271;" d file: +GLOBAL ./base/vpr_types.h /^ GLOBAL, DETAILED$/;" e enum:e_route_type +GLOBALS_H ./base/globals.h 13;" d +GOT_FROM_SCRATCH ./place/place.c 47;" d file: +GRAPHICS_H ./base/graphics.h 3;" d +GRAPH_BIDIR ./route/rr_graph.h /^ GRAPH_BIDIR, \/* Detailed bidirectional graph *\/$/;" e enum:e_graph_type +GRAPH_GLOBAL ./route/rr_graph.h /^ GRAPH_GLOBAL, \/* One node per channel with wire capacity > 1 and full connectivity *\/$/;" e enum:e_graph_type +GRAPH_UNIDIR ./route/rr_graph.h /^ GRAPH_UNIDIR, \/* Detailed unidir graph, untilable *\/$/;" e enum:e_graph_type +GRAPH_UNIDIR_TILEABLE ./route/rr_graph.h /^ GRAPH_UNIDIR_TILEABLE \/* Detail unidir graph with wire groups multiples of 2*L *\/$/;" e enum:e_graph_type +GREEN ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +Generate_PostSynthesis_Netlist ./base/ReadOptions.c /^static boolean Generate_PostSynthesis_Netlist;$/;" v file: +Generate_Post_Synthesis_Netlist ./base/ReadOptions.h /^ boolean Generate_Post_Synthesis_Netlist;$/;" m struct:s_options +GetBooleanProperty ../../libarchfpga/read_xml_util.c /^extern boolean GetBooleanProperty(INP ezxml_t Parent, INP char *Name,$/;" f +GetFloatProperty ../../libarchfpga/read_xml_util.c /^extern float GetFloatProperty(INP ezxml_t Parent, INP char *Name,$/;" f +GetIntProperty ../../libarchfpga/read_xml_util.c /^extern int GetIntProperty(INP ezxml_t Parent, INP char *Name,$/;" f +GetNodeTokens ../../libarchfpga/read_xml_util.c /^GetNodeTokens(INP ezxml_t Node) {$/;" f +GetPostSynthesisOption ./base/ReadOptions.c /^boolean GetPostSynthesisOption(void){$/;" f +GetTokenTypeFromChar ./util/token.c /^enum e_token_type GetTokenTypeFromChar(INP enum e_token_type cur_token_type,$/;" f +GetTokensFromString ./util/token.c /^t_token *GetTokensFromString(INP const char* inString, OUTP int * num_tokens) {$/;" f +GraphPause ./base/ReadOptions.h /^ int GraphPause;$/;" m struct:s_options +GraphPause ./base/vpr_types.h /^ int GraphPause; \/* user interactiveness graphics option *\/$/;" m struct:s_vpr_setup +GraphicsWND ./base/graphics.c /^GraphicsWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)$/;" f file: +H ../../libarchfpga/include/physical_types.h /^ int H;$/;" m struct:s_clb_grid +HASHSIZE ./util/hash.h 1;" d +HAVE_BCOPY ../../pcre/SRC/config.h 38;" d +HAVE_MEMMOVE ../../pcre/SRC/config.h 32;" d +HAVE_STRERROR ../../pcre/SRC/config.h 31;" d +HELP_OPT_NAME ./fpga_x2p/shell/read_opt_types.h 54;" d +HELP_OPT_TAG ./fpga_x2p/shell/read_opt_types.h 53;" d +HIGHLIGHTED ./base/draw.c /^ ALL_NETS, HIGHLIGHTED$/;" e enum:e_draw_net_type file: +HIGH_FANOUT_NET_LIM ./base/vpr_types.h 86;" d +HILL_CLIMBING ./pack/cluster.c /^ HILL_CLIMBING, NOT_HILL_CLIMBING$/;" e enum:e_gain_type file: +HUGE_NEGATIVE_FLOAT ./base/vpr_types.h 80;" d +HUGE_POSITIVE_FLOAT ./base/vpr_types.h 79;" d +IA ../../libarchfpga/util.c 731;" d file: +IC ../../libarchfpga/util.c 732;" d file: +IM ../../libarchfpga/util.c 733;" d file: +IMPOSSIBLE ./place/timing_place_lookup.h 1;" d +INC_DIRECTION ./base/vpr_types.h /^ INC_DIRECTION = 0, DEC_DIRECTION = 1, BI_DIRECTION = 2$/;" e enum:e_direction +INFEASIBLE ./pack/cluster.c /^ FEASIBLE, INFEASIBLE$/;" e enum:e_feasibility file: +INFINITE ./base/place_and_route.h 1;" d +INOUTP ../../libarchfpga/include/util.h 21;" d +INOUT_PORT ../../libarchfpga/include/logic_types.h /^ IN_PORT, OUT_PORT, INOUT_PORT, ERR_PORT$/;" e enum:PORTS +INP ../../libarchfpga/include/util.h 19;" d +INPUT ./pack/cluster.c /^ INPUT, OUTPUT$/;" e enum:e_net_relation_to_clustered_block file: +INPUT2INPUT_INTERC ../../libarchfpga/fpga_spice_include/spice_types.h /^ INPUT2INPUT_INTERC, $/;" e enum:e_spice_pin2pin_interc_type +INTRA_CLUSTER_EDGE ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +INTRINSIC_DELAY ./base/vpr_types.h /^ INTRINSIC_DELAY, DELAY_NORMALIZED, DEMAND_ONLY$/;" e enum:e_base_cost_type +INV_1X_C ./power/power.h /^ float INV_1X_C;$/;" m struct:s_power_commonly_used +INV_1X_C_in ./power/power.h /^ float INV_1X_C_in;$/;" m struct:s_power_commonly_used +INV_2X_C ./power/power.h /^ float INV_2X_C;$/;" m struct:s_power_commonly_used +IN_PORT ../../libarchfpga/include/logic_types.h /^ IN_PORT, OUT_PORT, INOUT_PORT, ERR_PORT$/;" e enum:PORTS +IO_TYPE ../../libarchfpga/read_xml_arch_file.c /^static t_type_ptr IO_TYPE = NULL;$/;" v file: +IO_TYPE ./base/globals.c /^t_type_ptr IO_TYPE = NULL;$/;" v +IO_TYPE_BACKUP ./place/timing_place_lookup.c /^static t_type_ptr IO_TYPE_BACKUP;$/;" v file: +IO_TYPE_INDEX ../../libarchfpga/include/read_xml_arch_file.h 16;" d +IPIN ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +IPIN_COST_INDEX ./base/vpr_types.h /^ IPIN_COST_INDEX,$/;" e enum:e_cost_indices +InEventLoop ./base/graphics.c /^static boolean InEventLoop = FALSE;$/;" v file: +InitSpice ../../libarchfpga/read_xml_spice_util.c /^void InitSpice(t_spice* spice) {$/;" f +InitSpiceMeasParams ../../libarchfpga/read_xml_spice_util.c /^void InitSpiceMeasParams(t_spice_meas_params* meas_params) {$/;" f +InitSpiceMonteCarloParams ../../libarchfpga/read_xml_spice_util.c /^void InitSpiceMonteCarloParams(t_spice_mc_params* mc_params) {$/;" f +InitSpiceParams ../../libarchfpga/read_xml_spice_util.c /^void InitSpiceParams(t_spice_params* params) {$/;" f +InitSpiceStimulateParams ../../libarchfpga/read_xml_spice_util.c /^void InitSpiceStimulateParams(t_spice_stimulate_params* stimulate_params) {$/;" f +InitSpiceVariationParams ../../libarchfpga/read_xml_spice_util.c /^void InitSpiceVariationParams(t_spice_mc_variation_params* mc_variation_params) {$/;" f +IsAuto ../../libarchfpga/include/physical_types.h /^ boolean IsAuto;$/;" m struct:s_clb_grid +IsEchoEnabled ./base/ReadOptions.c /^boolean IsEchoEnabled(INP t_options *Options) {$/;" f +IsPostSynthesisEnabled ./base/ReadOptions.c /^boolean IsPostSynthesisEnabled(INP t_options *Options) {$/;" f +IsTimingEnabled ./base/ReadOptions.c /^boolean IsTimingEnabled(INP t_options *Options) {$/;" f +IsWhitespace ../../libarchfpga/read_xml_util.c /^boolean IsWhitespace(char c) {$/;" f +KHAKI ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +LAST_CMD_CATEGORY ./fpga_x2p/shell/shell_types.h /^ LAST_CMD_CATEGORY$/;" e enum:e_cmd_category +LAST_CMD_NAME ./fpga_x2p/shell/shell_types.h 37;" d +LAST_OPT_NAME ./fpga_x2p/shell/read_opt_types.h 57;" d +LAST_OPT_TAG ./fpga_x2p/shell/read_opt_types.h 56;" d +LATCH_CLASS ../../libarchfpga/include/physical_types.h /^ UNKNOWN_CLASS = 0, LUT_CLASS = 1, LATCH_CLASS = 2, MEMORY_CLASS = 3$/;" e enum:e_pb_type_class +LEAVE_CLUSTERED ./pack/cluster.c /^ REMOVE_CLUSTERED, LEAVE_CLUSTERED$/;" e enum:e_removal_policy file: +LEFT ../../libarchfpga/include/physical_types.h /^ TOP = 0, RIGHT = 1, BOTTOM = 2, LEFT = 3$/;" e enum:e_side +LIGHTBLUE ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +LIGHTGREY ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +LINELENGTH ./pack/output_blif.c 18;" d file: +LINELENGTH ./pack/output_clustering.c 16;" d file: +LINKEDLIST_H ../../libarchfpga/fpga_spice_include/linkedlist.h 2;" d +LINK_SIZE ../../pcre/SRC/config.h 56;" d +LOGIC_TYPES_H ../../libarchfpga/include/logic_types.h 10;" d +LONGLINE ./route/segment_stats.c 9;" d file: +LUT_CLASS ../../libarchfpga/include/physical_types.h /^ UNKNOWN_CLASS = 0, LUT_CLASS = 1, LATCH_CLASS = 2, MEMORY_CLASS = 3$/;" e enum:e_pb_type_class +LUT_transistor_size ../../libarchfpga/include/physical_types.h /^ float LUT_transistor_size;$/;" m struct:s_power_arch +L_wire ./fpga_x2p/verilog/verilog_report_timing.c /^ int L_wire;$/;" m struct:s_wireL_cnt file: +LookaheadNodeTokens ../../libarchfpga/read_xml_util.c /^LookaheadNodeTokens(INP ezxml_t Node) {$/;" f +MAGENTA ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +MAGIC_NUMBER ../../pcre/SRC/internal.h 210;" d +MAJOR ./base/vpr_types.h 73;" d +MARKED_FRAC ./pack/cluster.c 87;" d file: +MATCH_LIMIT ../../pcre/SRC/config.h 68;" d +MATCH_MATCH ../../pcre/SRC/pcre.c 178;" d file: +MATCH_NOMATCH ../../pcre/SRC/pcre.c 179;" d file: +MAXLIT ../../pcre/SRC/pcre.c 83;" d file: +MAXPIXEL ./base/graphics.c 202;" d file: +MAXPIXEL ./base/graphics.c 225;" d file: +MAXPTS ./base/easygl_constants.h 10;" d +MAX_ATOM_PARSE ./base/read_blif.c 20;" d file: +MAX_BLOCK_COLOURS ./base/draw.c 21;" d file: +MAX_CHANNEL_WIDTH ../../libarchfpga/include/arch_types.h 25;" d +MAX_FONT_SIZE ./base/graphics.c 179;" d file: +MAX_INV_TIMING_COST ./place/place.c 64;" d file: +MAX_LEN ./place/place_stats.c 9;" d file: +MAX_LOGS ./power/power.h 33;" d +MAX_MOVES_BEFORE_RECOMPUTE ./place/place.c 36;" d file: +MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY ./place/place.c 41;" d file: +MAX_PATTERN_SIZE ../../pcre/SRC/internal.h 100;" d +MAX_PATTERN_SIZE ../../pcre/SRC/internal.h 113;" d +MAX_PATTERN_SIZE ../../pcre/SRC/internal.h 127;" d +MAX_SHORT ./base/vpr_types.h 75;" d +MAX_STRING_LEN ./util/vpr_utils.c 18;" d file: +MAX_X ./place/place_stats.c 8;" d file: +MEDIUMPURPLE ./base/easygl_constants.h /^TURQUOISE, MEDIUMPURPLE, DARKSLATEBLUE, DARKKHAKI, NUM_COLOR};$/;" e enum:color_types +MEMORY_CLASS ../../libarchfpga/include/physical_types.h /^ UNKNOWN_CLASS = 0, LUT_CLASS = 1, LATCH_CLASS = 2, MEMORY_CLASS = 3$/;" e enum:e_pb_type_class +MINOR ./base/vpr_types.h 72;" d +MINPIXEL ./base/graphics.c 203;" d file: +MINPIXEL ./base/graphics.c 226;" d file: +MODEL_INPUT ./base/vpr_types.h 299;" d +MODEL_LATCH ./base/vpr_types.h 298;" d +MODEL_LOGIC ./base/vpr_types.h 297;" d +MODEL_OUTPUT ./base/vpr_types.h 300;" d +MOLECULE_FORCED_PACK ./base/vpr_types.h /^ MOLECULE_SINGLE_ATOM, MOLECULE_FORCED_PACK$/;" e enum:e_pack_pattern_molecule_type +MOLECULE_SINGLE_ATOM ./base/vpr_types.h /^ MOLECULE_SINGLE_ATOM, MOLECULE_FORCED_PACK$/;" e enum:e_pack_pattern_molecule_type +MONO ../../libarchfpga/include/arch_types_mrfpga.h /^ CONV = 0, MONO, STTRAM, PCRAM_Xie, PCRAM_Pierre, NEM $/;" e enum:e_tech_comp +MRFPGA_H ./mrfpga/mrfpga_globals.h 2;" d +MULTI_BUFFERED ./base/vpr_types.h /^ MULTI_BUFFERED, SINGLE$/;" e enum:e_drivers +MUX_INTERC ../../libarchfpga/include/physical_types.h /^ COMPLETE_INTERC = 1, DIRECT_INTERC = 2, MUX_INTERC = 3$/;" e enum:e_interconnect +MWIDTH ./base/graphics.c 177;" d file: +MainWND ./base/graphics.c /^MainWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)$/;" f file: +MergeOptions ./base/ReadOptions.c /^static void MergeOptions(INOUTP t_options * dest, INP t_options * src, int id)$/;" f file: +NDEBUG ./base/vpr_types.h 63;" d +NEGATIVE_EPSILON ./base/vpr_types.h 84;" d +NEM ../../libarchfpga/include/arch_types_mrfpga.h /^ CONV = 0, MONO, STTRAM, PCRAM_Xie, PCRAM_Pierre, NEM $/;" e enum:e_tech_comp +NET_COUNT ./place/timing_place_lookup.c 41;" d file: +NET_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 2;" d +NET_TIMING_DRIVEN_PLACE ./base/vpr_types.h /^ BOUNDING_BOX_PLACE, NET_TIMING_DRIVEN_PLACE, PATH_TIMING_DRIVEN_PLACE$/;" e enum:e_place_algorithm +NET_USED ./place/timing_place_lookup.c 45;" d file: +NET_USED_SINK_BLOCK ./place/timing_place_lookup.c 48;" d file: +NET_USED_SOURCE_BLOCK ./place/timing_place_lookup.c 47;" d file: +NEVER_CLUSTER ./base/vpr_types.h 99;" d +NEWLINE ../../pcre/SRC/config.h 45;" d +NMOS ./power/power.h /^ NMOS, PMOS$/;" e enum:__anon11 +NMOS_1X_C_d ./power/power.h /^ float NMOS_1X_C_d;$/;" m struct:s_power_commonly_used +NMOS_1X_C_g ./power/power.h /^ float NMOS_1X_C_g;$/;" m struct:s_power_commonly_used +NMOS_1X_C_s ./power/power.h /^ float NMOS_1X_C_s;$/;" m struct:s_power_commonly_used +NMOS_1X_st_leakage ./power/power.h /^ float NMOS_1X_st_leakage;$/;" m struct:s_power_commonly_used +NMOS_2X_st_leakage ./power/power.h /^ float NMOS_2X_st_leakage;$/;" m struct:s_power_commonly_used +NMOS_inf ./power/power.h /^ t_transistor_inf NMOS_inf;$/;" m struct:s_power_tech +NONSPACE ./timing/slre.c /^ STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT$/;" e enum:__anon19 file: +NORMAL ./place/place.c /^ NORMAL, CHECK$/;" e enum:cost_methods file: +NORMAL_LUT_MODE_INDEX ./fpga_x2p/base/fpga_x2p_types.h 25;" d +NOT_FOUND ./base/place_and_route.h 2;" d +NOT_HILL_CLIMBING ./pack/cluster.c /^ HILL_CLIMBING, NOT_HILL_CLIMBING$/;" e enum:e_gain_type file: +NOT_UPDATED_YET ./place/place.c 45;" d file: +NOT_VALID ./base/vpr_types.h 100;" d +NO_CLUSTER ./base/vpr_types.h 98;" d +NO_FIXED_CHANNEL_WIDTH ./base/vpr_types.h 739;" d +NO_GAIN ./pack/cluster.c /^ GAIN, NO_GAIN$/;" e enum:e_gain_update file: +NO_GRAPHICS ./base/vpr_types.h 62;" d +NO_PICTURE ./base/vpr_types.h /^ NO_PICTURE, PLACEMENT, ROUTING$/;" e enum:pic_type +NO_PREVIOUS ./base/vpr_types.h 939;" d +NO_ROUTE_THROUGHS ./route/route_tree_timing.c 255;" d file: +NO_TIMING ./base/vpr_types.h /^ BREADTH_FIRST, TIMING_DRIVEN, NO_TIMING$/;" e enum:e_router_algorithm +NUM_BUCKETS ./timing/path_delay.c 148;" d file: +NUM_COLOR ./base/easygl_constants.h /^TURQUOISE, MEDIUMPURPLE, DARKSLATEBLUE, DARKKHAKI, NUM_COLOR};$/;" e enum:color_types +NUM_FONT_TYPES ./base/graphics.c 2781;" d file: +NUM_MODELS_IN_LIBRARY ../../libarchfpga/include/read_xml_arch_file.h 14;" d +NUM_RR_TYPES ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +NUM_TYPES_USED ./place/timing_place_lookup.c 59;" d file: +NetFile ./base/ReadOptions.h /^ char *NetFile;$/;" m struct:s_options +NetFile ./base/vpr_types.h /^ char *NetFile;$/;" m struct:s_file_name_opts +OFF ./base/graphics.c 1362;" d file: +ON ./base/graphics.c 1363;" d file: +OPEN ../../libarchfpga/include/physical_types.h /^ OPEN = -1, DRIVER = 0, RECEIVER = 1$/;" e enum:e_pin_type +OPEN ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +OPIN ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +OPIN_COST_INDEX ./base/vpr_types.h /^ OPIN_COST_INDEX,$/;" e enum:e_cost_indices +OPTIONTOKENS_H ./base/OptionTokens.h 2;" d +OPT_CHAR ./fpga_x2p/shell/read_opt_types.h /^ OPT_CHAR,$/;" e enum:opt_val_type +OPT_DEF ./fpga_x2p/shell/read_opt_types.h /^ OPT_DEF,$/;" e enum:opt_default +OPT_DOUBLE ./fpga_x2p/shell/read_opt_types.h /^ OPT_DOUBLE$/;" e enum:opt_val_type +OPT_FLOAT ./fpga_x2p/shell/read_opt_types.h /^ OPT_FLOAT,$/;" e enum:opt_val_type +OPT_INT ./fpga_x2p/shell/read_opt_types.h /^ OPT_INT,$/;" e enum:opt_val_type +OPT_NONDEF ./fpga_x2p/shell/read_opt_types.h /^ OPT_NONDEF$/;" e enum:opt_default +OPT_NONVAL ./fpga_x2p/shell/read_opt_types.h /^ OPT_NONVAL,$/;" e enum:opt_with_val +OPT_OPT ./fpga_x2p/shell/read_opt_types.h /^ OPT_OPT$/;" e enum:opt_manda +OPT_REQ ./fpga_x2p/shell/read_opt_types.h /^ OPT_REQ,$/;" e enum:opt_manda +OPT_WITHVAL ./fpga_x2p/shell/read_opt_types.h /^ OPT_WITHVAL$/;" e enum:opt_with_val +OP_ALT ../../pcre/SRC/internal.h /^ OP_ALT, \/* 60 Start of alternation *\/$/;" e enum:__anon25 +OP_ANY ../../pcre/SRC/internal.h /^ OP_ANY, \/* 11 Match any character *\/$/;" e enum:__anon25 +OP_ANYBYTE ../../pcre/SRC/internal.h /^ OP_ANYBYTE, \/* 12 Match any byte (\\C); different to OP_ANY for UTF-8 *\/$/;" e enum:__anon25 +OP_ASSERT ../../pcre/SRC/internal.h /^ OP_ASSERT, \/* 64 Positive lookahead *\/$/;" e enum:__anon25 +OP_ASSERTBACK ../../pcre/SRC/internal.h /^ OP_ASSERTBACK, \/* 66 Positive lookbehind *\/$/;" e enum:__anon25 +OP_ASSERTBACK_NOT ../../pcre/SRC/internal.h /^ OP_ASSERTBACK_NOT, \/* 67 Negative lookbehind *\/$/;" e enum:__anon25 +OP_ASSERT_NOT ../../pcre/SRC/internal.h /^ OP_ASSERT_NOT, \/* 65 Negative lookahead *\/$/;" e enum:__anon25 +OP_BRA ../../pcre/SRC/internal.h /^ OP_BRA \/* 75 This and greater values are used for brackets that$/;" e enum:__anon25 +OP_BRAMINZERO ../../pcre/SRC/internal.h /^ OP_BRAMINZERO, \/* 73 order. *\/$/;" e enum:__anon25 +OP_BRANUMBER ../../pcre/SRC/internal.h /^ OP_BRANUMBER, \/* 74 Used for extracting brackets whose number is greater$/;" e enum:__anon25 +OP_BRAZERO ../../pcre/SRC/internal.h /^ OP_BRAZERO, \/* 72 These two must remain together and in this *\/$/;" e enum:__anon25 +OP_CALLOUT ../../pcre/SRC/internal.h /^ OP_CALLOUT, \/* 59 Call out to external function if provided *\/$/;" e enum:__anon25 +OP_CHARS ../../pcre/SRC/internal.h /^ OP_CHARS, \/* 18 Match string of characters *\/$/;" e enum:__anon25 +OP_CIRC ../../pcre/SRC/internal.h /^ OP_CIRC, \/* 16 Start of line - varies with multiline switch *\/$/;" e enum:__anon25 +OP_CLASS ../../pcre/SRC/internal.h /^ OP_CLASS, \/* 55 Match a character class, chars < 256 only *\/$/;" e enum:__anon25 +OP_COND ../../pcre/SRC/internal.h /^ OP_COND, \/* 70 Conditional group *\/$/;" e enum:__anon25 +OP_CREF ../../pcre/SRC/internal.h /^ OP_CREF, \/* 71 Used to hold an extraction string number (cond ref) *\/$/;" e enum:__anon25 +OP_CRMINPLUS ../../pcre/SRC/internal.h /^ OP_CRMINPLUS, \/* 50 be in exactly the same order as those above. *\/$/;" e enum:__anon25 +OP_CRMINQUERY ../../pcre/SRC/internal.h /^ OP_CRMINQUERY, \/* 52 *\/$/;" e enum:__anon25 +OP_CRMINRANGE ../../pcre/SRC/internal.h /^ OP_CRMINRANGE, \/* 54 *\/$/;" e enum:__anon25 +OP_CRMINSTAR ../../pcre/SRC/internal.h /^ OP_CRMINSTAR, \/* 48 all these opcodes must come in pairs, with *\/$/;" e enum:__anon25 +OP_CRPLUS ../../pcre/SRC/internal.h /^ OP_CRPLUS, \/* 49 the minimizing one second. These codes must *\/$/;" e enum:__anon25 +OP_CRQUERY ../../pcre/SRC/internal.h /^ OP_CRQUERY, \/* 51 These are for character classes and back refs *\/$/;" e enum:__anon25 +OP_CRRANGE ../../pcre/SRC/internal.h /^ OP_CRRANGE, \/* 53 These are different to the three seta above. *\/$/;" e enum:__anon25 +OP_CRSTAR ../../pcre/SRC/internal.h /^ OP_CRSTAR, \/* 47 The maximizing and minimizing versions of *\/$/;" e enum:__anon25 +OP_DIGIT ../../pcre/SRC/internal.h /^ OP_DIGIT, \/* 6 \\d *\/$/;" e enum:__anon25 +OP_DOLL ../../pcre/SRC/internal.h /^ OP_DOLL, \/* 17 End of line - varies with multiline switch *\/$/;" e enum:__anon25 +OP_END ../../pcre/SRC/internal.h /^ OP_END, \/* 0 End of pattern *\/$/;" e enum:__anon25 +OP_EOD ../../pcre/SRC/internal.h /^ OP_EOD, \/* 14 End of data: \\z *\/$/;" e enum:__anon25 +OP_EODN ../../pcre/SRC/internal.h /^ OP_EODN, \/* 13 End of data or \\n at end of data: \\Z. *\/$/;" e enum:__anon25 +OP_EXACT ../../pcre/SRC/internal.h /^ OP_EXACT, \/* 28 Exactly n matches *\/$/;" e enum:__anon25 +OP_KET ../../pcre/SRC/internal.h /^ OP_KET, \/* 61 End of group that doesn't have an unbounded repeat *\/$/;" e enum:__anon25 +OP_KETRMAX ../../pcre/SRC/internal.h /^ OP_KETRMAX, \/* 62 These two must remain together and in this *\/$/;" e enum:__anon25 +OP_KETRMIN ../../pcre/SRC/internal.h /^ OP_KETRMIN, \/* 63 order. They are for groups the repeat for ever. *\/$/;" e enum:__anon25 +OP_LENGTHS ../../pcre/SRC/internal.h 425;" d +OP_MINPLUS ../../pcre/SRC/internal.h /^ OP_MINPLUS, \/* 23 This first set applies to single characters *\/$/;" e enum:__anon25 +OP_MINQUERY ../../pcre/SRC/internal.h /^ OP_MINQUERY, \/* 25 *\/$/;" e enum:__anon25 +OP_MINSTAR ../../pcre/SRC/internal.h /^ OP_MINSTAR, \/* 21 all these opcodes must come in pairs, with *\/$/;" e enum:__anon25 +OP_MINUPTO ../../pcre/SRC/internal.h /^ OP_MINUPTO, \/* 27 *\/$/;" e enum:__anon25 +OP_NAME_LIST ../../pcre/SRC/internal.h 402;" d +OP_NCLASS ../../pcre/SRC/internal.h /^ OP_NCLASS, \/* 56 Same, but the bitmap was created from a negative$/;" e enum:__anon25 +OP_NOT ../../pcre/SRC/internal.h /^ OP_NOT, \/* 19 Match anything but the following char *\/$/;" e enum:__anon25 +OP_NOTEXACT ../../pcre/SRC/internal.h /^ OP_NOTEXACT, \/* 37 Exactly n matches *\/$/;" e enum:__anon25 +OP_NOTMINPLUS ../../pcre/SRC/internal.h /^ OP_NOTMINPLUS, \/* 32 This set applies to "not" single characters *\/$/;" e enum:__anon25 +OP_NOTMINQUERY ../../pcre/SRC/internal.h /^ OP_NOTMINQUERY, \/* 34 *\/$/;" e enum:__anon25 +OP_NOTMINSTAR ../../pcre/SRC/internal.h /^ OP_NOTMINSTAR, \/* 30 all these opcodes must come in pairs, with *\/$/;" e enum:__anon25 +OP_NOTMINUPTO ../../pcre/SRC/internal.h /^ OP_NOTMINUPTO, \/* 36 *\/$/;" e enum:__anon25 +OP_NOTPLUS ../../pcre/SRC/internal.h /^ OP_NOTPLUS, \/* 31 the minimizing one second. *\/$/;" e enum:__anon25 +OP_NOTQUERY ../../pcre/SRC/internal.h /^ OP_NOTQUERY, \/* 33 *\/$/;" e enum:__anon25 +OP_NOTSTAR ../../pcre/SRC/internal.h /^ OP_NOTSTAR, \/* 29 The maximizing and minimizing versions of *\/$/;" e enum:__anon25 +OP_NOTUPTO ../../pcre/SRC/internal.h /^ OP_NOTUPTO, \/* 35 From 0 to n matches *\/$/;" e enum:__anon25 +OP_NOT_DIGIT ../../pcre/SRC/internal.h /^ OP_NOT_DIGIT, \/* 5 \\D *\/$/;" e enum:__anon25 +OP_NOT_WHITESPACE ../../pcre/SRC/internal.h /^ OP_NOT_WHITESPACE, \/* 7 \\S *\/$/;" e enum:__anon25 +OP_NOT_WORDCHAR ../../pcre/SRC/internal.h /^ OP_NOT_WORDCHAR, \/* 9 \\W *\/$/;" e enum:__anon25 +OP_NOT_WORD_BOUNDARY ../../pcre/SRC/internal.h /^ OP_NOT_WORD_BOUNDARY, \/* 3 \\B *\/$/;" e enum:__anon25 +OP_ONCE ../../pcre/SRC/internal.h /^ OP_ONCE, \/* 69 Once matched, don't back up into the subpattern *\/$/;" e enum:__anon25 +OP_OPT ../../pcre/SRC/internal.h /^ OP_OPT, \/* 15 Set runtime options *\/$/;" e enum:__anon25 +OP_PLUS ../../pcre/SRC/internal.h /^ OP_PLUS, \/* 22 the minimizing one second. *\/$/;" e enum:__anon25 +OP_QUERY ../../pcre/SRC/internal.h /^ OP_QUERY, \/* 24 *\/$/;" e enum:__anon25 +OP_RECURSE ../../pcre/SRC/internal.h /^ OP_RECURSE, \/* 58 Match a numbered subpattern (possibly recursive) *\/$/;" e enum:__anon25 +OP_REF ../../pcre/SRC/internal.h /^ OP_REF, \/* 57 Match a back reference *\/$/;" e enum:__anon25 +OP_REVERSE ../../pcre/SRC/internal.h /^ OP_REVERSE, \/* 68 Move pointer back - used in lookbehind assertions *\/$/;" e enum:__anon25 +OP_SOD ../../pcre/SRC/internal.h /^ OP_SOD, \/* 1 Start of data: \\A *\/$/;" e enum:__anon25 +OP_SOM ../../pcre/SRC/internal.h /^ OP_SOM, \/* 2 Start of match (subject + offset): \\G *\/$/;" e enum:__anon25 +OP_STAR ../../pcre/SRC/internal.h /^ OP_STAR, \/* 20 The maximizing and minimizing versions of *\/$/;" e enum:__anon25 +OP_TYPEEXACT ../../pcre/SRC/internal.h /^ OP_TYPEEXACT, \/* 46 Exactly n matches *\/$/;" e enum:__anon25 +OP_TYPEMINPLUS ../../pcre/SRC/internal.h /^ OP_TYPEMINPLUS, \/* 41 be in exactly the same order as those above. *\/$/;" e enum:__anon25 +OP_TYPEMINQUERY ../../pcre/SRC/internal.h /^ OP_TYPEMINQUERY, \/* 43 *\/$/;" e enum:__anon25 +OP_TYPEMINSTAR ../../pcre/SRC/internal.h /^ OP_TYPEMINSTAR, \/* 39 all these opcodes must come in pairs, with *\/$/;" e enum:__anon25 +OP_TYPEMINUPTO ../../pcre/SRC/internal.h /^ OP_TYPEMINUPTO, \/* 45 *\/$/;" e enum:__anon25 +OP_TYPEPLUS ../../pcre/SRC/internal.h /^ OP_TYPEPLUS, \/* 40 the minimizing one second. These codes must *\/$/;" e enum:__anon25 +OP_TYPEQUERY ../../pcre/SRC/internal.h /^ OP_TYPEQUERY, \/* 42 This set applies to character types such as \\d *\/$/;" e enum:__anon25 +OP_TYPESTAR ../../pcre/SRC/internal.h /^ OP_TYPESTAR, \/* 38 The maximizing and minimizing versions of *\/$/;" e enum:__anon25 +OP_TYPEUPTO ../../pcre/SRC/internal.h /^ OP_TYPEUPTO, \/* 44 From 0 to n matches *\/$/;" e enum:__anon25 +OP_UPTO ../../pcre/SRC/internal.h /^ OP_UPTO, \/* 26 From 0 to n matches *\/$/;" e enum:__anon25 +OP_WHITESPACE ../../pcre/SRC/internal.h /^ OP_WHITESPACE, \/* 8 \\s *\/$/;" e enum:__anon25 +OP_WORDCHAR ../../pcre/SRC/internal.h /^ OP_WORDCHAR, \/* 10 \\w *\/$/;" e enum:__anon25 +OP_WORD_BOUNDARY ../../pcre/SRC/internal.h /^ OP_WORD_BOUNDARY, \/* 4 \\b *\/$/;" e enum:__anon25 +OP_XCLASS ../../pcre/SRC/internal.h /^ OP_XCLASS, \/* 56 Extended class for handling UTF-8 chars within the$/;" e enum:__anon25 +OP_lengths ../../pcre/SRC/pcre.c /^static uschar OP_lengths[] = { OP_LENGTHS };$/;" v file: +OT_ACC_FAC ./base/OptionTokens.h /^ OT_ACC_FAC,$/;" e enum:e_OptionBaseToken +OT_ACTIVITY_FILE ./base/OptionTokens.h /^ OT_ACTIVITY_FILE,$/;" e enum:e_OptionBaseToken +OT_ALLOW_EARLY_EXIT ./base/OptionTokens.h /^ OT_ALLOW_EARLY_EXIT,$/;" e enum:e_OptionBaseToken +OT_ALLOW_UNRELATED_CLUSTERING ./base/OptionTokens.h /^ OT_ALLOW_UNRELATED_CLUSTERING,$/;" e enum:e_OptionBaseToken +OT_ALPHA_CLUSTERING ./base/OptionTokens.h /^ OT_ALPHA_CLUSTERING,$/;" e enum:e_OptionBaseToken +OT_ALPHA_T ./base/OptionTokens.h /^ OT_ALPHA_T,$/;" e enum:e_OptionBaseToken +OT_ARG_UNKNOWN ./base/OptionTokens.h /^ OT_ARG_UNKNOWN \/* Must be last since used for counting enum items *\/$/;" e enum:e_OptionArgToken +OT_ASTAR_FAC ./base/OptionTokens.h /^ OT_ASTAR_FAC,$/;" e enum:e_OptionBaseToken +OT_AUTO ./base/OptionTokens.h /^ OT_AUTO,$/;" e enum:e_OptionBaseToken +OT_BASE_COST_TYPE ./base/OptionTokens.h /^ OT_BASE_COST_TYPE,$/;" e enum:e_OptionBaseToken +OT_BASE_UNKNOWN ./base/OptionTokens.h /^ OT_BASE_UNKNOWN \/* Must be last since used for counting enum items *\/$/;" e enum:e_OptionBaseToken +OT_BB_FACTOR ./base/OptionTokens.h /^ OT_BB_FACTOR,$/;" e enum:e_OptionBaseToken +OT_BEND_COST ./base/OptionTokens.h /^ OT_BEND_COST,$/;" e enum:e_OptionBaseToken +OT_BETA_CLUSTERING ./base/OptionTokens.h /^ OT_BETA_CLUSTERING,$/;" e enum:e_OptionBaseToken +OT_BLIF_FILE ./base/OptionTokens.h /^ OT_BLIF_FILE,$/;" e enum:e_OptionBaseToken +OT_BLOCK_DIST ./base/OptionTokens.h /^ OT_BLOCK_DIST,$/;" e enum:e_OptionBaseToken +OT_BOUNDING_BOX ./base/OptionTokens.h /^ OT_BOUNDING_BOX,$/;" e enum:e_OptionArgToken +OT_BREADTH_FIRST ./base/OptionTokens.h /^ OT_BREADTH_FIRST,$/;" e enum:e_OptionArgToken +OT_BRUTE_FORCE ./base/OptionTokens.h /^ OT_BRUTE_FORCE,$/;" e enum:e_OptionArgToken +OT_CLUSTER_BLOCK_DELAY ./base/OptionTokens.h /^ OT_CLUSTER_BLOCK_DELAY,$/;" e enum:e_OptionBaseToken +OT_CLUSTER_SEED ./base/OptionTokens.h /^ OT_CLUSTER_SEED,$/;" e enum:e_OptionBaseToken +OT_CMOS_TECH_BEHAVIOR_FILE ./base/OptionTokens.h /^ OT_CMOS_TECH_BEHAVIOR_FILE,$/;" e enum:e_OptionBaseToken +OT_CONNECTION_DRIVEN_CLUSTERING ./base/OptionTokens.h /^ OT_CONNECTION_DRIVEN_CLUSTERING,$/;" e enum:e_OptionBaseToken +OT_CREATE_ECHO_FILE ./base/OptionTokens.h /^ OT_CREATE_ECHO_FILE,$/;" e enum:e_OptionBaseToken +OT_CRITICALITY_EXP ./base/OptionTokens.h /^ OT_CRITICALITY_EXP,$/;" e enum:e_OptionBaseToken +OT_DELAY_NORMALIZED ./base/OptionTokens.h /^ OT_DELAY_NORMALIZED,$/;" e enum:e_OptionArgToken +OT_DEMAND_ONLY ./base/OptionTokens.h /^ OT_DEMAND_ONLY,$/;" e enum:e_OptionArgToken +OT_DETAILED ./base/OptionTokens.h /^ OT_DETAILED,$/;" e enum:e_OptionArgToken +OT_ENABLE_TIMING_COMPUTATIONS ./base/OptionTokens.h /^ OT_ENABLE_TIMING_COMPUTATIONS,$/;" e enum:e_OptionBaseToken +OT_EXIT_T ./base/OptionTokens.h /^ OT_EXIT_T,$/;" e enum:e_OptionBaseToken +OT_FAST ./base/OptionTokens.h /^ OT_FAST,$/;" e enum:e_OptionBaseToken +OT_FIRST_ITER_PRES_FAC ./base/OptionTokens.h /^ OT_FIRST_ITER_PRES_FAC,$/;" e enum:e_OptionBaseToken +OT_FIX_PINS ./base/OptionTokens.h /^ OT_FIX_PINS,$/;" e enum:e_OptionBaseToken +OT_FPGA_BITSTREAM_GENERATOR ./base/OptionTokens.h /^ OT_FPGA_BITSTREAM_GENERATOR,$/;" e enum:e_OptionBaseToken +OT_FPGA_BITSTREAM_OUTPUT_FILE ./base/OptionTokens.h /^ OT_FPGA_BITSTREAM_OUTPUT_FILE,$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE ./base/OptionTokens.h /^ OT_FPGA_SPICE, \/* Xifan TANG: FPGA SPICE Model Support *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_DIR ./base/OptionTokens.h /^ OT_FPGA_SPICE_DIR, \/* Xifan TANG: FPGA SPICE Model Support *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_LEAKAGE_ONLY ./base/OptionTokens.h /^ OT_FPGA_SPICE_LEAKAGE_ONLY, \/* Xifan TANG: Print SPICE Testbench for MUXes *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION ./base/OptionTokens.h /^ OT_FPGA_SPICE_PARASITIC_NET_ESTIMATION, \/* Xifan TANG: turn on\/off the parasitic net estimation*\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_CB_MUX_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_CB_MUX_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for MUXes *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_CB_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_CB_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for CBs *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_GRID_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_GRID_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for Grids *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_HARDLOGIC_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_HARDLOGIC_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for hard logic s *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_IO_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_IO_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for hard logic s *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_LUT_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_LUT_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for LUTs *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_PB_MUX_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_PB_MUX_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for MUXes *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_SB_MUX_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_SB_MUX_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for MUXes *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_SB_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_SB_TESTBENCH, \/* Xifan TANG: Print SPICE Testbench for SBs *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_PRINT_TOP_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_SPICE_PRINT_TOP_TESTBENCH, \/* Xifan TANG: Print Top-level SPICE Testbench *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_SIMULATOR_PATH ./base/OptionTokens.h /^ OT_FPGA_SPICE_SIMULATOR_PATH,$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_SIM_MT_NUM ./base/OptionTokens.h /^ OT_FPGA_SPICE_SIM_MT_NUM, \/* number of multi-thread used in simulation *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION ./base/OptionTokens.h /^ OT_FPGA_SPICE_TESTBENCH_LOAD_EXTRACTION, \/* Xifan TANG: turn on\/off the testbench load extraction *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN, \/* Xifan TANG: Synthesizable Verilog Dump *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_DIR ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_DIR, \/* Xifan TANG: Synthesizable Verilog Dump *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_INCLUDE_ICARUS_SIMULATOR ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_INCLUDE_ICARUS_SIMULATOR,$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_INCLUDE_SIGNAL_INIT ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_INCLUDE_SIGNAL_INIT, \/* Xifan TANG: Include timing constraints in Verilog *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_INCLUDE_TIMING ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_INCLUDE_TIMING, \/* Xifan TANG: Include timing constraints in Verilog *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_AUTOCHECK_TOP_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_AUTOCHECK_TOP_TESTBENCH, \/* Xifan Tang: Synthesizable Verilog, turn on option: output testbench for top-level netlist *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_FORMAL_VERIFICATION_TOP_NETLIST ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_FORMAL_VERIFICATION_TOP_NETLIST, \/* Xifan Tang: Synthesizable Verilog, turn on option: output netlists in a compact way *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_INPUT_BLIF_TESTBENCH, \/* Xifan Tang: Synthesizable Verilog, turn on option: output testbench for the orignial input blif *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_MODELSIM_AUTODECK,$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_REPORT_TIMING_TCL ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_REPORT_TIMING_TCL,$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_SDC_ANALYSIS ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_SDC_ANALYSIS,$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_SDC_PNR ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_SDC_PNR,$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_TOP_TESTBENCH ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_TOP_TESTBENCH, \/* Xifan Tang: Synthesizable Verilog, turn on option: output testbench for top-level netlist *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_PRINT_USER_DEFINED_TEMPLATE ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_PRINT_USER_DEFINED_TEMPLATE,$/;" e enum:e_OptionBaseToken +OT_FPGA_VERILOG_SYN_REPORT_TIMING_RPT_PATH ./base/OptionTokens.h /^ OT_FPGA_VERILOG_SYN_REPORT_TIMING_RPT_PATH,$/;" e enum:e_OptionBaseToken +OT_FPGA_X2P_RENAME_ILLEGAL_PORT ./base/OptionTokens.h /^ OT_FPGA_X2P_RENAME_ILLEGAL_PORT, $/;" e enum:e_OptionBaseToken +OT_FPGA_X2P_SIGNAL_DENSITY_WEIGHT ./base/OptionTokens.h /^ OT_FPGA_X2P_SIGNAL_DENSITY_WEIGHT, \/* The weight of signal density in determining number of clock cycles in simulation *\/$/;" e enum:e_OptionBaseToken +OT_FPGA_X2P_SIM_WINDOW_SIZE ./base/OptionTokens.h /^ OT_FPGA_X2P_SIM_WINDOW_SIZE, \/* Window size in determining number of clock cycles in simulation *\/$/;" e enum:e_OptionBaseToken +OT_FULL_STATS ./base/OptionTokens.h /^ OT_FULL_STATS,$/;" e enum:e_OptionBaseToken +OT_GENERATE_POST_SYNTHESIS_NETLIST ./base/OptionTokens.h /^ OT_GENERATE_POST_SYNTHESIS_NETLIST,$/;" e enum:e_OptionBaseToken +OT_GLOBAL ./base/OptionTokens.h /^ OT_GLOBAL,$/;" e enum:e_OptionArgToken +OT_GLOBAL_CLOCKS ./base/OptionTokens.h /^ OT_GLOBAL_CLOCKS,$/;" e enum:e_OptionBaseToken +OT_GREEDY ./base/OptionTokens.h /^ OT_GREEDY,$/;" e enum:e_OptionArgToken +OT_HILL_CLIMBING_FLAG ./base/OptionTokens.h /^ OT_HILL_CLIMBING_FLAG,$/;" e enum:e_OptionBaseToken +OT_INITIAL_PRES_FAC ./base/OptionTokens.h /^ OT_INITIAL_PRES_FAC,$/;" e enum:e_OptionBaseToken +OT_INIT_T ./base/OptionTokens.h /^ OT_INIT_T,$/;" e enum:e_OptionBaseToken +OT_INNER_LOOP_RECOMPUTE_DIVIDER ./base/OptionTokens.h /^ OT_INNER_LOOP_RECOMPUTE_DIVIDER,$/;" e enum:e_OptionBaseToken +OT_INNER_NUM ./base/OptionTokens.h /^ OT_INNER_NUM,$/;" e enum:e_OptionBaseToken +OT_INTER_CLUSTER_NET_DELAY ./base/OptionTokens.h /^ OT_INTER_CLUSTER_NET_DELAY,$/;" e enum:e_OptionBaseToken +OT_INTRA_CLUSTER_NET_DELAY ./base/OptionTokens.h /^ OT_INTRA_CLUSTER_NET_DELAY,$/;" e enum:e_OptionBaseToken +OT_INTRINSIC_DELAY ./base/OptionTokens.h /^ OT_INTRINSIC_DELAY,$/;" e enum:e_OptionArgToken +OT_LP ./base/OptionTokens.h /^ OT_LP,$/;" e enum:e_OptionArgToken +OT_MAX_CRITICALITY ./base/OptionTokens.h /^ OT_MAX_CRITICALITY,$/;" e enum:e_OptionBaseToken +OT_MAX_INPUTS ./base/OptionTokens.h /^ OT_MAX_INPUTS,$/;" e enum:e_OptionArgToken +OT_MAX_ROUTER_ITERATIONS ./base/OptionTokens.h /^ OT_MAX_ROUTER_ITERATIONS,$/;" e enum:e_OptionBaseToken +OT_NET_FILE ./base/OptionTokens.h /^ OT_NET_FILE,$/;" e enum:e_OptionBaseToken +OT_NET_TIMING_DRIVEN ./base/OptionTokens.h /^ OT_NET_TIMING_DRIVEN,$/;" e enum:e_OptionArgToken +OT_NODISP ./base/OptionTokens.h /^ OT_NODISP,$/;" e enum:e_OptionBaseToken +OT_NO_TIMING ./base/OptionTokens.h /^ OT_NO_TIMING,$/;" e enum:e_OptionArgToken +OT_OFF ./base/OptionTokens.h /^ OT_OFF,$/;" e enum:e_OptionArgToken +OT_ON ./base/OptionTokens.h /^ OT_ON,$/;" e enum:e_OptionArgToken +OT_OUTFILE_PREFIX ./base/OptionTokens.h /^ OT_OUTFILE_PREFIX,$/;" e enum:e_OptionBaseToken +OT_PACK ./base/OptionTokens.h /^ OT_PACK,$/;" e enum:e_OptionBaseToken +OT_PACKER_ALGORITHM ./base/OptionTokens.h /^ OT_PACKER_ALGORITHM,$/;" e enum:e_OptionBaseToken +OT_PACK_CLB_PIN_REMAP ./base/OptionTokens.h /^ OT_PACK_CLB_PIN_REMAP,$/;" e enum:e_OptionBaseToken +OT_PATH_TIMING_DRIVEN ./base/OptionTokens.h /^ OT_PATH_TIMING_DRIVEN,$/;" e enum:e_OptionArgToken +OT_PLACE ./base/OptionTokens.h /^ OT_PLACE,$/;" e enum:e_OptionBaseToken +OT_PLACE_ALGORITHM ./base/OptionTokens.h /^ OT_PLACE_ALGORITHM,$/;" e enum:e_OptionBaseToken +OT_PLACE_CHAN_WIDTH ./base/OptionTokens.h /^ OT_PLACE_CHAN_WIDTH,$/;" e enum:e_OptionBaseToken +OT_PLACE_CLB_PIN_REMAP ./base/OptionTokens.h /^ OT_PLACE_CLB_PIN_REMAP,$/;" e enum:e_OptionBaseToken +OT_PLACE_COST_EXP ./base/OptionTokens.h /^ OT_PLACE_COST_EXP,$/;" e enum:e_OptionBaseToken +OT_PLACE_FILE ./base/OptionTokens.h /^ OT_PLACE_FILE,$/;" e enum:e_OptionBaseToken +OT_POWER ./base/OptionTokens.h /^ OT_POWER,$/;" e enum:e_OptionBaseToken +OT_POWER_OUT_FILE ./base/OptionTokens.h /^ OT_POWER_OUT_FILE,$/;" e enum:e_OptionBaseToken +OT_PRES_FAC_MULT ./base/OptionTokens.h /^ OT_PRES_FAC_MULT,$/;" e enum:e_OptionBaseToken +OT_RANDOM ./base/OptionTokens.h /^ OT_RANDOM,$/;" e enum:e_OptionArgToken +OT_READ_PLACE_ONLY ./base/OptionTokens.h /^ OT_READ_PLACE_ONLY,$/;" e enum:e_OptionBaseToken +OT_RECOMPUTE_CRIT_ITER ./base/OptionTokens.h /^ OT_RECOMPUTE_CRIT_ITER,$/;" e enum:e_OptionBaseToken +OT_RECOMPUTE_TIMING_AFTER ./base/OptionTokens.h /^ OT_RECOMPUTE_TIMING_AFTER,$/;" e enum:e_OptionBaseToken +OT_ROUTE ./base/OptionTokens.h /^ OT_ROUTE,$/;" e enum:e_OptionBaseToken +OT_ROUTER_ALGORITHM ./base/OptionTokens.h /^ OT_ROUTER_ALGORITHM,$/;" e enum:e_OptionBaseToken +OT_ROUTE_CHAN_WIDTH ./base/OptionTokens.h /^ OT_ROUTE_CHAN_WIDTH,$/;" e enum:e_OptionBaseToken +OT_ROUTE_FILE ./base/OptionTokens.h /^ OT_ROUTE_FILE,$/;" e enum:e_OptionBaseToken +OT_ROUTE_TYPE ./base/OptionTokens.h /^ OT_ROUTE_TYPE,$/;" e enum:e_OptionBaseToken +OT_SDC_FILE ./base/OptionTokens.h /^ OT_SDC_FILE,$/;" e enum:e_OptionBaseToken +OT_SEED ./base/OptionTokens.h /^ OT_SEED,$/;" e enum:e_OptionBaseToken +OT_SETTINGS_FILE ./base/OptionTokens.h /^ OT_SETTINGS_FILE,$/;" e enum:e_OptionBaseToken +OT_SHOW_PASS_TRANS ./base/OptionTokens.h /^ OT_SHOW_PASS_TRANS,$/;" e enum:e_OptionBaseToken +OT_SHOW_SRAM ./base/OptionTokens.h /^ OT_SHOW_SRAM,$/;" e enum:e_OptionBaseToken +OT_SKIP_CLUSTERING ./base/OptionTokens.h /^ OT_SKIP_CLUSTERING,$/;" e enum:e_OptionBaseToken +OT_SWEEP_HANGING_NETS_AND_INPUTS ./base/OptionTokens.h /^ OT_SWEEP_HANGING_NETS_AND_INPUTS,$/;" e enum:e_OptionBaseToken +OT_TD_PLACE_EXP_FIRST ./base/OptionTokens.h /^ OT_TD_PLACE_EXP_FIRST,$/;" e enum:e_OptionBaseToken +OT_TD_PLACE_EXP_LAST ./base/OptionTokens.h /^ OT_TD_PLACE_EXP_LAST,$/;" e enum:e_OptionBaseToken +OT_TIMING ./base/OptionTokens.h /^ OT_TIMING,$/;" e enum:e_OptionArgToken +OT_TIMING_ANALYSIS ./base/OptionTokens.h /^ OT_TIMING_ANALYSIS,$/;" e enum:e_OptionBaseToken +OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY ./base/OptionTokens.h /^ OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY,$/;" e enum:e_OptionBaseToken +OT_TIMING_DRIVEN ./base/OptionTokens.h /^ OT_TIMING_DRIVEN,$/;" e enum:e_OptionArgToken +OT_TIMING_DRIVEN_CLUSTERING ./base/OptionTokens.h /^ OT_TIMING_DRIVEN_CLUSTERING,$/;" e enum:e_OptionBaseToken +OT_TIMING_TRADEOFF ./base/OptionTokens.h /^ OT_TIMING_TRADEOFF,$/;" e enum:e_OptionBaseToken +OT_VERIFY_BINARY_SEARCH ./base/OptionTokens.h /^ OT_VERIFY_BINARY_SEARCH,$/;" e enum:e_OptionBaseToken +OUTP ../../libarchfpga/include/util.h 20;" d +OUTPUT ./pack/cluster.c /^ INPUT, OUTPUT$/;" e enum:e_net_relation_to_clustered_block file: +OUTPUT2OUTPUT_INTERC ../../libarchfpga/fpga_spice_include/spice_types.h /^ OUTPUT2OUTPUT_INTERC$/;" e enum:e_spice_pin2pin_interc_type +OUT_PORT ../../libarchfpga/include/logic_types.h /^ IN_PORT, OUT_PORT, INOUT_PORT, ERR_PORT$/;" e enum:PORTS +OVECCOUNT ../../pcre/SRC/main.c 23;" d file: +Operation ./base/vpr_types.h /^ enum e_operation Operation; \/* run VPR or do analysis only *\/$/;" m struct:s_vpr_setup typeref:enum:s_vpr_setup::e_operation +OptionArgTokenList ./base/OptionTokens.c /^struct s_TokenPair OptionArgTokenList[] = { { "on", OT_ON }, { "off", OT_OFF },$/;" v typeref:struct:s_TokenPair +OptionBaseTokenList ./base/OptionTokens.c /^struct s_TokenPair OptionBaseTokenList[] = {$/;" v typeref:struct:s_TokenPair +PACK_BRUTE_FORCE ./base/vpr_types.h /^ PACK_GREEDY, PACK_BRUTE_FORCE$/;" e enum:e_packer_algorithm +PACK_CMD ./fpga_x2p/shell/shell_types.h /^ PACK_CMD,$/;" e enum:e_cmd_category +PACK_GREEDY ./base/vpr_types.h /^ PACK_GREEDY, PACK_BRUTE_FORCE$/;" e enum:e_packer_algorithm +PACK_PATH_WEIGHT ./timing/path_delay.h 34;" d +PALCE_MACRO_H ./place/place_macro.h 136;" d +PATH_DELAY ./timing/path_delay.h 2;" d +PATH_TIMING_DRIVEN_PLACE ./base/vpr_types.h /^ BOUNDING_BOX_PLACE, NET_TIMING_DRIVEN_PLACE, PATH_TIMING_DRIVEN_PLACE$/;" e enum:e_place_algorithm +PB_PIN_CLOCK ../../libarchfpga/include/physical_types.h /^ PB_PIN_CLOCK$/;" e enum:e_pb_graph_pin_type +PB_PIN_EQ_AUTO_DETECT_H ./route/pb_pin_eq_auto_detect.h 3;" d +PB_PIN_INPAD ../../libarchfpga/include/physical_types.h /^ PB_PIN_INPAD,$/;" e enum:e_pb_graph_pin_type +PB_PIN_NORMAL ../../libarchfpga/include/physical_types.h /^ PB_PIN_NORMAL = 0,$/;" e enum:e_pb_graph_pin_type +PB_PIN_OUTPAD ../../libarchfpga/include/physical_types.h /^ PB_PIN_OUTPAD,$/;" e enum:e_pb_graph_pin_type +PB_PIN_SEQUENTIAL ../../libarchfpga/include/physical_types.h /^ PB_PIN_SEQUENTIAL,$/;" e enum:e_pb_graph_pin_type +PB_PIN_TERMINAL ../../libarchfpga/include/physical_types.h /^ PB_PIN_TERMINAL,$/;" e enum:e_pb_graph_pin_type +PB_TYPE_GRAPH_ANNOTATIONS_H ./pack/pb_type_graph_annotations.h 8;" d +PB_TYPE_GRAPH_H ./pack/pb_type_graph.h 2;" d +PCRAM_Pierre ../../libarchfpga/include/arch_types_mrfpga.h /^ CONV = 0, MONO, STTRAM, PCRAM_Xie, PCRAM_Pierre, NEM $/;" e enum:e_tech_comp +PCRAM_Xie ../../libarchfpga/include/arch_types_mrfpga.h /^ CONV = 0, MONO, STTRAM, PCRAM_Xie, PCRAM_Pierre, NEM $/;" e enum:e_tech_comp +PCRE_ANCHORED ../../pcre/SRC/pcre.h 51;" d +PCRE_CASELESS ../../pcre/SRC/pcre.h 47;" d +PCRE_CONFIG_LINK_SIZE ../../pcre/SRC/pcre.h 92;" d +PCRE_CONFIG_MATCH_LIMIT ../../pcre/SRC/pcre.h 94;" d +PCRE_CONFIG_NEWLINE ../../pcre/SRC/pcre.h 91;" d +PCRE_CONFIG_POSIX_MALLOC_THRESHOLD ../../pcre/SRC/pcre.h 93;" d +PCRE_CONFIG_UTF8 ../../pcre/SRC/pcre.h 90;" d +PCRE_DATA_SCOPE ../../pcre/SRC/pcre.h 22;" d +PCRE_DATA_SCOPE ../../pcre/SRC/pcre.h 26;" d +PCRE_DATA_SCOPE ../../pcre/SRC/pcre.h 31;" d +PCRE_DATE ../../pcre/SRC/pcre.h 15;" d +PCRE_DEFINITION ../../pcre/SRC/internal.h 164;" d +PCRE_DOLLAR_ENDONLY ../../pcre/SRC/pcre.h 52;" d +PCRE_DOTALL ../../pcre/SRC/pcre.h 49;" d +PCRE_ERROR_BADMAGIC ../../pcre/SRC/pcre.h 66;" d +PCRE_ERROR_BADOPTION ../../pcre/SRC/pcre.h 65;" d +PCRE_ERROR_CALLOUT ../../pcre/SRC/pcre.h 71;" d +PCRE_ERROR_MATCHLIMIT ../../pcre/SRC/pcre.h 70;" d +PCRE_ERROR_NOMATCH ../../pcre/SRC/pcre.h 63;" d +PCRE_ERROR_NOMEMORY ../../pcre/SRC/pcre.h 68;" d +PCRE_ERROR_NOSUBSTRING ../../pcre/SRC/pcre.h 69;" d +PCRE_ERROR_NULL ../../pcre/SRC/pcre.h 64;" d +PCRE_ERROR_UNKNOWN_NODE ../../pcre/SRC/pcre.h 67;" d +PCRE_EXTENDED ../../pcre/SRC/pcre.h 50;" d +PCRE_EXTRA ../../pcre/SRC/pcre.h 53;" d +PCRE_EXTRA_CALLOUT_DATA ../../pcre/SRC/pcre.h 100;" d +PCRE_EXTRA_MATCH_LIMIT ../../pcre/SRC/pcre.h 99;" d +PCRE_EXTRA_STUDY_DATA ../../pcre/SRC/pcre.h 98;" d +PCRE_FIRSTSET ../../pcre/SRC/internal.h 186;" d +PCRE_ICHANGED ../../pcre/SRC/internal.h 189;" d +PCRE_IMS ../../pcre/SRC/internal.h 178;" d +PCRE_INFO_BACKREFMAX ../../pcre/SRC/pcre.h 78;" d +PCRE_INFO_CAPTURECOUNT ../../pcre/SRC/pcre.h 77;" d +PCRE_INFO_FIRSTBYTE ../../pcre/SRC/pcre.h 79;" d +PCRE_INFO_FIRSTCHAR ../../pcre/SRC/pcre.h 80;" d +PCRE_INFO_FIRSTTABLE ../../pcre/SRC/pcre.h 81;" d +PCRE_INFO_LASTLITERAL ../../pcre/SRC/pcre.h 82;" d +PCRE_INFO_NAMECOUNT ../../pcre/SRC/pcre.h 84;" d +PCRE_INFO_NAMEENTRYSIZE ../../pcre/SRC/pcre.h 83;" d +PCRE_INFO_NAMETABLE ../../pcre/SRC/pcre.h 85;" d +PCRE_INFO_OPTIONS ../../pcre/SRC/pcre.h 75;" d +PCRE_INFO_SIZE ../../pcre/SRC/pcre.h 76;" d +PCRE_INFO_STUDYSIZE ../../pcre/SRC/pcre.h 86;" d +PCRE_MAJOR ../../pcre/SRC/pcre.h 13;" d +PCRE_MINOR ../../pcre/SRC/pcre.h 14;" d +PCRE_MULTILINE ../../pcre/SRC/pcre.h 48;" d +PCRE_NOTBOL ../../pcre/SRC/pcre.h 54;" d +PCRE_NOTEMPTY ../../pcre/SRC/pcre.h 57;" d +PCRE_NOTEOL ../../pcre/SRC/pcre.h 55;" d +PCRE_NO_AUTO_CAPTURE ../../pcre/SRC/pcre.h 59;" d +PCRE_REQCHSET ../../pcre/SRC/internal.h 187;" d +PCRE_STARTLINE ../../pcre/SRC/internal.h 188;" d +PCRE_STUDY_MAPPED ../../pcre/SRC/internal.h 193;" d +PCRE_UNGREEDY ../../pcre/SRC/pcre.h 56;" d +PCRE_UTF8 ../../pcre/SRC/pcre.h 58;" d +PHYSICAL_TYPES_H ../../libarchfpga/include/physical_types.h 27;" d +PI ./base/graphics.c 181;" d file: +PLACEMENT ./base/vpr_types.h /^ NO_PICTURE, PLACEMENT, ROUTING$/;" e enum:pic_type +PLACE_ALWAYS ./base/vpr_types.h /^ PLACE_NEVER, PLACE_ONCE, PLACE_ALWAYS$/;" e enum:pfreq +PLACE_CMD ./fpga_x2p/shell/shell_types.h /^ PLACE_CMD,$/;" e enum:e_cmd_category +PLACE_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 3;" d +PLACE_NEVER ./base/vpr_types.h /^ PLACE_NEVER, PLACE_ONCE, PLACE_ALWAYS$/;" e enum:pfreq +PLACE_ONCE ./base/vpr_types.h /^ PLACE_NEVER, PLACE_ONCE, PLACE_ALWAYS$/;" e enum:pfreq +PLACE_PATH_WEIGHT ./timing/path_delay.h 36;" d +PLUM ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +PLUS ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +PLUSQ ./timing/slre.c /^ STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT$/;" e enum:__anon19 file: +PMOS ./power/power.h /^ NMOS, PMOS$/;" e enum:__anon11 +PMOS_1X_C_d ./power/power.h /^ float PMOS_1X_C_d;$/;" m struct:s_power_commonly_used +PMOS_1X_C_g ./power/power.h /^ float PMOS_1X_C_g;$/;" m struct:s_power_commonly_used +PMOS_1X_C_s ./power/power.h /^ float PMOS_1X_C_s;$/;" m struct:s_power_commonly_used +PMOS_1X_st_leakage ./power/power.h /^ float PMOS_1X_st_leakage;$/;" m struct:s_power_commonly_used +PMOS_2X_st_leakage ./power/power.h /^ float PMOS_2X_st_leakage;$/;" m struct:s_power_commonly_used +PMOS_inf ./power/power.h /^ t_transistor_inf PMOS_inf;$/;" m struct:s_power_tech +PN_ratio ./power/power.h /^ float PN_ratio; \/* Ratio of PMOS to NMOS in inverter *\/$/;" m struct:s_power_tech +PORTS ../../libarchfpga/include/logic_types.h /^enum PORTS {$/;" g +POSIX_MALLOC_THRESHOLD ../../pcre/SRC/internal.h 661;" d +POSTSCRIPT ./base/graphics.c /^ POSTSCRIPT = 1$/;" e enum:__anon2 file: +POWER_BREAKDOWN_ENTRY_TYPE_BUFS_WIRES ./power/power.c /^ POWER_BREAKDOWN_ENTRY_TYPE_BUFS_WIRES$/;" e enum:__anon8 file: +POWER_BREAKDOWN_ENTRY_TYPE_COMPONENT ./power/power.c /^ POWER_BREAKDOWN_ENTRY_TYPE_COMPONENT,$/;" e enum:__anon8 file: +POWER_BREAKDOWN_ENTRY_TYPE_INTERC ./power/power.c /^ POWER_BREAKDOWN_ENTRY_TYPE_INTERC,$/;" e enum:__anon8 file: +POWER_BREAKDOWN_ENTRY_TYPE_MODE ./power/power.c /^ POWER_BREAKDOWN_ENTRY_TYPE_MODE,$/;" e enum:__anon8 file: +POWER_BREAKDOWN_ENTRY_TYPE_PB ./power/power.c /^ POWER_BREAKDOWN_ENTRY_TYPE_PB,$/;" e enum:__anon8 file: +POWER_BREAKDOWN_ENTRY_TYPE_TITLE ./power/power.c /^ POWER_BREAKDOWN_ENTRY_TYPE_TITLE = 0,$/;" e enum:__anon8 file: +POWER_BUFFER_TYPE_ABSOLUTE_SIZE ../../libarchfpga/include/physical_types.h /^ POWER_BUFFER_TYPE_ABSOLUTE_SIZE$/;" e enum:__anon21 +POWER_BUFFER_TYPE_AUTO ../../libarchfpga/include/physical_types.h /^ POWER_BUFFER_TYPE_AUTO,$/;" e enum:__anon21 +POWER_BUFFER_TYPE_NONE ../../libarchfpga/include/physical_types.h /^ POWER_BUFFER_TYPE_NONE,$/;" e enum:__anon21 +POWER_BUFFER_TYPE_UNDEFINED ../../libarchfpga/include/physical_types.h /^ POWER_BUFFER_TYPE_UNDEFINED = 0,$/;" e enum:__anon21 +POWER_CALLIB_COMPONENT_BUFFER ./power/power_callibrate.h /^ POWER_CALLIB_COMPONENT_BUFFER = 0,$/;" e enum:__anon12 +POWER_CALLIB_COMPONENT_BUFFER_WITH_LEVR ./power/power_callibrate.h /^ POWER_CALLIB_COMPONENT_BUFFER_WITH_LEVR,$/;" e enum:__anon12 +POWER_CALLIB_COMPONENT_FF ./power/power_callibrate.h /^ POWER_CALLIB_COMPONENT_FF,$/;" e enum:__anon12 +POWER_CALLIB_COMPONENT_LUT ./power/power_callibrate.h /^ POWER_CALLIB_COMPONENT_LUT,$/;" e enum:__anon12 +POWER_CALLIB_COMPONENT_MAX ./power/power_callibrate.h /^ POWER_CALLIB_COMPONENT_MAX$/;" e enum:__anon12 +POWER_CALLIB_COMPONENT_MUX ./power/power_callibrate.h /^ POWER_CALLIB_COMPONENT_MUX,$/;" e enum:__anon12 +POWER_COMPONENT_CLOCK ./power/power_components.h /^ POWER_COMPONENT_CLOCK, \/* Clock network *\/$/;" e enum:__anon13 +POWER_COMPONENT_CLOCK_BUFFER ./power/power_components.h /^ POWER_COMPONENT_CLOCK_BUFFER, \/* Buffers in clock network *\/$/;" e enum:__anon13 +POWER_COMPONENT_CLOCK_WIRE ./power/power_components.h /^ POWER_COMPONENT_CLOCK_WIRE, \/* Wires in clock network *\/$/;" e enum:__anon13 +POWER_COMPONENT_IGNORE ./power/power_components.h /^ POWER_COMPONENT_IGNORE = 0, \/* *\/$/;" e enum:__anon13 +POWER_COMPONENT_MAX_NUM ./power/power_components.h /^ POWER_COMPONENT_MAX_NUM$/;" e enum:__anon13 +POWER_COMPONENT_PB ./power/power_components.h /^ POWER_COMPONENT_PB, \/* Logic Blocks, and other hard blocks *\/$/;" e enum:__anon13 +POWER_COMPONENT_PB_BUFS_WIRE ./power/power_components.h /^ POWER_COMPONENT_PB_BUFS_WIRE, \/* Local buffers and wire capacitance *\/$/;" e enum:__anon13 +POWER_COMPONENT_PB_INTERC_MUXES ./power/power_components.h /^ POWER_COMPONENT_PB_INTERC_MUXES, \/* Local interconnect structures (muxes) *\/$/;" e enum:__anon13 +POWER_COMPONENT_PB_OTHER ./power/power_components.h /^ POWER_COMPONENT_PB_OTHER, \/* Power from other estimation methods - not transistor-level *\/$/;" e enum:__anon13 +POWER_COMPONENT_PB_PRIMITIVES ./power/power_components.h /^ POWER_COMPONENT_PB_PRIMITIVES, \/* Primitives (LUTs, FF, etc) *\/$/;" e enum:__anon13 +POWER_COMPONENT_ROUTE_CB ./power/power_components.h /^ POWER_COMPONENT_ROUTE_CB, \/* Connection box*\/$/;" e enum:__anon13 +POWER_COMPONENT_ROUTE_GLB_WIRE ./power/power_components.h /^ POWER_COMPONENT_ROUTE_GLB_WIRE, \/* Wires *\/$/;" e enum:__anon13 +POWER_COMPONENT_ROUTE_SB ./power/power_components.h /^ POWER_COMPONENT_ROUTE_SB, \/* Switch-box *\/$/;" e enum:__anon13 +POWER_COMPONENT_ROUTING ./power/power_components.h /^ POWER_COMPONENT_ROUTING, \/* Power for routing fabric (not local routing) *\/$/;" e enum:__anon13 +POWER_COMPONENT_TOTAL ./power/power_components.h /^ POWER_COMPONENT_TOTAL, \/* Total power for entire FPGA *\/$/;" e enum:__anon13 +POWER_DRC_MIN_DIFF_L ./power/power_sizing.h 34;" d +POWER_DRC_MIN_L ./power/power_sizing.h 32;" d +POWER_DRC_MIN_W ./power/power_sizing.h 33;" d +POWER_DRC_POLY_OVERHANG ./power/power_sizing.h 36;" d +POWER_DRC_SPACING ./power/power_sizing.h 35;" d +POWER_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 6;" d +POWER_LOG_ERROR ./power/power.h /^ POWER_LOG_ERROR, POWER_LOG_WARNING, POWER_LOG_NUM_TYPES$/;" e enum:__anon10 +POWER_LOG_NUM_TYPES ./power/power.h /^ POWER_LOG_ERROR, POWER_LOG_WARNING, POWER_LOG_NUM_TYPES$/;" e enum:__anon10 +POWER_LOG_WARNING ./power/power.h /^ POWER_LOG_ERROR, POWER_LOG_WARNING, POWER_LOG_NUM_TYPES$/;" e enum:__anon10 +POWER_LUT_SLOW ./power/power_components.h 37;" d +POWER_LUT_SLOW ./power/power_components.h 39;" d +POWER_METHOD_ABSOLUTE ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_ABSOLUTE \/* Dynamic: Aboslute, Static: Absolute *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_AUTO_SIZES ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_AUTO_SIZES, \/* Transistor-level, auto-sized buffers\/wires *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_C_INTERNAL ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_C_INTERNAL, \/* Dynamic: Equiv. Internal capacitance, Static: Absolute *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_IGNORE ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_UNDEFINED = 0, POWER_METHOD_IGNORE, \/* Ignore power of this PB, and all children PB *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_SPECIFY_SIZES ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_SPECIFY_SIZES, \/* Transistor-level, user-specified buffers\/wires *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_SUM_OF_CHILDREN ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_SUM_OF_CHILDREN, \/* Ignore power of this PB, but consider children *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_TOGGLE_PINS ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_TOGGLE_PINS, \/* Dynamic: Energy per pin toggle, Static: Absolute *\/$/;" e enum:e_power_estimation_method_ +POWER_METHOD_UNDEFINED ../../libarchfpga/include/physical_types.h /^ POWER_METHOD_UNDEFINED = 0, POWER_METHOD_IGNORE, \/* Ignore power of this PB, and all children PB *\/$/;" e enum:e_power_estimation_method_ +POWER_MTA_L ./power/power_sizing.h 39;" d +POWER_MTA_W ./power/power_sizing.h 38;" d +POWER_RET_CODE_ERRORS ./power/power.h /^ POWER_RET_CODE_SUCCESS = 0, POWER_RET_CODE_ERRORS, POWER_RET_CODE_WARNINGS$/;" e enum:__anon9 +POWER_RET_CODE_SUCCESS ./power/power.h /^ POWER_RET_CODE_SUCCESS = 0, POWER_RET_CODE_ERRORS, POWER_RET_CODE_WARNINGS$/;" e enum:__anon9 +POWER_RET_CODE_WARNINGS ./power/power.h /^ POWER_RET_CODE_SUCCESS = 0, POWER_RET_CODE_ERRORS, POWER_RET_CODE_WARNINGS$/;" e enum:__anon9 +POWER_WIRE_TYPE_ABSOLUTE_LENGTH ../../libarchfpga/include/physical_types.h /^ POWER_WIRE_TYPE_ABSOLUTE_LENGTH,$/;" e enum:__anon20 +POWER_WIRE_TYPE_AUTO ../../libarchfpga/include/physical_types.h /^ POWER_WIRE_TYPE_AUTO$/;" e enum:__anon20 +POWER_WIRE_TYPE_C ../../libarchfpga/include/physical_types.h /^ POWER_WIRE_TYPE_C,$/;" e enum:__anon20 +POWER_WIRE_TYPE_IGNORED ../../libarchfpga/include/physical_types.h /^ POWER_WIRE_TYPE_IGNORED,$/;" e enum:__anon20 +POWER_WIRE_TYPE_RELATIVE_LENGTH ../../libarchfpga/include/physical_types.h /^ POWER_WIRE_TYPE_RELATIVE_LENGTH,$/;" e enum:__anon20 +POWER_WIRE_TYPE_UNDEFINED ../../libarchfpga/include/physical_types.h /^ POWER_WIRE_TYPE_UNDEFINED = 0,$/;" e enum:__anon20 +PREPACK_H ./pack/prepack.h 8;" d +PROC_TIME ./base/place_and_route.h 6;" d +PRODUCTION_CMD ./fpga_x2p/shell/shell_types.h /^ PRODUCTION_CMD,$/;" e enum:e_cmd_category +PTRANS_FLAG ./route/check_rr_graph.c 15;" d file: +PUBLIC_EXEC_OPTIONS ../../pcre/SRC/internal.h 203;" d +PUBLIC_OPTIONS ../../pcre/SRC/internal.h 198;" d +PUBLIC_STUDY_OPTIONS ../../pcre/SRC/internal.h 206;" d +PULSE ../../libarchfpga/include/physical_types.h /^ UNIFORM, GAUSSIAN, PULSE, DELTA$/;" e enum:e_stat +PUT ../../pcre/SRC/internal.h 105;" d +PUT ../../pcre/SRC/internal.h 118;" d +PUT ../../pcre/SRC/internal.h 93;" d +PUT2 ../../pcre/SRC/internal.h 144;" d +PUT2INC ../../pcre/SRC/internal.h 151;" d +PUTINC ../../pcre/SRC/internal.h 137;" d +PackerOpts ./base/vpr_types.h /^ struct s_packer_opts PackerOpts; \/* Options for packer *\/$/;" m struct:s_vpr_setup typeref:struct:s_vpr_setup::s_packer_opts +PinFile ./base/ReadOptions.h /^ char *PinFile;$/;" m struct:s_options +PlaceAlgorithm ./base/ReadOptions.h /^ enum e_place_algorithm PlaceAlgorithm;$/;" m struct:s_options typeref:enum:s_options::e_place_algorithm +PlaceAlphaT ./base/ReadOptions.h /^ float PlaceAlphaT;$/;" m struct:s_options +PlaceChanWidth ./base/ReadOptions.h /^ int PlaceChanWidth;$/;" m struct:s_options +PlaceExitT ./base/ReadOptions.h /^ float PlaceExitT;$/;" m struct:s_options +PlaceFile ./base/ReadOptions.h /^ char *PlaceFile;$/;" m struct:s_options +PlaceFile ./base/vpr_types.h /^ char *PlaceFile;$/;" m struct:s_file_name_opts +PlaceInitT ./base/ReadOptions.h /^ float PlaceInitT;$/;" m struct:s_options +PlaceInnerNum ./base/ReadOptions.h /^ float PlaceInnerNum;$/;" m struct:s_options +PlaceTimingTradeoff ./base/ReadOptions.h /^ float PlaceTimingTradeoff;$/;" m struct:s_options +PlacerOpts ./base/vpr_types.h /^ struct s_placer_opts PlacerOpts; \/* Options for placer *\/$/;" m struct:s_vpr_setup typeref:struct:s_vpr_setup::s_placer_opts +PowerCallibInputs ./power/PowerSpicedComponent.c /^PowerCallibInputs::PowerCallibInputs(PowerSpicedComponent * parent_,$/;" f class:PowerCallibInputs +PowerCallibInputs ./power/PowerSpicedComponent.h /^class PowerCallibInputs {$/;" c +PowerCallibSize ./power/PowerSpicedComponent.h /^ PowerCallibSize(float size, float power_) :$/;" f class:PowerCallibSize +PowerCallibSize ./power/PowerSpicedComponent.h /^class PowerCallibSize {$/;" c +PowerFile ./base/ReadOptions.h /^ char *PowerFile;$/;" m struct:s_options +PowerFile ./base/vpr_types.h /^ char *PowerFile;$/;" m struct:s_file_name_opts +PowerOpts ./base/vpr_types.h /^ t_power_opts PowerOpts;$/;" m struct:s_vpr_setup +PowerSpicedComponent ./power/PowerSpicedComponent.c /^PowerSpicedComponent::PowerSpicedComponent($/;" f class:PowerSpicedComponent +PowerSpicedComponent ./power/PowerSpicedComponent.h /^class PowerSpicedComponent {$/;" c +PrintPb_types_rec ../../libarchfpga/read_xml_arch_file.c /^static void PrintPb_types_rec(INP FILE * Echo, INP const t_pb_type * pb_type,$/;" f file: +ProceedPressed ./base/graphics.c /^static int ProceedPressed;$/;" v file: +ProcessCB_SB ../../libarchfpga/read_xml_arch_file.c /^static void ProcessCB_SB(INOUTP ezxml_t Node, INOUTP boolean * list,$/;" f file: +ProcessChanWidthDistr ../../libarchfpga/read_xml_arch_file.c /^static void ProcessChanWidthDistr(INOUTP ezxml_t Node,$/;" f file: +ProcessChanWidthDistrDir ../../libarchfpga/read_xml_arch_file.c /^static void ProcessChanWidthDistrDir(INOUTP ezxml_t Node, OUTP t_chan * chan) {$/;" f file: +ProcessClocks ../../libarchfpga/read_xml_arch_file.c /^static void ProcessClocks(ezxml_t Parent, t_clock_arch * clocks) {$/;" f file: +ProcessComplexBlockProps ../../libarchfpga/read_xml_arch_file.c /^static void ProcessComplexBlockProps(ezxml_t Node, t_type_descriptor * Type) {$/;" f file: +ProcessComplexBlocks ../../libarchfpga/read_xml_arch_file.c /^static void ProcessComplexBlocks(INOUTP ezxml_t Node,$/;" f file: +ProcessDevice ../../libarchfpga/read_xml_arch_file.c /^static void ProcessDevice(INOUTP ezxml_t Node, OUTP struct s_arch *arch,$/;" f file: +ProcessDirects ../../libarchfpga/read_xml_arch_file.c /^static void ProcessDirects(INOUTP ezxml_t Parent, OUTP t_direct_inf **Directs,$/;" f file: +ProcessInterconnect ../../libarchfpga/read_xml_arch_file.c /^static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) {$/;" f file: +ProcessLayout ../../libarchfpga/read_xml_arch_file.c /^static void ProcessLayout(INOUTP ezxml_t Node, OUTP struct s_arch *arch) {$/;" f file: +ProcessLutClass ../../libarchfpga/read_xml_arch_file.c /^void ProcessLutClass(INOUTP t_pb_type *lut_pb_type) {$/;" f +ProcessMemoryClass ../../libarchfpga/read_xml_arch_file.c /^static void ProcessMemoryClass(INOUTP t_pb_type *mem_pb_type) {$/;" f file: +ProcessMode ../../libarchfpga/read_xml_arch_file.c /^static void ProcessMode(INOUTP ezxml_t Parent, t_mode * mode,$/;" f file: +ProcessModels ../../libarchfpga/read_xml_arch_file.c /^static void ProcessModels(INOUTP ezxml_t Node, OUTP struct s_arch *arch) {$/;" f file: +ProcessMrFPGATiming ../../libarchfpga/read_xml_mrfpga.c /^void ProcessMrFPGATiming(INOUTP ezxml_t Cur, $/;" f +ProcessOption ./base/ReadOptions.c /^ProcessOption(INP char **Args, INOUTP t_options * Options) {$/;" f file: +ProcessPb_Type ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPb_Type(INOUTP ezxml_t Parent, t_pb_type * pb_type,$/;" f file: +ProcessPb_TypePort ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPb_TypePort(INOUTP ezxml_t Parent, t_port * port,$/;" f file: +ProcessPb_TypePort_Power ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPb_TypePort_Power(ezxml_t Parent, t_port * port,$/;" f file: +ProcessPb_TypePower ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPb_TypePower(ezxml_t Parent, t_pb_type * pb_type) {$/;" f file: +ProcessPb_TypePowerEstMethod ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPb_TypePowerEstMethod(ezxml_t Parent, t_pb_type * pb_type) {$/;" f file: +ProcessPb_TypePowerPinToggle ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPb_TypePowerPinToggle(ezxml_t parent, t_pb_type * pb_type) {$/;" f file: +ProcessPinToPinAnnotations ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPinToPinAnnotations(ezxml_t Parent,$/;" f file: +ProcessPower ../../libarchfpga/read_xml_arch_file.c /^static void ProcessPower( INOUTP ezxml_t parent,$/;" f file: +ProcessSegments ../../libarchfpga/read_xml_arch_file.c /^static void ProcessSegments(INOUTP ezxml_t Parent,$/;" f file: +ProcessSpiceMCVariationParams ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceMCVariationParams(ezxml_t Parent,$/;" f file: +ProcessSpiceMeasParams ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceMeasParams(ezxml_t Parent,$/;" f file: +ProcessSpiceModel ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModel(ezxml_t Parent,$/;" f file: +ProcessSpiceModelBuffer ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelBuffer(ezxml_t Node,$/;" f file: +ProcessSpiceModelDelayInfo ../../libarchfpga/read_xml_spice.c /^void ProcessSpiceModelDelayInfo(ezxml_t Node, $/;" f file: +ProcessSpiceModelGate ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelGate(ezxml_t Node, $/;" f file: +ProcessSpiceModelLUT ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelLUT(ezxml_t Node, $/;" f file: +ProcessSpiceModelMUX ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelMUX(ezxml_t Node, $/;" f file: +ProcessSpiceModelPassGateLogic ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelPassGateLogic(ezxml_t Node,$/;" f file: +ProcessSpiceModelPort ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelPort(ezxml_t Node,$/;" f file: +ProcessSpiceModelPortLutOutputMask ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelPortLutOutputMask(ezxml_t Node,$/;" f file: +ProcessSpiceModelRRAM ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelRRAM(ezxml_t Node, $/;" f file: +ProcessSpiceModelWireParam ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceModelWireParam(ezxml_t Parent,$/;" f file: +ProcessSpiceMonteCarloParams ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceMonteCarloParams(ezxml_t Parent, $/;" f file: +ProcessSpiceParams ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceParams(ezxml_t Parent,$/;" f file: +ProcessSpiceSRAM ../../libarchfpga/read_xml_spice.c /^void ProcessSpiceSRAM(INOUTP ezxml_t Node, OUTP struct s_arch* arch) {$/;" f +ProcessSpiceSRAMOrganization ../../libarchfpga/read_xml_spice.c /^void ProcessSpiceSRAMOrganization(INOUTP ezxml_t Node, $/;" f file: +ProcessSpiceSettings ../../libarchfpga/read_xml_spice.c /^void ProcessSpiceSettings(ezxml_t Parent,$/;" f +ProcessSpiceStimulateParams ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceStimulateParams(ezxml_t Parent,$/;" f file: +ProcessSpiceStimulateParamsRiseFall ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceStimulateParamsRiseFall(ezxml_t Parent,$/;" f file: +ProcessSpiceTechLibTransistors ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceTechLibTransistors(ezxml_t Parent,$/;" f file: +ProcessSpiceTransistorType ../../libarchfpga/read_xml_spice.c /^static void ProcessSpiceTransistorType(ezxml_t Parent,$/;" f file: +ProcessSwitchSegmentPatterns ../../libarchfpga/read_xml_arch_file.c /^static void ProcessSwitchSegmentPatterns(INOUTP ezxml_t Parent,$/;" f file: +ProcessSwitches ../../libarchfpga/read_xml_arch_file.c /^static void ProcessSwitches(INOUTP ezxml_t Parent,$/;" f file: +ProcessTechComp ../../libarchfpga/read_xml_mrfpga.c /^ProcessTechComp(INOUTP ezxml_t Node,$/;" f +ProcessTechHack ../../libarchfpga/read_xml_mrfpga.c /^ProcessTechHack(INOUTP ezxml_t Node,$/;" f +ProcessTechnology ../../libarchfpga/read_xml_mrfpga.c /^ProcessTechnology(INOUTP ezxml_t Node,$/;" f +ProcessWireBuffer ../../libarchfpga/read_xml_mrfpga.c /^ProcessWireBuffer(INOUTP ezxml_t Node,$/;" f +Process_Fc ../../libarchfpga/read_xml_arch_file.c /^static void Process_Fc(ezxml_t Node, t_type_descriptor * Type) {$/;" f file: +ProcessmrFPGA ../../libarchfpga/read_xml_mrfpga.c /^ProcessmrFPGA(INOUTP ezxml_t Node,$/;" f +Provenance ./base/ReadOptions.h /^ int Provenance[OT_BASE_UNKNOWN];$/;" m struct:s_options +QUEST ./timing/slre.c /^ STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT$/;" e enum:__anon19 file: +R ../../libarchfpga/include/arch_types_mrfpga.h /^ float R; $/;" m struct:s_memristor_inf +R ../../libarchfpga/include/arch_types_mrfpga.h /^ float R;$/;" m struct:s_buffer_inf +R ../../libarchfpga/include/physical_types.h /^ float R;$/;" m struct:s_switch_inf +R ./base/vpr_types.h /^ float R;$/;" m struct:s_rr_node +RANDOM ./base/vpr_types.h /^ FREE, RANDOM, USER$/;" e enum:e_pad_loc_type +READLINE_H ../../libarchfpga/include/ReadLine.h 2;" d +READOPTIONS_H ./base/ReadOptions.h 2;" d +READ_BLIF_H ./base/read_blif.h 2;" d +READ_NETLIST_H ./base/read_netlist.h 9;" d +READ_PLACE_H ./base/read_place.h 2;" d +READ_SDC_H ./timing/read_sdc.h 2;" d +READ_SETTINGS_H ./base/read_settings.h 2;" d +READ_XML_ARCH_FILE_H ../../libarchfpga/include/read_xml_arch_file.h 2;" d +READ_XML_UTIL_H ../../libarchfpga/include/read_xml_util.h 2;" d +RECEIVER ../../libarchfpga/include/physical_types.h /^ OPEN = -1, DRIVER = 0, RECEIVER = 1$/;" e enum:e_pin_type +REC_STACK_SAVE_MAX ../../pcre/SRC/pcre.c 75;" d file: +RED ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +REJECTED ./place/place.c /^ REJECTED, ACCEPTED, ABORTED$/;" e enum:swap_result file: +REMOVE_CLUSTERED ./pack/cluster.c /^ REMOVE_CLUSTERED, LEAVE_CLUSTERED$/;" e enum:e_removal_policy file: +REQ_BYTE_MAX ../../pcre/SRC/pcre.c 89;" d file: +REQ_CASELESS ../../pcre/SRC/internal.h 220;" d +REQ_NONE ../../pcre/SRC/internal.h 215;" d +REQ_UNSET ../../pcre/SRC/internal.h 214;" d +REQ_VARY ../../pcre/SRC/internal.h 221;" d +RET_SWSEG_TRACK_APPLIED ./route/rr_graph_swseg.c /^ RET_SWSEG_TRACK_APPLIED$/;" e enum:ret_track_swseg_pattern file: +RET_SWSEG_TRACK_DIR_UNMATCH ./route/rr_graph_swseg.c /^ RET_SWSEG_TRACK_DIR_UNMATCH,$/;" e enum:ret_track_swseg_pattern file: +RET_SWSEG_TRACK_NON_SEG_LEN_PATTERN ./route/rr_graph_swseg.c /^ RET_SWSEG_TRACK_NON_SEG_LEN_PATTERN,$/;" e enum:ret_track_swseg_pattern file: +RIGHT ../../libarchfpga/include/physical_types.h /^ TOP = 0, RIGHT = 1, BOTTOM = 2, LEFT = 3$/;" e enum:e_side +ROUND_UP ./route/route_timing.c 682;" d file: +ROUTE_CMD ./fpga_x2p/shell/shell_types.h /^ ROUTE_CMD,$/;" e enum:e_cmd_category +ROUTE_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 4;" d +ROUTE_PATH_WEIGHT ./timing/path_delay.h 37;" d +ROUTING ./base/vpr_types.h /^ NO_PICTURE, PLACEMENT, ROUTING$/;" e enum:pic_type +RR_GRAPH2_H ./route/rr_graph2.h 2;" d +RR_GRAPH_H ./route/rr_graph.h 2;" d +RR_GRAPH_NO_WARN ./route/rr_graph.h /^ RR_GRAPH_NO_WARN = 0x00,$/;" e enum:__anon17 +RR_GRAPH_SBOX_H ./route/rr_graph_sbox.h 2;" d +RR_GRAPH_WARN_CHAN_WIDTH_CHANGED ./route/rr_graph.h /^ RR_GRAPH_WARN_CHAN_WIDTH_CHANGED = 0x02$/;" e enum:__anon17 +RR_GRAPH_WARN_FC_CLIPPED ./route/rr_graph.h /^ RR_GRAPH_WARN_FC_CLIPPED = 0x01,$/;" e enum:__anon17 +RUN_FLOW ./base/vpr_types.h /^ RUN_FLOW, TIMING_ANALYSIS_ONLY$/;" e enum:e_operation +R_minW_nmos ../../libarchfpga/include/physical_types.h /^ float R_minW_nmos;$/;" m struct:s_arch +R_minW_nmos ./base/vpr_types.h /^ float R_minW_nmos;$/;" m struct:s_det_routing_arch +R_minW_pmos ../../libarchfpga/include/physical_types.h /^ float R_minW_pmos;$/;" m struct:s_arch +R_minW_pmos ./base/vpr_types.h /^ float R_minW_pmos;$/;" m struct:s_det_routing_arch +R_opin_cblock ../../libarchfpga/include/arch_types_mrfpga.h /^ float R_opin_cblock;$/;" m struct:s_arch_mrfpga +R_opin_cblock ../../libarchfpga/include/physical_types.h /^ float R_opin_cblock;$/;" m struct:s_timing_inf +R_upstream ./route/route_common.h /^ float R_upstream;$/;" m struct:s_heap +R_upstream ./route/route_tree_timing.h /^ float R_upstream;$/;" m struct:s_rt_node +ReadBaseCostType ./base/ReadOptions.c /^ReadBaseCostType(INP char **Args, OUTP enum e_base_cost_type *BaseCostType) {$/;" f file: +ReadBaseToken ./base/ReadOptions.c /^ReadBaseToken(INP char **Args, OUTP enum e_OptionBaseToken *Token) {$/;" f file: +ReadClusterSeed ./base/ReadOptions.c /^ReadClusterSeed(INP char **Args, OUTP enum e_cluster_seed *Type) {$/;" f file: +ReadFixPins ./base/ReadOptions.c /^ReadFixPins(INP char **Args, OUTP char **PinFile) {$/;" f file: +ReadFloat ./base/ReadOptions.c /^ReadFloat(INP char ** Args, OUTP float *Val) {$/;" f file: +ReadInt ./base/ReadOptions.c /^ReadInt(INP char **Args, OUTP int *Val) {$/;" f file: +ReadLineTokens ../../libarchfpga/ReadLine.c /^ReadLineTokens(INOUTP FILE * InFile, INOUTP int *LineNum) {$/;" f +ReadOnOff ./base/ReadOptions.c /^ReadOnOff(INP char **Args, OUTP boolean * Val) {$/;" f file: +ReadOptions ./base/ReadOptions.c /^void ReadOptions(INP int argc, INP char **argv, OUTP t_options * Options) {$/;" f +ReadPackerAlgorithm ./base/ReadOptions.c /^ReadPackerAlgorithm(INP char **Args, OUTP enum e_packer_algorithm *Algo) {$/;" f file: +ReadPlaceAlgorithm ./base/ReadOptions.c /^ReadPlaceAlgorithm(INP char **Args, OUTP enum e_place_algorithm *Algo) {$/;" f file: +ReadRouteType ./base/ReadOptions.c /^ReadRouteType(INP char **Args, OUTP enum e_route_type *Type) {$/;" f file: +ReadRouterAlgorithm ./base/ReadOptions.c /^ReadRouterAlgorithm(INP char **Args, OUTP enum e_router_algorithm *Algo) {$/;" f file: +ReadString ./base/ReadOptions.c /^ReadString(INP char **Args, OUTP char **Val) {$/;" f file: +ReadToken ./base/ReadOptions.c /^ReadToken(INP char **Args, OUTP enum e_OptionArgToken *Token) {$/;" f file: +RecomputeCritIter ./base/ReadOptions.h /^ int RecomputeCritIter;$/;" m struct:s_options +Rmetal ../../libarchfpga/include/physical_types.h /^ float Rmetal;$/;" m struct:s_segment_inf +Rmetal ./base/vpr_types.h /^ float Rmetal;$/;" m struct:s_seg_details +RouteChanWidth ./base/ReadOptions.h /^ int RouteChanWidth;$/;" m struct:s_options +RouteFile ./base/ReadOptions.h /^ char *RouteFile;$/;" m struct:s_options +RouteFile ./base/vpr_types.h /^ char *RouteFile;$/;" m struct:s_file_name_opts +RouteType ./base/ReadOptions.h /^ enum e_route_type RouteType;$/;" m struct:s_options typeref:enum:s_options::e_route_type +RouterAlgorithm ./base/ReadOptions.h /^ enum e_router_algorithm RouterAlgorithm;$/;" m struct:s_options typeref:enum:s_options::e_router_algorithm +RouterOpts ./base/vpr_types.h /^ struct s_router_opts RouterOpts; \/* router options *\/$/;" m struct:s_vpr_setup typeref:struct:s_vpr_setup::s_router_opts +RoutingArch ./base/vpr_types.h /^ struct s_det_routing_arch RoutingArch; \/* routing architecture *\/$/;" m struct:s_vpr_setup typeref:struct:s_vpr_setup::s_det_routing_arch +Rseg_global ../../libarchfpga/include/arch_types_mrfpga.h /^ float Rseg_global;$/;" m struct:s_arch_mrfpga +Rseg_global ./mrfpga/mrfpga_globals.c /^float Rseg_global, Cseg_global;$/;" v +SAME_TRACK ./route/rr_graph2.c 23;" d file: +SBOX_ERROR ./route/rr_graph_sbox.c 99;" d file: +SBType ../../libarchfpga/include/physical_types.h /^ enum e_switch_block_type SBType;$/;" m struct:s_arch typeref:enum:s_arch::e_switch_block_type +SCALE_DISTANCE_VAL ./pack/cluster.c 48;" d file: +SCALE_NUM_PATHS ./pack/cluster.c 39;" d file: +SCREEN ./base/graphics.c /^ SCREEN = 0,$/;" e enum:__anon2 file: +SDCFile ../../libarchfpga/include/physical_types.h /^ char * SDCFile; \/* only here for convenience of passing to path_delay.c *\/$/;" m struct:s_timing_inf +SDCFile ./base/ReadOptions.h /^ char *SDCFile;$/;" m struct:s_options +SDCFile ./base/vpr_types.h /^ char *SDCFile;$/;" m struct:s_file_name_opts +SDC_FILE_POSTFIX ./fpga_x2p/shell/shell_file_postfix.h 8;" d +SDC_TOKENS ./timing/read_sdc.c 452;" d file: +SDF_Adder_delay_printing ./base/verilog_writer.c /^void SDF_Adder_delay_printing(FILE *SDF , t_pb *pb)$/;" f +SDF_Mult_delay_printing ./base/verilog_writer.c /^void SDF_Mult_delay_printing(FILE *SDF , t_pb *pb)$/;" f +SDF_interconnect_delay_printing ./base/verilog_writer.c /^void SDF_interconnect_delay_printing(FILE *SDF , conn_list *downhill)$/;" f +SDF_ram_dual_port_delay_printing ./base/verilog_writer.c /^void SDF_ram_dual_port_delay_printing(FILE *SDF , t_pb *pb)$/;" f +SDF_ram_single_port_delay_printing ./base/verilog_writer.c /^void SDF_ram_single_port_delay_printing(FILE *SDF , t_pb *pb)$/;" f +SELECT_ERROR ./base/graphics.c 217;" d file: +SETUPGRID_H ./base/SetupGrid.h 2;" d +SETUPVPR_H ./base/SetupVPR.h 2;" d +SETUP_CMD ./fpga_x2p/shell/shell_types.h /^ SETUP_CMD,$/;" e enum:e_cmd_category +SHELL_ERROR ./fpga_x2p/shell/read_opt_types.h 62;" d +SHELL_FAIL ./fpga_x2p/shell/read_opt_types.h 61;" d +SHELL_SUCCESS ./fpga_x2p/shell/read_opt_types.h 60;" d +SINGLE ./base/vpr_types.h /^ MULTI_BUFFERED, SINGLE$/;" e enum:e_drivers +SINK ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +SINK_BLOCK ./place/timing_place_lookup.c 50;" d file: +SINK_COST_INDEX ./base/vpr_types.h /^ SINK_COST_INDEX,$/;" e enum:e_cost_indices +SLACK_DEFINITION ./timing/path_delay.h 8;" d +SLRE_CASE_INSENSITIVE ./timing/slre.h /^enum slre_option {SLRE_CASE_INSENSITIVE = 1};$/;" e enum:slre_option +SLRE_FLOAT ./timing/slre.h /^enum slre_capture {SLRE_STRING, SLRE_INT, SLRE_FLOAT};$/;" e enum:slre_capture +SLRE_H ./timing/slre.h 78;" d +SLRE_INT ./timing/slre.h /^enum slre_capture {SLRE_STRING, SLRE_INT, SLRE_FLOAT};$/;" e enum:slre_capture +SLRE_STRING ./timing/slre.h /^enum slre_capture {SLRE_STRING, SLRE_INT, SLRE_FLOAT};$/;" e enum:slre_capture +SMALL_NET ./place/place.c 27;" d file: +SOLID ./base/easygl_constants.h /^enum line_types {SOLID, DASHED};$/;" e enum:line_types +SOURCE ./base/vpr_types.h /^ SOURCE = 0, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES$/;" e enum:e_rr_type +SOURCE_BLOCK ./place/timing_place_lookup.c 49;" d file: +SOURCE_COST_INDEX ./base/vpr_types.h /^ SOURCE_COST_INDEX = 0,$/;" e enum:e_cost_indices +SPACE ./timing/slre.c /^ STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT$/;" e enum:__anon19 file: +SPICE_ABS ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_FRAC, SPICE_ABS$/;" e enum:e_spice_accuracy_type +SPICE_CB_MUX_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_CB_MUX_TB, $/;" e enum:e_spice_tb_type +SPICE_CB_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_CB_TB,$/;" e enum:e_spice_tb_type +SPICE_FRAC ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_FRAC, SPICE_ABS$/;" e enum:e_spice_accuracy_type +SPICE_GRID_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_GRID_TB,$/;" e enum:e_spice_tb_type +SPICE_HARDLOGIC_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_HARDLOGIC_TB$/;" e enum:e_spice_tb_type +SPICE_IO_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_IO_TB,$/;" e enum:e_spice_tb_type +SPICE_LIB_ACADEMIA ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_LIB_ACADEMIA$/;" e enum:e_spice_tech_lib_type +SPICE_LIB_INDUSTRY ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_LIB_INDUSTRY,$/;" e enum:e_spice_tech_lib_type +SPICE_LUT_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_LUT_TB,$/;" e enum:e_spice_tb_type +SPICE_MEASURE_DYNAMIC_POWER ./fpga_x2p/spice/spice_utils.h /^ SPICE_MEASURE_LEAKAGE_POWER, SPICE_MEASURE_DYNAMIC_POWER$/;" e enum:e_measure_type +SPICE_MEASURE_LEAKAGE_POWER ./fpga_x2p/spice/spice_utils.h /^ SPICE_MEASURE_LEAKAGE_POWER, SPICE_MEASURE_DYNAMIC_POWER$/;" e enum:e_measure_type +SPICE_MODEL_BUF_BUF ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_BUF_BUF$/;" e enum:e_spice_model_buffer_type +SPICE_MODEL_BUF_INV ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_BUF_INV, $/;" e enum:e_spice_model_buffer_type +SPICE_MODEL_CHAN_WIRE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_CHAN_WIRE, $/;" e enum:e_spice_model_type +SPICE_MODEL_DELAY_FALL ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_DELAY_FALL$/;" e enum:spice_model_delay_type +SPICE_MODEL_DELAY_RISE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_DELAY_RISE, $/;" e enum:spice_model_delay_type +SPICE_MODEL_DESIGN_CMOS ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_DESIGN_CMOS, $/;" e enum:e_spice_model_design_tech +SPICE_MODEL_DESIGN_RRAM ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_DESIGN_RRAM$/;" e enum:e_spice_model_design_tech +SPICE_MODEL_FF ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_FF, $/;" e enum:e_spice_model_type +SPICE_MODEL_GATE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_GATE $/;" e enum:e_spice_model_type +SPICE_MODEL_GATE_AND ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_GATE_AND, $/;" e enum:e_spice_model_gate_type +SPICE_MODEL_GATE_OR ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_GATE_OR$/;" e enum:e_spice_model_gate_type +SPICE_MODEL_HARDLOGIC ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_HARDLOGIC,$/;" e enum:e_spice_model_type +SPICE_MODEL_INVBUF ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_INVBUF, $/;" e enum:e_spice_model_type +SPICE_MODEL_IOPAD ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_IOPAD, $/;" e enum:e_spice_model_type +SPICE_MODEL_LUT ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_LUT, $/;" e enum:e_spice_model_type +SPICE_MODEL_MUX ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_MUX, $/;" e enum:e_spice_model_type +SPICE_MODEL_PASSGATE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PASSGATE, $/;" e enum:e_spice_model_type +SPICE_MODEL_PASS_GATE_TRANSISTOR ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PASS_GATE_TRANSISTOR$/;" e enum:e_spice_model_pass_gate_logic_type +SPICE_MODEL_PASS_GATE_TRANSMISSION ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PASS_GATE_TRANSMISSION, $/;" e enum:e_spice_model_pass_gate_logic_type +SPICE_MODEL_PORT_BL ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_BL,$/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_BLB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_BLB,$/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_CLOCK ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_CLOCK, $/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_INOUT ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_INOUT, $/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_INPUT ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_INPUT, $/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_OUTPUT ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_OUTPUT, $/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_SRAM ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_SRAM,$/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_WL ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_WL,$/;" e enum:e_spice_model_port_type +SPICE_MODEL_PORT_WLB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_PORT_WLB$/;" e enum:e_spice_model_port_type +SPICE_MODEL_SCFF ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_SCFF,$/;" e enum:e_spice_model_type +SPICE_MODEL_SRAM ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_SRAM, $/;" e enum:e_spice_model_type +SPICE_MODEL_STRUCTURE_CROSSBAR ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_STRUCTURE_CROSSBAR $/;" e enum:e_spice_model_structure +SPICE_MODEL_STRUCTURE_MULTILEVEL ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_STRUCTURE_MULTILEVEL, $/;" e enum:e_spice_model_structure +SPICE_MODEL_STRUCTURE_ONELEVEL ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_STRUCTURE_ONELEVEL, $/;" e enum:e_spice_model_structure +SPICE_MODEL_STRUCTURE_TREE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_STRUCTURE_TREE, $/;" e enum:e_spice_model_structure +SPICE_MODEL_WIRE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_MODEL_WIRE, $/;" e enum:e_spice_model_type +SPICE_PB_MUX_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_PB_MUX_TB, $/;" e enum:e_spice_tb_type +SPICE_PB_PORT_CLOCK ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_PB_PORT_CLOCK$/;" e enum:e_spice_pb_port_type +SPICE_PB_PORT_INPUT ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_PB_PORT_INPUT,$/;" e enum:e_spice_pb_port_type +SPICE_PB_PORT_OUTPUT ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_PB_PORT_OUTPUT,$/;" e enum:e_spice_pb_port_type +SPICE_SB_MUX_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_SB_MUX_TB, $/;" e enum:e_spice_tb_type +SPICE_SB_TB ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_SB_TB,$/;" e enum:e_spice_tb_type +SPICE_SRAM_MEMORY_BANK ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_SRAM_MEMORY_BANK$/;" e enum:e_sram_orgz +SPICE_SRAM_SCAN_CHAIN ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_SRAM_SCAN_CHAIN,$/;" e enum:e_sram_orgz +SPICE_SRAM_STANDALONE ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_SRAM_STANDALONE,$/;" e enum:e_sram_orgz +SPICE_TRANS_IO_NMOS ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_TRANS_IO_NMOS, $/;" e enum:e_spice_trans_type +SPICE_TRANS_IO_PMOS ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_TRANS_IO_PMOS$/;" e enum:e_spice_trans_type +SPICE_TRANS_NMOS ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_TRANS_NMOS, $/;" e enum:e_spice_trans_type +SPICE_TRANS_PMOS ../../libarchfpga/fpga_spice_include/spice_types.h /^ SPICE_TRANS_PMOS, $/;" e enum:e_spice_trans_type +STAR ./timing/slre.c /^ END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,$/;" e enum:__anon19 file: +STARQ ./timing/slre.c /^ STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT$/;" e enum:__anon19 file: +STRING ../../pcre/SRC/pcre.c 387;" d file: +STTRAM ../../libarchfpga/include/arch_types_mrfpga.h /^ CONV = 0, MONO, STTRAM, PCRAM_Xie, PCRAM_Pierre, NEM $/;" e enum:e_tech_comp +SUBSET ../../libarchfpga/include/physical_types.h /^ SUBSET, WILTON, UNIVERSAL, FULL$/;" e enum:e_switch_block_type +SWSEG_UNBUF_CB ../../libarchfpga/include/physical_types.h /^ SWSEG_UNBUF_SB, SWSEG_UNBUF_CB$/;" e enum:e_swseg_pattern_type +SWSEG_UNBUF_SB ../../libarchfpga/include/physical_types.h /^ SWSEG_UNBUF_SB, SWSEG_UNBUF_CB$/;" e enum:e_swseg_pattern_type +Seed ./base/ReadOptions.h /^ int Seed;$/;" m struct:s_options +Segments ../../libarchfpga/include/physical_types.h /^ t_segment_inf * Segments;$/;" m struct:s_arch +Segments ./base/vpr_types.h /^ t_segment_inf * Segments; \/* wires in routing architecture *\/$/;" m struct:s_vpr_setup +SetPostSynthesisOption ./base/ReadOptions.c /^void SetPostSynthesisOption(boolean post_synthesis_enabled){$/;" f +SettingsFile ./base/ReadOptions.h /^ char *SettingsFile;$/;" m struct:s_options +SetupAnnealSched ./base/SetupVPR.c /^static void SetupAnnealSched(INP t_options Options,$/;" f file: +SetupBitstreamGenOpts ./base/SetupVPR.c /^static void SetupBitstreamGenOpts(t_options Options, $/;" f file: +SetupEmptyType ../../libarchfpga/read_xml_arch_file.c /^static void SetupEmptyType(void) {$/;" f file: +SetupFpgaSpiceOpts ./base/SetupVPR.c /^static void SetupFpgaSpiceOpts(t_options Options, $/;" f file: +SetupGridLocations ../../libarchfpga/read_xml_arch_file.c /^static void SetupGridLocations(ezxml_t Locations, t_type_descriptor * Type) {$/;" f file: +SetupOperation ./base/SetupVPR.c /^static void SetupOperation(INP t_options Options,$/;" f file: +SetupPackerOpts ./base/SetupVPR.c /^void SetupPackerOpts(INP t_options Options, INP boolean TimingEnabled,$/;" f +SetupPinEquivalenceAutoDetect ../../libarchfpga/read_xml_arch_file.c /^void SetupPinEquivalenceAutoDetect(ezxml_t Parent, t_type_descriptor* Type) {$/;" f file: +SetupPinLocationsAndPinClasses ../../libarchfpga/read_xml_arch_file.c /^static void SetupPinLocationsAndPinClasses(ezxml_t Locations,$/;" f file: +SetupPlacerOpts ./base/SetupVPR.c /^static void SetupPlacerOpts(INP t_options Options, INP boolean TimingEnabled,$/;" f file: +SetupPowerOpts ./base/SetupVPR.c /^static void SetupPowerOpts(t_options Options, t_power_opts *power_opts,$/;" f file: +SetupRouterOpts ./base/SetupVPR.c /^static void SetupRouterOpts(INP t_options Options, INP boolean TimingEnabled,$/;" f file: +SetupRoutingArch ./base/SetupVPR.c /^static void SetupRoutingArch(INP t_arch Arch,$/;" f file: +SetupSpiceOpts ./base/SetupVPR.c /^static void SetupSpiceOpts(t_options Options, $/;" f file: +SetupSwitches ./base/SetupVPR.c /^static void SetupSwitches(INP t_arch Arch,$/;" f file: +SetupSwitches_mrFPGA ./base/SetupVPR.c /^static void SetupSwitches_mrFPGA(INP t_arch Arch,$/;" f file: +SetupSynVerilogOpts ./base/SetupVPR.c /^static void SetupSynVerilogOpts(t_options Options, $/;" f file: +SetupTiming ./base/SetupVPR.c /^static void SetupTiming(INP t_options Options, INP t_arch Arch,$/;" f file: +SetupVPR ./base/SetupVPR.c /^void SetupVPR(INP t_options *Options, INP boolean TimingEnabled,$/;" f +ShowAnnealSched ./base/ShowSetup.c /^static void ShowAnnealSched(INP struct s_annealing_sched AnnealSched) {$/;" f file: +ShowGraphics ./base/vpr_types.h /^ boolean ShowGraphics; \/* option to show graphics *\/$/;" m struct:s_vpr_setup +ShowOperation ./base/ShowSetup.c /^static void ShowOperation(INP enum e_operation Operation) {$/;" f file: +ShowPackerOpts ./base/ShowSetup.c /^static void ShowPackerOpts(INP struct s_packer_opts PackerOpts) {$/;" f file: +ShowPlaceTiming ./base/ReadOptions.h /^ boolean ShowPlaceTiming;$/;" m struct:s_options +ShowPlacerOpts ./base/ShowSetup.c /^static void ShowPlacerOpts(INP t_options Options,$/;" f file: +ShowRouterOpts ./base/ShowSetup.c /^static void ShowRouterOpts(INP struct s_router_opts RouterOpts) {$/;" f file: +ShowRoutingArch ./base/ShowSetup.c /^static void ShowRoutingArch(INP struct s_det_routing_arch RoutingArch) {$/;" f file: +ShowSetup ./base/ShowSetup.c /^void ShowSetup(INP t_options options, INP t_vpr_setup vpr_setup) {$/;" f +SpiceOpts ./base/vpr_types.h /^ t_spice_opts SpiceOpts; \/* Xifan TANG: SPICE Support*\/$/;" m struct:s_fpga_spice_opts +StatusWND ./base/graphics.c /^StatusWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)$/;" f file: +Str ./base/vpr_types.h /^ const char *Str;$/;" m struct:s_TokenPair +Switches ../../libarchfpga/include/physical_types.h /^ struct s_switch_inf *Switches;$/;" m struct:s_arch typeref:struct:s_arch::s_switch_inf +SynVerilogOpts ./base/vpr_types.h /^ t_syn_verilog_opts SynVerilogOpts; \/* Xifan TANG: Synthesizable verilog dumping*\/$/;" m struct:s_fpga_spice_opts +SyncModelsPbTypes ../../libarchfpga/read_xml_arch_file.c /^static void SyncModelsPbTypes(INOUTP struct s_arch *arch,$/;" f file: +SyncModelsPbTypes_rec ../../libarchfpga/read_xml_arch_file.c /^static void SyncModelsPbTypes_rec(INOUTP struct s_arch *arch,$/;" f file: +TABLENGTH ./pack/output_blif.c 19;" d file: +TAB_LENGTH ./pack/output_clustering.c 17;" d file: +THISTLE ./base/easygl_constants.h /^CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL,$/;" e enum:color_types +TIMING_ANALYSIS_ONLY ./base/vpr_types.h /^ RUN_FLOW, TIMING_ANALYSIS_ONLY$/;" e enum:e_operation +TIMING_DRIVEN ./base/vpr_types.h /^ BREADTH_FIRST, TIMING_DRIVEN, NO_TIMING$/;" e enum:e_router_algorithm +TIMING_GAIN_PATH_WEIGHT ./timing/path_delay.h 35;" d +TIMING_PLACE ./place/timing_place.h 2;" d +TN_CB_IPIN ./base/vpr_types.h /^ TN_CB_IPIN, \/* input pin to complex block *\/$/;" e enum:__anon7 +TN_CB_OPIN ./base/vpr_types.h /^ TN_CB_OPIN, \/* output pin from complex block *\/$/;" e enum:__anon7 +TN_CONSTANT_GEN_SOURCE ./base/vpr_types.h /^ TN_CONSTANT_GEN_SOURCE \/* source of a constant logic 1 or 0 *\/$/;" e enum:__anon7 +TN_FF_CLOCK ./base/vpr_types.h /^ TN_FF_CLOCK, \/* clock pin of flip-flop *\/$/;" e enum:__anon7 +TN_FF_IPIN ./base/vpr_types.h /^ TN_FF_IPIN, \/* input pin to a flip-flop - goes to TN_FF_SINK *\/$/;" e enum:__anon7 +TN_FF_OPIN ./base/vpr_types.h /^ TN_FF_OPIN, \/* output pin from a flip-flop - comes from TN_FF_SOURCE *\/$/;" e enum:__anon7 +TN_FF_SINK ./base/vpr_types.h /^ TN_FF_SINK, \/* sink (D) pin of flip-flop *\/$/;" e enum:__anon7 +TN_FF_SOURCE ./base/vpr_types.h /^ TN_FF_SOURCE, \/* source (Q) pin of flip-flop *\/$/;" e enum:__anon7 +TN_INPAD_OPIN ./base/vpr_types.h /^ TN_INPAD_OPIN, \/* output from an input I\/O pad *\/$/;" e enum:__anon7 +TN_INPAD_SOURCE ./base/vpr_types.h /^ TN_INPAD_SOURCE, \/* input to an input I\/O pad *\/$/;" e enum:__anon7 +TN_INTERMEDIATE_NODE ./base/vpr_types.h /^ TN_INTERMEDIATE_NODE, \/* Used in post-packed timing graph only: $/;" e enum:__anon7 +TN_OUTPAD_IPIN ./base/vpr_types.h /^ TN_OUTPAD_IPIN, \/* input to an output I\/O pad *\/$/;" e enum:__anon7 +TN_OUTPAD_SINK ./base/vpr_types.h /^ TN_OUTPAD_SINK, \/* output from an output I\/O pad *\/$/;" e enum:__anon7 +TN_PRIMITIVE_IPIN ./base/vpr_types.h /^ TN_PRIMITIVE_IPIN, \/* input pin to a primitive (e.g. a LUT) *\/$/;" e enum:__anon7 +TN_PRIMITIVE_OPIN ./base/vpr_types.h /^ TN_PRIMITIVE_OPIN, \/* output pin from a primitive (e.g. a LUT) *\/$/;" e enum:__anon7 +TOKENS ../../libarchfpga/include/arch_types.h 19;" d +TOKENS ./base/vpr_types.h 66;" d +TOKEN_CLOSE_SQUARE_BRACKET ./util/token.h /^ TOKEN_CLOSE_SQUARE_BRACKET,$/;" e enum:e_token_type +TOKEN_CLOSE_SQUIG_BRACKET ./util/token.h /^ TOKEN_CLOSE_SQUIG_BRACKET,$/;" e enum:e_token_type +TOKEN_COLON ./util/token.h /^ TOKEN_COLON,$/;" e enum:e_token_type +TOKEN_DOT ./util/token.h /^ TOKEN_DOT$/;" e enum:e_token_type +TOKEN_H ./util/token.h 8;" d +TOKEN_INT ./util/token.h /^ TOKEN_INT,$/;" e enum:e_token_type +TOKEN_NULL ./util/token.h /^ TOKEN_NULL,$/;" e enum:e_token_type +TOKEN_OPEN_SQUARE_BRACKET ./util/token.h /^ TOKEN_OPEN_SQUARE_BRACKET,$/;" e enum:e_token_type +TOKEN_OPEN_SQUIG_BRACKET ./util/token.h /^ TOKEN_OPEN_SQUIG_BRACKET,$/;" e enum:e_token_type +TOKEN_STRING ./util/token.h /^ TOKEN_STRING,$/;" e enum:e_token_type +TOP ../../libarchfpga/include/physical_types.h /^ TOP = 0, RIGHT = 1, BOTTOM = 2, LEFT = 3$/;" e enum:e_side +TRUE ../../libarchfpga/include/util.h /^ FALSE, TRUE$/;" e enum:__anon23 +TRUE ../../pcre/SRC/internal.h 228;" d +TRUE ./base/graphics.c 145;" d file: +TURQUOISE ./base/easygl_constants.h /^TURQUOISE, MEDIUMPURPLE, DARKSLATEBLUE, DARKKHAKI, NUM_COLOR};$/;" e enum:color_types +TYPICAL_CORNER ../../libarchfpga/fpga_spice_include/spice_types.h /^ TYPICAL_CORNER,$/;" e enum:e_process_corner +T_AREA_HEIGHT ./base/graphics.c 178;" d file: +T_arr ./base/vpr_types.h /^ float T_arr; \/* Arrival time of the last input signal to this node. *\/$/;" m struct:s_tnode +T_crit ./power/power.h /^ float T_crit;$/;" m struct:s_solution_inf +T_ipin_cblock ../../libarchfpga/include/physical_types.h /^ float T_ipin_cblock;$/;" m struct:s_arch +T_ipin_cblock ../../libarchfpga/include/physical_types.h /^ float T_ipin_cblock;$/;" m struct:s_timing_inf +T_linear ./base/vpr_types.h /^ float T_linear;$/;" m struct:s_rr_indexed_data +T_opin_cblock ../../libarchfpga/include/arch_types_mrfpga.h /^ float T_opin_cblock;$/;" m struct:s_arch_mrfpga +T_opin_cblock ../../libarchfpga/include/physical_types.h /^ float T_opin_cblock;$/;" m struct:s_timing_inf +T_quadratic ./base/vpr_types.h /^ float T_quadratic;$/;" m struct:s_rr_indexed_data +T_req ./base/vpr_types.h /^ float T_req; \/* Required arrival time of the last input signal to this node $/;" m struct:s_tnode +Tdel ../../libarchfpga/include/arch_types_mrfpga.h /^ float Tdel; $/;" m struct:s_memristor_inf +Tdel ../../libarchfpga/include/arch_types_mrfpga.h /^ float Tdel;$/;" m struct:s_buffer_inf +Tdel ../../libarchfpga/include/physical_types.h /^ float Tdel;$/;" m struct:s_switch_inf +Tdel ./base/vpr_types.h /^ float Tdel; \/* delay to go to to_node along this edge *\/$/;" m struct:s_tedge +Tdel ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" m struct:s_buffer_plan file: +Tdel ./route/route_tree_timing.h /^ float Tdel;$/;" m struct:s_rt_node +Tdel ./timing/net_delay_types.h /^ float Tdel;$/;" m struct:s_rc_node +Timing ./base/vpr_types.h /^ t_timing_inf Timing; \/* timing information *\/$/;" m struct:s_vpr_setup +TimingAnalysis ./base/ReadOptions.h /^ boolean TimingAnalysis;$/;" m struct:s_options +TimingEnabled ./base/vpr_types.h /^ boolean TimingEnabled; \/* Is VPR timing enabled *\/$/;" m struct:s_vpr_setup +UNDEFINED ../../libarchfpga/include/arch_types.h 22;" d +UNDEFINED ./base/vpr_types.h 103;" d +UNIFORM ../../libarchfpga/include/physical_types.h /^ UNIFORM, GAUSSIAN, PULSE, DELTA$/;" e enum:e_stat +UNIVERSAL ../../libarchfpga/include/physical_types.h /^ SUBSET, WILTON, UNIVERSAL, FULL$/;" e enum:e_switch_block_type +UNI_DIRECTIONAL ../../libarchfpga/include/physical_types.h /^ UNI_DIRECTIONAL, BI_DIRECTIONAL$/;" e enum:e_directionality +UNKNOWN_CLASS ../../libarchfpga/include/physical_types.h /^ UNKNOWN_CLASS = 0, LUT_CLASS = 1, LATCH_CLASS = 2, MEMORY_CLASS = 3$/;" e enum:e_pb_type_class +UN_SET ./route/rr_graph2.c 24;" d file: +UPDATED_ONCE ./place/place.c 46;" d file: +USER ./base/vpr_types.h /^ FREE, RANDOM, USER$/;" e enum:e_pad_loc_type +USER_SCHED ./base/vpr_types.h /^ AUTO_SCHED, USER_SCHED$/;" e enum:sched_type +UTIL_H ../../libarchfpga/include/util.h 2;" d +UpdateAndCheckModels ../../libarchfpga/read_xml_arch_file.c /^static void UpdateAndCheckModels(INOUTP struct s_arch *arch) {$/;" f file: +VERILOG_PORT_CONKT ./fpga_x2p/verilog/verilog_global.h /^VERILOG_PORT_CONKT$/;" e enum:e_dump_verilog_port_type +VERILOG_PORT_INOUT ./fpga_x2p/verilog/verilog_global.h /^VERILOG_PORT_INOUT,$/;" e enum:e_dump_verilog_port_type +VERILOG_PORT_INPUT ./fpga_x2p/verilog/verilog_global.h /^VERILOG_PORT_INPUT,$/;" e enum:e_dump_verilog_port_type +VERILOG_PORT_OUTPUT ./fpga_x2p/verilog/verilog_global.h /^VERILOG_PORT_OUTPUT,$/;" e enum:e_dump_verilog_port_type +VERILOG_PORT_REG ./fpga_x2p/verilog/verilog_global.h /^VERILOG_PORT_REG,$/;" e enum:e_dump_verilog_port_type +VERILOG_PORT_WIRE ./fpga_x2p/verilog/verilog_global.h /^VERILOG_PORT_WIRE,$/;" e enum:e_dump_verilog_port_type +VERILOG_TB_AUTOCHECK_TOP ./fpga_x2p/verilog/verilog_global.h /^VERILOG_TB_AUTOCHECK_TOP,$/;" e enum:e_verilog_tb_type +VERILOG_TB_BLIF_TOP ./fpga_x2p/verilog/verilog_global.h /^VERILOG_TB_BLIF_TOP,$/;" e enum:e_verilog_tb_type +VERILOG_TB_FORMAL_VERIFICATION ./fpga_x2p/verilog/verilog_global.h /^VERILOG_TB_FORMAL_VERIFICATION$/;" e enum:e_verilog_tb_type +VERILOG_TB_TOP ./fpga_x2p/verilog/verilog_global.h /^VERILOG_TB_TOP,$/;" e enum:e_verilog_tb_type +VPACK_COMB ./base/vpr_types.h /^ VPACK_INPAD = -2, VPACK_OUTPAD, VPACK_COMB, VPACK_LATCH, VPACK_EMPTY$/;" e enum:logical_block_types +VPACK_EMPTY ./base/vpr_types.h /^ VPACK_INPAD = -2, VPACK_OUTPAD, VPACK_COMB, VPACK_LATCH, VPACK_EMPTY$/;" e enum:logical_block_types +VPACK_INPAD ./base/vpr_types.h /^ VPACK_INPAD = -2, VPACK_OUTPAD, VPACK_COMB, VPACK_LATCH, VPACK_EMPTY$/;" e enum:logical_block_types +VPACK_LATCH ./base/vpr_types.h /^ VPACK_INPAD = -2, VPACK_OUTPAD, VPACK_COMB, VPACK_LATCH, VPACK_EMPTY$/;" e enum:logical_block_types +VPACK_MAX_INPUTS ./base/vpr_types.h /^ VPACK_TIMING, VPACK_MAX_INPUTS$/;" e enum:e_cluster_seed +VPACK_OUTPAD ./base/vpr_types.h /^ VPACK_INPAD = -2, VPACK_OUTPAD, VPACK_COMB, VPACK_LATCH, VPACK_EMPTY$/;" e enum:logical_block_types +VPACK_TIMING ./base/vpr_types.h /^ VPACK_TIMING, VPACK_MAX_INPUTS$/;" e enum:e_cluster_seed +VPRSetupArch ./base/SetupVPR.c /^void VPRSetupArch(t_arch* arch, $/;" f +VPR_API_H ./base/vpr_api.h 27;" d +VPR_TYPES_H ./base/vpr_types.h 34;" d +VPR_UTILS_H ./util/vpr_utils.h 2;" d +VPR_VERSION ../../libarchfpga/include/arch_types.h 16;" d +Vdd ./power/power.h /^ float Vdd;$/;" m struct:s_power_tech +W ../../libarchfpga/include/physical_types.h /^ int W;$/;" m struct:s_clb_grid +WARNTAG ../../libarchfpga/include/util.h 27;" d +WHITE ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +WILTON ../../libarchfpga/include/physical_types.h /^ SUBSET, WILTON, UNIVERSAL, FULL$/;" e enum:e_switch_block_type +WIRED_LUT_LOGICAL_BLOCK_ID ./fpga_x2p/base/fpga_x2p_types.h 16;" d +WIRED_LUT_MODE_INDEX ./fpga_x2p/base/fpga_x2p_types.h 24;" d +WIRE_MODEL_PIE ../../libarchfpga/fpga_spice_include/spice_types.h /^ WIRE_MODEL_PIE,$/;" e enum:e_wire_model_type +WIRE_MODEL_T ../../libarchfpga/fpga_spice_include/spice_types.h /^ WIRE_MODEL_T$/;" e enum:e_wire_model_type +WIRE_SEGMENT_LENGTH ./base/vpr_api.c 517;" d file: +WL ./base/place_and_route.h 5;" d +WNEED ./base/place_and_route.h 4;" d +WORST_CORNER ../../libarchfpga/fpga_spice_include/spice_types.h /^ WORST_CORNER$/;" e enum:e_process_corner +W_seed ./base/globals.c /^int W_seed = -1;$/;" v +X11 ./base/graphics.h 13;" d +XCL_END ../../pcre/SRC/internal.h 274;" d +XCL_MAP ../../pcre/SRC/internal.h 272;" d +XCL_NOT ../../pcre/SRC/internal.h 271;" d +XCL_RANGE ../../pcre/SRC/internal.h 276;" d +XCL_SINGLE ../../pcre/SRC/internal.h 275;" d +XPOST ./base/graphics.c 161;" d file: +XSTRING ../../pcre/SRC/pcre.c 388;" d file: +XTOWORLD ./base/graphics.c 167;" d file: +XmlReadArch ../../libarchfpga/read_xml_arch_file.c /^void XmlReadArch(INP const char *ArchFile, INP boolean timing_enabled,$/;" f +YELLOW ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" e enum:color_types +YPOST ./base/graphics.c 162;" d file: +YTOWORLD ./base/graphics.c 168;" d file: +_EZXML_H ../../libarchfpga/include/ezxml.h 26;" d +_PCRE_H ../../pcre/SRC/pcre.h 8;" d +__POWER_CMOS_TECH_H__ ./power/power_cmos_tech.h 26;" d +__POWER_COMPONENTS_H__ ./power/power_components.h 24;" d +__POWER_H__ ./power/power.h 23;" d +__POWER_LOW_LEVEL_H__ ./power/power_lowlevel.h 24;" d +__POWER_MISC_H__ ./power/power_callibrate.h 23;" d +__POWER_POWERSPICEDCOMPONENT_NMOS_H__ ./power/PowerSpicedComponent.h 19;" d +__POWER_TRANSISTOR_CNT_H__ ./power/power_sizing.h 24;" d +__POWER_UTIL_H__ ./power/power_util.h 23;" d +_drawcurve ./base/graphics.c /^static void _drawcurve(t_point *points, int npoints, int fill) {$/;" f file: +abs_variation ../../libarchfpga/fpga_spice_include/spice_types.h /^ float abs_variation;$/;" m struct:s_spice_mc_variation_params +absolute_length ../../libarchfpga/include/physical_types.h /^ float absolute_length;$/;" m union:s_port_power::__anon22 +absolute_power_per_instance ../../libarchfpga/include/physical_types.h /^ t_power_usage absolute_power_per_instance; \/* User-provided absolute power per block *\/$/;" m struct:s_pb_type_power +absorb_buffer_luts ./base/read_blif.c /^static void absorb_buffer_luts(void) {$/;" f file: +acc_cost ./route/route_common.h /^ float acc_cost;$/;" m struct:__anon15 +acc_fac ./base/ReadOptions.h /^ float acc_fac;$/;" m struct:s_options +acc_fac ./base/vpr_types.h /^ float acc_fac;$/;" m struct:s_router_opts +accuracy ../../libarchfpga/fpga_spice_include/spice_types.h /^ float accuracy;$/;" m struct:s_spice_meas_params +accuracy_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_accuracy_type accuracy_type;$/;" m struct:s_spice_meas_params typeref:enum:s_spice_meas_params::e_spice_accuracy_type +adapt_truth_table_for_frac_lut ./fpga_x2p/base/fpga_x2p_lut_utils.c /^void adapt_truth_table_for_frac_lut(t_pb_graph_pin* lut_out_pb_graph_pin, $/;" f +add_activity_to_net ./base/read_blif.c /^bool add_activity_to_net(char * net_name, float probability, float density) {$/;" f +add_conf_bit_info_to_llist ./fpga_x2p/base/fpga_x2p_utils.c /^add_conf_bit_info_to_llist(t_llist* head, int index, $/;" f +add_const_input ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean add_const_input;$/;" m struct:s_spice_model_mux +add_data_point ./power/PowerSpicedComponent.c /^void PowerSpicedComponent::add_data_point(int num_inputs, float transistor_size,$/;" f class:PowerSpicedComponent +add_delay_to_array ./mrfpga/buffer_insertion.c /^static void add_delay_to_array( float* sink_delay, t_linked_int* index, float delay_addition )$/;" f file: +add_delay_to_buffer_list ./mrfpga/buffer_insertion.c /^static void add_delay_to_buffer_list( t_buffer_plan_list list, float Tdel , boolean skip_first )$/;" f file: +add_delay_to_buffer_plan ./mrfpga/buffer_insertion.c /^static t_buffer_plan add_delay_to_buffer_plan( t_buffer_plan plan, float Tdel )$/;" f file: +add_entry ./power/PowerSpicedComponent.c /^PowerCallibInputs * PowerSpicedComponent::add_entry(int num_inputs) {$/;" f class:PowerSpicedComponent +add_heap_node_to_rr_graph_heap ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void add_heap_node_to_rr_graph_heap(t_rr_graph* local_rr_graph,$/;" f +add_latch ./base/read_blif.c /^static void add_latch(int doall, INP t_model *latch_model) {$/;" f file: +add_lut ./base/read_blif.c /^static boolean add_lut(int doall, t_model *logic_model) {$/;" f file: +add_molecule_to_pb_stats_candidates ./pack/cluster.c /^static void add_molecule_to_pb_stats_candidates(t_pack_molecule *molecule,$/;" f file: +add_mux_conf_bits_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^add_mux_conf_bits_to_llist(int mux_size,$/;" f +add_mux_conf_bits_to_sram_orgz_info ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void add_mux_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +add_mux_membank_conf_bits_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^add_mux_membank_conf_bits_to_llist(int mux_size,$/;" f +add_mux_scff_conf_bits_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^add_mux_scff_conf_bits_to_llist(int mux_size,$/;" f +add_net_rr_terminal_cluster ./pack/cluster_legality.c /^static void add_net_rr_terminal_cluster(int iblk_net,$/;" f file: +add_net_to_hash ./base/read_netlist.c /^static int add_net_to_hash(INOUTP struct s_hash **nhash, INP char *net_name,$/;" f file: +add_node_to_rr_graph_heap ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void add_node_to_rr_graph_heap(t_rr_graph* local_rr_graph,$/;" f +add_one_conf_bit_to_sram_orgz_info ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void add_one_conf_bit_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info) {$/;" f +add_one_spice_tb_info_to_llist ./fpga_x2p/spice/spice_utils.c /^t_llist* add_one_spice_tb_info_to_llist(t_llist* cur_head, $/;" f +add_one_subckt_file_name_to_llist ./fpga_x2p/base/fpga_x2p_utils.c /^t_llist* add_one_subckt_file_name_to_llist(t_llist* cur_head, $/;" f +add_opin_fast_edge_to_ipin ./route/rr_graph_opincb.c /^int add_opin_fast_edge_to_ipin(t_rr_node* opin, $/;" f file: +add_opin_list_ipin_list_fast_edge ./route/rr_graph_opincb.c /^int add_opin_list_ipin_list_fast_edge(int num_opins, t_rr_node** opin_list, $/;" f file: +add_opin_rr_edges_to_chan_rr_node ./route/pb_pin_eq_auto_detect.c /^int add_opin_rr_edges_to_chan_rr_node(t_rr_node* chan_rr_node,$/;" f +add_override_constraint ./timing/read_sdc.c /^static void add_override_constraint(char ** from_list, int num_from, char ** to_list, int num_to, $/;" f file: +add_path_to_route_tree ./route/route_tree_timing.c /^add_path_to_route_tree(struct s_heap *hptr, t_rt_node ** sink_rt_node_ptr) {$/;" f file: +add_pattern_name_to_hash ./pack/prepack.c /^static int add_pattern_name_to_hash(INOUTP struct s_hash **nhash,$/;" f file: +add_route_tree_to_heap ./route/route_timing.c /^static void add_route_tree_to_heap(t_rt_node * rt_node, int target_node,$/;" f file: +add_rr_graph_C_from_switches ./route/rr_graph_timing_params.c /^void add_rr_graph_C_from_switches(float C_ipin_cblock) {$/;" f +add_rr_graph_fast_edge_opin_to_cb ./route/rr_graph_opincb.c /^int add_rr_graph_fast_edge_opin_to_cb(t_ivec*** LL_rr_node_indices) {$/;" f +add_rr_graph_one_grid_fast_edge_opin_to_cb ./route/rr_graph_opincb.c /^int add_rr_graph_one_grid_fast_edge_opin_to_cb(int grid_x, $/;" f file: +add_rr_graph_switch_segment_pattern ./route/rr_graph_swseg.c /^int add_rr_graph_switch_segment_pattern(enum e_directionality directionality,$/;" f +add_rr_node_edge_to_one_wired_lut ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void add_rr_node_edge_to_one_wired_lut(t_pb_graph_node* cur_pb_graph_node,$/;" f +add_size ./power/PowerSpicedComponent.c /^void PowerCallibInputs::add_size(float transistor_size, float power) {$/;" f class:PowerCallibInputs +add_sram_conf_bits_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^add_sram_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, $/;" f +add_sram_conf_bits_to_sram_orgz_info ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void add_sram_conf_bits_to_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +add_sram_membank_conf_bits_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void add_sram_membank_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, int mem_index, $/;" f +add_sram_scff_conf_bits_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^add_sram_scff_conf_bits_to_llist(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +add_subckt ./base/read_blif.c /^static void add_subckt(int doall, t_model *user_models) {$/;" f file: +add_to_heap ./route/route_common.c /^static void add_to_heap(struct s_heap *hptr) {$/;" f file: +add_to_mod_list ./route/route_common.c /^void add_to_mod_list(float *fptr) {$/;" f +add_to_rc_tree ./timing/net_delay.c /^void add_to_rc_tree(t_rc_node * parent_rc, t_rc_node * child_rc,$/;" f +add_to_rr_graph_mod_list ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void add_to_rr_graph_mod_list(t_rr_graph* local_rr_graph,$/;" f +add_to_sort_heap ./util/heapsort.c /^static void add_to_sort_heap(int *heap, float *sort_values, int index,$/;" f file: +add_virtual_sources_to_rr_graph_multi_sources ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^int add_virtual_sources_to_rr_graph_multi_sources(t_rr_graph* local_rr_graph) {$/;" f +add_vpack_net ./base/read_blif.c /^static int add_vpack_net(char *ptr, int type, int bnum, int bport, int bpin,$/;" f file: +add_wire_to_switch ./base/SetupVPR.c /^static void add_wire_to_switch(struct s_det_routing_arch *det_routing_arch) {$/;" f file: +addr ../../libarchfpga/fpga_spice_include/spice_types.h /^ int addr; \/* Address to write the value *\/$/;" m struct:s_conf_bit +adjustButton ./base/graphics.c /^static int windowAdjustFlag = 0, adjustButton = -1;$/;" v file: +adjustRect ./base/graphics.c /^static RECT adjustRect, updateRect;$/;" v file: +adjust_one_rr_occ_and_pcost ./route/route_common.c /^static void adjust_one_rr_occ_and_pcost(int inode, int add_or_sub,$/;" f file: +adjustwin ./base/graphics.c /^adjustwin (void (*drawscreen) (void)) $/;" f file: +advanced_rram_design ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean advanced_rram_design;$/;" m struct:s_spice_model_mux +after_call ../../pcre/SRC/internal.h /^ const uschar *after_call; \/* "Return value": points after the call in the expr *\/$/;" m struct:recursion_info +alloc_SRAM_values_from_truth_table ./power/power_util.c /^char * alloc_SRAM_values_from_truth_table(int LUT_size,$/;" f +alloc_and_add_fully_capacity_rr_edges_to_one_grid ./route/pb_pin_eq_auto_detect.c /^int alloc_and_add_fully_capacity_rr_edges_to_one_grid(int grid_x, int grid_y, int grid_z,$/;" f +alloc_and_add_fully_capacity_rr_edges_to_source_opin ./route/pb_pin_eq_auto_detect.c /^int alloc_and_add_fully_capacity_rr_edges_to_source_opin(t_type_ptr cur_type_descriptor,$/;" f +alloc_and_add_fully_capacity_sb_rr_edges_to_one_grid ./route/pb_pin_eq_auto_detect.c /^int alloc_and_add_fully_capacity_sb_rr_edges_to_one_grid(int grid_x, int grid_y, int grid_z,$/;" f +alloc_and_add_grids_fully_capacity_rr_edges ./route/pb_pin_eq_auto_detect.c /^int alloc_and_add_grids_fully_capacity_rr_edges(t_ivec*** LL_rr_node_indices,$/;" f +alloc_and_add_grids_fully_capacity_sb_rr_edges ./route/pb_pin_eq_auto_detect.c /^int alloc_and_add_grids_fully_capacity_sb_rr_edges(t_ivec*** LL_rr_node_indices,$/;" f +alloc_and_assign_internal_structures ./place/timing_place_lookup.c /^static void alloc_and_assign_internal_structures(struct s_net **original_net,$/;" f file: +alloc_and_build_connection_blocks_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void alloc_and_build_connection_blocks_info(t_det_routing_arch RoutingArch,$/;" f file: +alloc_and_build_switch_blocks_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void alloc_and_build_switch_blocks_info(t_det_routing_arch RoutingArch,$/;" f file: +alloc_and_init_clustering ./pack/cluster.c /^static void alloc_and_init_clustering(boolean global_clocks, float alpha,$/;" f file: +alloc_and_init_globals_clb_to_clb_directs ./base/SetupVPR.c /^void alloc_and_init_globals_clb_to_clb_directs(int num_directs, $/;" f +alloc_and_init_netlist_from_hash ./base/read_netlist.c /^static struct s_net *alloc_and_init_netlist_from_hash(INP int ncount,$/;" f file: +alloc_and_init_pattern_list_from_hash ./pack/prepack.c /^static t_pack_patterns *alloc_and_init_pattern_list_from_hash(INP int ncount,$/;" f file: +alloc_and_load_actual_fc ./route/rr_graph.c /^alloc_and_load_actual_fc(INP int L_num_types, INP t_type_ptr types,$/;" f file: +alloc_and_load_all_pb_graphs ./pack/pb_type_graph.c /^void alloc_and_load_all_pb_graphs(boolean load_power_structures) {$/;" f +alloc_and_load_blk_pin_from_port_pin ./util/vpr_utils.c /^static void alloc_and_load_blk_pin_from_port_pin(void) {$/;" f file: +alloc_and_load_clb_opins_used_locally ./route/route_common.c /^alloc_and_load_clb_opins_used_locally(void) {$/;" f file: +alloc_and_load_clb_to_clb_directs ./util/vpr_utils.c /^t_clb_to_clb_directs * alloc_and_load_clb_to_clb_directs(INP t_direct_inf *directs, $/;" f +alloc_and_load_cluster_info ./pack/cluster.c /^static void alloc_and_load_cluster_info(INP int num_clb, INOUTP t_block *clb) {$/;" f file: +alloc_and_load_cluster_legality_checker ./pack/cluster_legality.c /^void alloc_and_load_cluster_legality_checker(void) {$/;" f +alloc_and_load_cluster_placement_stats ./pack/cluster_placement.c /^t_cluster_placement_stats *alloc_and_load_cluster_placement_stats(void) {$/;" f +alloc_and_load_complete_interc_edges ./pack/pb_type_graph.c /^static void alloc_and_load_complete_interc_edges($/;" f file: +alloc_and_load_default_child_for_pb_type ../../libarchfpga/read_xml_arch_file.c /^static void alloc_and_load_default_child_for_pb_type( INOUTP t_pb_type *pb_type,$/;" f file: +alloc_and_load_direct_interc_edges ./pack/pb_type_graph.c /^static void alloc_and_load_direct_interc_edges($/;" f file: +alloc_and_load_echo_file_info ./base/ReadOptions.c /^void alloc_and_load_echo_file_info() {$/;" f +alloc_and_load_edges_and_switches ./route/rr_graph.c /^void alloc_and_load_edges_and_switches(INP t_rr_node * L_rr_node, INP int inode,$/;" f +alloc_and_load_final_routing_trace ./base/vpr_api.c /^static t_trace *alloc_and_load_final_routing_trace() {$/;" f file: +alloc_and_load_for_fast_cost_update ./place/place.c /^static void alloc_and_load_for_fast_cost_update(float place_cost_exp) {$/;" f file: +alloc_and_load_global_route_seg_details ./route/rr_graph.c /^alloc_and_load_global_route_seg_details(INP int nodes_per_chan,$/;" f file: +alloc_and_load_grid ./base/SetupGrid.c /^void alloc_and_load_grid(INOUTP int *num_instances_type) {$/;" f +alloc_and_load_idirect_from_blk_pin ./util/vpr_utils.c /^void alloc_and_load_idirect_from_blk_pin(t_direct_inf* directs, int num_directs, $/;" f +alloc_and_load_imacro_from_iblk ./place/place_macro.c /^static void alloc_and_load_imacro_from_iblk(t_pl_macro * macros, int num_macros) {$/;" f file: +alloc_and_load_interconnect_pins ./pack/pb_type_graph.c /^static void alloc_and_load_interconnect_pins(t_interconnect_pins * interc_pins,$/;" f file: +alloc_and_load_is_clock ./pack/pack.c /^boolean *alloc_and_load_is_clock(boolean global_clocks) {$/;" f +alloc_and_load_legalizer_for_cluster ./pack/cluster_legality.c /^void alloc_and_load_legalizer_for_cluster(INP t_block* clb, INP int clb_index,$/;" f +alloc_and_load_mode_interconnect ./pack/pb_type_graph.c /^static void alloc_and_load_mode_interconnect($/;" f file: +alloc_and_load_mux_graph ./power/power_util.c /^static t_mux_node * alloc_and_load_mux_graph(int num_inputs, int levels) {$/;" f file: +alloc_and_load_mux_graph_recursive ./power/power_util.c /^static void alloc_and_load_mux_graph_recursive(t_mux_node * node,$/;" f file: +alloc_and_load_mux_interc_edges ./pack/pb_type_graph.c /^static void alloc_and_load_mux_interc_edges( INP t_interconnect * interconnect,$/;" f file: +alloc_and_load_net_pin_index ./util/vpr_utils.c /^int ** alloc_and_load_net_pin_index() {$/;" f +alloc_and_load_netlist_clocks_and_ios ./timing/read_sdc.c /^static void alloc_and_load_netlist_clocks_and_ios(void) {$/;" f file: +alloc_and_load_output_file_names ./base/ReadOptions.c /^void alloc_and_load_output_file_names(const char *default_name) {$/;" f +alloc_and_load_pack_molecules ./pack/prepack.c /^t_pack_molecule *alloc_and_load_pack_molecules($/;" f +alloc_and_load_pack_patterns ./pack/prepack.c /^t_pack_patterns *alloc_and_load_pack_patterns(OUTP int *num_packing_patterns) {$/;" f +alloc_and_load_pb_graph ./pack/pb_type_graph.c /^static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node,$/;" f file: +alloc_and_load_pb_stats ./pack/cluster.c /^static void alloc_and_load_pb_stats(t_pb *pb, int max_models,$/;" f file: +alloc_and_load_perturb_ipins ./route/rr_graph.c /^alloc_and_load_perturb_ipins(INP int nodes_per_chan, INP int L_num_types,$/;" f file: +alloc_and_load_phy_pb_children_for_one_mapped_block ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void alloc_and_load_phy_pb_children_for_one_mapped_block(t_pb* cur_op_pb,$/;" f +alloc_and_load_phy_pb_for_mapped_block ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void alloc_and_load_phy_pb_for_mapped_block(int num_mapped_blocks, t_block* mapped_block,$/;" f +alloc_and_load_phy_pb_rr_graph_net_rr_terminals ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void alloc_and_load_phy_pb_rr_graph_net_rr_terminals(INP t_pb* cur_op_pb,$/;" f +alloc_and_load_phy_pb_rr_graph_nets ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void alloc_and_load_phy_pb_rr_graph_nets(INP t_pb* cur_op_pb,$/;" f +alloc_and_load_pin_locations_from_pb_graph ./pack/pb_type_graph.c /^static void alloc_and_load_pin_locations_from_pb_graph(t_type_descriptor *type) {$/;" f file: +alloc_and_load_pin_to_track_map ./route/rr_graph.c /^alloc_and_load_pin_to_track_map(INP enum e_pin_type pin_type,$/;" f file: +alloc_and_load_placement_macros ./place/place_macro.c /^int alloc_and_load_placement_macros(t_direct_inf* directs, int num_directs, t_pl_macro ** macros){$/;" f +alloc_and_load_placement_structs ./place/place.c /^static void alloc_and_load_placement_structs($/;" f file: +alloc_and_load_port_pin_from_blk_pin ./util/vpr_utils.c /^static void alloc_and_load_port_pin_from_blk_pin(void) {$/;" f file: +alloc_and_load_port_pin_ptrs_from_string ./pack/pb_type_graph.c /^t_pb_graph_pin *** alloc_and_load_port_pin_ptrs_from_string(INP int line_num,$/;" f +alloc_and_load_pre_packing_timing_graph ./timing/path_delay.c /^t_slack * alloc_and_load_pre_packing_timing_graph(float block_delay,$/;" f +alloc_and_load_prev_node_list_rr_graph_rr_nodes ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_and_load_prev_node_list_rr_graph_rr_nodes(t_rr_graph* local_rr_graph) {$/;" f +alloc_and_load_rc_tree ./timing/net_delay.c /^alloc_and_load_rc_tree(int inet, t_rc_node ** rc_node_free_list_ptr,$/;" f +alloc_and_load_rr_clb_source ./route/rr_graph.c /^static void alloc_and_load_rr_clb_source(t_ivec *** L_rr_node_indices) {$/;" f file: +alloc_and_load_rr_graph ./route/rr_graph.c /^static void alloc_and_load_rr_graph(INP int num_nodes,$/;" f file: +alloc_and_load_rr_graph_for_pb_graph_node ./pack/cluster_legality.c /^void alloc_and_load_rr_graph_for_pb_graph_node($/;" f +alloc_and_load_rr_graph_for_phy_pb ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void alloc_and_load_rr_graph_for_phy_pb(INP t_pb* cur_op_pb,$/;" f +alloc_and_load_rr_graph_for_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void alloc_and_load_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* top_pb_graph_node, $/;" f +alloc_and_load_rr_graph_route_structs ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_and_load_rr_graph_route_structs(t_rr_graph* local_rr_graph) {$/;" f +alloc_and_load_rr_graph_rr_node ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_and_load_rr_graph_rr_node(INOUTP t_rr_graph* local_rr_graph,$/;" f +alloc_and_load_rr_graph_rr_node_indices ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_and_load_rr_graph_rr_node_indices(t_rr_graph* local_rr_graph,$/;" f +alloc_and_load_rr_graph_switch_inf ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_and_load_rr_graph_switch_inf(INOUTP t_rr_graph* local_rr_graph,$/;" f +alloc_and_load_rr_indexed_data ./route/rr_graph_indexed_data.c /^void alloc_and_load_rr_indexed_data(INP t_segment_inf * segment_inf,$/;" f +alloc_and_load_rr_node_indices ./route/rr_graph2.c /^alloc_and_load_rr_node_indices(INP int nodes_per_chan, INP int L_nx,$/;" f +alloc_and_load_rr_node_route_structs ./route/route_common.c /^void alloc_and_load_rr_node_route_structs(void) {$/;" f +alloc_and_load_seg_details ./route/rr_graph2.c /^alloc_and_load_seg_details(INOUTP int *nodes_per_chan, INP int max_len,$/;" f +alloc_and_load_sharable_switch_trans ./route/rr_graph_area.c /^alloc_and_load_sharable_switch_trans(int num_switch, float trans_sram_bit,$/;" f file: +alloc_and_load_switch_block_conn ./route/rr_graph_sbox.c /^alloc_and_load_switch_block_conn(INP int nodes_per_chan,$/;" f +alloc_and_load_timing_graph ./timing/path_delay.c /^t_slack * alloc_and_load_timing_graph(t_timing_inf timing_inf) {$/;" f +alloc_and_load_timing_graph_levels ./timing/path_delay2.c /^int alloc_and_load_timing_graph_levels(void) {$/;" f +alloc_and_load_tnode_fanin_and_check_edges ./timing/path_delay2.c /^alloc_and_load_tnode_fanin_and_check_edges(int *num_sinks_ptr) {$/;" f file: +alloc_and_load_tnodes ./timing/path_delay.c /^static void alloc_and_load_tnodes(t_timing_inf timing_inf) {$/;" f file: +alloc_and_load_tnodes_from_prepacked_netlist ./timing/path_delay.c /^static void alloc_and_load_tnodes_from_prepacked_netlist(float block_delay,$/;" f file: +alloc_and_load_track_to_pin_lookup ./route/rr_graph.c /^alloc_and_load_track_to_pin_lookup(INP int ****pin_to_track_map, INP int *Fc,$/;" f file: +alloc_and_load_try_swap_structs ./place/place.c /^static void alloc_and_load_try_swap_structs() {$/;" f file: +alloc_and_load_unsharable_switch_trans ./route/rr_graph_area.c /^alloc_and_load_unsharable_switch_trans(int num_switch, float trans_sram_bit,$/;" f file: +alloc_block ./place/timing_place_lookup.c /^static void alloc_block(void) {$/;" f file: +alloc_cb_info_array ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^t_cb** alloc_cb_info_array(int LL_nx, int LL_ny) {$/;" f +alloc_crit ./place/timing_place.c /^static float ** alloc_crit(t_chunk *chunk_list_ptr) {$/;" f file: +alloc_delta_arrays ./place/timing_place_lookup.c /^static void alloc_delta_arrays(void) {$/;" f file: +alloc_draw_structs ./base/draw.c /^void alloc_draw_structs(void) {$/;" f +alloc_global_routing_conf_bits ./fpga_x2p/verilog/verilog_api.c /^void alloc_global_routing_conf_bits() {$/;" f file: +alloc_hash_table ./util/hash.c /^alloc_hash_table(void) {$/;" f +alloc_heap_data ./route/route_common.c /^alloc_heap_data(void) {$/;" f file: +alloc_internal_cb_nets ./base/read_netlist.c /^static void alloc_internal_cb_nets(INOUTP t_pb *top_level,$/;" f file: +alloc_isink_to_inode ./mrfpga/buffer_insertion.c /^static int alloc_isink_to_inode( int inet, int** isink_to_inode_ptr )$/;" f file: +alloc_ivector_and_copy_int_list ../../libarchfpga/util.c /^void alloc_ivector_and_copy_int_list(t_linked_int ** list_head_ptr,$/;" f +alloc_legal_placements ./place/place.c /^static void alloc_legal_placements() {$/;" f file: +alloc_linked_f_pointer ./route/route_common.c /^alloc_linked_f_pointer(void) {$/;" f file: +alloc_linked_rc_edge ./timing/net_delay.c /^alloc_linked_rc_edge(t_linked_rc_edge ** rc_edge_free_list_ptr) {$/;" f +alloc_linked_rt_edge ./route/route_tree_timing.c /^alloc_linked_rt_edge(void) {$/;" f file: +alloc_lookups_and_criticalities ./place/timing_place.c /^t_slack * alloc_lookups_and_criticalities(t_chan_width_dist chan_width_dist,$/;" f +alloc_matrix ../../libarchfpga/util.c /^alloc_matrix(int nrmin, int nrmax, int ncmin, int ncmax, size_t elsize) {$/;" f +alloc_matrix3 ../../libarchfpga/util.c /^alloc_matrix3(int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax,$/;" f +alloc_matrix4 ../../libarchfpga/util.c /^alloc_matrix4(int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax,$/;" f +alloc_net ./place/timing_place_lookup.c /^static void alloc_net(void) {$/;" f file: +alloc_net_delay ./timing/net_delay.c /^alloc_net_delay(t_chunk *chunk_list_ptr, struct s_net *nets,$/;" f +alloc_net_rr_terminals ./route/rr_graph.c /^static void alloc_net_rr_terminals(void) {$/;" f file: +alloc_net_rr_terminals_cluster ./pack/cluster_legality.c /^static void alloc_net_rr_terminals_cluster(void) {$/;" f file: +alloc_one_conf_bit_info ./fpga_x2p/base/fpga_x2p_utils.c /^alloc_one_conf_bit_info(int index,$/;" f +alloc_one_mem_bank_info ./fpga_x2p/base/fpga_x2p_utils.c /^t_mem_bank_info* alloc_one_mem_bank_info() {$/;" f +alloc_one_scff_info ./fpga_x2p/base/fpga_x2p_utils.c /^t_scff_info* alloc_one_scff_info() {$/;" f +alloc_one_sram_orgz_info ./fpga_x2p/base/fpga_x2p_utils.c /^t_sram_orgz_info* alloc_one_sram_orgz_info() {$/;" f +alloc_one_standalone_sram_info ./fpga_x2p/base/fpga_x2p_utils.c /^t_standalone_sram_info* alloc_one_standalone_sram_info() {$/;" f +alloc_pb_rr_graph_rr_indexed_data ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void alloc_pb_rr_graph_rr_indexed_data(t_rr_graph* local_rr_graph) {$/;" f +alloc_pin_classes_in_pb_graph_node ./pack/cluster_feasibility_filter.c /^static void alloc_pin_classes_in_pb_graph_node($/;" f file: +alloc_rc_node ./timing/net_delay.c /^alloc_rc_node(t_rc_node ** rc_node_free_list_ptr) {$/;" f +alloc_route_static_structs ./route/route_common.c /^void alloc_route_static_structs(void) {$/;" f +alloc_route_structs ./route/route_common.c /^alloc_route_structs(void) {$/;" f +alloc_route_tree_timing_structs ./route/route_tree_timing.c /^void alloc_route_tree_timing_structs(void) {$/;" f +alloc_routing_structs ./place/timing_place_lookup.c /^static void alloc_routing_structs(struct s_router_opts router_opts,$/;" f file: +alloc_rr_graph_heap_data ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^t_heap * alloc_rr_graph_heap_data(t_rr_graph* local_rr_graph) {$/;" f +alloc_rr_graph_linked_f_pointer ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^t_linked_f_pointer* alloc_rr_graph_linked_f_pointer(t_rr_graph* local_rr_graph) {$/;" f +alloc_rr_graph_net_rr_sources_and_sinks ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_rr_graph_net_rr_sources_and_sinks(t_rr_graph* local_rr_graph) {$/;" f +alloc_rr_graph_net_rr_terminals ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_rr_graph_net_rr_terminals(t_rr_graph* local_rr_graph) {$/;" f +alloc_rr_graph_route_static_structs ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_rr_graph_route_static_structs(t_rr_graph* local_rr_graph,$/;" f +alloc_rr_graph_rr_indexed_data ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void alloc_rr_graph_rr_indexed_data(t_rr_graph* local_rr_graph, int L_num_rr_indexed_data) {$/;" f +alloc_rr_graph_trace_data ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^t_trace* alloc_rr_graph_trace_data(t_rr_graph* local_rr_graph) {$/;" f +alloc_rt_node ./route/route_tree_timing.c /^alloc_rt_node(void) {$/;" f file: +alloc_saved_routing ./route/route_common.c /^alloc_saved_routing(t_ivec ** clb_opins_used_locally,$/;" f +alloc_sb_info_array ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^t_sb** alloc_sb_info_array(int LL_nx, int LL_ny) {$/;" f +alloc_sblock_pattern_lookup ./route/rr_graph2.c /^alloc_sblock_pattern_lookup(INP int L_nx, INP int L_ny, INP int nodes_per_chan) {$/;" f +alloc_slacks ./timing/path_delay.c /^static t_slack * alloc_slacks(void) {$/;" f file: +alloc_spice_model_grid_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void alloc_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) {$/;" f +alloc_spice_model_num_tedges ./fpga_x2p/base/fpga_x2p_timing_utils.c /^void alloc_spice_model_num_tedges(t_spice_model* cur_spice_model) {$/;" f +alloc_spice_model_routing_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void alloc_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) {$/;" f +alloc_timing_driven_route_structs ./route/route_timing.c /^void alloc_timing_driven_route_structs(float **pin_criticality_ptr,$/;" f +alloc_timing_stats ./timing/path_delay.c /^static void alloc_timing_stats(void) {$/;" f file: +alloc_trace_data ./route/route_common.c /^alloc_trace_data(void) {$/;" f file: +allocate_and_load_critical_path ./timing/path_delay.c /^t_linked_int * allocate_and_load_critical_path(void) {$/;" f +allocate_wired_lut_pbs ./fpga_x2p/base/fpga_x2p_lut_utils.c /^void allocate_wired_lut_pbs(t_pb*** wired_lut_pbs, $/;" f +allow_early_exit ./base/ReadOptions.h /^ boolean allow_early_exit;$/;" m struct:s_options +allow_early_exit ./base/vpr_types.h /^ boolean allow_early_exit;$/;" m struct:s_packer_opts +allow_unrelated_clustering ./base/ReadOptions.h /^ boolean allow_unrelated_clustering;$/;" m struct:s_options +allow_unrelated_clustering ./base/vpr_types.h /^ boolean allow_unrelated_clustering;$/;" m struct:s_packer_opts +alpha ./base/ReadOptions.h /^ float alpha;$/;" m struct:s_options +alpha ./base/vpr_types.h /^ float alpha;$/;" m struct:s_packer_opts +alpha_t ./base/vpr_types.h /^ float alpha_t;$/;" m struct:s_annealing_sched +anchored ./timing/slre.c /^ int anchored; \/\/ Must match from string start$/;" m struct:slre file: +angnorm ./base/graphics.c /^angnorm (float ang) $/;" f file: +annotate_grid_block_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void annotate_grid_block_info() {$/;" f +annotate_pb_type_port_to_phy_pb_type ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void annotate_pb_type_port_to_phy_pb_type(t_pb_type* cur_pb_type, $/;" f +annotate_physical_mode_pin_to_pb_type ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void annotate_physical_mode_pin_to_pb_type(t_port* cur_pb_type_port,$/;" f +annotate_physical_mode_pins_in_pb_graph_node ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void annotate_physical_mode_pins_in_pb_graph_node() {$/;" f +annotate_spice_model_timing ./fpga_x2p/base/fpga_x2p_timing_utils.c /^void annotate_spice_model_timing(t_spice_model* cur_spice_model) {$/;" f +annotations ../../libarchfpga/include/physical_types.h /^ t_pin_to_pin_annotation *annotations; \/* [0..num_annotations-1] *\/$/;" m struct:s_interconnect +annotations ../../libarchfpga/include/physical_types.h /^ t_pin_to_pin_annotation *annotations; \/* [0..num_annotations-1] *\/$/;" m struct:s_pb_type +anyof ./timing/slre.c /^static void anyof(struct slre *r, const char **re) {$/;" f file: +apply_swseg_pattern_chanx_track ./route/rr_graph_swseg.c /^ apply_swseg_pattern_chanx_track(INP int track_id,$/;" f file: +apply_swseg_pattern_chany_track ./route/rr_graph_swseg.c /^ apply_swseg_pattern_chany_track(INP int track_id,$/;" f file: +arch ./fpga_x2p/shell/shell_types.h /^ t_arch arch;$/;" m struct:s_shell_env +arch_mrfpga ../../libarchfpga/include/physical_types.h /^ t_arch_mrfpga arch_mrfpga;$/;" m struct:s_arch +area ../../libarchfpga/fpga_spice_include/spice_types.h /^ float area; \/\/Xifan TANG$/;" m struct:s_sram_inf +area ../../libarchfpga/include/physical_types.h /^ float area;$/;" m struct:s_type_descriptor +aspect ./base/vpr_types.h /^ float aspect;$/;" m struct:s_packer_opts +assess_swap ./place/place.c /^static enum swap_result assess_swap(float delta_c, float t) {$/;" f file: +assign_blocks_and_route_net ./place/timing_place_lookup.c /^static float assign_blocks_and_route_net(t_type_ptr source_type,$/;" f file: +assign_locations ./place/timing_place_lookup.c /^static void assign_locations(t_type_ptr source_type, int source_x_loc,$/;" f file: +assign_lut_truth_table ./fpga_x2p/base/fpga_x2p_lut_utils.c /^char** assign_lut_truth_table(t_logical_block* mapped_logical_block,$/;" f +assign_pb_graph_node_pin_temp_net_num_by_mode_index ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void assign_pb_graph_node_pin_temp_net_num_by_mode_index(t_pb_graph_pin* cur_pb_graph_pin,$/;" f +assign_post_routing_lut_truth_table ./fpga_x2p/base/fpga_x2p_lut_utils.c /^char** assign_post_routing_lut_truth_table(t_logical_block* mapped_logical_block,$/;" f +assign_post_routing_wired_lut_truth_table ./fpga_x2p/base/fpga_x2p_lut_utils.c /^char** assign_post_routing_wired_lut_truth_table(int lut_output_vpack_net_num,$/;" f +astar_fac ./base/ReadOptions.h /^ float astar_fac;$/;" m struct:s_options +astar_fac ./base/vpr_types.h /^ float astar_fac;$/;" m struct:s_router_opts +attr ../../libarchfpga/include/ezxml.h /^ char ***attr; \/* default attributes *\/$/;" m struct:ezxml_root +attr ../../libarchfpga/include/ezxml.h /^ char **attr; \/* tag attributes { name, value, name, value, ... NULL } *\/$/;" m struct:ezxml +auto_compute_inter_cluster_net_delay ./base/vpr_types.h /^ boolean auto_compute_inter_cluster_net_delay;$/;" m struct:s_packer_opts +auto_detect_and_reserve_locally_used_opins ./route/route_common.c /^void auto_detect_and_reserve_locally_used_opins(float pres_fac, boolean rip_up_local_opins,$/;" f +auto_detect_and_reserve_used_opins ./route/pb_pin_eq_auto_detect.c /^void auto_detect_and_reserve_used_opins(float pres_fac) {$/;" f +auto_select_max_sim_num_clock_cycles ./fpga_x2p/spice/spice_grid_testbench.c /^static int auto_select_max_sim_num_clock_cycles = TRUE;$/;" v file: +auto_select_max_sim_num_clock_cycles ./fpga_x2p/spice/spice_mux_testbench.c /^static int auto_select_max_sim_num_clock_cycles = TRUE;$/;" v file: +auto_select_max_sim_num_clock_cycles ./fpga_x2p/spice/spice_primitive_testbench.c /^static int auto_select_max_sim_num_clock_cycles = TRUE;$/;" v file: +auto_select_max_sim_num_clock_cycles ./fpga_x2p/spice/spice_routing_testbench.c /^static int auto_select_max_sim_num_clock_cycles = TRUE;$/;" v file: +auto_select_num_sim_clock_cycle ./fpga_x2p/base/fpga_x2p_utils.c /^void auto_select_num_sim_clock_cycle(t_spice* spice,$/;" f +auto_select_sim_num_clk_cycle ../../libarchfpga/fpga_spice_include/spice_types.h /^ int auto_select_sim_num_clk_cycle;$/;" m struct:s_spice_meas_params +autocheck_testbench_postfix ./fpga_x2p/verilog/verilog_global.c /^char* autocheck_testbench_postfix = "_autocheck";$/;" v +autocheck_testbench_reference_output_postfix ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^static char* autocheck_testbench_reference_output_postfix = "_benchmark";$/;" v file: +autocheck_testbench_verification_output_postfix ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^static char* autocheck_testbench_verification_output_postfix = "_verification";$/;" v file: +autocheck_top_testbench_verilog_file_postfix ./fpga_x2p/verilog/verilog_global.c /^char* autocheck_top_testbench_verilog_file_postfix = "_autocheck_top_tb.v"; \/* !!! must be consist with the modelsim_autocheck_testbench_module_postfix *\/ $/;" v +autochecked_simulation_flag ./fpga_x2p/verilog/verilog_global.c /^char* autochecked_simulation_flag = "AUTOCHECKED_SIMULATION"; \/\/ the flag to enable autochecked functional verification$/;" v +autosize_buffer ../../libarchfpga/include/physical_types.h /^ boolean autosize_buffer; \/* autosize clock buffers *\/$/;" m struct:s_clock_network +back_annotate_one_pb_rr_node_map_info_rec ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb,$/;" f file: +back_annotate_pb_rr_node_map_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void back_annotate_pb_rr_node_map_info() {$/;" f file: +back_annotate_rr_node_map_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void back_annotate_rr_node_map_info() {$/;" f file: +backannotate_clb_nets_act_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void backannotate_clb_nets_act_info() {$/;" f file: +backannotate_clb_nets_init_val ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void backannotate_clb_nets_init_val() {$/;" f file: +backannotate_one_pb_rr_nodes_net_info_rec ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void backannotate_one_pb_rr_nodes_net_info_rec(t_phy_pb* cur_pb) {$/;" f file: +backannotate_pb_rr_nodes_net_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void backannotate_pb_rr_nodes_net_info() {$/;" f file: +backannotate_pb_wired_luts ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void backannotate_pb_wired_luts(int num_mapped_blocks, t_block* mapped_block,$/;" f file: +backannotate_rr_graph_routing_results_to_net_name ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void backannotate_rr_graph_routing_results_to_net_name(t_rr_graph* local_rr_graph) {$/;" f +backannotate_rr_nodes_parasitic_net_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void backannotate_rr_nodes_parasitic_net_info() {$/;" f file: +background_cindex ./base/graphics.c /^ int background_cindex;$/;" m struct:__anon5 file: +backref_map ../../pcre/SRC/internal.h /^ unsigned int backref_map; \/* Bitmap of low back refs *\/$/;" m struct:compile_data +backup_one_pb_rr_node_pack_prev_node_edge ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void backup_one_pb_rr_node_pack_prev_node_edge(t_rr_node* pb_rr_node) {$/;" f +backward_expand_pack_pattern_from_edge ./pack/prepack.c /^static void backward_expand_pack_pattern_from_edge($/;" f file: +backward_infer_pattern ./pack/prepack.c /^static void backward_infer_pattern(INOUTP t_pb_graph_pin *pb_graph_pin) {$/;" f file: +backward_path_cost ./route/route_common.h /^ float backward_path_cost;$/;" m struct:__anon15 +backward_path_cost ./route/route_common.h /^ float backward_path_cost;$/;" m struct:s_heap +backward_weight ./base/vpr_types.h /^ float forward_weight, backward_weight; \/* Weightings of the importance of paths $/;" m struct:s_tnode +base_cost ../../libarchfpga/include/cad_types.h /^ float base_cost; \/* base cost of pattern eg. If a group of logical blocks match a pattern of smaller primitives, that is better than the same group using bigger primitives *\/$/;" m struct:s_pack_patterns +base_cost ../../libarchfpga/include/cad_types.h /^ float base_cost; \/* cost independant of current status of packing *\/$/;" m struct:s_cluster_placement_primitive +base_cost ./base/vpr_types.h /^ float base_cost;$/;" m struct:s_rr_indexed_data +base_cost_type ./base/ReadOptions.h /^ enum e_base_cost_type base_cost_type;$/;" m struct:s_options typeref:enum:s_options::e_base_cost_type +base_cost_type ./base/vpr_types.h /^ enum e_base_cost_type base_cost_type;$/;" m struct:s_router_opts typeref:enum:s_router_opts::e_base_cost_type +base_gain ./base/vpr_types.h /^ float base_gain; \/* Intrinsic "goodness" score for molecule independant of rest of netlist *\/$/;" m struct:s_pack_molecule +basics_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* basics_spice_file_name = "inv_buf_trans_gate.sp";$/;" v +bb_coords ./place/place.c /^static struct s_bb *bb_coords = NULL, *bb_num_on_edges = NULL;$/;" v typeref:struct:s_bb file: +bb_factor ./base/ReadOptions.h /^ int bb_factor;$/;" m struct:s_options +bb_factor ./base/vpr_types.h /^ int bb_factor;$/;" m struct:s_router_opts +bb_num_on_edges ./place/place.c /^static struct s_bb *bb_coords = NULL, *bb_num_on_edges = NULL;$/;" v typeref:struct: file: +bb_updated_before ./place/place.c /^static char * bb_updated_before = NULL;$/;" v file: +bench_postfix ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^static char* bench_postfix = "_bench";$/;" v file: +bend_cost ./base/ReadOptions.h /^ float bend_cost;$/;" m struct:s_options +bend_cost ./base/vpr_types.h /^ float bend_cost;$/;" m struct:s_router_opts +best_routing ./pack/cluster_legality.c /^static struct s_trace **best_routing;$/;" v typeref:struct:s_trace file: +beta ./base/ReadOptions.h /^ float beta;$/;" m struct:s_options +beta ./base/vpr_types.h /^ float beta;$/;" m struct:s_packer_opts +binary_not ./power/power_callibrate.c /^static char binary_not(char c) {$/;" f file: +binary_search ./base/globals.c /^int binary_search = -1;$/;" v +binary_search_place_and_route ./base/place_and_route.c /^static int binary_search_place_and_route(struct s_placer_opts placer_opts,$/;" f file: +bitfield ./base/vpr_types.h /^typedef size_t bitfield;$/;" t +bitstream_output_file ./base/vpr_types.h /^ char* bitstream_output_file;$/;" m struct:s_bitstream_gen_opts +bl ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_conf_bit* bl;$/;" m struct:s_conf_bit_info +blif ./base/read_blif.c /^static FILE *blif;$/;" v file: +blif_circuit_name ./base/globals.c /^char *blif_circuit_name = NULL;$/;" v +blif_file_name ./base/vpr_types.h /^ char *blif_file_name;$/;" m struct:s_packer_opts +blif_hash ./base/read_blif.c /^static struct s_hash **blif_hash;$/;" v typeref:struct:s_hash file: +blif_model ../../libarchfpga/include/physical_types.h /^ char *blif_model;$/;" m struct:s_pb_type +blif_testbench_verilog_file_postfix ./fpga_x2p/verilog/verilog_global.c /^char* blif_testbench_verilog_file_postfix = "_blif_tb.v";$/;" v +blk_index ./place/place_macro.h /^ int blk_index;$/;" m struct:s_pl_macro_member +block ./base/globals.c /^struct s_block *block = NULL;$/;" v typeref:struct:s_block +block ./base/globals_declare.h /^struct s_block *block;$/;" v typeref:struct:s_block +block ./base/vpr_types.h /^ int block; \/* logical block primitive which this tnode is part of *\/$/;" m struct:s_tnode +block_color ./base/draw.c /^static enum color_types *net_color, *block_color;$/;" v typeref:enum: file: +block_criticality ./pack/cluster.c /^static float *block_criticality = NULL;$/;" v file: +block_delay ./base/ReadOptions.h /^ float block_delay;$/;" m struct:s_options +block_delay ./base/vpr_types.h /^ float block_delay;$/;" m struct:s_packer_opts +block_dist ./base/ReadOptions.h /^ int block_dist;$/;" m struct:s_options +block_dist ./base/vpr_types.h /^ int block_dist;$/;" m struct:s_placer_opts +block_id ../../libarchfpga/include/cad_types.h /^ int block_id;$/;" m struct:s_pack_pattern_block +block_num ./place/place.c /^ int block_num;$/;" m struct:s_pl_moved_block file: +blocks ./base/vpr_types.h /^ int *blocks;$/;" m struct:s_grid_tile +blocks_affected ./place/place.c /^static t_pl_blocks_to_be_moved blocks_affected;$/;" v file: +boolean ../../libarchfpga/include/util.h /^typedef int boolean;$/;" t +boolean ../../libarchfpga/include/util.h /^} boolean;$/;" t typeref:enum:__anon23 +branch_chain ../../pcre/SRC/internal.h /^typedef struct branch_chain {$/;" s +branch_chain ../../pcre/SRC/internal.h /^} branch_chain;$/;" t typeref:struct:branch_chain +breadth_first_add_one_source_to_rr_graph_heap ./fpga_x2p/router/fpga_x2p_router.c /^void breadth_first_add_one_source_to_rr_graph_heap(t_rr_graph* local_rr_graph,$/;" f +breadth_first_add_source_to_heap ./route/route_breadth_first.c /^static void breadth_first_add_source_to_heap(int inet) {$/;" f file: +breadth_first_add_source_to_heap_cluster ./pack/cluster_legality.c /^static void breadth_first_add_source_to_heap_cluster(int inet) {$/;" f file: +breadth_first_add_source_to_rr_graph_heap ./fpga_x2p/router/fpga_x2p_router.c /^void breadth_first_add_source_to_rr_graph_heap(t_rr_graph* local_rr_graph,$/;" f +breadth_first_expand_neighbours ./route/route_breadth_first.c /^static void breadth_first_expand_neighbours(int inode, float pcost, int inet,$/;" f file: +breadth_first_expand_neighbours_cluster ./pack/cluster_legality.c /^static void breadth_first_expand_neighbours_cluster(int inode, float pcost,$/;" f file: +breadth_first_expand_rr_graph_neighbours ./fpga_x2p/router/fpga_x2p_router.c /^void breadth_first_expand_rr_graph_neighbours(t_rr_graph* local_rr_graph,$/;" f +breadth_first_expand_rr_graph_trace_segment ./fpga_x2p/router/fpga_x2p_router.c /^void breadth_first_expand_rr_graph_trace_segment(t_rr_graph* local_rr_graph,$/;" f +breadth_first_expand_trace_segment ./route/route_breadth_first.c /^static void breadth_first_expand_trace_segment(struct s_trace *start_ptr,$/;" f file: +breadth_first_expand_trace_segment_cluster ./pack/cluster_legality.c /^static void breadth_first_expand_trace_segment_cluster($/;" f file: +breadth_first_route_net ./route/route_breadth_first.c /^static boolean breadth_first_route_net(int inet, float bend_cost) {$/;" f file: +breadth_first_route_net_cluster ./pack/cluster_legality.c /^static boolean breadth_first_route_net_cluster(int inet) {$/;" f file: +breadth_first_route_one_multi_source_net_pb_rr_graph ./fpga_x2p/router/fpga_x2p_router.c /^boolean breadth_first_route_one_multi_source_net_pb_rr_graph(t_rr_graph* local_rr_graph, $/;" f +breadth_first_route_one_net_pb_rr_graph ./fpga_x2p/router/fpga_x2p_router.c /^boolean breadth_first_route_one_net_pb_rr_graph(t_rr_graph* local_rr_graph, $/;" f +breadth_first_route_one_single_source_net_pb_rr_graph ./fpga_x2p/router/fpga_x2p_router.c /^boolean breadth_first_route_one_single_source_net_pb_rr_graph(t_rr_graph* local_rr_graph, $/;" f +break_loops ./fpga_x2p/verilog/verilog_sdc.c /^ boolean break_loops;$/;" m struct:s_sdc_opts file: +break_loops_mux ./fpga_x2p/verilog/verilog_sdc.c /^ boolean break_loops_mux;$/;" m struct:s_sdc_opts file: +buf_size ../../libarchfpga/include/physical_types.h /^ float buf_size;$/;" m struct:s_switch_inf +buffer_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_buffer* buffer_info;$/;" m struct:s_spice_model_design_tech_info +buffer_net ./place/timing_place_lookup.c /^static void buffer_net( float* cur_net_delay )$/;" f file: +buffer_size ../../libarchfpga/include/physical_types.h /^ float buffer_size; \/* if not autosized, the clock buffer size *\/$/;" m struct:s_clock_network +buffer_size ../../libarchfpga/include/physical_types.h /^ float buffer_size;$/;" m struct:s_pb_graph_pin_power +buffer_size ../../libarchfpga/include/physical_types.h /^ float buffer_size;$/;" m struct:s_port_power +buffer_size_inf ./power/power.h /^ t_power_buffer_size_inf * buffer_size_inf;$/;" m struct:s_power_tech +buffer_type ../../libarchfpga/include/physical_types.h /^ e_power_buffer_type buffer_type;$/;" m struct:s_port_power +buffered ../../libarchfpga/include/physical_types.h /^ boolean buffered;$/;" m struct:s_switch_inf +buffered ./base/vpr_types.h /^ int buffered;$/;" m struct:s_rr_node +build_bidir_rr_opins ./route/rr_graph.c /^static void build_bidir_rr_opins(INP int i, INP int j,$/;" f file: +build_default_menu ./base/graphics.c /^build_default_menu (void) $/;" f file: +build_ending_rr_node_for_one_sb_wire ./fpga_x2p/verilog/verilog_report_timing.c /^void build_ending_rr_node_for_one_sb_wire(t_rr_node* wire_rr_node, $/;" f +build_one_connection_block_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void build_one_connection_block_info(t_cb* cur_cb, int cb_x, int cb_y, t_rr_type cb_type,$/;" f +build_one_switch_block_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void build_one_switch_block_info(t_sb* cur_sb, int sb_x, int sb_y, $/;" f +build_prev_node_list_rr_nodes ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void build_prev_node_list_rr_nodes(int LL_num_rr_nodes,$/;" f +build_rr_graph ./route/rr_graph.c /^void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types,$/;" f +build_rr_sinks_sources ./route/rr_graph.c /^static void build_rr_sinks_sources(INP int i, INP int j,$/;" f file: +build_rr_xchan ./route/rr_graph.c /^static void build_rr_xchan(INP int i, INP int j,$/;" f file: +build_rr_ychan ./route/rr_graph.c /^static void build_rr_ychan(INP int i, INP int j,$/;" f file: +build_textarea ./base/graphics.c /^static void build_textarea (void) $/;" f file: +build_unidir_rr_opins ./route/rr_graph.c /^static void build_unidir_rr_opins(INP int i, INP int j,$/;" f file: +button ./base/graphics.c /^static t_button *button = NULL; \/* [0..num_buttons-1] *\/$/;" v file: +cal_capacitance_from_routing ./mrfpga/cal_capacitance.c /^void cal_capacitance_from_routing ( ) {$/;" f +calc_buffer_stage_effort ./power/power_util.c /^float calc_buffer_stage_effort(int N, float final_stage_size) {$/;" f +calculate_constraint ./timing/read_sdc.c /^static float calculate_constraint(t_sdc_clock source_domain, t_sdc_clock sink_domain) {$/;" f file: +callibrate ./power/PowerSpicedComponent.c /^void PowerCallibInputs::callibrate() {$/;" f class:PowerCallibInputs +callibrate ./power/PowerSpicedComponent.c /^void PowerSpicedComponent::callibrate(void) {$/;" f class:PowerSpicedComponent +callout_data ../../pcre/SRC/internal.h /^ void *callout_data; \/* To pass back to callouts *\/$/;" m struct:match_data +callout_data ../../pcre/SRC/pcre.h /^ void *callout_data; \/* Data passed in with the call *\/$/;" m struct:pcre_callout_block +callout_data ../../pcre/SRC/pcre.h /^ void *callout_data; \/* Data passed back in callouts *\/$/;" m struct:pcre_extra +callout_number ../../pcre/SRC/pcre.h /^ int callout_number; \/* Number compiled into pattern *\/$/;" m struct:pcre_callout_block +cap ./timing/slre.c /^struct cap {$/;" s file: +cap_val ../../libarchfpga/fpga_spice_include/spice_types.h /^ float cap_val; $/;" m struct:s_spice_model_wire_param +capacitance ../../libarchfpga/include/physical_types.h /^ float capacitance;$/;" m struct:s_pb_graph_edge +capacity ../../libarchfpga/include/physical_types.h /^ int capacity;$/;" m struct:s_type_descriptor +capacity ./base/vpr_types.h /^ float capacity;$/;" m struct:s_place_region +capacity ./base/vpr_types.h /^ short capacity;$/;" m struct:s_rr_node +captab ../../libarchfpga/fpga_spice_include/spice_types.h /^ int captab;$/;" m struct:s_spice_params +capture ./timing/slre.c /^static const char *capture(const struct cap *caps, int num_caps, va_list ap) {$/;" f file: +capture_float ./timing/slre.c /^static const char *capture_float(const struct cap *cap, void *p, size_t len) {$/;" f file: +capture_int ./timing/slre.c /^static const char *capture_int(const struct cap *cap, void *p, size_t len) {$/;" f file: +capture_last ../../pcre/SRC/internal.h /^ int capture_last; \/* Most recent capture number *\/$/;" m struct:match_data +capture_last ../../pcre/SRC/pcre.h /^ int capture_last; \/* Most recently closed capture *\/$/;" m struct:pcre_callout_block +capture_string ./timing/slre.c /^static const char *capture_string(const struct cap *cap, void *p, size_t len) {$/;" f file: +capture_top ../../pcre/SRC/pcre.h /^ int capture_top; \/* Max current capture *\/$/;" m struct:pcre_callout_block +casecmp ./timing/slre.c /^static int casecmp(const void *p1, const void *p2, size_t len) {$/;" f file: +cat_llists ../../libarchfpga/linkedlist.c /^t_llist* cat_llists(t_llist* head1,$/;" f +category ./fpga_x2p/shell/shell_types.h /^ e_cmd_category category;$/;" m struct:s_shell_cmd +cb ../../libarchfpga/include/physical_types.h /^ boolean *cb;$/;" m struct:s_segment_inf +cb ./base/vpr_types.h /^ boolean *cb;$/;" m struct:s_seg_details +cb_len ../../libarchfpga/include/physical_types.h /^ int cb_len;$/;" m struct:s_segment_inf +cb_switches ../../libarchfpga/include/physical_types.h /^ t_switch_inf* cb_switches;$/;" m struct:s_arch +cb_type_descriptors ../../libarchfpga/read_xml_arch_file.c /^static struct s_type_descriptor *cb_type_descriptors;$/;" v typeref:struct:s_type_descriptor file: +cbit_cntrl ../../pcre/SRC/internal.h 647;" d +cbit_digit ../../pcre/SRC/internal.h 640;" d +cbit_graph ../../pcre/SRC/internal.h 644;" d +cbit_length ../../pcre/SRC/internal.h 648;" d +cbit_lower ../../pcre/SRC/internal.h 642;" d +cbit_print ../../pcre/SRC/internal.h 645;" d +cbit_punct ../../pcre/SRC/internal.h 646;" d +cbit_space ../../pcre/SRC/internal.h 638;" d +cbit_upper ../../pcre/SRC/internal.h 641;" d +cbit_word ../../pcre/SRC/internal.h 643;" d +cbit_xdigit ../../pcre/SRC/internal.h 639;" d +cbits ../../pcre/SRC/internal.h /^ const uschar *cbits; \/* Points to character type table *\/$/;" m struct:compile_data +cbits_offset ../../pcre/SRC/internal.h 655;" d +cbx_index_high ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** cbx_index_high;$/;" m struct:s_spice_model +cbx_index_low ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** cbx_index_low;$/;" m struct:s_spice_model +cbx_info ./base/globals.c /^t_cb** cbx_info = NULL;$/;" v +cbx_spice_file_name_prefix ./fpga_x2p/spice/spice_globals.c /^char* cbx_spice_file_name_prefix = "cbx_";$/;" v +cbx_verilog_file_name_prefix ./fpga_x2p/verilog/verilog_global.c /^char* cbx_verilog_file_name_prefix = "cbx_";$/;" v +cby_index_high ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** cby_index_high;$/;" m struct:s_spice_model +cby_index_low ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** cby_index_low;$/;" m struct:s_spice_model +cby_info ./base/globals.c /^t_cb** cby_info = NULL;$/;" v +cby_spice_file_name_prefix ./fpga_x2p/spice/spice_globals.c /^char* cby_spice_file_name_prefix = "cby_";$/;" v +cby_verilog_file_name_prefix ./fpga_x2p/verilog/verilog_global.c /^char* cby_verilog_file_name_prefix = "cby_";$/;" v +cc_constraints ./base/vpr_types.h /^ t_override_constraint * cc_constraints; \/* [0..num_cc_constraints - 1] array of such constraints *\/$/;" m struct:s_timing_constraints +cf_constraints ./base/vpr_types.h /^ t_override_constraint * cf_constraints; \/* [0..num_cf_constraints - 1] array of such constraints *\/$/;" m struct:s_timing_constraints +chain_name ../../libarchfpga/include/physical_types.h /^ char *chain_name;$/;" m struct:s_port +chain_pattern ./base/vpr_types.h /^ t_model_chain_pattern *chain_pattern; \/* If this is a chain molecule, chain that this molecule matches *\/$/;" m struct:s_pack_molecule +chain_root_pin ../../libarchfpga/include/cad_types.h /^ t_pb_graph_pin *chain_root_pin; \/* pointer to logic block input pin that drives this chain from the preceding logic block *\/ $/;" m struct:s_pack_patterns +chan_length ../../libarchfpga/fpga_spice_include/spice_types.h /^ float chan_length;$/;" m struct:s_spice_transistor_type +chan_rr_node ./base/vpr_types.h /^ t_rr_node*** chan_rr_node;$/;" m struct:s_cb +chan_rr_node ./base/vpr_types.h /^ t_rr_node*** chan_rr_node;$/;" m struct:s_sb +chan_rr_node_direction ./base/vpr_types.h /^ enum PORTS** chan_rr_node_direction;$/;" m struct:s_cb typeref:enum:s_cb::PORTS +chan_rr_node_direction ./base/vpr_types.h /^ enum PORTS** chan_rr_node_direction;$/;" m struct:s_sb typeref:enum:s_sb::PORTS +chan_width ./base/vpr_types.h /^ int* chan_width;$/;" m struct:s_cb +chan_width ./base/vpr_types.h /^ int* chan_width;$/;" m struct:s_sb +chan_width_io ../../libarchfpga/include/physical_types.h /^ float chan_width_io;$/;" m struct:s_chan_width_dist +chan_width_x ./base/globals.c /^int *chan_width_x = NULL; \/* [0..ny] *\/$/;" v +chan_width_x ./base/globals_declare.h /^int *chan_width_x, *chan_width_y; \/* numerical form *\/$/;" v +chan_width_y ./base/globals.c /^int *chan_width_y = NULL; \/* [0..nx] *\/$/;" v +chan_width_y ./base/globals_declare.h /^int *chan_width_x, *chan_width_y; \/* numerical form *\/$/;" v +chan_x_dist ../../libarchfpga/include/physical_types.h /^ t_chan chan_x_dist;$/;" m struct:s_chan_width_dist +chan_y_dist ../../libarchfpga/include/physical_types.h /^ t_chan chan_y_dist;$/;" m struct:s_chan_width_dist +change_button_text ./base/graphics.c /^void change_button_text(const char *button_name, const char *new_button_text) {$/;" f +change_button_text ./base/graphics.c /^void change_button_text(const char *button_text, const char *new_button_text) { }$/;" f +channel_width ./power/power.h /^ int channel_width;$/;" m struct:s_solution_inf +chanx_chany_adjacent ./route/check_route.c /^static int chanx_chany_adjacent(int chanx_node, int chany_node) {$/;" f file: +chanx_place_cost_fac ./place/place.c /^static float **chanx_place_cost_fac, **chany_place_cost_fac;$/;" v file: +chanx_spice_file_name_prefix ./fpga_x2p/spice/spice_globals.c /^char* chanx_spice_file_name_prefix = "chanx_";$/;" v +chanx_verilog_file_name_prefix ./fpga_x2p/verilog/verilog_global.c /^char* chanx_verilog_file_name_prefix = "chanx_";$/;" v +chany_place_cost_fac ./place/place.c /^static float **chanx_place_cost_fac, **chany_place_cost_fac;$/;" v file: +chany_spice_file_name_prefix ./fpga_x2p/spice/spice_globals.c /^char* chany_spice_file_name_prefix = "chany_";$/;" v +chany_verilog_file_name_prefix ./fpga_x2p/verilog/verilog_global.c /^char* chany_verilog_file_name_prefix = "chany_";$/;" v +checkTokenType ./util/token.c /^boolean checkTokenType(INP t_token token, OUTP enum e_token_type token_type) {$/;" f +check_adjacent ./route/check_route.c /^static boolean check_adjacent(int from_node, int to_node) {$/;" f file: +check_all_tracks_reach_pins ./route/rr_graph.c /^static void check_all_tracks_reach_pins(t_type_ptr type,$/;" f file: +check_and_add_mux_to_linked_list ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void check_and_add_mux_to_linked_list(t_llist** muxes_head,$/;" f +check_and_add_one_global_port_to_llist ./fpga_x2p/base/fpga_x2p_setup.c /^t_llist* check_and_add_one_global_port_to_llist(t_llist* old_head, $/;" f file: +check_and_count_models ./base/read_blif.c /^static void check_and_count_models(int doall, const char* model_name,$/;" f file: +check_and_rename_logical_block_and_net_names ./fpga_x2p/base/fpga_x2p_setup.c /^int check_and_rename_logical_block_and_net_names(t_llist* LL_reserved_syntax_char_head, $/;" f file: +check_clb_conn ./base/check_netlist.c /^static int check_clb_conn(int iblk, int num_conn) {$/;" f file: +check_clb_internal_nets ./base/check_netlist.c /^static int check_clb_internal_nets(int iblk) {$/;" f file: +check_clocks ./pack/cluster.c /^static void check_clocks(boolean *is_clock) {$/;" f file: +check_cluster_logical_blocks ./pack/cluster.c /^static void check_cluster_logical_blocks(t_pb *pb, boolean *blocks_checked) {$/;" f file: +check_clustering ./pack/cluster.c /^static void check_clustering(int num_clb, t_block *clb, boolean *is_clock) {$/;" f file: +check_conflict_syntax_char_in_string ./fpga_x2p/base/fpga_x2p_setup.c /^int check_conflict_syntax_char_in_string(t_llist* LL_reserved_syntax_char_head,$/;" f file: +check_connections_to_global_clb_pins ./base/check_netlist.c /^static int check_connections_to_global_clb_pins(int inet) {$/;" f file: +check_consistency_logical_block_net_num ./fpga_x2p/base/fpga_x2p_utils.c /^int check_consistency_logical_block_net_num(t_logical_block* lgk_blk, $/;" f +check_des_blk_pin ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int check_des_blk_pin(int n_blks, t_block* blk,$/;" f +check_dptr_exist_in_llist ../../libarchfpga/linkedlist.c /^boolean check_dptr_exist_in_llist(t_llist* head, void* data_ptr) {$/;" f +check_drive_rr_node_imply_short ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^boolean check_drive_rr_node_imply_short(t_sb cur_sb_info,$/;" f +check_escape ../../pcre/SRC/pcre.c /^check_escape(const uschar **ptrptr, const char **errorptr, int bracount,$/;" f file: +check_ff_spice_model_ports ./fpga_x2p/base/fpga_x2p_utils.c /^void check_ff_spice_model_ports(t_spice_model* cur_spice_model,$/;" f +check_fontsize ./base/graphics.c /^static int check_fontsize(int pointsize,$/;" f file: +check_for_duplicated_names ./base/check_netlist.c /^static int check_for_duplicated_names(void) {$/;" f file: +check_keywords_conflict ./fpga_x2p/base/fpga_x2p_setup.c /^void check_keywords_conflict(t_arch Arch) {$/;" f +check_locally_used_clb_opins ./route/check_route.c /^static void check_locally_used_clb_opins(t_ivec ** clb_opins_used_locally,$/;" f file: +check_lookahead_pins_used ./pack/cluster.c /^static boolean check_lookahead_pins_used(t_pb *cur_pb) {$/;" f file: +check_macro_can_be_placed ./place/place.c /^static int check_macro_can_be_placed(int imacro, int itype, int x, int y, int z) {$/;" f file: +check_macros_contained ./place/place_macro.c /^int check_macros_contained(t_pl_macro pl_macro_a,$/;" f +check_mem_model_blwl_inverted ./fpga_x2p/base/fpga_x2p_utils.c /^void check_mem_model_blwl_inverted(t_spice_model* cur_mem_model, $/;" f +check_negative_variation ./fpga_x2p/base/fpga_x2p_utils.c /^boolean check_negative_variation(float avg_val, $/;" f +check_net ./base/read_blif.c /^static void check_net(boolean sweep_hanging_nets_and_inputs) {$/;" f file: +check_netlist ./base/check_netlist.c /^void check_netlist() {$/;" f +check_node ./route/check_rr_graph.c /^void check_node(int inode, enum e_route_type route_type) {$/;" f +check_node_and_range ./route/check_route.c /^static void check_node_and_range(int inode, enum e_route_type route_type) {$/;" f file: +check_pass_transistors ./route/check_rr_graph.c /^static void check_pass_transistors(int from_node) {$/;" f file: +check_pb_graph ./pack/pb_type_graph.c /^static int check_pb_graph(void) {$/;" f file: +check_pb_graph_edge ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge) {$/;" f +check_pb_graph_pin_edges ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin) {$/;" f +check_pin_number_match_phy_pb_graph_pin ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^boolean check_pin_number_match_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph_pin, $/;" f +check_place ./place/place.c /^static void check_place(float bb_cost, float timing_cost, $/;" f file: +check_posix_name ../../pcre/SRC/pcre.c /^check_posix_name(const uschar *ptr, int len)$/;" f file: +check_posix_syntax ../../pcre/SRC/pcre.c /^check_posix_syntax(const uschar *ptr, const uschar **endptr, compile_data *cd)$/;" f file: +check_primitives ./base/check_netlist.c /^static int check_primitives(int iblk, int isub) {$/;" f file: +check_route ./route/check_route.c /^void check_route(enum e_route_type route_type, int num_switch,$/;" f +check_rr_graph ./route/check_rr_graph.c /^void check_rr_graph(INP t_graph_type graph_type, INP t_type_ptr types,$/;" f +check_sink ./route/check_route.c /^static void check_sink(int inode, int inet, boolean * pin_done) {$/;" f file: +check_source ./route/check_route.c /^static void check_source(int inode, int inet) {$/;" f file: +check_spice_model_name_conflict_syntax_char ./fpga_x2p/base/fpga_x2p_setup.c /^void check_spice_model_name_conflict_syntax_char(t_arch Arch,$/;" f file: +check_spice_model_structure_match_switch_inf ./fpga_x2p/base/fpga_x2p_utils.c /^boolean check_spice_model_structure_match_switch_inf(t_switch_inf target_switch_inf) {$/;" f +check_spice_models ../../libarchfpga/read_xml_spice.c /^static void check_spice_models(int num_spice_model,$/;" f file: +check_spice_models_grid_tb_cnt ./fpga_x2p/base/fpga_x2p_utils.c /^void check_spice_models_grid_tb_cnt(int num_spice_models,$/;" f +check_sram_spice_model_ports ./fpga_x2p/base/fpga_x2p_utils.c /^void check_sram_spice_model_ports(t_spice_model* cur_spice_model,$/;" f +check_src_blk_pin ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int check_src_blk_pin(int n_blks, t_block* blk,$/;" f +check_subblock_internal_nets ./base/check_netlist.c /^static int check_subblock_internal_nets(int iblk, int isub) {$/;" f file: +check_subblocks ./base/check_netlist.c /^static int check_subblocks(int iblk) {$/;" f file: +check_subckt_file_exist_in_llist ./fpga_x2p/base/fpga_x2p_utils.c /^boolean check_subckt_file_exist_in_llist(t_llist* subckt_llist_head,$/;" f +check_switch ./route/check_route.c /^static void check_switch(struct s_trace *tptr, int num_switch) {$/;" f file: +check_tech_lib ../../libarchfpga/read_xml_spice.c /^static void check_tech_lib(t_spice_tech_lib tech_lib, $/;" f file: +check_timing_graph ./timing/path_delay2.c /^void check_timing_graph(int num_sinks) {$/;" f +child ../../libarchfpga/include/ezxml.h /^ ezxml_t child; \/* head of sub tag list, NULL if none *\/$/;" m struct:ezxml +child ./route/route_tree_timing.h /^ struct s_rt_node *child;$/;" m struct:s_linked_rt_edge typeref:struct:s_linked_rt_edge::s_rt_node +child ./timing/net_delay_types.h /^ struct s_rc_node *child;$/;" m struct:s_linked_rc_edge typeref:struct:s_linked_rc_edge::s_rc_node +child_list ./route/route_tree_timing.h /^ t_linked_rt_edge *child_list;$/;" m union:s_rt_node::__anon16 +child_list ./timing/net_delay_types.h /^ t_linked_rc_edge *child_list;$/;" m union:s_rc_node::__anon18 +child_pb_graph_nodes ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_node ***child_pb_graph_nodes; \/* [0..num_modes-1][0..num_pb_type_in_mode-1][0..num_pb-1] *\/$/;" m struct:s_pb_graph_node typeref:struct:s_pb_graph_node::s_pb_graph_node +child_pbs ./base/vpr_types.h /^ struct s_pb **child_pbs; \/* children pbs attached to this pb [0..num_child_pb_types - 1][0..child_type->num_pb - 1] *\/$/;" m struct:s_pb typeref:struct:s_pb::s_pb +child_pbs ./fpga_x2p/base/fpga_x2p_types.h /^ t_phy_pb **child_pbs; \/* children pbs attached to this pb [0..num_child_pb_types - 1][0..child_type->num_pb - 1] *\/$/;" m struct:fpga_spice_phy_pb +children ./power/power.h /^ t_mux_node * children; \/* Multiplexers that drive the inputs [0..num_inputs-1] *\/$/;" m struct:s_mux_node +chomp_file_name_postfix ./fpga_x2p/base/fpga_x2p_utils.c /^char* chomp_file_name_postfix(char* file_name) {$/;" f +chomp_spice_node_prefix ./fpga_x2p/base/fpga_x2p_utils.c /^char* chomp_spice_node_prefix(char* spice_node_prefix) {$/;" f +chomp_verilog_node_prefix ./fpga_x2p/verilog/verilog_utils.c /^char* chomp_verilog_node_prefix(char* verilog_node_prefix) {$/;" f +chunk_ptr_head ../../libarchfpga/include/util.h /^ struct s_linked_vptr *chunk_ptr_head; $/;" m struct:s_chunk typeref:struct:s_chunk::s_linked_vptr +circuit_p_io_removed ./base/globals.c /^struct s_linked_vptr *circuit_p_io_removed = NULL;$/;" v typeref:struct:s_linked_vptr +class ../../pcre/SRC/pcre.c 58;" d file: +class_inf ../../libarchfpga/include/physical_types.h /^ struct s_class *class_inf; \/* [0..num_class-1] *\/$/;" m struct:s_type_descriptor typeref:struct:s_type_descriptor::s_class +class_type ../../libarchfpga/include/physical_types.h /^ enum e_pb_type_class class_type;$/;" m struct:s_pb_type typeref:enum:s_pb_type::e_pb_type_class +clay_logical_equivalence_handling ./base/vpr_api.c /^static void clay_logical_equivalence_handling(const t_arch *arch) {$/;" f file: +clay_lut_input_rebalancing ./base/vpr_api.c /^static void clay_lut_input_rebalancing(int iblock, t_pb *pb) {$/;" f file: +clay_reload_ble_locations ./base/vpr_api.c /^static void clay_reload_ble_locations(int iblock) {$/;" f file: +clb2clb_direct ./base/globals.c /^t_clb_to_clb_directs* clb2clb_direct = NULL;$/;" v +clb_grid ../../libarchfpga/include/physical_types.h /^ struct s_clb_grid clb_grid;$/;" m struct:s_arch typeref:struct:s_arch::s_clb_grid +clb_index ./base/vpr_types.h /^ int clb_index; \/* Complex block index that this logical block got mapped to *\/$/;" m struct:s_logical_block +clb_net ./base/globals.c /^struct s_net *clb_net = NULL;$/;" v typeref:struct:s_net +clb_net_density ./power/power_util.c /^float clb_net_density(int net_idx) {$/;" f +clb_net_prob ./power/power_util.c /^float clb_net_prob(int net_idx) {$/;" f +clb_opins_used_locally ./place/timing_place_lookup.c /^static t_ivec **clb_opins_used_locally;$/;" v file: +clb_to_vpack_net_mapping ./base/globals.c /^int *clb_to_vpack_net_mapping = NULL; \/* [0..num_clb_nets - 1] *\/$/;" v +clear_buffer ./mrfpga/buffer_insertion.c /^void clear_buffer( )$/;" f +clearscreen ./base/graphics.c /^clearscreen (void) $/;" f +clearscreen ./base/graphics.c /^void clearscreen (void) { }$/;" f +clock ../../libarchfpga/include/physical_types.h /^ char * clock;$/;" m struct:s_pin_to_pin_annotation +clock_delay ./base/vpr_types.h /^ float clock_delay; \/* The time taken for a clock signal to get to the flip-flop or I\/O (assumed 0 for I\/Os). *\/$/;" m struct:s_tnode +clock_domain ./base/vpr_types.h /^ int clock_domain; \/* Index of the clock in g_sdc->constrained_clocks which this flip-flop or I\/O is constrained on. *\/$/;" m struct:s_tnode +clock_inf ../../libarchfpga/include/physical_types.h /^ t_clock_network *clock_inf; \/* Details about each clock *\/$/;" m struct:s_clock_arch +clock_input_name ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^static char* clock_input_name = NULL;$/;" v file: +clock_name ./base/vpr_types.h /^ char * clock_name; \/* Clock it was constrained on *\/$/;" m struct:s_io +clock_names ./timing/read_sdc.c /^ char ** clock_names;$/;" m struct:s_sdc_exclusive_group file: +clock_net ./base/vpr_types.h /^ int clock_net; \/* Clock net connected to this logical_block. *\/$/;" m struct:s_logical_block +clock_net ./base/vpr_types.h /^ int clock_net; \/* Records clock net driving a flip-flop, valid only for lowest-level, flip-flop PBs *\/$/;" m struct:s_pb +clock_net_tnode ./base/vpr_types.h /^ struct s_tnode *clock_net_tnode; \/* correspnding clock net tnode *\/$/;" m struct:s_logical_block typeref:struct:s_logical_block::s_tnode +clock_pins ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin **clock_pins; \/* [0..num_clock_ports-1] [0..num_port_pins-1]*\/$/;" m struct:s_pb_graph_node +clock_slew_fall_time ../../libarchfpga/fpga_spice_include/spice_types.h /^ float clock_slew_fall_time; $/;" m struct:s_spice_stimulate_params +clock_slew_fall_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_accuracy_type clock_slew_fall_type;$/;" m struct:s_spice_stimulate_params typeref:enum:s_spice_stimulate_params::e_spice_accuracy_type +clock_slew_rise_time ../../libarchfpga/fpga_spice_include/spice_types.h /^ float clock_slew_rise_time; $/;" m struct:s_spice_stimulate_params +clock_slew_rise_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_accuracy_type clock_slew_rise_type;$/;" m struct:s_spice_stimulate_params typeref:enum:s_spice_stimulate_params::e_spice_accuracy_type +clocks ../../libarchfpga/include/physical_types.h /^ t_clock_arch * clocks;$/;" m struct:s_arch +close ../../libarchfpga/ezxml.c 61;" d file: +close_graphics ./base/graphics.c /^close_graphics (void) $/;" f +close_graphics ./base/graphics.c /^void close_graphics (void) { }$/;" f +close_postscript ./base/graphics.c /^void close_postscript (void) $/;" f +close_postscript ./base/graphics.c /^void close_postscript (void) { }$/;" f +cluster_placement_primitive ../../libarchfpga/include/physical_types.h /^ struct s_cluster_placement_primitive *cluster_placement_primitive; \/* pointer to indexing structure useful during packing stage *\/$/;" m struct:s_pb_graph_node typeref:struct:s_pb_graph_node::s_cluster_placement_primitive +cluster_seed_type ./base/ReadOptions.h /^ enum e_cluster_seed cluster_seed_type;$/;" m struct:s_options typeref:enum:s_options::e_cluster_seed +cluster_seed_type ./base/vpr_types.h /^ enum e_cluster_seed cluster_seed_type;$/;" m struct:s_packer_opts typeref:enum:s_packer_opts::e_cluster_seed +cluster_size ./base/ReadOptions.h /^ int cluster_size;$/;" m struct:s_options +cmd ./fpga_x2p/shell/shell_types.h /^ t_shell_cmd* cmd;$/;" m struct:s_shell_env +cmd_category ./fpga_x2p/shell/shell_cmds.h /^t_cmd_category cmd_category[] = {$/;" v +cmd_category ./fpga_x2p/shell/shell_types.h /^ t_cmd_category* cmd_category;$/;" m struct:s_shell_env +cmos_variation ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_mc_variation_params cmos_variation;$/;" m struct:s_spice_mc_params +cnt ../../libarchfpga/fpga_spice_include/spice_types.h /^ int cnt; \/* Used in mux_testbench only*\/$/;" m struct:s_spice_mux_model +cnt ../../libarchfpga/fpga_spice_include/spice_types.h /^ int cnt;$/;" m struct:s_spice_model +cnt ./fpga_x2p/verilog/verilog_report_timing.c /^ int cnt;$/;" m struct:s_wireL_cnt file: +code ./timing/slre.c /^ unsigned char code[256];$/;" m struct:slre file: +code_size ./timing/slre.c /^ int code_size;$/;" m struct:slre file: +col_rel ../../libarchfpga/include/physical_types.h /^ float col_rel;$/;" m struct:s_grid_loc_def +color_types ./base/easygl_constants.h /^enum color_types {WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW,$/;" g +colors ./base/graphics.c /^static int colors[NUM_COLOR];$/;" v file: +combine_buffer_plan ./mrfpga/buffer_insertion.c /^static t_buffer_plan combine_buffer_plan( t_buffer_plan slow_branch, t_buffer_plan* plan_whole, int num_whole, int num_pins )$/;" f file: +commit_lookahead_pins_used ./pack/cluster.c /^static void commit_lookahead_pins_used(t_pb *cur_pb) {$/;" f file: +commit_primitive ./pack/cluster_placement.c /^void commit_primitive(INOUTP t_cluster_placement_stats *cluster_placement_stats,$/;" f +comp_bb_cost ./place/place.c /^static float comp_bb_cost(enum cost_methods method) {$/;" f file: +comp_delta_td_cost ./place/place.c /^static void comp_delta_td_cost(float *delta_timing, float *delta_delay) {$/;" f file: +comp_td_costs ./place/place.c /^static void comp_td_costs(float *timing_cost, float *connection_delay_sum) {$/;" f file: +comp_td_point_to_point_delay ./place/place.c /^static float comp_td_point_to_point_delay(int inet, int ipin) {$/;" f file: +comp_width ./base/place_and_route.c /^static float comp_width(t_chan * chan, float x, float separation) {$/;" f file: +compact_verilog_get_grid_phy_block_subckt_name ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^char* compact_verilog_get_grid_phy_block_subckt_name(t_type_ptr grid_type_descriptor,$/;" f +compact_verilog_update_grid_spice_model_and_sram_orgz_info ./fpga_x2p/verilog/verilog_compact_netlist.c /^void compact_verilog_update_grid_spice_model_and_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,$/;" f file: +compact_verilog_update_one_spice_model_grid_index ./fpga_x2p/verilog/verilog_compact_netlist.c /^void compact_verilog_update_one_spice_model_grid_index(t_type_ptr phy_block_type,$/;" f file: +compact_verilog_update_sram_orgz_info_grid_index ./fpga_x2p/verilog/verilog_compact_netlist.c /^void compact_verilog_update_sram_orgz_info_grid_index(t_sram_orgz_info* cur_sram_orgz_info,$/;" f file: +compare_molecule_gain ./pack/cluster.c /^static int compare_molecule_gain(const void *a, const void *b) {$/;" f file: +compare_pack_pattern ./pack/prepack.c /^static int compare_pack_pattern(const t_pack_patterns *pattern_a, const t_pack_patterns *pattern_b) {$/;" f file: +compile ./timing/slre.c /^static void compile(struct slre *r, const char **re) {$/;" f file: +compile2 ./timing/slre.c /^static const char *compile2(struct slre *r, const char *re) {$/;" f file: +compile_branch ../../pcre/SRC/pcre.c /^compile_branch(int *optionsptr, int *brackets, uschar **codeptr,$/;" f file: +compile_data ../../pcre/SRC/internal.h /^typedef struct compile_data {$/;" s +compile_data ../../pcre/SRC/internal.h /^} compile_data;$/;" t typeref:struct:compile_data +compile_regex ../../pcre/SRC/pcre.c /^compile_regex(int options, int oldims, int *brackets, uschar **codeptr,$/;" f file: +complete_truth_table_line ./fpga_x2p/base/fpga_x2p_lut_utils.c /^char* complete_truth_table_line(int lut_size,$/;" f +component_callibration ./power/power.h /^ PowerSpicedComponent ** component_callibration;$/;" m struct:s_power_commonly_used +component_usage ./power/PowerSpicedComponent.h /^ float (*component_usage)(int num_inputs, float transistor_size);$/;" m class:PowerSpicedComponent +components ./power/power_components.h /^ t_power_usage * components;$/;" m struct:s_power_breakdown +compress_netlist ./base/read_blif.c /^static void compress_netlist(void) {$/;" f file: +compute_and_mark_lookahead_pins_used ./pack/cluster.c /^static void compute_and_mark_lookahead_pins_used(int ilogical_block) {$/;" f file: +compute_and_mark_lookahead_pins_used_for_pin ./pack/cluster.c /^static void compute_and_mark_lookahead_pins_used_for_pin($/;" f file: +compute_delay_lookup_tables ./place/timing_place_lookup.c /^void compute_delay_lookup_tables(struct s_router_opts router_opts,$/;" f +compute_delta_arrays ./place/timing_place_lookup.c /^static void compute_delta_arrays(struct s_router_opts router_opts,$/;" f file: +compute_delta_clb_to_clb ./place/timing_place_lookup.c /^static void compute_delta_clb_to_clb(struct s_router_opts router_opts,$/;" f file: +compute_delta_clb_to_io ./place/timing_place_lookup.c /^static void compute_delta_clb_to_io(struct s_router_opts router_opts,$/;" f file: +compute_delta_io_to_clb ./place/timing_place_lookup.c /^static void compute_delta_io_to_clb(struct s_router_opts router_opts,$/;" f file: +compute_delta_io_to_io ./place/timing_place_lookup.c /^static void compute_delta_io_to_io(struct s_router_opts router_opts,$/;" f file: +compute_primitive_base_cost ./util/vpr_utils.c /^float compute_primitive_base_cost(INP t_pb_graph_node *primitive) {$/;" f +conf_bit_head ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_llist* conf_bit_head; $/;" m struct:s_sram_orgz_info +conf_bits_head ./fpga_x2p/verilog/verilog_global.c /^t_llist* conf_bits_head = NULL;$/;" v +conf_bits_lsb ./base/vpr_types.h /^ int conf_bits_lsb; \/* LSB of configuration bits *\/$/;" m struct:s_cb +conf_bits_lsb ./base/vpr_types.h /^ int conf_bits_lsb; \/* LSB of configuration bits *\/$/;" m struct:s_sb +conf_bits_msb ./base/vpr_types.h /^ int conf_bits_msb; \/* MSB of configuration bits *\/$/;" m struct:s_cb +conf_bits_msb ./base/vpr_types.h /^ int conf_bits_msb; \/* MSB of configuration bits *\/$/;" m struct:s_sb +config_one_spice_model_buffer ./fpga_x2p/base/fpga_x2p_utils.c /^void config_one_spice_model_buffer(int num_spice_models, $/;" f +config_peripheral_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* config_peripheral_verilog_file_name = "config_peripherals.v";$/;" v +config_spice_model_input_output_buffers_pass_gate ./fpga_x2p/base/fpga_x2p_utils.c /^void config_spice_model_input_output_buffers_pass_gate(int num_spice_models, $/;" f +config_spice_model_port_inv_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^void config_spice_model_port_inv_spice_model(int num_spice_models, $/;" f +config_spice_models_sram_port_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^void config_spice_models_sram_port_spice_model(int num_spice_model,$/;" f +configure_lut_sram_bits_per_line_rec ./fpga_x2p/base/fpga_x2p_lut_utils.c /^void configure_lut_sram_bits_per_line_rec(int** sram_bits, $/;" f +configure_one_tedge_delay ./fpga_x2p/base/fpga_x2p_timing_utils.c /^void configure_one_tedge_delay(t_spice_model_tedge* cur_tedge,$/;" f +configure_tedges_delay_matrix ./fpga_x2p/base/fpga_x2p_timing_utils.c /^void configure_tedges_delay_matrix(enum spice_model_delay_type delay_type,$/;" f +conn_list ./base/verilog_writer.h /^}conn_list;$/;" t typeref:struct:found_connectivity +connect_one_rr_node_for_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void connect_one_rr_node_for_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin,$/;" f +connect_pb_des_pin_to_src_pin ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void connect_pb_des_pin_to_src_pin(t_pb* src_pb,$/;" f +connection_driven ./base/ReadOptions.h /^ boolean connection_driven;$/;" m struct:s_options +connection_driven ./base/vpr_types.h /^ boolean connection_driven;$/;" m struct:s_packer_opts +connectiongain ./base/vpr_types.h /^ std::map connectiongain; \/* [0..num_logical_blocks-1] Weighted sum of connections to attraction function *\/$/;" m struct:s_pb_stats +connections ../../libarchfpga/include/cad_types.h /^ struct s_pack_pattern_connections *connections; \/* linked list of connections of logic blocks in pattern *\/$/;" m struct:s_pack_pattern_block typeref:struct:s_pack_pattern_block::s_pack_pattern_connections +const_input_val ../../libarchfpga/fpga_spice_include/spice_types.h /^ int const_input_val;$/;" m struct:s_spice_model_mux +constant_net_delay ./base/ReadOptions.h /^ float constant_net_delay;$/;" m struct:s_options +constant_net_delay ./base/vpr_types.h /^ float constant_net_delay; \/* timing information when place and route not run *\/$/;" m struct:s_vpr_setup +constrain_cbs ./fpga_x2p/verilog/verilog_sdc.c /^ boolean constrain_cbs;$/;" m struct:s_sdc_opts file: +constrain_pbs ./fpga_x2p/verilog/verilog_sdc.c /^ boolean constrain_pbs;$/;" m struct:s_sdc_opts file: +constrain_routing_channels ./fpga_x2p/verilog/verilog_sdc.c /^ boolean constrain_routing_channels;$/;" m struct:s_sdc_opts file: +constrain_sbs ./fpga_x2p/verilog/verilog_sdc.c /^ boolean constrain_sbs;$/;" m struct:s_sdc_opts file: +constrained_clocks ./base/vpr_types.h /^ t_clock * constrained_clocks; \/* [0..g_sdc->num_constrained_clocks - 1] array of clocks with timing constraints *\/$/;" m struct:s_timing_constraints +constrained_inputs ./base/vpr_types.h /^ t_io * constrained_inputs; \/* [0..num_constrained_inputs - 1] array of inputs with timing constraints *\/$/;" m struct:s_timing_constraints +constrained_outputs ./base/vpr_types.h /^ t_io * constrained_outputs; \/* [0..num_constrained_outputs - 1] array of outputs with timing constraints *\/$/;" m struct:s_timing_constraints +constraint ./base/vpr_types.h /^ float constraint;$/;" m struct:s_override_constraint +cont ../../libarchfpga/util.c /^static int cont; \/* line continued? *\/$/;" v file: +convert_cb_type_to_string ./fpga_x2p/base/fpga_x2p_utils.c /^char* convert_cb_type_to_string(t_rr_type chan_type) {$/;" f +convert_chan_rr_node_direction_to_string ./fpga_x2p/base/fpga_x2p_utils.c /^char* convert_chan_rr_node_direction_to_string(enum PORTS chan_rr_node_direction) {$/;" f +convert_chan_type_to_string ./fpga_x2p/base/fpga_x2p_utils.c /^char* convert_chan_type_to_string(t_rr_type chan_type) {$/;" f +convert_const_input_value_to_str ./fpga_x2p/spice/spice_utils.c /^char* convert_const_input_value_to_str(int const_input_val) {$/;" f +convert_modelsim_time_unit_to_float ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^float convert_modelsim_time_unit_to_float(char* modelsim_time_unit) {$/;" f +convert_option_mandatory_to_str ./fpga_x2p/shell/read_opt.c /^char* convert_option_mandatory_to_str(enum opt_manda cur) {$/;" f +convert_process_corner_to_string ./fpga_x2p/base/fpga_x2p_utils.c /^char* convert_process_corner_to_string(enum e_process_corner process_corner) {$/;" f +convert_side_index_to_string ./fpga_x2p/base/fpga_x2p_utils.c /^char* convert_side_index_to_string(int side) {$/;" f +convert_spice_model_port_type_to_verilog_port_type ./fpga_x2p/verilog/verilog_utils.c /^convert_spice_model_port_type_to_verilog_port_type(enum e_spice_model_port_type spice_model_port_type) {$/;" f +copy_delay ./mrfpga/buffer_insertion.c /^static void copy_delay( float* base, float* source, t_linked_int* index )$/;" f file: +copy_from_float_array ./mrfpga/buffer_insertion.c /^static float* copy_from_float_array( float* source, int num )$/;" f file: +copy_from_list ./mrfpga/mrfpga_util.c /^t_linked_int* copy_from_list( t_linked_int* base, t_linked_int* target )$/;" f +copy_sram_orgz_info ./fpga_x2p/base/fpga_x2p_utils.c /^void copy_sram_orgz_info(t_sram_orgz_info* des_sram_orgz_info,$/;" f +cost ./base/vpr_types.h /^ float cost;$/;" m struct:s_place_region +cost ./route/route_common.h /^ float cost;$/;" m struct:s_heap +cost_index ./base/vpr_types.h /^ short cost_index;$/;" m struct:s_rr_node +cost_methods ./place/place.c /^enum cost_methods {$/;" g file: +could_be_empty ../../pcre/SRC/pcre.c /^could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr,$/;" f file: +could_be_empty_branch ../../pcre/SRC/pcre.c /^could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8)$/;" f file: +count ./base/read_blif.c /^ int count;$/;" m struct:s_model_stats file: +count ./util/hash.h /^ int count;$/;" m struct:s_hash +count_bidir_routing_transistors ./route/rr_graph_area.c /^void count_bidir_routing_transistors(int num_switch, float R_minW_nmos,$/;" f +count_blk_one_class_num_conflict ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int count_blk_one_class_num_conflict(t_block* target_blk, int class_index,$/;" f +count_cb_info_num_ipin_rr_nodes ./fpga_x2p/base/fpga_x2p_utils.c /^int count_cb_info_num_ipin_rr_nodes(t_cb cur_cb_info) {$/;" f +count_connections ./place/place.c /^static int count_connections() {$/;" f file: +count_netlist_clocks ./base/stats.c /^int count_netlist_clocks(void) {$/;" f +count_netlist_clocks_as_constrained_clocks ./timing/read_sdc.c /^static void count_netlist_clocks_as_constrained_clocks(void) {$/;" f file: +count_netlist_ios_as_constrained_ios ./timing/read_sdc.c /^static void count_netlist_ios_as_constrained_ios(char * clock_name, float io_delay) {$/;" f file: +count_num_conf_bit_one_interc ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_num_conf_bit_one_interc(t_interconnect* cur_interc,$/;" f +count_num_conf_bits_one_generic_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_conf_bits_one_generic_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_conf_bits_one_lut_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_conf_bits_one_mux_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_conf_bits_one_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_conf_bits_one_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_conf_bits_pb_type_mode_interc ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode,$/;" f +count_num_mode_bits_one_generic_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_mode_bits_one_generic_spice_model(t_spice_model* cur_spice_model) {$/;" f +count_num_mode_bits_one_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_mode_bits_one_spice_model(t_spice_model* cur_spice_model) {$/;" f +count_num_reserved_conf_bit_one_interc ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_reserved_conf_bit_one_interc(t_interconnect* cur_interc,$/;" f +count_num_reserved_conf_bits_one_lut_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_reserved_conf_bits_one_lut_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_reserved_conf_bits_one_mux_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_reserved_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_reserved_conf_bits_one_rram_sram_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_reserved_conf_bits_one_rram_sram_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_reserved_conf_bits_one_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_reserved_conf_bits_one_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_reserved_conf_bits_pb_type_mode_interc ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_num_reserved_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode,$/;" f +count_num_sram_bits_one_generic_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_sram_bits_one_generic_spice_model(t_spice_model* cur_spice_model) {$/;" f +count_num_sram_bits_one_lut_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_sram_bits_one_lut_spice_model(t_spice_model* cur_spice_model) {$/;" f +count_num_sram_bits_one_mux_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_sram_bits_one_mux_spice_model(t_spice_model* cur_spice_model,$/;" f +count_num_sram_bits_one_spice_model ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int count_num_sram_bits_one_spice_model(t_spice_model* cur_spice_model,$/;" f +count_pb_graph_node_input_edge_in_phy_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_pb_graph_node_input_edge_in_phy_mode(t_pb_graph_pin* cur_pb_graph_pin,$/;" f +count_pb_graph_node_output_edge_in_phy_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_pb_graph_node_output_edge_in_phy_mode(t_pb_graph_pin* cur_pb_graph_pin,$/;" f +count_pin_number_one_pb_graph_node ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_pin_number_one_pb_graph_node(t_pb_graph_node* cur_pb_graph_node) {$/;" f +count_pin_number_one_port_pb_graph_node ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int count_pin_number_one_port_pb_graph_node(int num_ports, int* num_pins) {$/;" f +count_routing_memristor_buffer ./mrfpga/buffer_insertion.c /^void count_routing_memristor_buffer( int num_per_channel, float buffer_size )$/;" f +count_routing_transistors ./route/rr_graph_area.c /^void count_routing_transistors(enum e_directionality directionality,$/;" f +count_sinks_internal_cb_rr_graph_net_nums ./base/read_netlist.c /^static int count_sinks_internal_cb_rr_graph_net_nums($/;" f file: +count_unidir_routing_transistors ./route/rr_graph_area.c /^void count_unidir_routing_transistors(t_segment_inf * segment_inf,$/;" f +count_verilog_connection_box_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_connection_box_interc_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_connection_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_connection_box_interc_reserved_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_connection_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_connection_box_one_side_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_connection_box_one_side_reserved_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_connection_box_reserved_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_switch_box_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_switch_box_interc_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_switch_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_switch_box_interc_reserved_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_switch_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +count_verilog_switch_box_reserved_conf_bits ./fpga_x2p/verilog/verilog_routing.c /^int count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +cpd ./base/vpr_types.h /^ float ** cpd;$/;" m struct:s_timing_stats +cpt_subckt_name ./fpga_x2p/spice/spice_globals.c /^char* cpt_subckt_name = "cpt";$/;" v +create_button ./base/graphics.c /^void create_button (const char *prev_button_text , const char *button_text, $/;" f +create_button ./base/graphics.c /^void create_button (const char *prev_button_text , const char *button_text,$/;" f +create_dir_path ./fpga_x2p/base/fpga_x2p_utils.c /^int create_dir_path(char* dir_path) {$/;" f +create_llist ../../libarchfpga/linkedlist.c /^t_llist* create_llist(int len) {$/;" f +create_wireL_report_timing_tcl_file_handler ./fpga_x2p/verilog/verilog_report_timing.c /^FILE* create_wireL_report_timing_tcl_file_handler(t_trpt_opts trpt_opts, $/;" f +criticality_exp ./base/ReadOptions.h /^ float criticality_exp;$/;" m struct:s_options +criticality_exp ./base/vpr_types.h /^ float criticality_exp;$/;" m struct:s_router_opts +critindexarray ./pack/cluster.c /^static int *critindexarray = NULL;$/;" v file: +cross_count ./place/place.c /^static const float cross_count[50] = { \/* [0..49] *\/1.0, 1.0, 1.0, 1.0828, 1.1536, 1.2206, 1.2823, 1.3385, 1.3991, 1.4493, 1.4974,$/;" v file: +ctype_digit ../../pcre/SRC/internal.h 630;" d +ctype_letter ../../pcre/SRC/internal.h 629;" d +ctype_meta ../../pcre/SRC/internal.h 633;" d +ctype_space ../../pcre/SRC/internal.h 628;" d +ctype_word ../../pcre/SRC/internal.h 632;" d +ctype_xdigit ../../pcre/SRC/internal.h 631;" d +ctypes ../../pcre/SRC/internal.h /^ const uschar *ctypes; \/* Points to table of type maps *\/$/;" m struct:compile_data +ctypes ../../pcre/SRC/internal.h /^ const uschar *ctypes; \/* Points to table of type maps *\/$/;" m struct:match_data +ctypes_offset ../../pcre/SRC/internal.h 656;" d +cur ../../libarchfpga/include/ezxml.h /^ ezxml_t cur; \/* current xml tree insertion point *\/$/;" m struct:ezxml_root +curr_cluster_index ./pack/cluster_legality.c /^static int curr_cluster_index;$/;" v file: +curr_molecule ./base/vpr_types.h /^ t_pack_molecule *curr_molecule; \/* current molecule being considered for packing *\/$/;" m struct:s_cluster_placement_stats +current ../../pcre/SRC/internal.h /^ uschar *current;$/;" m struct:branch_chain +current_draw_mode ./base/graphics.c /^static e_draw_mode current_draw_mode;$/;" v file: +current_gc ./base/graphics.c /^static GC gc, gcxor, gc_menus, current_gc;$/;" v file: +current_position ../../pcre/SRC/pcre.h /^ int current_position; \/* Where we currently are *\/$/;" m struct:pcre_callout_block +current_random ../../libarchfpga/util.c /^static unsigned int current_random = 0;$/;" v file: +currentcolor ./base/graphics.c /^static int currentcolor;$/;" v file: +currentfontsize ./base/graphics.c /^static int currentfontsize;$/;" v file: +currentlinestyle ./base/graphics.c /^static int currentlinestyle;$/;" v file: +currentlinewidth ./base/graphics.c /^static int currentlinewidth;$/;" v file: +cxClient ./base/graphics.c /^static int cxClient, cyClient;$/;" v file: +cyClient ./base/graphics.c /^static int cxClient, cyClient;$/;" v file: +data ../../libarchfpga/include/util.h /^ int data;$/;" m struct:s_linked_int +data ./timing/slre.c /^ unsigned char data[256];$/;" m struct:slre file: +data ./util/token.h /^ char *data;$/;" m struct:s_token +data_size ./timing/slre.c /^ int data_size;$/;" m struct:slre file: +data_vptr ../../libarchfpga/include/util.h /^ void *data_vptr;$/;" m struct:s_linked_vptr +dc ../../libarchfpga/include/physical_types.h /^ float dc;$/;" m struct:s_chan +dealloc_mux_graph ./power/power.c /^static void dealloc_mux_graph(t_mux_node * node) {$/;" f file: +dealloc_mux_graph_rec ./power/power.c /^static void dealloc_mux_graph_rec(t_mux_node * node) {$/;" f file: +decode_and_add_sram_membank_conf_bit_to_llist ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^decode_and_add_sram_membank_conf_bit_to_llist(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +decode_cmos_mux_sram_bits ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void decode_cmos_mux_sram_bits(t_spice_model* mux_spice_model,$/;" f +decode_memory_bank_sram ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void decode_memory_bank_sram(t_spice_model* cur_sram_spice_model, int sram_bit,$/;" f +decode_mode_bits ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int* decode_mode_bits(char* mode_bits, int* num_sram_bits) {$/;" f +decode_multilevel_4t1r_mux ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void decode_multilevel_4t1r_mux(int num_level, int num_input_basis,$/;" f +decode_multilevel_mux_sram_bits ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int* decode_multilevel_mux_sram_bits(int fan_in,$/;" f +decode_one_level_4t1r_mux ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void decode_one_level_4t1r_mux(int path_id, $/;" f +decode_onelevel_mux_sram_bits ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int* decode_onelevel_mux_sram_bits(int fan_in,$/;" f +decode_physical_mode_pin_annotation ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void decode_physical_mode_pin_annotation(int phy_pb_type_port_size,$/;" f +decode_rram_mux ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void decode_rram_mux(t_spice_model* mux_spice_model,$/;" f +decode_tree_mux_sram_bits ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int* decode_tree_mux_sram_bits(int fan_in,$/;" f +def_clk_name ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^static char* def_clk_name = "clk";$/;" v file: +default_lb_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_lb_dir_name = "lb\/";$/;" v +default_message ./base/draw.c /^static char default_message[BUFSIZE]; \/* Default screen message on screen *\/$/;" v file: +default_mode_num_conf_bits ../../libarchfpga/include/physical_types.h /^ int default_mode_num_conf_bits;$/;" m struct:s_pb_type +default_mode_num_iopads ../../libarchfpga/include/physical_types.h /^ int default_mode_num_iopads;$/;" m struct:s_pb_type +default_mode_num_mode_bits ../../libarchfpga/include/physical_types.h /^ int default_mode_num_mode_bits;$/;" m struct:s_pb_type +default_mode_num_reserved_conf_bits ../../libarchfpga/include/physical_types.h /^ int default_mode_num_reserved_conf_bits;$/;" m struct:s_pb_type +default_modelsim_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_modelsim_dir_name = "msim_projects\/";$/;" v +default_msim_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_msim_dir_name = "MSIM\/";$/;" v +default_output_name ./base/globals.c /^char *default_output_name = NULL;$/;" v +default_report_timing_rpt_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_report_timing_rpt_dir_name = "RPT\/";$/;" v +default_rr_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_rr_dir_name = "routing\/";$/;" v +default_sdc_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_sdc_dir_name = "SDC\/";$/;" v +default_sdc_folder ./fpga_x2p/base/fpga_x2p_globals.c /^char* default_sdc_folder = "SDC\/";$/;" v +default_signal_init_value ./fpga_x2p/base/fpga_x2p_globals.c /^int default_signal_init_value = 0;$/;" v +default_snpsfm_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_snpsfm_dir_name = "SNPS_FM\/";$/;" v +default_spice_dir_path ./fpga_x2p/spice/spice_api.c /^static char* default_spice_dir_path = "spice_netlists\/";$/;" v file: +default_src_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_src_dir_name = "SRC\/";$/;" v +default_submodule_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_submodule_dir_name = "sub_module\/";$/;" v +default_tcl_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_tcl_dir_name = "SCRIPTS\/";$/;" v +default_val ../../libarchfpga/fpga_spice_include/spice_types.h /^ int default_val;$/;" m struct:s_spice_model_port +default_verilog_dir_name ./fpga_x2p/verilog/verilog_global.c /^char* default_verilog_dir_name = "syn_verilogs\/";$/;" v +define_idle_mode ../../libarchfpga/include/physical_types.h /^ int define_idle_mode; $/;" m struct:s_mode +define_physical_mode ../../libarchfpga/include/physical_types.h /^ int define_physical_mode; $/;" m struct:s_mode +defines_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* defines_verilog_file_name = "fpga_defines.v";$/;" v +defines_verilog_simulation_file_name ./fpga_x2p/verilog/verilog_global.c /^char* defines_verilog_simulation_file_name = "define_simulation.v";$/;" v +delay ./base/vpr_types.h /^ float delay; \/* Delay through the I\/O in this constraint *\/$/;" m struct:s_io +delay_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_delay_info* delay_info;$/;" m struct:s_spice_model +delay_max ../../libarchfpga/include/physical_types.h /^ float delay_max;$/;" m struct:s_pb_graph_edge +delay_min ../../libarchfpga/include/physical_types.h /^ float delay_min;$/;" m struct:s_pb_graph_edge +delayless_switch ./base/vpr_types.h /^ short delayless_switch;$/;" m struct:s_det_routing_arch +delayless_switch_index ./fpga_x2p/base/fpga_x2p_types.h /^ int delayless_switch_index;$/;" m struct:fpga_spice_rr_graph +delete_in_vptr_list ../../libarchfpga/util.c /^delete_in_vptr_list(struct s_linked_vptr *head) {$/;" f +delta_clb_to_clb ./place/timing_place_lookup.c /^float **delta_clb_to_clb;$/;" v +delta_clb_to_io ./place/timing_place_lookup.c /^float **delta_clb_to_io;$/;" v +delta_io_to_clb ./place/timing_place_lookup.c /^float **delta_io_to_clb;$/;" v +delta_io_to_io ./place/timing_place_lookup.c /^float **delta_io_to_io;$/;" v +dens ../../libarchfpga/include/physical_types.h /^ float dens; \/* Switching density of net assigned to this clock *\/$/;" m struct:s_clock_network +density ../../libarchfpga/fpga_spice_include/spice_types.h /^ float density;$/;" m struct:s_spice_net_info +density ./base/vpr_types.h /^ float density;$/;" m struct:s_net_power +depth ../../libarchfpga/include/physical_types.h /^ int depth; \/* depth of pb_type *\/$/;" m struct:s_pb_type +description ./fpga_x2p/shell/read_opt_types.h /^ char* description;$/;" m struct:s_opt_info +deselect_all ./base/draw.c /^static void deselect_all(void) {$/;" f file: +design_param_header_file_name ./fpga_x2p/spice/spice_globals.c /^char* design_param_header_file_name = "design_params.sp";$/;" v +design_param_postfix_input_buf_size ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_input_buf_size = "_input_buf_size"; $/;" v +design_param_postfix_output_buf_size ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_output_buf_size = "_output_buf_size"; $/;" v +design_param_postfix_pass_gate_logic_nmos_size ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_pass_gate_logic_nmos_size = "_pgl_nmos_size"; $/;" v +design_param_postfix_pass_gate_logic_pmos_size ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_pass_gate_logic_pmos_size = "_pgl_pmos_size"; $/;" v +design_param_postfix_rram_roff ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_rram_roff = "_rram_roff"; $/;" v +design_param_postfix_rram_ron ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_rram_ron = "_rram_ron"; $/;" v +design_param_postfix_rram_wprog_reset_nmos ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_rram_wprog_reset_nmos = "_rram_wprog_reset_nmos"; $/;" v +design_param_postfix_rram_wprog_reset_pmos ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_rram_wprog_reset_pmos = "_rram_wprog_reset_pmos"; $/;" v +design_param_postfix_rram_wprog_set_nmos ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_rram_wprog_set_nmos = "_rram_wprog_set_nmos"; $/;" v +design_param_postfix_rram_wprog_set_pmos ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_rram_wprog_set_pmos = "_rram_wprog_set_pmos"; $/;" v +design_param_postfix_wire_param_cap_val ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_wire_param_cap_val = "_wire_param_cap_val"; $/;" v +design_param_postfix_wire_param_res_val ./fpga_x2p/spice/spice_globals.c /^char* design_param_postfix_wire_param_res_val = "_wire_param_res_val"; $/;" v +design_tech ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_design_tech design_tech;$/;" m struct:s_spice_model typeref:enum:s_spice_model::e_spice_model_design_tech +design_tech_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_design_tech_info design_tech_info;$/;" m struct:s_spice_model +destroy_button ./base/graphics.c /^destroy_button (const char *button_text) $/;" f +destroy_button ./base/graphics.c /^void destroy_button (const char *button_text) { }$/;" f +determine_actual_pb_interc_type ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^enum e_interconnect determine_actual_pb_interc_type(t_interconnect* def_interc, $/;" f +determine_blwl_decoder_size ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void determine_blwl_decoder_size(INP t_sram_orgz_info* cur_sram_orgz_info,$/;" f +determine_decoder_size ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^int determine_decoder_size(int num_addr_out) {$/;" f +determine_io_grid_side ./fpga_x2p/base/fpga_x2p_utils.c /^int determine_io_grid_side(int x,$/;" f +determine_lut_path_id ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int determine_lut_path_id(int lut_size,$/;" f +determine_lut_truth_table_on_set ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int determine_lut_truth_table_on_set(int truth_table_len,$/;" f +determine_num_input_basis_multilevel_mux ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int determine_num_input_basis_multilevel_mux(int mux_size,$/;" f +determine_num_sram_bits_mux_basis_subckt ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int determine_num_sram_bits_mux_basis_subckt(t_spice_model* mux_spice_model,$/;" f +determine_rr_node_default_prev_node ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int determine_rr_node_default_prev_node(t_rr_node* cur_rr_node) {$/;" f +determine_sb_port_coordinator ./fpga_x2p/base/fpga_x2p_utils.c /^void determine_sb_port_coordinator(t_sb cur_sb_info, int side, $/;" f +determine_tree_mux_level ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int determine_tree_mux_level(int mux_size) {$/;" f +determine_verilog_generic_port_split_sign ./fpga_x2p/verilog/verilog_utils.c /^char determine_verilog_generic_port_split_sign(enum e_dump_verilog_port_type dump_port_type) {$/;" f +diff_sram_orgz_info ./fpga_x2p/base/fpga_x2p_utils.c /^t_sram_orgz_info* diff_sram_orgz_info(t_sram_orgz_info* des_sram_orgz_info, $/;" f +dir ../../libarchfpga/include/logic_types.h /^ enum PORTS dir; \/* port direction *\/$/;" m struct:s_model_ports typeref:enum:s_model_ports::PORTS +direction ./base/vpr_types.h /^ enum e_direction direction; \/* UDSD by AY *\/$/;" m struct:s_rr_node typeref:enum:s_rr_node::e_direction +direction ./base/vpr_types.h /^ enum e_direction direction; \/* UDSD by AY *\/$/;" m struct:s_seg_details typeref:enum:s_seg_details::e_direction +directionality ../../libarchfpga/include/physical_types.h /^ enum e_directionality directionality;$/;" m struct:s_segment_inf typeref:enum:s_segment_inf::e_directionality +directionality ./base/vpr_types.h /^ enum e_directionality directionality; \/* UDSD by AY *\/$/;" m struct:s_det_routing_arch typeref:enum:s_det_routing_arch::e_directionality +directionality ./base/vpr_types.h /^ enum e_directionality directionality; \/* UDSD by AY *\/$/;" m struct:s_cb typeref:enum:s_cb::e_directionality +directionality ./base/vpr_types.h /^ enum e_directionality directionality; \/* UDSD by AY *\/$/;" m struct:s_sb typeref:enum:s_sb::e_directionality +disabled_in_packing ../../libarchfpga/include/physical_types.h /^ boolean disabled_in_packing;$/;" m struct:s_mode +discover_all_forced_connections ./pack/cluster_feasibility_filter.c /^static void discover_all_forced_connections(INOUTP t_pb_graph_node *pb_graph_node) {$/;" f file: +discover_pattern_names_in_pb_graph_node ./pack/prepack.c /^static void discover_pattern_names_in_pb_graph_node($/;" f file: +disp_type ./base/graphics.c /^ int disp_type;$/;" m struct:__anon5 file: +display ./base/graphics.c /^static Display *display;$/;" v file: +display_height ./base/graphics.c /^static int display_width, display_height; \/* screen size *\/$/;" v file: +display_width ./base/graphics.c /^static int display_width, display_height; \/* screen size *\/$/;" v file: +displaybuffer ./base/graphics.c /^void displaybuffer(void) { }$/;" f +displaybuffer ./base/graphics.c /^void displaybuffer(void) {$/;" f +distr ./route/rr_graph.c /^ int *distr;$/;" m struct:s_mux_size_distribution file: +doPacking ./base/vpr_types.h /^ boolean doPacking;$/;" m struct:s_packer_opts +doPlacement ./base/vpr_types.h /^ boolean doPlacement;$/;" m struct:s_placer_opts +doRouting ./base/vpr_types.h /^ boolean doRouting;$/;" m struct:s_router_opts +do_clustering ./pack/cluster.c /^void do_clustering(const t_arch *arch, t_pack_molecule *molecule_head,$/;" f +do_constant_net_delay_timing_analysis ./timing/path_delay.c /^void do_constant_net_delay_timing_analysis(t_timing_inf timing_inf,$/;" f +do_fpga_spice ./base/vpr_types.h /^ boolean do_fpga_spice;$/;" m struct:s_fpga_spice_opts +do_lut_rebalancing ./timing/path_delay.c /^static void do_lut_rebalancing() {$/;" f file: +do_path_counting ./timing/path_delay.c /^static void do_path_counting(float criticality_denom) {$/;" f file: +do_power ./base/vpr_types.h /^ boolean do_power; \/* Perform power estimation? *\/$/;" m struct:s_power_opts +do_quicksort_float_index ./fpga_x2p/base/quicksort.c /^void do_quicksort_float_index(int len, $/;" f +do_spice ./base/vpr_types.h /^ boolean do_spice;$/;" m struct:s_spice_opts +do_timing_analysis ./timing/path_delay.c /^void do_timing_analysis(t_slack * slacks, boolean is_prepacked, boolean do_lut_input_balancing, boolean is_final_analysis) {$/;" f +do_timing_analysis_for_constraint ./timing/path_delay.c /^static float do_timing_analysis_for_constraint(int source_clock_domain, int sink_clock_domain, $/;" f file: +domain_constraint ./base/vpr_types.h /^ float ** domain_constraint; \/* [0..num_constrained_clocks - 1 (source)][0..num_constrained_clocks - 1 (destination)] *\/$/;" m struct:s_timing_constraints +done_callibration ./power/PowerSpicedComponent.h /^ bool done_callibration;$/;" m class:PowerCallibInputs +done_callibration ./power/PowerSpicedComponent.h /^ bool done_callibration;$/;" m class:PowerSpicedComponent +dptr ../../libarchfpga/fpga_spice_include/linkedlist.h /^ void* dptr;$/;" m struct:s_llist +draw_chanx_to_chanx_edge ./base/draw.c /^static void draw_chanx_to_chanx_edge(int from_node, int from_track, int to_node,$/;" f file: +draw_chanx_to_chany_edge ./base/draw.c /^static void draw_chanx_to_chany_edge(int chanx_node, int chanx_track,$/;" f file: +draw_chany_to_chany_edge ./base/draw.c /^static void draw_chany_to_chany_edge(int from_node, int from_track, int to_node,$/;" f file: +draw_congestion ./base/draw.c /^static void draw_congestion(void) {$/;" f file: +draw_message ./base/graphics.c /^draw_message (void) $/;" f +draw_message ./base/graphics.c /^void draw_message (void) { }$/;" f +draw_pin_to_chan_edge ./base/draw.c /^static void draw_pin_to_chan_edge(int pin_node, int chan_node) {$/;" f file: +draw_pin_to_pin ./base/draw.c /^static void draw_pin_to_pin(int opin_node, int ipin_node) {$/;" f file: +draw_route_type ./base/draw.c /^static enum e_route_type draw_route_type;$/;" v typeref:enum:e_route_type file: +draw_rr ./base/draw.c /^void draw_rr(void) {$/;" f +draw_rr_chanx ./base/draw.c /^static void draw_rr_chanx(int inode, int itrack) {$/;" f file: +draw_rr_chany ./base/draw.c /^static void draw_rr_chany(int inode, int itrack) {$/;" f file: +draw_rr_edges ./base/draw.c /^static void draw_rr_edges(int inode) {$/;" f file: +draw_rr_pin ./base/draw.c /^static void draw_rr_pin(int inode, enum color_types color) {$/;" f file: +draw_rr_switch ./base/draw.c /^static void draw_rr_switch(float from_x, float from_y, float to_x, float to_y,$/;" f file: +draw_rr_toggle ./base/draw.c /^static enum e_draw_rr_toggle draw_rr_toggle = DRAW_NO_RR; \/* UDSD by AY *\/$/;" v typeref:enum:e_draw_rr_toggle file: +draw_triangle_along_line ./base/draw.c /^static void draw_triangle_along_line(float xend, float yend, float x1, float x2,$/;" f file: +draw_x ./base/draw.c /^static void draw_x(float x, float y, float size) {$/;" f file: +drawarc ./base/graphics.c /^drawarc (float xc, float yc, float rad, float startang, $/;" f +drawarc ./base/graphics.c /^void drawarc (float xcen, float ycen, float rad, float startang,$/;" f +drawbut ./base/graphics.c /^static void drawbut (int bnum) $/;" f file: +drawcurve ./base/graphics.c /^void drawcurve(t_point *points, int npoints) { }$/;" f +drawcurve ./base/graphics.c /^void drawcurve(t_point *points,$/;" f +drawellipticarc ./base/graphics.c /^drawellipticarc (float xc, float yc, float radx, float rady, float startang, float angextent) $/;" f +drawellipticarc ./base/graphics.c /^void drawellipticarc (float xc, float yc, float radx, float rady, float startang, float angextent) { }$/;" f +drawline ./base/graphics.c /^drawline (float x1, float y1, float x2, float y2) $/;" f +drawline ./base/graphics.c /^void drawline (float x1, float y1, float x2, float y2) { }$/;" f +drawmenu ./base/graphics.c /^static void drawmenu(void) $/;" f file: +drawnets ./base/draw.c /^static void drawnets(void) {$/;" f file: +drawplace ./base/draw.c /^static void drawplace(void) {$/;" f file: +drawrect ./base/graphics.c /^drawrect (float x1, float y1, float x2, float y2) $/;" f +drawrect ./base/graphics.c /^void drawrect (float x1, float y1, float x2, float y2) { }$/;" f +drawroute ./base/draw.c /^static void drawroute(enum e_draw_net_type draw_net_type) {$/;" f file: +drawscreen ./base/draw.c /^static void drawscreen() {$/;" f file: +drawscreen_ptr ./base/graphics.c /^static void (*drawscreen_ptr)(void);$/;" v file: +drawtext ./base/graphics.c /^drawtext (float xc, float yc, const char *text, float boundx) $/;" f +drawtext ./base/graphics.c /^void drawtext (float xc, float yc, const char *text, float boundx) { }$/;" f +drawtobuffer ./base/graphics.c /^void drawtobuffer(void) { }$/;" f +drawtobuffer ./base/graphics.c /^void drawtobuffer(void) {$/;" f +drawtoscreen ./base/graphics.c /^void drawtoscreen(void) { }$/;" f +drawtoscreen ./base/graphics.c /^void drawtoscreen(void) {$/;" f +drive_rr_nodes ./base/vpr_types.h /^ t_rr_node** drive_rr_nodes;$/;" m struct:s_rr_node +drive_switches ./base/vpr_types.h /^ int* drive_switches;$/;" m struct:s_rr_node +driver_pb ./base/verilog_writer.h /^ t_pb *driver_pb;$/;" m struct:found_connectivity +driver_pin ../../libarchfpga/include/physical_types.h /^ int driver_pin;$/;" m struct:s_pb_graph_edge +driver_pin ./base/verilog_writer.h /^ t_pb_graph_pin *driver_pin;$/;" m struct:found_connectivity +driver_set ../../libarchfpga/include/physical_types.h /^ int driver_set;$/;" m struct:s_pb_graph_edge +driver_switch ./base/vpr_types.h /^ short driver_switch; \/* Xifan TANG: Switch Segment Pattern Support*\/$/;" m struct:s_rr_node +driver_switch_type ./power/power.h /^ short driver_switch_type; \/* Switch type that drives this resource *\/$/;" m struct:s_rr_node_power +driver_to_load_delay ./base/verilog_writer.h /^ float driver_to_load_delay;$/;" m struct:found_connectivity +drivers ./base/vpr_types.h /^ enum e_drivers drivers; \/* UDSD by AY *\/$/;" m struct:s_rr_node typeref:enum:s_rr_node::e_drivers +drivers ./base/vpr_types.h /^ enum e_drivers drivers; \/* UDSD by AY *\/$/;" m struct:s_seg_details typeref:enum:s_seg_details::e_drivers +dum_parse ./base/read_blif.c /^void dum_parse(char *buf) {$/;" f +dummy_type_descriptors ./place/timing_place_lookup.c /^static t_type_descriptor dummy_type_descriptors[NUM_TYPES_USED];$/;" v file: +dump_compact_verilog_defined_grids ./fpga_x2p/verilog/verilog_compact_netlist.c /^void dump_compact_verilog_defined_grids(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_compact_verilog_defined_one_grid ./fpga_x2p/verilog/verilog_compact_netlist.c /^void dump_compact_verilog_defined_one_grid(t_sram_orgz_info* cur_sram_orgz_info,$/;" f file: +dump_compact_verilog_grid_pins ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_compact_verilog_grid_pins(FILE* fp,$/;" f +dump_compact_verilog_io_grid_block_subckt_pins ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_compact_verilog_io_grid_block_subckt_pins(FILE* fp,$/;" f +dump_compact_verilog_io_grid_pins ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_compact_verilog_io_grid_pins(FILE* fp,$/;" f +dump_compact_verilog_logic_blocks ./fpga_x2p/verilog/verilog_compact_netlist.c /^void dump_compact_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_compact_verilog_one_physical_block ./fpga_x2p/verilog/verilog_compact_netlist.c /^void dump_compact_verilog_one_physical_block(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_compact_verilog_top_netlist ./fpga_x2p/verilog/verilog_compact_netlist.c /^void dump_compact_verilog_top_netlist(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_conf_bits_to_bitstream_file ./fpga_x2p/bitstream/fpga_bitstream.c /^void dump_conf_bits_to_bitstream_file(FILE* fp, $/;" f file: +dump_explicit_port_map ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean dump_explicit_port_map;$/;" m struct:s_spice_model +dump_fpga_spice_bitstream ./fpga_x2p/bitstream/fpga_bitstream.c /^void dump_fpga_spice_bitstream(char* bitstream_file_name, $/;" f +dump_include_user_defined_verilog_netlists ./fpga_x2p/verilog/verilog_utils.c /^void dump_include_user_defined_verilog_netlists(FILE* fp,$/;" f +dump_one_verilog_template_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_one_verilog_template_module(FILE* fp,$/;" f +dump_one_verilog_template_module_one_port ./fpga_x2p/verilog/verilog_submodules.c /^void dump_one_verilog_template_module_one_port(FILE* fp, int* cnt,$/;" f +dump_rr_graph ./route/rr_graph.c /^void dump_rr_graph(INP const char *file_name) {$/;" f +dump_sdc_one_clb_muxes ./fpga_x2p/verilog/verilog_sdc.c /^void dump_sdc_one_clb_muxes(FILE* fp,$/;" f +dump_sdc_pb_graph_node_muxes ./fpga_x2p/verilog/verilog_sdc.c /^void dump_sdc_pb_graph_node_muxes (FILE* fp,$/;" f +dump_sdc_pb_graph_pin_interc ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void dump_sdc_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_sdc_pb_graph_pin_muxes ./fpga_x2p/verilog/verilog_sdc.c /^void dump_sdc_pb_graph_pin_muxes (FILE* fp,$/;" f +dump_sdc_pb_graph_port_interc ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void dump_sdc_pb_graph_port_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_sdc_physical_blocks ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void dump_sdc_physical_blocks(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_sdc_rec_one_pb_muxes ./fpga_x2p/verilog/verilog_sdc.c /^void dump_sdc_rec_one_pb_muxes(FILE* fp,$/;" f +dump_seg_details ./route/rr_graph2.c /^void dump_seg_details(t_seg_details * seg_details, int nodes_per_chan,$/;" f +dump_simulation_preproc ./fpga_x2p/verilog/verilog_utils.c /^void dump_simulation_preproc(FILE* fp, $/;" f +dump_structural_verilog ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean dump_structural_verilog;$/;" m struct:s_spice_model +dump_syn_verilog ./base/vpr_types.h /^ boolean dump_syn_verilog;$/;" m struct:s_syn_verilog_opts +dump_verilog_autocheck_top_testbench ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^void dump_verilog_autocheck_top_testbench(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_clb2clb_directs ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_clb2clb_directs(FILE* fp, $/;" f +dump_verilog_cmos_mux_config_bus ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_cmos_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, $/;" f +dump_verilog_cmos_mux_config_bus_ports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_model, $/;" f +dump_verilog_cmos_mux_mem_submodule ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_mem_submodule(FILE* fp,$/;" f +dump_verilog_cmos_mux_multilevel_structure ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_multilevel_structure(FILE* fp, $/;" f +dump_verilog_cmos_mux_one_basis_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_one_basis_module(FILE* fp, $/;" f +dump_verilog_cmos_mux_one_basis_module_structural ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp, $/;" f file: +dump_verilog_cmos_mux_onelevel_structure ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_onelevel_structure(FILE* fp, $/;" f +dump_verilog_cmos_mux_submodule ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_submodule(FILE* fp,$/;" f +dump_verilog_cmos_mux_tree_structure ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_cmos_mux_tree_structure(FILE* fp, $/;" f +dump_verilog_config_peripherals ./fpga_x2p/verilog/verilog_decoder.c /^void dump_verilog_config_peripherals(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_configuration_circuits ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_configuration_circuits(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_configuration_circuits_memory_bank ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_configuration_circuits_memory_bank(FILE* fp, $/;" f file: +dump_verilog_configuration_circuits_scan_chains ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_configuration_circuits_scan_chains(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_configuration_circuits_standalone_srams ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_configuration_circuits_standalone_srams(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_connection_box_interc ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_connection_box_mux ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_connection_box_mux(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_connection_box_short_interc ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_connection_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_dangling_des_pb_graph_pin_interc ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_dangling_des_pb_graph_pin_interc(FILE* fp,$/;" f +dump_verilog_decoder ./fpga_x2p/verilog/verilog_decoder.c /^void dump_verilog_decoder(FILE* fp,$/;" f file: +dump_verilog_decoder_memory_bank_ports ./fpga_x2p/verilog/verilog_decoder.c /^void dump_verilog_decoder_memory_bank_ports(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_defined_channels ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_channels(FILE* fp,$/;" f +dump_verilog_defined_connection_boxes ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_connection_boxes(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_defined_one_channel ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_one_channel(FILE* fp,$/;" f file: +dump_verilog_defined_one_connection_box ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_one_connection_box(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_defined_one_grid ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_one_grid(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_defined_one_switch_box ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_one_switch_box(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_defined_switch_boxes ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_defined_switch_boxes(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_defines_preproc ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_defines_preproc(char* subckt_dir,$/;" f +dump_verilog_file_header ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_file_header(FILE* fp,$/;" f +dump_verilog_formal_verfication_top_netlist_call_top_module ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verfication_top_netlist_call_top_module(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_formal_verification_mux_sram_ports_wiring ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_formal_verification_mux_sram_ports_wiring(FILE* fp, $/;" f +dump_verilog_formal_verification_sram_ports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_formal_verification_sram_ports(FILE* fp, $/;" f +dump_verilog_formal_verification_sram_ports_wiring ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_formal_verification_sram_ports_wiring(FILE* fp, $/;" f +dump_verilog_formal_verification_top_netlist ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_formal_verification_top_netlist_config_bitstream ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist_config_bitstream(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_formal_verification_top_netlist_connect_global_ports ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist_connect_global_ports(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_formal_verification_top_netlist_connect_ios ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist_connect_ios(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_formal_verification_top_netlist_initialization ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist_initialization(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_formal_verification_top_netlist_internal_wires ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_formal_verification_top_netlist_ports ./fpga_x2p/verilog/verilog_verification_top_netlist.c /^void dump_verilog_formal_verification_top_netlist_ports(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_gate_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_gate_module(FILE* fp,$/;" f +dump_verilog_generic_port ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_generic_port(FILE* fp, $/;" f +dump_verilog_generic_port_no_repeat ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_generic_port_no_repeat(FILE* fp, $/;" f +dump_verilog_global_ports ./fpga_x2p/verilog/verilog_utils.c /^int dump_verilog_global_ports(FILE* fp, t_llist* head,$/;" f +dump_verilog_grid_block_subckt_pins ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_grid_block_subckt_pins(FILE* fp,$/;" f +dump_verilog_grid_common_port ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_grid_common_port(FILE* fp, t_spice_model* cur_verilog_model,$/;" f +dump_verilog_grid_pins ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_grid_pins(FILE* fp,$/;" f +dump_verilog_grid_side_pin_with_given_index ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, $/;" f +dump_verilog_grid_side_pins ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_grid_side_pins(FILE* fp,$/;" f +dump_verilog_hard_wired_gnd ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_hard_wired_gnd(FILE* fp, $/;" f +dump_verilog_hard_wired_vdd ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_hard_wired_vdd(FILE* fp, $/;" f +dump_verilog_input_blif_testbench ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_input_blif_testbench(char* circuit_name,$/;" f +dump_verilog_input_blif_testbench_call_top_module ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_input_blif_testbench_call_top_module(FILE* fp, $/;" f file: +dump_verilog_input_blif_testbench_ports ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_input_blif_testbench_ports(FILE* fp,$/;" f file: +dump_verilog_input_blif_testbench_stimuli ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_input_blif_testbench_stimuli(FILE* fp,$/;" f file: +dump_verilog_invbuf_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_invbuf_module(FILE* fp,$/;" f +dump_verilog_io_grid_block_subckt_pins ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_io_grid_block_subckt_pins(FILE* fp,$/;" f +dump_verilog_io_grid_pins ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_io_grid_pins(FILE* fp,$/;" f +dump_verilog_logic_blocks ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_logic_blocks(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_mem_config_bus ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mem_config_bus(FILE* fp, t_spice_model* mem_spice_model, $/;" f +dump_verilog_mem_module_one_port_map ./fpga_x2p/verilog/verilog_utils.c /^int dump_verilog_mem_module_one_port_map(FILE* fp,$/;" f +dump_verilog_mem_module_port_map ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mem_module_port_map(FILE* fp, $/;" f +dump_verilog_mem_sram_submodule ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mem_sram_submodule(FILE* fp,$/;" f +dump_verilog_membank_config_module ./fpga_x2p/verilog/verilog_decoder.c /^void dump_verilog_membank_config_module(FILE* fp,$/;" f file: +dump_verilog_modelsim_autodeck ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^void dump_verilog_modelsim_autodeck(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_modelsim_proc_auto_script ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^void dump_verilog_modelsim_proc_auto_script(char* modelsim_proc_filename,$/;" f file: +dump_verilog_modelsim_proc_script ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^void dump_verilog_modelsim_proc_script(char* modelsim_proc_filename,$/;" f file: +dump_verilog_modelsim_top_auto_script ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^void dump_verilog_modelsim_top_auto_script(char* modelsim_top_auto_script_filename,$/;" f file: +dump_verilog_modelsim_top_script ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^void dump_verilog_modelsim_top_script(char* modelsim_top_script_filename,$/;" f file: +dump_verilog_mux_basis_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_mux_basis_module(FILE* fp, $/;" f +dump_verilog_mux_config_bus ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mux_config_bus(FILE* fp, t_spice_model* mux_spice_model, $/;" f +dump_verilog_mux_config_bus_ports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_model, $/;" f +dump_verilog_mux_mem_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_mux_mem_module(FILE* fp, $/;" f +dump_verilog_mux_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_mux_module(FILE* fp, $/;" f +dump_verilog_mux_one_basis_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_mux_one_basis_module(FILE* fp, $/;" f +dump_verilog_mux_sram_one_local_outport ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mux_sram_one_local_outport(FILE* fp, $/;" f +dump_verilog_mux_sram_one_outport ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mux_sram_one_outport(FILE* fp, $/;" f +dump_verilog_mux_sram_submodule ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_mux_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_one_clb2clb_direct ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_one_clb2clb_direct(FILE* fp, $/;" f file: +dump_verilog_one_sb_chan_pin ./fpga_x2p/verilog/verilog_tcl_utils.c /^void dump_verilog_one_sb_chan_pin(FILE* fp, $/;" f +dump_verilog_one_sb_routing_pin ./fpga_x2p/verilog/verilog_tcl_utils.c /^void dump_verilog_one_sb_routing_pin(FILE* fp,$/;" f +dump_verilog_one_sb_wire_segemental_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void dump_verilog_one_sb_wire_segemental_report_timing(FILE* fp,$/;" f +dump_verilog_passgate_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_passgate_module(FILE* fp,$/;" f +dump_verilog_pb_generic_primitive ./fpga_x2p/verilog/verilog_primitives.c /^void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_pb_graph_interc ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_graph_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_pb_graph_pin_interc ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_pb_graph_port_interc ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_graph_port_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_pb_graph_primitive_node ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_graph_primitive_node(FILE* fp,$/;" f +dump_verilog_pb_primitive_lut ./fpga_x2p/verilog/verilog_primitives.c /^void dump_verilog_pb_primitive_lut(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_pb_primitive_verilog_model ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_primitive_verilog_model(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_pb_type_bus_ports ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_type_bus_ports(FILE* fp,$/;" f +dump_verilog_pb_type_ports ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_pb_type_ports(FILE* fp,$/;" f +dump_verilog_phy_pb_graph_node_rec ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_phy_pb_graph_node_rec(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_physical_block ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_physical_block(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_physical_grid_blocks ./fpga_x2p/verilog/verilog_pbtypes.c /^void dump_verilog_physical_grid_blocks(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_preproc ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_preproc(FILE* fp, $/;" f +dump_verilog_random_testbench_call_top_module ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_random_testbench_call_top_module(FILE* fp,$/;" f file: +dump_verilog_random_top_testbench ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_random_top_testbench(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_reserved_sram_one_port ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_reserved_sram_one_port(FILE* fp, $/;" f +dump_verilog_reserved_sram_ports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_reserved_sram_ports(FILE* fp, $/;" f +dump_verilog_routing_chan_subckt ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_routing_connection_box_subckt ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_routing_connection_box_subckt(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_routing_resources ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_routing_switch_box_subckt ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_routing_switch_box_subckt(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_rram_mux_multilevel_structure ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_rram_mux_multilevel_structure(FILE* fp, $/;" f +dump_verilog_rram_mux_one_basis_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_rram_mux_one_basis_module(FILE* fp, $/;" f +dump_verilog_rram_mux_one_basis_module_structural ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_rram_mux_one_basis_module_structural(FILE* fp, $/;" f file: +dump_verilog_rram_mux_onelevel_structure ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_rram_mux_onelevel_structure(FILE* fp, $/;" f +dump_verilog_rram_mux_submodule ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_rram_mux_submodule(FILE* fp,$/;" f +dump_verilog_rram_mux_tree_structure ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_rram_mux_tree_structure(FILE* fp, $/;" f +dump_verilog_sb_through_routing_pins ./fpga_x2p/verilog/verilog_report_timing.c /^void dump_verilog_sb_through_routing_pins(FILE* fp,$/;" f +dump_verilog_scan_chain_config_module ./fpga_x2p/verilog/verilog_decoder.c /^void dump_verilog_scan_chain_config_module(FILE* fp,$/;" f file: +dump_verilog_scff_config_bus ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_scff_config_bus(FILE* fp,$/;" f +dump_verilog_sdc_file_header ./fpga_x2p/verilog/verilog_tcl_utils.c /^void dump_verilog_sdc_file_header(FILE* fp,$/;" f +dump_verilog_simulation_preproc ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_simulation_preproc(char* subckt_dir,$/;" f +dump_verilog_sram_config_bus_internal_wires ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_config_bus_internal_wires(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_sram_local_ports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_local_ports(FILE* fp, $/;" f +dump_verilog_sram_one_local_outport ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_one_local_outport(FILE* fp, $/;" f +dump_verilog_sram_one_outport ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_one_outport(FILE* fp, $/;" f +dump_verilog_sram_one_port ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_one_port(FILE* fp, $/;" f +dump_verilog_sram_outports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_outports(FILE* fp, $/;" f +dump_verilog_sram_ports ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_ports(FILE* fp, $/;" f +dump_verilog_sram_submodule ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_sram_submodule(FILE* fp, t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_standalone_sram_config_module ./fpga_x2p/verilog/verilog_decoder.c /^void dump_verilog_standalone_sram_config_module(FILE* fp,$/;" f file: +dump_verilog_subckt_header_file ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_subckt_header_file(t_llist* subckt_llist_head,$/;" f +dump_verilog_submodule_essentials ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_essentials(char* verilog_dir, char* submodule_dir,$/;" f +dump_verilog_submodule_luts ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_luts(char* verilog_dir,$/;" f +dump_verilog_submodule_memories ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_memories(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_submodule_muxes ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_submodule_one_lut ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_one_lut(FILE* fp, $/;" f +dump_verilog_submodule_one_mem ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_one_mem(FILE* fp, $/;" f +dump_verilog_submodule_signal_init ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_signal_init(FILE* fp,$/;" f +dump_verilog_submodule_templates ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_templates(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_submodule_timing ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_timing(FILE* fp,$/;" f +dump_verilog_submodule_wires ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodule_wires(char* verilog_dir,$/;" f +dump_verilog_submodules ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_switch_box_chan_port ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_switch_box_chan_port(FILE* fp,$/;" f +dump_verilog_switch_box_interc ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_switch_box_mux ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_switch_box_short_interc ./fpga_x2p/verilog/verilog_routing.c /^void dump_verilog_switch_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_timeout_and_vcd ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^void dump_verilog_timeout_and_vcd(FILE * fp,$/;" f file: +dump_verilog_timeout_and_vcd ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_timeout_and_vcd(FILE * fp,$/;" f file: +dump_verilog_top_auto_testbench_call_benchmark ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^void dump_verilog_top_auto_testbench_call_benchmark(FILE* fp, $/;" f file: +dump_verilog_top_auto_testbench_check ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^void dump_verilog_top_auto_testbench_check(FILE* fp){$/;" f file: +dump_verilog_top_auto_testbench_ports ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^void dump_verilog_top_auto_testbench_ports(FILE* fp,$/;" f file: +dump_verilog_top_module_ports ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_top_module_ports(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_top_netlist_internal_wires ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_top_netlist_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_top_netlist_memory_bank_internal_wires ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_top_netlist_memory_bank_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_netlist_ports ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_top_netlist_ports(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_top_netlist_scan_chain_internal_wires ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_top_netlist_scan_chain_internal_wires(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_netlist_scan_chain_ports ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void dump_verilog_top_netlist_scan_chain_ports(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_random_stimuli ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_top_random_stimuli(FILE* fp,$/;" f file: +dump_verilog_top_random_testbench_call_benchmark ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_top_random_testbench_call_benchmark(FILE* fp, $/;" f file: +dump_verilog_top_random_testbench_check ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_top_random_testbench_check(FILE* fp){$/;" f file: +dump_verilog_top_random_testbench_ports ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^void dump_verilog_top_random_testbench_ports(FILE* fp,$/;" f file: +dump_verilog_top_testbench ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_top_testbench_call_top_module ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_call_top_module(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +dump_verilog_top_testbench_conf_bits_serial ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_find_num_config_clock_cycles ./fpga_x2p/verilog/verilog_top_testbench.c /^int dump_verilog_top_testbench_find_num_config_clock_cycles(t_sram_orgz_info* cur_sram_orgz_info,$/;" f file: +dump_verilog_top_testbench_global_ports ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head,$/;" f +dump_verilog_top_testbench_global_ports_stimuli ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_global_ports_stimuli(FILE* fp, t_llist* head) {$/;" f +dump_verilog_top_testbench_memory_bank_conf_bits_serial ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_memory_bank_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_one_conf_bit_serial ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_one_conf_bit_serial(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_ports ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_ports(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_rram_memory_bank_conf_bits_serial ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_rram_memory_bank_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_scan_chain_conf_bits_serial ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_scan_chain_conf_bits_serial(FILE* fp, $/;" f file: +dump_verilog_top_testbench_sram_memory_bank_conf_bits_serial ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_sram_memory_bank_conf_bits_serial(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_stimuli ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_stimuli(t_sram_orgz_info* cur_sram_orgz_info, $/;" f +dump_verilog_top_testbench_stimuli_serial_version ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_stimuli_serial_version(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_stimuli_serial_version_tasks ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_stimuli_serial_version_tasks(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_stimuli_serial_version_tasks_memory_bank ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_stimuli_serial_version_tasks_memory_bank(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_stimuli_serial_version_tasks_scan_chain ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_stimuli_serial_version_tasks_scan_chain(t_sram_orgz_info* cur_sram_orgz_info, $/;" f file: +dump_verilog_top_testbench_wire_one_global_port_stimuli ./fpga_x2p/verilog/verilog_top_testbench.c /^void dump_verilog_top_testbench_wire_one_global_port_stimuli(FILE* fp, t_spice_model_port* cur_global_port, $/;" f file: +dump_verilog_toplevel_one_grid_side_pin_with_given_index ./fpga_x2p/verilog/verilog_utils.c /^void dump_verilog_toplevel_one_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type, $/;" f +dump_verilog_wire_module ./fpga_x2p/verilog/verilog_submodules.c /^void dump_verilog_wire_module(FILE* fp,$/;" f +dumped_num_conf_bits ./fpga_x2p/bitstream/fpga_bitstream.c /^static int dumped_num_conf_bits = 0;$/;" v file: +dynamic ../../libarchfpga/include/physical_types.h /^ float dynamic;$/;" m struct:s_power_usage +e ../../libarchfpga/include/ezxml.h /^ char *e; \/* end of work area *\/$/;" m struct:ezxml_root +e_Fc_type ../../libarchfpga/include/physical_types.h /^enum e_Fc_type {$/;" g +e_OptionArgToken ./base/OptionTokens.h /^enum e_OptionArgToken {$/;" g +e_OptionBaseToken ./base/OptionTokens.h /^enum e_OptionBaseToken {$/;" g +e_base_cost_type ./base/vpr_types.h /^enum e_base_cost_type {$/;" g +e_block_pack_status ./base/vpr_types.h /^enum e_block_pack_status {$/;" g +e_cluster_seed ./base/vpr_types.h /^enum e_cluster_seed {$/;" g +e_cmd_category ./fpga_x2p/shell/shell_types.h /^enum e_cmd_category {$/;" g +e_cost_indices ./base/vpr_types.h /^enum e_cost_indices {$/;" g +e_detailed_routing_stages ./pack/cluster.c /^enum e_detailed_routing_stages {$/;" g file: +e_dir_err ./fpga_x2p/base/fpga_x2p_utils.c /^enum e_dir_err {$/;" g file: +e_direction ./base/vpr_types.h /^enum e_direction {$/;" g +e_directionality ../../libarchfpga/include/physical_types.h /^enum e_directionality {$/;" g +e_draw_mode ./base/graphics.h /^enum e_draw_mode {DRAW_NORMAL = 0, DRAW_XOR};$/;" g +e_draw_net_type ./base/draw.c /^enum e_draw_net_type {$/;" g file: +e_draw_rr_toggle ./base/draw.c /^enum e_draw_rr_toggle {$/;" g file: +e_drivers ./base/vpr_types.h /^enum e_drivers {$/;" g +e_dump_verilog_port_type ./fpga_x2p/verilog/verilog_global.h /^enum e_dump_verilog_port_type {$/;" g +e_echo_files ./base/ReadOptions.h /^enum e_echo_files {$/;" g +e_edge_dir ./base/draw.c /^enum e_edge_dir {$/;" g file: +e_feasibility ./pack/cluster.c /^enum e_feasibility {$/;" g file: +e_gain_type ./pack/cluster.c /^enum e_gain_type {$/;" g file: +e_gain_update ./pack/cluster.c /^enum e_gain_update {$/;" g file: +e_graph_type ./route/rr_graph.h /^enum e_graph_type {$/;" g +e_grid_loc_type ../../libarchfpga/include/physical_types.h /^enum e_grid_loc_type {$/;" g +e_interconnect ../../libarchfpga/include/physical_types.h /^enum e_interconnect {$/;" g +e_measure_type ./fpga_x2p/spice/spice_utils.h /^enum e_measure_type {$/;" g +e_net_relation_to_clustered_block ./pack/cluster.c /^enum e_net_relation_to_clustered_block {$/;" g file: +e_operation ./base/vpr_types.h /^enum e_operation {$/;" g +e_output_files ./base/ReadOptions.h /^enum e_output_files {$/;" g +e_pack_pattern_molecule_type ./base/vpr_types.h /^enum e_pack_pattern_molecule_type {$/;" g +e_packer_algorithm ./base/vpr_types.h /^enum e_packer_algorithm {$/;" g +e_pad_loc_type ./base/vpr_types.h /^enum e_pad_loc_type {$/;" g +e_pb_graph_pin_type ../../libarchfpga/include/physical_types.h /^enum e_pb_graph_pin_type {$/;" g +e_pb_type_class ../../libarchfpga/include/physical_types.h /^enum e_pb_type_class {$/;" g +e_pin_location_distr ../../libarchfpga/include/physical_types.h /^enum e_pin_location_distr {$/;" g +e_pin_to_pin_annotation_format ../../libarchfpga/include/physical_types.h /^enum e_pin_to_pin_annotation_format {$/;" g +e_pin_to_pin_annotation_type ../../libarchfpga/include/physical_types.h /^enum e_pin_to_pin_annotation_type {$/;" g +e_pin_to_pin_capacitance_annotations ../../libarchfpga/include/physical_types.h /^enum e_pin_to_pin_capacitance_annotations {$/;" g +e_pin_to_pin_delay_annotations ../../libarchfpga/include/physical_types.h /^enum e_pin_to_pin_delay_annotations {$/;" g +e_pin_to_pin_mode_select_annotations ../../libarchfpga/include/physical_types.h /^enum e_pin_to_pin_mode_select_annotations {$/;" g +e_pin_to_pin_pack_pattern_annotations ../../libarchfpga/include/physical_types.h /^enum e_pin_to_pin_pack_pattern_annotations {$/;" g +e_pin_type ../../libarchfpga/include/physical_types.h /^enum e_pin_type {$/;" g +e_place_algorithm ./base/vpr_types.h /^enum e_place_algorithm {$/;" g +e_power_breakdown_entry_type ./power/power.c /^} e_power_breakdown_entry_type;$/;" t typeref:enum:__anon8 file: +e_power_buffer_type ../../libarchfpga/include/physical_types.h /^} e_power_buffer_type;$/;" t typeref:enum:__anon21 +e_power_callib_component ./power/power_callibrate.h /^} e_power_callib_component;$/;" t typeref:enum:__anon12 +e_power_component_type ./power/power_components.h /^} e_power_component_type;$/;" t typeref:enum:__anon13 +e_power_estimation_method ../../libarchfpga/include/physical_types.h /^typedef enum e_power_estimation_method_ e_power_estimation_method;$/;" t typeref:enum:e_power_estimation_method_ +e_power_estimation_method_ ../../libarchfpga/include/physical_types.h /^enum e_power_estimation_method_ {$/;" g +e_power_log_type ./power/power.h /^} e_power_log_type;$/;" t typeref:enum:__anon10 +e_power_ret_code ./power/power.h /^} e_power_ret_code;$/;" t typeref:enum:__anon9 +e_power_wire_type ../../libarchfpga/include/physical_types.h /^} e_power_wire_type;$/;" t typeref:enum:__anon20 +e_process_corner ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_process_corner {$/;" g +e_removal_policy ./pack/cluster.c /^enum e_removal_policy {$/;" g file: +e_route_type ./base/vpr_types.h /^enum e_route_type {$/;" g +e_router_algorithm ./base/vpr_types.h /^enum e_router_algorithm {$/;" g +e_rr_type ./base/vpr_types.h /^typedef enum e_rr_type {$/;" g +e_side ../../libarchfpga/include/physical_types.h /^enum e_side {$/;" g +e_spice_accuracy_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_accuracy_type {$/;" g +e_spice_ff_trigger_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_ff_trigger_type {$/;" g +e_spice_model_buffer_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_buffer_type {$/;" g +e_spice_model_design_tech ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_design_tech {$/;" g +e_spice_model_gate_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_gate_type {$/;" g +e_spice_model_pass_gate_logic_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_pass_gate_logic_type {$/;" g +e_spice_model_port_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_port_type {$/;" g +e_spice_model_structure ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_structure {$/;" g +e_spice_model_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_model_type {$/;" g +e_spice_pb_port_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_pb_port_type {$/;" g +e_spice_pin2pin_interc_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_pin2pin_interc_type {$/;" g +e_spice_tb_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_tb_type {$/;" g +e_spice_tech_lib_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_tech_lib_type {$/;" g +e_spice_trans_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_spice_trans_type {$/;" g +e_sram_orgz ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_sram_orgz {$/;" g +e_stat ../../libarchfpga/include/physical_types.h /^enum e_stat {$/;" g +e_switch_block_type ../../libarchfpga/include/physical_types.h /^enum e_switch_block_type {$/;" g +e_swseg_pattern_type ../../libarchfpga/include/physical_types.h /^enum e_swseg_pattern_type {$/;" g +e_tech_comp ../../libarchfpga/include/arch_types_mrfpga.h /^enum e_tech_comp { $/;" g +e_tnode_type ./base/vpr_types.h /^} e_tnode_type;$/;" t typeref:enum:__anon7 +e_token_type ./util/token.h /^enum e_token_type {$/;" g +e_tx_type ./power/power.h /^} e_tx_type;$/;" t typeref:enum:__anon11 +e_verilog_tb_type ./fpga_x2p/verilog/verilog_global.h /^enum e_verilog_tb_type {$/;" g +e_wire_model_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum e_wire_model_type {$/;" g +echoFileEnabled ./base/ReadOptions.c /^static boolean *echoFileEnabled = NULL;$/;" v file: +echoFileNames ./base/ReadOptions.c /^static char **echoFileNames = NULL;$/;" v file: +echo_input ./base/read_blif.c /^void echo_input(char *blif_file, char *echo_file, t_model *library_models) {$/;" f +echo_pb_graph ./pack/pb_type_graph.c /^void echo_pb_graph(char * filename) {$/;" f +echo_pb_pins ./pack/pb_type_graph.c /^static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports,$/;" f file: +echo_pb_rec ./pack/pb_type_graph.c /^static void echo_pb_rec(const INP t_pb_graph_node *pb_graph_node, INP int level,$/;" f file: +edge ./route/rr_graph_util.h /^ int edge;$/;" m struct:s_linked_edge +edges ./base/vpr_types.h /^ int *edges;$/;" m struct:s_rr_node +edges_head ./pack/pb_type_graph.c /^static struct s_linked_vptr *edges_head;$/;" v typeref:struct:s_linked_vptr file: +emit ./timing/slre.c /^static void emit(struct slre *r, int code) {$/;" f file: +empty_heap ./route/route_common.c /^void empty_heap(void) {$/;" f +empty_rr_graph_heap ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void empty_rr_graph_heap(t_rr_graph* local_rr_graph) {$/;" f +enable_or_disable_button ./base/graphics.c /^void enable_or_disable_button (int ibutton, bool enabled) {$/;" f +enable_or_disable_button ./base/graphics.c /^void enable_or_disable_button(int ibutton, bool enabled) { }$/;" f +enable_timing_computations ./base/vpr_types.h /^ boolean enable_timing_computations;$/;" m struct:s_placer_opts +enabled ./base/graphics.c /^ bool enabled;$/;" m struct:__anon4 file: +encode_decoder_addr ./fpga_x2p/bitstream/fpga_bitstream.c /^void encode_decoder_addr(int input,$/;" f +end_match_ptr ../../pcre/SRC/internal.h /^ const uschar *end_match_ptr; \/* Subject position at end match *\/$/;" m struct:match_data +end_offset_top ../../pcre/SRC/internal.h /^ int end_offset_top; \/* Highwater mark at end of match *\/$/;" m struct:match_data +end_subject ../../pcre/SRC/internal.h /^ const uschar *end_subject; \/* End of the subject string *\/$/;" m struct:match_data +endlines ./base/read_blif.c /^static int ilines, olines, model_lines, endlines;$/;" v file: +endonly ../../pcre/SRC/internal.h /^ BOOL endonly; \/* Dollar not before final \\n *\/$/;" m struct:match_data +energy_per_toggle ../../libarchfpga/include/physical_types.h /^ float energy_per_toggle;$/;" m struct:s_port_power +ent ../../libarchfpga/include/ezxml.h /^ char **ent; \/* general entities (ampersand sequences) *\/$/;" m struct:ezxml_root +entries ./power/PowerSpicedComponent.h /^ std::vector entries;$/;" m class:PowerSpicedComponent +entries ./power/PowerSpicedComponent.h /^ std::vector entries;$/;" m class:PowerCallibInputs +eptrblock ../../pcre/SRC/pcre.c /^typedef struct eptrblock {$/;" s file: +eptrblock ../../pcre/SRC/pcre.c /^} eptrblock;$/;" t typeref:struct:eptrblock file: +equivalent ../../libarchfpga/include/physical_types.h /^ boolean equivalent;$/;" m struct:s_port +err ../../libarchfpga/include/ezxml.h /^ char err[EZXML_ERRL]; \/* error string *\/$/;" m struct:ezxml_root +error_no_match ./timing/slre.c /^static const char *error_no_match = "No match";$/;" v file: +error_string ./timing/slre.c /^ const char *error_string; \/\/ Error string$/;" m struct:slre file: +escapes ../../pcre/SRC/pcre.c /^static const short int escapes[] = {$/;" v file: +essentials_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* essentials_verilog_file_name = "inv_buf_passgate.v";$/;" v +esti_distance_num_seg_delay ./fpga_x2p/clb_pin_remap/post_place_timing.c /^float esti_distance_num_seg_delay(int distance,$/;" f +esti_one_segment_net_delay ./fpga_x2p/clb_pin_remap/post_place_timing.c /^float esti_one_segment_net_delay(int distance, t_segment_inf segment_inf) {$/;" f +esti_pin2pin_one_net_delay ./fpga_x2p/clb_pin_remap/post_place_timing.c /^float esti_pin2pin_one_net_delay(t_block src_blk,$/;" f +esti_pin_chan_coordinate ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void esti_pin_chan_coordinate(int* pin_x, int* pin_y,$/;" f +estimate_post_place_one_net_sink_delay ./fpga_x2p/clb_pin_remap/post_place_timing.c /^float estimate_post_place_one_net_sink_delay(int net_index, $/;" f +estimation_method ../../libarchfpga/include/physical_types.h /^ e_power_estimation_method estimation_method;$/;" m struct:s_pb_type_power +event_loop ./base/graphics.c /^event_loop (void (*act_on_mousebutton)(float x, float y), $/;" f +event_loop ./base/graphics.c /^void event_loop (void (*act_on_mousebutton) (float x, float y),$/;" f +exact ./timing/slre.c /^static void exact(struct slre *r, const char **re) {$/;" f file: +exact_one_char ./timing/slre.c /^static void exact_one_char(struct slre *r, int ch) {$/;" f file: +execute ./fpga_x2p/shell/shell_types.h /^ void (*execute)(t_shell_env*, t_opt_info*);$/;" m struct:s_shell_cmd +exist ../../libarchfpga/fpga_spice_include/spice_types.h /^ int exist;$/;" m struct:s_spice_model_buffer +exists_free_primitive_for_logical_block ./pack/cluster_placement.c /^boolean exists_free_primitive_for_logical_block($/;" f +exit_crit ./place/place.c /^static int exit_crit(float t, float cost,$/;" f file: +exit_opts ./fpga_x2p/shell/cmd_exit.h /^t_opt_info exit_opts[] = {$/;" v +exit_t ./base/vpr_types.h /^ float exit_t;$/;" m struct:s_annealing_sched +expand_forced_pack_molecule_placement ./pack/cluster_placement.c /^static boolean expand_forced_pack_molecule_placement($/;" f file: +expand_pack_molecule_pin_edge ./pack/cluster_placement.c /^static t_pb_graph_pin *expand_pack_molecule_pin_edge(INP int pattern_id,$/;" f file: +expand_pb_graph_node_and_load_output_to_input_connections ./pack/cluster_feasibility_filter.c /^static void expand_pb_graph_node_and_load_output_to_input_connections($/;" f file: +expand_pb_graph_node_and_load_pin_class_by_depth ./pack/cluster_feasibility_filter.c /^static void expand_pb_graph_node_and_load_pin_class_by_depth($/;" f file: +expand_routing_trace ./base/vpr_api.c /^static t_trace *expand_routing_trace(t_trace *trace, int ivpack_net) {$/;" f file: +expected_lowest_cost_primitive ./base/vpr_types.h /^ t_pb_graph_node *expected_lowest_cost_primitive; \/* predicted ideal primitive to use for this logical block *\/$/;" m struct:s_logical_block +ext_clock_rr_node_index ./pack/cluster_legality.c /^ ext_clock_rr_node_index, max_ext_index;$/;" v file: +ext_input_rr_node_index ./pack/cluster_legality.c /^static int ext_input_rr_node_index, ext_output_rr_node_index,$/;" v file: +ext_output_rr_node_index ./pack/cluster_legality.c /^static int ext_input_rr_node_index, ext_output_rr_node_index,$/;" v file: +ezxml ../../libarchfpga/include/ezxml.h /^struct ezxml {$/;" s +ezxml_add_child ../../libarchfpga/ezxml.c /^ezxml_t ezxml_add_child(ezxml_t xml, char *name, size_t off) {$/;" f +ezxml_add_child_d ../../libarchfpga/include/ezxml.h 149;" d +ezxml_ampencode ../../libarchfpga/ezxml.c /^ezxml_ampencode(const char *s, size_t len, char **dst, size_t * dlen,$/;" f file: +ezxml_attr ../../libarchfpga/ezxml.c /^ezxml_attr(ezxml_t xml, const char *attr) {$/;" f +ezxml_char_content ../../libarchfpga/ezxml.c /^static void ezxml_char_content(ezxml_root_t root, char *s,$/;" f file: +ezxml_child ../../libarchfpga/ezxml.c /^ezxml_t ezxml_child(ezxml_t xml, const char *name) {$/;" f +ezxml_close_tag ../../libarchfpga/ezxml.c /^static ezxml_t ezxml_close_tag(ezxml_root_t root, char *name, char *s) {$/;" f file: +ezxml_cut ../../libarchfpga/ezxml.c /^ezxml_t ezxml_cut(ezxml_t xml) {$/;" f +ezxml_decode ../../libarchfpga/ezxml.c /^ezxml_decode(char *s, char **ent, char t) {$/;" f file: +ezxml_ent_ok ../../libarchfpga/ezxml.c /^static int ezxml_ent_ok(char *name, char *s, char **ent) {$/;" f file: +ezxml_err ../../libarchfpga/ezxml.c /^static ezxml_t ezxml_err(ezxml_root_t root, char *s, const char *err, ...) {$/;" f file: +ezxml_error ../../libarchfpga/ezxml.c /^ezxml_error(ezxml_t xml) {$/;" f +ezxml_free ../../libarchfpga/ezxml.c /^void ezxml_free(ezxml_t xml) {$/;" f +ezxml_free_attr ../../libarchfpga/ezxml.c /^static void ezxml_free_attr(char **attr) {$/;" f file: +ezxml_get ../../libarchfpga/ezxml.c /^ezxml_t ezxml_get(ezxml_t xml, ...) {$/;" f +ezxml_idx ../../libarchfpga/ezxml.c /^ezxml_t ezxml_idx(ezxml_t xml, int idx) {$/;" f +ezxml_insert ../../libarchfpga/ezxml.c /^ezxml_t ezxml_insert(ezxml_t xml, ezxml_t dest, size_t off) {$/;" f +ezxml_internal_dtd ../../libarchfpga/ezxml.c /^static short ezxml_internal_dtd(ezxml_root_t root, char *s,$/;" f file: +ezxml_move ../../libarchfpga/include/ezxml.h 178;" d +ezxml_name ../../libarchfpga/include/ezxml.h 108;" d +ezxml_new ../../libarchfpga/ezxml.c /^ezxml_t ezxml_new(char *name) {$/;" f +ezxml_new_d ../../libarchfpga/include/ezxml.h 142;" d +ezxml_next ../../libarchfpga/include/ezxml.h 101;" d +ezxml_open_tag ../../libarchfpga/ezxml.c /^static void ezxml_open_tag(ezxml_root_t root, int line, char *name, char **attr) {$/;" f file: +ezxml_parse_fd ../../libarchfpga/ezxml.c /^ezxml_t ezxml_parse_fd(int fd) {$/;" f +ezxml_parse_file ../../libarchfpga/ezxml.c /^ezxml_t ezxml_parse_file(const char *file) {$/;" f +ezxml_parse_fp ../../libarchfpga/ezxml.c /^ezxml_t ezxml_parse_fp(FILE * fp) {$/;" f +ezxml_parse_str ../../libarchfpga/ezxml.c /^ezxml_t ezxml_parse_str(char *s, size_t len) {$/;" f +ezxml_pi ../../libarchfpga/ezxml.c /^ezxml_pi(ezxml_t xml, const char *target) {$/;" f +ezxml_proc_inst ../../libarchfpga/ezxml.c /^static void ezxml_proc_inst(ezxml_root_t root, char *s, size_t len) {$/;" f file: +ezxml_remove ../../libarchfpga/include/ezxml.h 181;" d +ezxml_root ../../libarchfpga/include/ezxml.h /^struct ezxml_root { \/* additional data for the root tag *\/$/;" s +ezxml_root_t ../../libarchfpga/include/ezxml.h /^typedef struct ezxml_root *ezxml_root_t;$/;" t typeref:struct:ezxml_root +ezxml_set_attr ../../libarchfpga/ezxml.c /^ezxml_t ezxml_set_attr(ezxml_t xml, char *name, char *value) {$/;" f +ezxml_set_attr_d ../../libarchfpga/include/ezxml.h 164;" d +ezxml_set_flag ../../libarchfpga/ezxml.c /^ezxml_t ezxml_set_flag(ezxml_t xml, short flag) {$/;" f +ezxml_set_txt ../../libarchfpga/ezxml.c /^ezxml_t ezxml_set_txt(ezxml_t xml, char *txt) {$/;" f +ezxml_set_txt_d ../../libarchfpga/include/ezxml.h 156;" d +ezxml_str2utf8 ../../libarchfpga/ezxml.c /^ezxml_str2utf8(char **s, size_t * len) {$/;" f file: +ezxml_t ../../libarchfpga/include/ezxml.h /^typedef struct ezxml *ezxml_t;$/;" t typeref:struct:ezxml +ezxml_toxml ../../libarchfpga/ezxml.c /^ezxml_toxml(ezxml_t xml) {$/;" f +ezxml_toxml_r ../../libarchfpga/ezxml.c /^ezxml_toxml_r(ezxml_t xml, char **s, size_t * len, size_t * max, size_t start,$/;" f file: +ezxml_txt ../../libarchfpga/include/ezxml.h 111;" d +ezxml_vget ../../libarchfpga/ezxml.c /^ezxml_t ezxml_vget(ezxml_t xml, va_list ap) {$/;" f +f_blk_pin_from_port_pin ./util/vpr_utils.c /^static int *** f_blk_pin_from_port_pin = NULL;$/;" v file: +f_direct_type_from_blk_pin ./place/place_macro.c /^static int ** f_direct_type_from_blk_pin = NULL;$/;" v file: +f_idirect_from_blk_pin ./place/place_macro.c /^static int ** f_idirect_from_blk_pin = NULL;$/;" v file: +f_imacro_from_iblk ./place/place_macro.c /^static int * f_imacro_from_iblk = NULL;$/;" v file: +f_net_to_driver_tnode ./timing/path_delay.c /^static int * f_net_to_driver_tnode; $/;" v file: +f_per_stage ../../libarchfpga/fpga_spice_include/spice_types.h /^ int f_per_stage;$/;" m struct:s_spice_model_buffer +f_port_from_blk_pin ./util/vpr_utils.c /^static int ** f_port_from_blk_pin = NULL;$/;" v file: +f_port_pin_from_blk_pin ./util/vpr_utils.c /^static int ** f_port_pin_from_blk_pin = NULL;$/;" v file: +f_timing_stats ./timing/path_delay.c /^static t_timing_stats * f_timing_stats = NULL; \/* Critical path delay and worst-case slack per constraint. *\/$/;" v file: +factor ./power/PowerSpicedComponent.h /^ float factor;$/;" m class:PowerCallibSize +falling_edge ./timing/read_sdc.c /^ float falling_edge;$/;" m struct:s_sdc_clock file: +fan_in ../../libarchfpga/include/physical_types.h /^ int fan_in;$/;" m struct:s_interconnect +fan_in ./base/vpr_types.h /^ short fan_in;$/;" m struct:s_rr_node +fan_out ../../libarchfpga/include/physical_types.h /^ int fan_out;$/;" m struct:s_interconnect +fanout ./base/vpr_types.h /^ int fanout;$/;" m struct:s_clock +fast ../../libarchfpga/fpga_spice_include/spice_types.h /^ int fast;$/;" m struct:s_spice_params +fc ./base/place_and_route.h /^ int fc; \/* at this fc *\/$/;" m struct:s_fmap_cell +fc_constraints ./base/vpr_types.h /^ t_override_constraint * fc_constraints; \/* [0..num_fc_constraints - 1] *\/$/;" m struct:s_timing_constraints +fc_in ./base/vpr_types.h /^ int fc_in;$/;" m struct:s_cb +fc_out ./base/vpr_types.h /^ int fc_out;$/;" m struct:s_sb +fcc ../../pcre/SRC/internal.h /^ const uschar *fcc; \/* Points to case-flipping table *\/$/;" m struct:compile_data +fcc_offset ../../pcre/SRC/internal.h 654;" d +fclose_wire_L_file_handler_in_llist ./fpga_x2p/verilog/verilog_report_timing.c /^void fclose_wire_L_file_handler_in_llist(t_llist* rr_path_cnt) {$/;" f +fcn ./base/graphics.c /^ void (*fcn) (void (*drawscreen) (void));$/;" m struct:__anon4 file: +feasible_blocks ./base/vpr_types.h /^ struct s_pack_molecule **feasible_blocks;$/;" m struct:s_pb_stats typeref:struct:s_pb_stats::s_pack_molecule +feasible_routing ./route/route_common.c /^boolean feasible_routing(void) {$/;" f +feasible_routing_rr_graph ./fpga_x2p/router/fpga_x2p_router.c /^boolean feasible_routing_rr_graph(t_rr_graph* local_rr_graph, $/;" f +ff_constraints ./base/vpr_types.h /^ t_override_constraint * ff_constraints; \/* [0..num_ff_constraints - 1] array of such constraints *\/$/;" m struct:s_timing_constraints +file_exists ../../libarchfpga/util.c /^boolean file_exists(const char * filename) {$/;" f +file_handler ./fpga_x2p/verilog/verilog_report_timing.c /^ FILE* file_handler;$/;" m struct:s_wireL_cnt file: +file_line_number ../../libarchfpga/util.c /^int file_line_number; \/* file in line number being parsed *\/$/;" v +file_line_number ./base/vpr_types.h /^ int file_line_number; \/* line in the SDC file I\/O was constrained on - used for error reporting *\/$/;" m struct:s_io +file_line_number ./base/vpr_types.h /^ int file_line_number; \/* line in the SDC file clock was constrained on - used for error reporting *\/$/;" m struct:s_override_constraint +fillarc ./base/graphics.c /^fillarc (float xc, float yc, float rad, float startang, float angextent) {$/;" f +fillarc ./base/graphics.c /^void fillarc (float xcen, float ycen, float rad, float startang,$/;" f +fillcurve ./base/graphics.c /^void fillcurve(t_point *points, int npoints) { }$/;" f +fillcurve ./base/graphics.c /^void fillcurve(t_point *points,$/;" f +fillellipticarc ./base/graphics.c /^fillellipticarc (float xc, float yc, float radx, float rady, float startang, $/;" f +fillellipticarc ./base/graphics.c /^void fillellipticarc (float xc, float yc, float radx, float rady, float startang, float angextent) { }$/;" f +fillpoly ./base/graphics.c /^fillpoly (t_point *points, int npoints) $/;" f +fillpoly ./base/graphics.c /^void fillpoly (t_point *points, int npoints) { }$/;" f +fillrect ./base/graphics.c /^fillrect (float x1, float y1, float x2, float y2) $/;" f +fillrect ./base/graphics.c /^void fillrect (float x1, float y1, float x2, float y2) { }$/;" f +findPortByName ../../libarchfpga/read_xml_arch_file.c /^static t_port * findPortByName(const char * name, t_pb_type * pb_type,$/;" f file: +find_affected_blocks ./place/place.c /^static int find_affected_blocks(int b_from, int x_to, int y_to, int z_to) {$/;" f file: +find_affected_nets ./place/place.c /^static int find_affected_nets(int *nets_to_update) {$/;" f file: +find_all_the_macro ./place/place_macro.c /^static void find_all_the_macro (int * num_of_macro, int * pl_macro_member_blk_num_of_this_blk, $/;" f file: +find_bl_wl_ports_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^void find_bl_wl_ports_spice_model(t_spice_model* cur_spice_model,$/;" f +find_blb_wlb_ports_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^void find_blb_wlb_ports_spice_model(t_spice_model* cur_spice_model,$/;" f +find_blk_net_pin_side ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int find_blk_net_pin_side(t_block target_blk,$/;" f +find_blk_net_pin_sides ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void find_blk_net_pin_sides(t_block target_blk,$/;" f +find_blk_net_type_pins ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void find_blk_net_type_pins(int n_blks, t_block* blk,$/;" f +find_bracket ../../pcre/SRC/pcre.c /^find_bracket(const uschar *code, BOOL utf8, int number)$/;" f file: +find_cc_constraint ./timing/read_sdc.c /^static int find_cc_constraint(char * source_clock_name, char * sink_clock_name) {$/;" f file: +find_cf_constraint ./timing/path_delay.c /^static int find_cf_constraint(char * source_clock_name, char * sink_ff_name) {$/;" f file: +find_clock ./timing/path_delay.c /^static int find_clock(char * net_name) {$/;" f file: +find_clock_name ./base/verilog_writer.c /^char *find_clock_name(void)$/;" f +find_connected_primitives_downhill ./base/verilog_writer.c /^conn_list *find_connected_primitives_downhill(int block_num , t_pb *pb , conn_list*list)$/;" f +find_constrained_clock ./timing/read_sdc.c /^static int find_constrained_clock(char * ptr) {$/;" f file: +find_drive_rr_nodes_switch_box ./fpga_x2p/base/fpga_x2p_utils.c /^void find_drive_rr_nodes_switch_box(int switch_box_x,$/;" f +find_expansion_edge_of_pattern ./pack/prepack.c /^static t_pb_graph_edge * find_expansion_edge_of_pattern(INP int pattern_index,$/;" f file: +find_fanin_rr_node ./pack/output_blif.c /^static int find_fanin_rr_node(t_pb *cur_pb, enum PORTS type, int rr_node_index) {$/;" f file: +find_ff_clock_tnode ./timing/path_delay.c /^static t_tnode * find_ff_clock_tnode(int inode, boolean is_prepacked) {$/;" f file: +find_firstassertedchar ../../pcre/SRC/pcre.c /^find_firstassertedchar(const uschar *code, int *options, BOOL inassert)$/;" f file: +find_fixedlength ../../pcre/SRC/pcre.c /^find_fixedlength(uschar *code, int options)$/;" f file: +find_grid_mapped_logical_block ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int find_grid_mapped_logical_block(int x, int y,$/;" f +find_index ./base/verilog_writer.c /^int find_index(char *row,int inputs)\/*returns the index of the 64bit truth table that this temporary truth table row corresponds to*\/$/;" f +find_input ./timing/path_delay.c /^static int find_input(char * net_name) {$/;" f file: +find_interc_des_pb_graph_pin ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void find_interc_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin,$/;" f +find_interc_fan_in_des_pb_graph_pin ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin,$/;" f +find_iopad_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_model* find_iopad_spice_model(int num_spice_model,$/;" f +find_label_of_track ./route/rr_graph2.c /^static int find_label_of_track(int *wire_mux_on_track, int num_wire_muxes,$/;" f file: +find_length_llist ../../libarchfpga/linkedlist.c /^int find_length_llist(t_llist* head) {$/;" f +find_matched_block_id_for_one_grid ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int find_matched_block_id_for_one_grid(int x, int y) {$/;" f +find_mosfet_tech_lib ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib,$/;" f +find_name_matched_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_model* find_name_matched_spice_model(char* spice_model_name,$/;" f +find_new_root_atom_for_chain ./pack/prepack.c /^static int find_new_root_atom_for_chain(INP int block_index, INP t_pack_patterns *list_of_pack_pattern) {$/;" f file: +find_number_of_inputs ./base/verilog_writer.c /^int find_number_of_inputs(t_pb *pb)$/;" f +find_output ./timing/path_delay.c /^static int find_output(char * net_name) {$/;" f file: +find_parent_pb_type_child_index ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int find_parent_pb_type_child_index(t_pb_type* parent_pb_type,$/;" f +find_path_id_between_pb_rr_nodes ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int find_path_id_between_pb_rr_nodes(t_rr_node* local_rr_graph,$/;" f +find_path_id_prev_rr_node ./fpga_x2p/base/fpga_x2p_utils.c /^int find_path_id_prev_rr_node(int num_drive_rr_nodes,$/;" f +find_pb_graph_pin_in_edges_interc_spice_model ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_spice_model* find_pb_graph_pin_in_edges_interc_spice_model(t_pb_graph_pin pb_graph_pin) {$/;" f +find_pb_graph_pin_in_edges_interc_type ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin) {$/;" f +find_pb_graph_pin_in_edges_interc_verilog_model ./fpga_x2p/verilog/verilog_pbtypes.c /^t_spice_model* find_pb_graph_pin_in_edges_interc_verilog_model(t_pb_graph_pin pb_graph_pin) {$/;" f +find_pb_mapped_logical_block_rec ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int find_pb_mapped_logical_block_rec(t_pb* cur_pb,$/;" f +find_pb_type_idle_mode_index ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int find_pb_type_idle_mode_index(t_pb_type cur_pb_type) {$/;" f +find_pb_type_physical_mode_index ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int find_pb_type_physical_mode_index(t_pb_type cur_pb_type) {$/;" f +find_pb_type_port_match_spice_model_port ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type,$/;" f +find_pb_type_ports_match_spice_model_port_type ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type,$/;" f +find_prev_rr_nodes_with_src ./fpga_x2p/base/fpga_x2p_utils.c /^void find_prev_rr_nodes_with_src(t_rr_node* src_rr_node,$/;" f +find_rr_nodes_ipin_driver_switch ./route/rr_graph_opincb.c /^void find_rr_nodes_ipin_driver_switch() {$/;" f file: +find_spice_model_config_done_ports ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_model_port** find_spice_model_config_done_ports(t_spice_model* spice_model,$/;" f +find_spice_model_port_by_name ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_model_port* find_spice_model_port_by_name(t_spice_model* cur_spice_model,$/;" f +find_spice_model_ports ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_model_port** find_spice_model_ports(t_spice_model* spice_model,$/;" f +find_spice_mux_arch_special_basis_size ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int find_spice_mux_arch_special_basis_size(t_spice_mux_arch spice_mux_arch) {$/;" f +find_spice_testbench_pb_pin_mux_load_inv_size ./fpga_x2p/spice/spice_utils.c /^float find_spice_testbench_pb_pin_mux_load_inv_size(t_spice_model* fan_out_spice_model) {$/;" f +find_spice_testbench_rr_mux_load_inv_size ./fpga_x2p/spice/spice_utils.c /^float find_spice_testbench_rr_mux_load_inv_size(t_rr_node* load_rr_node,$/;" f +find_src_pb_pin_to_rr_nodes ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void find_src_pb_pin_to_rr_nodes(t_pb* src_pb,$/;" f +find_tnode_net_name ./timing/path_delay.c /^static char * find_tnode_net_name(int inode, boolean is_prepacked) {$/;" f file: +find_to ./place/place.c /^static boolean find_to(int x_from, int y_from, t_type_ptr type, float rlim, int *x_to, int *y_to) {$/;" f file: +find_type_col ./base/SetupGrid.c /^static t_type_ptr find_type_col(INP int x) {$/;" f file: +findfontsize ./base/graphics.c /^int findfontsize(float ymax) { }$/;" f +findfontsize ./base/graphics.c /^int findfontsize(float ymax) {$/;" f +first_byte ../../pcre/SRC/internal.h /^ unsigned short int first_byte;$/;" m struct:real_pcre +first_iter_pres_fac ./base/ReadOptions.h /^ float first_iter_pres_fac;$/;" m struct:s_options +first_iter_pres_fac ./base/vpr_types.h /^ float first_iter_pres_fac;$/;" m struct:s_router_opts +first_significant_code ../../pcre/SRC/pcre.c /^first_significant_code(const uschar *code, int *options, int optbit)$/;" f file: +fix_name ./base/verilog_writer.c /^char *fix_name(char *name)$/;" f +fixed_channel_width ./base/vpr_types.h /^ int fixed_channel_width;$/;" m struct:s_router_opts +fixup_branch ./timing/slre.c /^static void fixup_branch(struct slre *r, int fixup) {$/;" f file: +flag_postfix ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^static char* flag_postfix = "_flag";$/;" v file: +flags ../../libarchfpga/include/ezxml.h /^ short flags; \/* additional information *\/$/;" m struct:ezxml +flags ../../pcre/SRC/pcre.h /^ unsigned long int flags; \/* Bits for which fields are set *\/$/;" m struct:pcre_extra +flush_intermediate_queues ./pack/cluster_placement.c /^static void flush_intermediate_queues($/;" f file: +flushinput ./base/graphics.c /^flushinput (void) $/;" f +flushinput ./base/graphics.c /^void flushinput (void) { }$/;" f +font_info ./base/graphics.c /^static LOGFONT *font_info[MAX_FONT_SIZE+1]; \/* Data for each size *\/$/;" v file: +font_info ./base/graphics.c /^static XFontStruct *font_info[MAX_FONT_SIZE+1]; \/* Data for each size *\/$/;" v file: +font_is_loaded ./base/graphics.c /^static bool font_is_loaded[MAX_FONT_SIZE + 1];$/;" v file: +force_post_place_route_cb_input_pins ./pack/cluster_legality.c /^void force_post_place_route_cb_input_pins(int iblock) {$/;" f +force_setcolor ./base/graphics.c /^static void force_setcolor (int cindex) $/;" f file: +force_setfontsize ./base/graphics.c /^static void force_setfontsize (int pointsize) $/;" f file: +force_setlinestyle ./base/graphics.c /^static void force_setlinestyle (int linestyle) $/;" f file: +force_setlinewidth ./base/graphics.c /^static void force_setlinewidth (int linewidth) $/;" f file: +formal_random_top_tb_postfix ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^static char* formal_random_top_tb_postfix = "_top_formal_verification_random_tb";$/;" v file: +formal_simulation_flag ./fpga_x2p/verilog/verilog_global.c /^char* formal_simulation_flag = "FORMAL_SIMULATION"; \/\/ the flag to enable formal functional verification$/;" v +formal_verification_top_module_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* formal_verification_top_module_port_postfix = "_fm";$/;" v +formal_verification_top_module_postfix ./fpga_x2p/verilog/verilog_global.c /^char* formal_verification_top_module_postfix = "_top_formal_verification";$/;" v +formal_verification_top_module_uut_name ./fpga_x2p/verilog/verilog_global.c /^char* formal_verification_top_module_uut_name = "U0_formal_verification";$/;" v +formal_verification_top_postfix ./fpga_x2p/verilog/verilog_global.c /^char* formal_verification_top_postfix = "_top_formal_verification";$/;" v +formal_verification_verilog_file_postfix ./fpga_x2p/verilog/verilog_global.c /^char* formal_verification_verilog_file_postfix = "_top_formal_verification.v"; $/;" v +formality_include_user_defined_verilog_netlists ./fpga_x2p/verilog/verilog_formality_autodeck.c /^void formality_include_user_defined_verilog_netlists(FILE* fp,$/;" f file: +formality_script_name_postfix ./fpga_x2p/verilog/verilog_global.c /^char* formality_script_name_postfix = "_formality_script.tcl";$/;" v +format ../../libarchfpga/include/physical_types.h /^ enum e_pin_to_pin_annotation_format format;$/;" m struct:s_pin_to_pin_annotation typeref:enum:s_pin_to_pin_annotation::e_pin_to_pin_annotation_format +format_dir_path ./fpga_x2p/base/fpga_x2p_utils.c /^char* format_dir_path(char* dir_path) {$/;" f +format_spice_node_prefix ./fpga_x2p/base/fpga_x2p_utils.c /^char* format_spice_node_prefix(char* spice_node_prefix) {$/;" f +format_verilog_node_prefix ./fpga_x2p/verilog/verilog_utils.c /^char* format_verilog_node_prefix(char* verilog_node_prefix) {$/;" f +forward_expand_pack_pattern_from_edge ./pack/prepack.c /^static void forward_expand_pack_pattern_from_edge($/;" f file: +forward_infer_pattern ./pack/prepack.c /^static void forward_infer_pattern(INOUTP t_pb_graph_pin *pb_graph_pin) {$/;" f file: +forward_weight ./base/vpr_types.h /^ float forward_weight, backward_weight; \/* Weightings of the importance of paths $/;" m struct:s_tnode +found_connectivity ./base/verilog_writer.h /^typedef struct found_connectivity{$/;" s +found_pins ./base/verilog_writer.h /^typedef struct found_pins{$/;" s +fpga_bitstream_file ./base/ReadOptions.h /^ char* fpga_bitstream_file;$/;" m struct:s_options +fpga_bitstream_opts ./fpga_x2p/shell/cmd_fpga_bitstream.h /^t_opt_info fpga_bitstream_opts[] = {$/;" v +fpga_spice_atof_2D ./fpga_x2p/base/fpga_x2p_timing_utils.c /^float** fpga_spice_atof_2D(int num_in_port, int num_out_port, char* str) {$/;" f +fpga_spice_bitstream_logic_block_log_file_postfix ./fpga_x2p/base/fpga_x2p_globals.c /^char* fpga_spice_bitstream_logic_block_log_file_postfix = "_lb_bitstream.log";$/;" v +fpga_spice_bitstream_output_file_postfix ./fpga_x2p/base/fpga_x2p_globals.c /^char* fpga_spice_bitstream_output_file_postfix = ".bitstream";$/;" v +fpga_spice_bitstream_routing_log_file_postfix ./fpga_x2p/base/fpga_x2p_globals.c /^char* fpga_spice_bitstream_routing_log_file_postfix = "_routing_bitstream.log";$/;" v +fpga_spice_create_one_subckt_filename ./fpga_x2p/base/fpga_x2p_utils.c /^char* fpga_spice_create_one_subckt_filename(char* file_name_prefix,$/;" f +fpga_spice_generate_bitstream_connection_box_interc ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_connection_box_interc(FILE* fp,$/;" f file: +fpga_spice_generate_bitstream_connection_box_mux ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_connection_box_mux(FILE* fp,$/;" f file: +fpga_spice_generate_bitstream_connection_box_short_interc ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_connection_box_short_interc(t_cb* cur_cb_info,$/;" f file: +fpga_spice_generate_bitstream_logic_block ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_logic_block(char* lb_bitstream_log_file_path,$/;" f +fpga_spice_generate_bitstream_one_physical_block ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_one_physical_block(FILE* fp,$/;" f +fpga_spice_generate_bitstream_pb_generic_primitive ./fpga_x2p/bitstream/fpga_bitstream_primitives.c /^void fpga_spice_generate_bitstream_pb_generic_primitive(FILE* fp,$/;" f +fpga_spice_generate_bitstream_pb_graph_interc ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_pb_graph_interc(FILE* fp,$/;" f +fpga_spice_generate_bitstream_pb_graph_pin_interc ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_pb_graph_pin_interc(FILE* fp,$/;" f +fpga_spice_generate_bitstream_pb_graph_port_interc ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_pb_graph_port_interc(FILE* fp,$/;" f +fpga_spice_generate_bitstream_pb_primitive ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_pb_primitive(FILE* fp,$/;" f +fpga_spice_generate_bitstream_pb_primitive_lut ./fpga_x2p/bitstream/fpga_bitstream_primitives.c /^void fpga_spice_generate_bitstream_pb_primitive_lut(FILE* fp,$/;" f +fpga_spice_generate_bitstream_phy_pb_graph_node_rec ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_phy_pb_graph_node_rec(FILE* fp,$/;" f +fpga_spice_generate_bitstream_physical_grid_block ./fpga_x2p/bitstream/fpga_bitstream_pbtypes.c /^void fpga_spice_generate_bitstream_physical_grid_block(FILE* fp,$/;" f +fpga_spice_generate_bitstream_routing_chan_subckt ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_routing_chan_subckt(int x, int y,$/;" f file: +fpga_spice_generate_bitstream_routing_connection_box_subckt ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_routing_connection_box_subckt(FILE* fp,$/;" f file: +fpga_spice_generate_bitstream_routing_resources ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_routing_resources(char* routing_bitstream_log_file_path,$/;" f +fpga_spice_generate_bitstream_routing_switch_box_subckt ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_routing_switch_box_subckt(FILE* fp, $/;" f file: +fpga_spice_generate_bitstream_switch_box_interc ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_switch_box_interc(FILE* fp,$/;" f file: +fpga_spice_generate_bitstream_switch_box_mux ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_switch_box_mux(FILE* fp,$/;" f file: +fpga_spice_generate_bitstream_switch_box_short_interc ./fpga_x2p/bitstream/fpga_bitstream_routing.c /^void fpga_spice_generate_bitstream_switch_box_short_interc(t_sb* cur_sb_info,$/;" f file: +fpga_spice_inpad_model ./fpga_x2p/base/fpga_x2p_globals.c /^t_spice_model* fpga_spice_inpad_model = NULL;$/;" v +fpga_spice_iopad_model ./fpga_x2p/base/fpga_x2p_globals.c /^t_spice_model* fpga_spice_iopad_model = NULL;$/;" v +fpga_spice_leakage_only ./base/vpr_types.h /^ boolean fpga_spice_leakage_only;$/;" m struct:s_spice_opts +fpga_spice_opts ./fpga_x2p/shell/cmd_fpga_spice.h /^t_opt_info fpga_spice_opts[] = {$/;" v +fpga_spice_outpad_model ./fpga_x2p/base/fpga_x2p_globals.c /^t_spice_model* fpga_spice_outpad_model = NULL;$/;" v +fpga_spice_parasitic_net_estimation ./base/ReadOptions.h /^ boolean fpga_spice_parasitic_net_estimation;$/;" m struct:s_options +fpga_spice_parasitic_net_estimation ./base/vpr_types.h /^ boolean fpga_spice_parasitic_net_estimation;$/;" m struct:s_spice_opts +fpga_spice_phy_pb ./fpga_x2p/base/fpga_x2p_types.h /^struct fpga_spice_phy_pb {$/;" s +fpga_spice_print_cb_mux_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_cb_mux_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_cb_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_cb_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_grid_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_grid_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_hardlogic_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_hardlogic_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_io_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_io_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_lut_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_lut_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_pb_mux_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_pb_mux_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_sb_mux_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_sb_mux_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_sb_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_sb_testbench; $/;" m struct:s_spice_opts +fpga_spice_print_top_testbench ./base/vpr_types.h /^ boolean fpga_spice_print_top_testbench; $/;" m struct:s_spice_opts +fpga_spice_rr_graph ./fpga_x2p/base/fpga_x2p_types.h /^struct fpga_spice_rr_graph {$/;" s +fpga_spice_signal_density_weight ./base/ReadOptions.h /^ float fpga_spice_signal_density_weight;$/;" m struct:s_options +fpga_spice_sim_mt_num ./base/ReadOptions.h /^ int fpga_spice_sim_mt_num;$/;" m struct:s_options +fpga_spice_sim_multi_thread_num ./base/vpr_types.h /^ int fpga_spice_sim_multi_thread_num;$/;" m struct:s_spice_opts +fpga_spice_sim_window_size ./base/ReadOptions.h /^ float fpga_spice_sim_window_size;$/;" m struct:s_options +fpga_spice_simulator_path ./base/ReadOptions.h /^ char* fpga_spice_simulator_path;$/;" m struct:s_options +fpga_spice_sram_model ./fpga_x2p/base/fpga_x2p_globals.c /^t_spice_model* fpga_spice_sram_model = NULL;$/;" v +fpga_spice_sram_orgz_type ./fpga_x2p/base/fpga_x2p_globals.c /^enum e_sram_orgz fpga_spice_sram_orgz_type = SPICE_SRAM_STANDALONE;$/;" v typeref:enum:e_sram_orgz +fpga_spice_strtok ./fpga_x2p/base/fpga_x2p_utils.c /^char** fpga_spice_strtok(char* str, $/;" f +fpga_spice_testbench_load_extraction ./base/ReadOptions.h /^ boolean fpga_spice_testbench_load_extraction;$/;" m struct:s_options +fpga_spice_testbench_load_extraction ./base/vpr_types.h /^ boolean fpga_spice_testbench_load_extraction;$/;" m struct:s_spice_opts +fpga_syn_verilog_dir ./base/ReadOptions.h /^ char* fpga_syn_verilog_dir;$/;" m struct:s_options +fpga_verilog_modelsim_ini_path ./base/ReadOptions.h /^ char* fpga_verilog_modelsim_ini_path;$/;" m struct:s_options +fpga_verilog_opts ./fpga_x2p/shell/cmd_fpga_verilog.h /^t_opt_info fpga_verilog_opts[] = {$/;" v +fpga_verilog_reference_benchmark_file ./base/ReadOptions.h /^ char* fpga_verilog_reference_benchmark_file;$/;" m struct:s_options +fpga_verilog_report_timing_path ./base/ReadOptions.h /^ char* fpga_verilog_report_timing_path;$/;" m struct:s_options +fpga_x2p_free ./fpga_x2p/base/fpga_x2p_setup.c /^void fpga_x2p_free(t_arch* Arch) {$/;" f +fpga_x2p_setup ./fpga_x2p/base/fpga_x2p_setup.c /^void fpga_x2p_setup(t_vpr_setup vpr_setup,$/;" f +fpga_x2p_setup_opts ./fpga_x2p/shell/cmd_fpga_x2p_setup.h /^t_opt_info fpga_x2p_setup_opts[] = {$/;" v +fprint_call_defined_channels ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_channels(FILE* fp,$/;" f +fprint_call_defined_connection_boxes ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_connection_boxes(FILE* fp) {$/;" f +fprint_call_defined_grids ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_grids(FILE* fp) {$/;" f +fprint_call_defined_one_channel ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_one_channel(FILE* fp,$/;" f +fprint_call_defined_one_connection_box ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_one_connection_box(FILE* fp,$/;" f +fprint_call_defined_one_switch_box ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_one_switch_box(FILE* fp,$/;" f +fprint_call_defined_switch_boxes ./fpga_x2p/spice/spice_utils.c /^void fprint_call_defined_switch_boxes(FILE* fp) {$/;" f +fprint_commented_sram_bits ./fpga_x2p/base/fpga_x2p_utils.c /^void fprint_commented_sram_bits(FILE* fp,$/;" f +fprint_connection_box_interc ./fpga_x2p/spice/spice_routing.c /^void fprint_connection_box_interc(FILE* fp,$/;" f +fprint_connection_box_mux ./fpga_x2p/spice/spice_routing.c /^void fprint_connection_box_mux(FILE* fp,$/;" f +fprint_connection_box_short_interc ./fpga_x2p/spice/spice_routing.c /^void fprint_connection_box_short_interc(FILE* fp,$/;" f +fprint_global_pad_ports_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_global_pad_ports_spice_model(FILE* fp, $/;" f +fprint_global_vdds_logical_block_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_global_vdds_logical_block_spice_model(FILE* fp,$/;" f +fprint_global_vdds_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_global_vdds_spice_model(FILE* fp, $/;" f +fprint_grid_block_subckt_pins ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_grid_block_subckt_pins(FILE* fp,$/;" f +fprint_grid_blocks ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_grid_blocks(char* subckt_dir,$/;" f +fprint_grid_float_port_stimulation ./fpga_x2p/spice/spice_utils.c /^void fprint_grid_float_port_stimulation(FILE* fp) {$/;" f +fprint_grid_global_vdds_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_grid_global_vdds_spice_model(FILE* fp, int x, int y, $/;" f +fprint_grid_physical_blocks ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_grid_physical_blocks(char* subckt_dir,$/;" f +fprint_grid_pins ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_grid_pins(FILE* fp,$/;" f +fprint_grid_side_pin_with_given_index ./fpga_x2p/spice/spice_routing.c /^void fprint_grid_side_pin_with_given_index(FILE* fp,$/;" f +fprint_grid_side_pins ./fpga_x2p/spice/spice_routing.c /^void fprint_grid_side_pins(FILE* fp,$/;" f +fprint_grid_splited_vdds_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_grid_splited_vdds_spice_model(FILE* fp, int grid_x, int grid_y,$/;" f +fprint_grid_testbench_one_grid_stimulation ./fpga_x2p/spice/spice_grid_testbench.c /^void fprint_grid_testbench_one_grid_stimulation(FILE* fp, $/;" f +fprint_include_user_defined_netlists ./fpga_x2p/spice/spice_utils.c /^void fprint_include_user_defined_netlists(FILE* fp,$/;" f +fprint_io_grid_block_subckt_pins ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_io_grid_block_subckt_pins(FILE* fp,$/;" f +fprint_io_grid_pins ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_io_grid_pins(FILE* fp,$/;" f +fprint_measure_grid_vdds_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_measure_grid_vdds_spice_model(FILE* fp, int grid_x, int grid_y,$/;" f +fprint_measure_vdds_cbs ./fpga_x2p/spice/spice_top_netlist.c /^void fprint_measure_vdds_cbs(FILE* fp,$/;" f file: +fprint_measure_vdds_logical_block_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_measure_vdds_logical_block_spice_model(FILE* fp,$/;" f +fprint_measure_vdds_sbs ./fpga_x2p/spice/spice_top_netlist.c /^void fprint_measure_vdds_sbs(FILE* fp,$/;" f file: +fprint_measure_vdds_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_measure_vdds_spice_model(FILE* fp,$/;" f +fprint_one_design_param_w_wo_variation ./fpga_x2p/spice/spice_utils.c /^void fprint_one_design_param_w_wo_variation(FILE* fp,$/;" f +fprint_pb_primitive_generic ./fpga_x2p/spice/spice_primitive.c /^void fprint_pb_primitive_generic(FILE* fp,$/;" f +fprint_pb_primitive_lut ./fpga_x2p/spice/spice_lut.c /^void fprint_pb_primitive_lut(FILE* fp,$/;" f +fprint_pb_primitive_spice_model ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_pb_primitive_spice_model(FILE* fp,$/;" f +fprint_pb_type_ports ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_pb_type_ports(FILE* fp,$/;" f +fprint_routing_chan_subckt ./fpga_x2p/spice/spice_routing.c /^void fprint_routing_chan_subckt(char* subckt_dir,$/;" f +fprint_routing_connection_box_subckt ./fpga_x2p/spice/spice_routing.c /^void fprint_routing_connection_box_subckt(char* subckt_dir,$/;" f +fprint_routing_switch_box_subckt ./fpga_x2p/spice/spice_routing.c /^void fprint_routing_switch_box_subckt(char* subckt_dir, $/;" f +fprint_run_hspice_shell_script ./fpga_x2p/spice/spice_run_scripts.c /^void fprint_run_hspice_shell_script(t_spice spice,$/;" f +fprint_spice_block ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_block(FILE* fp,$/;" f +fprint_spice_cb_testbench_global_ports ./fpga_x2p/spice/spice_routing_testbench.c /^void fprint_spice_cb_testbench_global_ports(FILE* fp,$/;" f file: +fprint_spice_circuit_param ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_circuit_param(FILE* fp,$/;" f +fprint_spice_clb2clb_directs ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_clb2clb_directs(FILE* fp, $/;" f +fprint_spice_cmos_mux_multilevel_structure ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_cmos_mux_multilevel_structure(FILE* fp, $/;" f +fprint_spice_cmos_mux_onelevel_structure ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_cmos_mux_onelevel_structure(FILE* fp, char* mux_basis_subckt_name,$/;" f +fprint_spice_cmos_mux_tree_structure ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_cmos_mux_tree_structure(FILE* fp, char* mux_basis_subckt_name,$/;" f +fprint_spice_dangling_des_pb_graph_pin_interc ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_dangling_des_pb_graph_pin_interc(FILE* fp,$/;" f +fprint_spice_design_param_header ./fpga_x2p/spice/spice_heads.c /^void fprint_spice_design_param_header(char* design_param_file_name,$/;" f file: +fprint_spice_generic_testbench_global_ports ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_generic_testbench_global_ports(FILE* fp, $/;" f +fprint_spice_global_ports ./fpga_x2p/spice/spice_utils.c /^int fprint_spice_global_ports(FILE* fp, t_llist* head) {$/;" f +fprint_spice_global_vdd_connection_boxes ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_global_vdd_connection_boxes(FILE* fp) {$/;" f +fprint_spice_global_vdd_switch_boxes ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_global_vdd_switch_boxes(FILE* fp) {$/;" f +fprint_spice_grid_testbench_call_defined_core_grids ./fpga_x2p/spice/spice_grid_testbench.c /^void fprint_spice_grid_testbench_call_defined_core_grids(FILE* fp) {$/;" f +fprint_spice_grid_testbench_call_one_defined_grid ./fpga_x2p/spice/spice_grid_testbench.c /^void fprint_spice_grid_testbench_call_one_defined_grid(FILE* fp, int ix, int iy) {$/;" f +fprint_spice_grid_testbench_global_ports ./fpga_x2p/spice/spice_grid_testbench.c /^void fprint_spice_grid_testbench_global_ports(FILE* fp, int x, int y,$/;" f file: +fprint_spice_grid_testbench_measurements ./fpga_x2p/spice/spice_grid_testbench.c /^void fprint_spice_grid_testbench_measurements(FILE* fp, int grid_x, int grid_y, $/;" f file: +fprint_spice_grid_testbench_stimulations ./fpga_x2p/spice/spice_grid_testbench.c /^void fprint_spice_grid_testbench_stimulations(FILE* fp, $/;" f file: +fprint_spice_head ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_head(FILE* fp,$/;" f +fprint_spice_idle_block ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_idle_block(FILE* fp,$/;" f +fprint_spice_idle_pb_graph_node_rec ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_idle_pb_graph_node_rec(FILE* fp,$/;" f +fprint_spice_include_key_subckts ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_include_key_subckts(FILE* fp,$/;" f +fprint_spice_include_param_headers ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_include_param_headers(FILE* fp,$/;" f +fprint_spice_lut_subckt ./fpga_x2p/spice/spice_lut.c /^void fprint_spice_lut_subckt(FILE* fp,$/;" f +fprint_spice_meas_header ./fpga_x2p/spice/spice_heads.c /^void fprint_spice_meas_header(char* meas_file_name,$/;" f file: +fprint_spice_mux_model_basis_cmos_subckt ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_mux_model_basis_cmos_subckt(FILE* fp, char* subckt_name,$/;" f file: +fprint_spice_mux_model_basis_rram_subckt ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_mux_model_basis_rram_subckt(FILE* fp, char* subckt_name,$/;" f file: +fprint_spice_mux_model_basis_subckt ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_mux_model_basis_subckt(FILE* fp, $/;" f file: +fprint_spice_mux_model_cmos_subckt ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_mux_model_cmos_subckt(FILE* fp,$/;" f +fprint_spice_mux_model_rram_subckt ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_mux_model_rram_subckt(FILE* fp,$/;" f +fprint_spice_mux_model_subckt ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_mux_model_subckt(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_call_one_grid_cb_muxes ./fpga_x2p/spice/spice_mux_testbench.c /^int fprint_spice_mux_testbench_call_one_grid_cb_muxes(FILE* fp, $/;" f file: +fprint_spice_mux_testbench_call_one_grid_pb_muxes ./fpga_x2p/spice/spice_mux_testbench.c /^int fprint_spice_mux_testbench_call_one_grid_pb_muxes(FILE* fp, int ix, int iy,$/;" f file: +fprint_spice_mux_testbench_call_one_grid_sb_muxes ./fpga_x2p/spice/spice_mux_testbench.c /^int fprint_spice_mux_testbench_call_one_grid_sb_muxes(FILE* fp, $/;" f file: +fprint_spice_mux_testbench_cb_interc ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_cb_interc(FILE* fp, $/;" f +fprint_spice_mux_testbench_cb_mux_meas ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_cb_mux_meas(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_cb_one_mux ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_cb_one_mux(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_global_ports ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_global_ports(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_measurements ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_measurements(FILE* fp, $/;" f file: +fprint_spice_mux_testbench_one_mux ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_one_mux(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_graph_node_pin_interc ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_graph_node_pin_interc(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_graph_node_pin_mux ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_graph_node_pin_mux(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_interc ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_interc(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_mux_meas ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_mux_meas(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_muxes_rec ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_muxes_rec(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_pin_interc ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_pin_interc(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_pb_pin_mux ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_pb_pin_mux(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_sb_mux_meas ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_sb_mux_meas(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_sb_one_mux ./fpga_x2p/spice/spice_mux_testbench.c /^int fprint_spice_mux_testbench_sb_one_mux(FILE* fp,$/;" f file: +fprint_spice_mux_testbench_stimulations ./fpga_x2p/spice/spice_mux_testbench.c /^void fprint_spice_mux_testbench_stimulations(FILE* fp, $/;" f file: +fprint_spice_netlist_generic_measurements ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_netlist_generic_measurements(FILE* fp, $/;" f +fprint_spice_netlist_measurement_one_design_param ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_netlist_measurement_one_design_param(FILE* fp,$/;" f +fprint_spice_netlist_transient_setting ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_netlist_transient_setting(FILE* fp, $/;" f +fprint_spice_one_cb_testbench ./fpga_x2p/spice/spice_routing_testbench.c /^int fprint_spice_one_cb_testbench(char* formatted_spice_dir,$/;" f +fprint_spice_one_clb2clb_direct ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_one_clb2clb_direct(FILE* fp, $/;" f +fprint_spice_one_grid_testbench ./fpga_x2p/spice/spice_grid_testbench.c /^int fprint_spice_one_grid_testbench(char* formatted_spice_dir,$/;" f +fprint_spice_one_mux_testbench ./fpga_x2p/spice/spice_mux_testbench.c /^int fprint_spice_one_mux_testbench(char* formatted_spice_dir,$/;" f +fprint_spice_one_primitive_testbench ./fpga_x2p/spice/spice_primitive_testbench.c /^int fprint_spice_one_primitive_testbench(char* formatted_spice_dir,$/;" f +fprint_spice_one_sb_testbench ./fpga_x2p/spice/spice_routing_testbench.c /^int fprint_spice_one_sb_testbench(char* formatted_spice_dir,$/;" f +fprint_spice_one_specific_sram_subckt ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_one_specific_sram_subckt(FILE* fp,$/;" f +fprint_spice_one_sram_subckt ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_one_sram_subckt(FILE* fp,$/;" f +fprint_spice_options ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_options(FILE* fp,$/;" f +fprint_spice_pb_graph_interc ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_pb_graph_interc(FILE* fp, $/;" f +fprint_spice_pb_graph_node_rec ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_pb_graph_node_rec(FILE* fp, $/;" f +fprint_spice_pb_graph_primitive_node ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_pb_graph_primitive_node(FILE* fp,$/;" f +fprint_spice_phy_pb_graph_node_rec ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_phy_pb_graph_node_rec(FILE* fp, $/;" f +fprint_spice_physical_block ./fpga_x2p/spice/spice_pbtypes.c /^void fprint_spice_physical_block(FILE* fp,$/;" f +fprint_spice_primitive_testbench_call_one_grid_defined_primitives ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_call_one_grid_defined_primitives(FILE* fp,$/;" f +fprint_spice_primitive_testbench_call_one_primitive ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_call_one_primitive(FILE* fp, $/;" f +fprint_spice_primitive_testbench_global_ports ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_global_ports(FILE* fp, int grid_x, int grid_y, $/;" f file: +fprint_spice_primitive_testbench_measurements ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_measurements(FILE* fp, int grid_x, int grid_y, $/;" f +fprint_spice_primitive_testbench_one_pb_primitive ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_one_pb_primitive(FILE* fp, $/;" f +fprint_spice_primitive_testbench_one_primitive_input_stimuli ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_one_primitive_input_stimuli(FILE* fp, $/;" f +fprint_spice_primitive_testbench_one_primitive_output_loads ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_one_primitive_output_loads(FILE* fp, $/;" f +fprint_spice_primitive_testbench_rec_pb_primitives ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_rec_pb_primitives(FILE* fp, $/;" f +fprint_spice_primitive_testbench_stimulations ./fpga_x2p/spice/spice_primitive_testbench.c /^void fprint_spice_primitive_testbench_stimulations(FILE* fp, int grid_x, int grid_y, $/;" f file: +fprint_spice_routing_testbench_call_one_cb_tb ./fpga_x2p/spice/spice_routing_testbench.c /^int fprint_spice_routing_testbench_call_one_cb_tb(FILE* fp,$/;" f file: +fprint_spice_routing_testbench_call_one_sb_tb ./fpga_x2p/spice/spice_routing_testbench.c /^int fprint_spice_routing_testbench_call_one_sb_tb(FILE* fp, $/;" f file: +fprint_spice_routing_testbench_global_ports ./fpga_x2p/spice/spice_routing_testbench.c /^void fprint_spice_routing_testbench_global_ports(FILE* fp,$/;" f file: +fprint_spice_rram_mux_multilevel_structure ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_rram_mux_multilevel_structure(FILE* fp, char* mux_basis_subckt_name,$/;" f +fprint_spice_rram_mux_onelevel_structure ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_rram_mux_onelevel_structure(FILE* fp, $/;" f +fprint_spice_rram_mux_tree_structure ./fpga_x2p/spice/spice_mux.c /^void fprint_spice_rram_mux_tree_structure(FILE* fp, char* mux_basis_subckt_name,$/;" f +fprint_spice_sb_testbench_global_ports ./fpga_x2p/spice/spice_routing_testbench.c /^void fprint_spice_sb_testbench_global_ports(FILE* fp,$/;" f file: +fprint_spice_sram_one_outport ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_sram_one_outport(FILE* fp,$/;" f +fprint_spice_stimulate_header ./fpga_x2p/spice/spice_heads.c /^void fprint_spice_stimulate_header(char* stimulate_file_name,$/;" f file: +fprint_spice_testbench_generic_global_ports_stimuli ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_generic_global_ports_stimuli(FILE* fp,$/;" f +fprint_spice_testbench_global_ports_stimuli ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_global_ports_stimuli(FILE* fp, $/;" f +fprint_spice_testbench_global_sram_inport_stimuli ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_global_sram_inport_stimuli(FILE* fp,$/;" f +fprint_spice_testbench_global_vdd_port_stimuli ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_global_vdd_port_stimuli(FILE* fp,$/;" f +fprint_spice_testbench_one_cb_mux_loads ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_one_cb_mux_loads(FILE* fp, int* testbench_load_cnt,$/;" f +fprint_spice_testbench_one_grid_pin_loads ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_one_grid_pin_loads(FILE* fp, int x, int y, $/;" f +fprint_spice_testbench_one_grid_pin_stimulation ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_one_grid_pin_stimulation(FILE* fp, int x, int y, $/;" f +fprint_spice_testbench_pb_graph_pin_inv_loads_rec ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_pb_graph_pin_inv_loads_rec(FILE* fp, int* testbench_load_cnt, $/;" f +fprint_spice_testbench_rr_node_load_version ./fpga_x2p/spice/spice_utils.c /^char* fprint_spice_testbench_rr_node_load_version(FILE* fp, int* testbench_load_cnt,$/;" f +fprint_spice_testbench_wire_one_global_port_stimuli ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_testbench_wire_one_global_port_stimuli(FILE* fp, $/;" f +fprint_spice_toplevel_one_grid_side_pin_with_given_index ./fpga_x2p/spice/spice_utils.c /^void fprint_spice_toplevel_one_grid_side_pin_with_given_index(FILE* fp, $/;" f +fprint_spice_wire_model ./fpga_x2p/spice/spice_subckt.c /^void fprint_spice_wire_model(FILE* fp,$/;" f +fprint_splited_vdds_logical_block_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_splited_vdds_logical_block_spice_model(FILE* fp,$/;" f +fprint_splited_vdds_spice_model ./fpga_x2p/spice/spice_utils.c /^void fprint_splited_vdds_spice_model(FILE* fp,$/;" f +fprint_stimulate_dangling_grid_pins ./fpga_x2p/spice/spice_utils.c /^void fprint_stimulate_dangling_grid_pins(FILE* fp) {$/;" f +fprint_stimulate_dangling_io_grid_pins ./fpga_x2p/spice/spice_utils.c /^void fprint_stimulate_dangling_io_grid_pins(FILE* fp,$/;" f +fprint_stimulate_dangling_normal_grid_pins ./fpga_x2p/spice/spice_utils.c /^void fprint_stimulate_dangling_normal_grid_pins(FILE* fp,$/;" f +fprint_stimulate_dangling_one_grid_pin ./fpga_x2p/spice/spice_utils.c /^void fprint_stimulate_dangling_one_grid_pin(FILE* fp,$/;" f +fprint_switch_box_chan_port ./fpga_x2p/spice/spice_routing.c /^void fprint_switch_box_chan_port(FILE* fp,$/;" f +fprint_switch_box_interc ./fpga_x2p/spice/spice_routing.c /^void fprint_switch_box_interc(FILE* fp, $/;" f +fprint_switch_box_mux ./fpga_x2p/spice/spice_routing.c /^void fprint_switch_box_mux(FILE* fp, $/;" f +fprint_switch_box_short_interc ./fpga_x2p/spice/spice_routing.c /^void fprint_switch_box_short_interc(FILE* fp, $/;" f +fprint_tech_lib ./fpga_x2p/spice/spice_utils.c /^void fprint_tech_lib(FILE* fp,$/;" f +fprint_top_netlist_global_ports ./fpga_x2p/spice/spice_top_netlist.c /^void fprint_top_netlist_global_ports(FILE* fp,$/;" f file: +fprint_top_netlist_measurements ./fpga_x2p/spice/spice_top_netlist.c /^void fprint_top_netlist_measurements(FILE* fp, $/;" f file: +fprint_top_netlist_stimulations ./fpga_x2p/spice/spice_top_netlist.c /^void fprint_top_netlist_stimulations(FILE* fp,$/;" f file: +fprint_voltage_pulse_params ./fpga_x2p/spice/spice_utils.c /^void fprint_voltage_pulse_params(FILE* fp,$/;" f +fprintf_spice_mux_testbench_pb_graph_port_interc ./fpga_x2p/spice/spice_mux_testbench.c /^void fprintf_spice_mux_testbench_pb_graph_port_interc(FILE* fp,$/;" f file: +fprintf_spice_pb_graph_pin_interc ./fpga_x2p/spice/spice_pbtypes.c /^void fprintf_spice_pb_graph_pin_interc(FILE* fp,$/;" f +fprintf_spice_pb_graph_port_interc ./fpga_x2p/spice/spice_pbtypes.c /^void fprintf_spice_pb_graph_port_interc(FILE* fp,$/;" f +fprintf_spice_routing_testbench_generic_stimuli ./fpga_x2p/spice/spice_routing_testbench.c /^void fprintf_spice_routing_testbench_generic_stimuli(FILE* fp,$/;" f file: +fptr ./base/vpr_types.h /^ float *fptr;$/;" m struct:s_linked_f_pointer +frac_cb ../../libarchfpga/include/physical_types.h /^ float frac_cb;$/;" m struct:s_segment_inf +frac_lut ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean frac_lut;$/;" m struct:s_spice_model_lut +frac_sb ../../libarchfpga/include/physical_types.h /^ float frac_sb;$/;" m struct:s_segment_inf +freeGrid ./base/SetupGrid.c /^void freeGrid() {$/;" f +freeTokens ./util/token.c /^void freeTokens(INP t_token *tokens, INP int num_tokens) {$/;" f +free_2D_matrix ./fpga_x2p/base/fpga_x2p_timing_utils.c /^void free_2D_matrix(void** delay_matrix,$/;" f +free_all_pb_graph_nodes ./pack/pb_type_graph.c /^void free_all_pb_graph_nodes(void) {$/;" f +free_and_reset_internal_structures ./place/timing_place_lookup.c /^static void free_and_reset_internal_structures(struct s_net *original_net,$/;" f file: +free_arch ./base/vpr_api.c /^void free_arch(t_arch* Arch) {$/;" f +free_backannotate_vpr_post_route_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void free_backannotate_vpr_post_route_info() {$/;" f +free_best_buffer_list ./mrfpga/buffer_insertion.c /^static void free_best_buffer_list( )$/;" f file: +free_blk_pin_from_port_pin ./util/vpr_utils.c /^void free_blk_pin_from_port_pin(void) {$/;" f +free_buffer_list ./mrfpga/buffer_insertion.c /^static void free_buffer_list( t_buffer_plan_list list )$/;" f file: +free_cb ./util/vpr_utils.c /^void free_cb(t_pb *pb) {$/;" f +free_cb_info_array ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void free_cb_info_array(t_cb*** LL_cb_info, int LL_nx, int LL_ny) {$/;" f +free_chunk_memory ../../libarchfpga/util.c /^void free_chunk_memory(t_chunk *chunk_info) {$/;" f +free_chunk_memory_trace ./route/route_common.c /^void free_chunk_memory_trace(void) {$/;" f +free_circuit ./base/vpr_api.c /^void free_circuit() {$/;" f +free_clb_nets_spice_net_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void free_clb_nets_spice_net_info() {$/;" f +free_clock_constraint ./timing/read_sdc.c /^static void free_clock_constraint(t_clock *& clock_array, int num_clocks) {$/;" f file: +free_cluster_legality_checker ./pack/cluster_legality.c /^void free_cluster_legality_checker(void) {$/;" f +free_cluster_placement_stats ./pack/cluster_placement.c /^void free_cluster_placement_stats($/;" f +free_complex_block_types ./base/vpr_api.c /^static void free_complex_block_types(void) {$/;" f file: +free_conf_bit ./fpga_x2p/base/fpga_x2p_utils.c /^void free_conf_bit(t_conf_bit* conf_bit) {$/;" f +free_conf_bit_info ./fpga_x2p/base/fpga_x2p_utils.c /^void free_conf_bit_info(t_conf_bit_info* conf_bit_info) {$/;" f +free_crit ./place/timing_place.c /^static void free_crit(t_chunk *chunk_list_ptr){$/;" f file: +free_delta_arrays ./place/timing_place_lookup.c /^static void free_delta_arrays(void) {$/;" f file: +free_draw_structs ./base/draw.c /^void free_draw_structs(void) {$/;" f +free_echo_file_info ./base/ReadOptions.c /^void free_echo_file_info() {$/;" f +free_edge_list_head ./route/rr_graph2.c /^t_linked_edge *free_edge_list_head = NULL;$/;" v +free_fast_cost_update ./place/place.c /^static void free_fast_cost_update(void) {$/;" f file: +free_global_routing_conf_bits ./fpga_x2p/verilog/verilog_api.c /^void free_global_routing_conf_bits() {$/;" f file: +free_hash_table ./util/hash.c /^void free_hash_table(struct s_hash **hash_table) {$/;" f +free_heap_data ./route/route_common.c /^void free_heap_data(struct s_heap *hptr) {$/;" f +free_imacro_from_iblk ./place/place_macro.c /^static void free_imacro_from_iblk(void) {$/;" f file: +free_int_list ../../libarchfpga/util.c /^void free_int_list(t_linked_int ** int_list_head_ptr) {$/;" f +free_io_constraint ./timing/read_sdc.c /^static void free_io_constraint(t_io *& io_array, int num_ios) {$/;" f file: +free_ivec_matrix ../../libarchfpga/util.c /^void free_ivec_matrix(struct s_ivec **ivec_matrix, int nrmin, int nrmax,$/;" f +free_ivec_matrix3 ../../libarchfpga/util.c /^void free_ivec_matrix3(struct s_ivec ***ivec_matrix3, int nrmin, int nrmax,$/;" f +free_ivec_vector ../../libarchfpga/util.c /^void free_ivec_vector(struct s_ivec *ivec_vector, int nrmin, int nrmax) {$/;" f +free_legal_placements ./place/place.c /^static void free_legal_placements() {$/;" f file: +free_legalizer_for_cluster ./pack/cluster_legality.c /^void free_legalizer_for_cluster(INP t_block* clb, boolean free_local_rr_graph) {$/;" f +free_linked_list ./base/verilog_writer.c /^pb_list *free_linked_list(pb_list *list)$/;" f +free_linked_list_conn ./base/verilog_writer.c /^conn_list *free_linked_list_conn(conn_list *list)$/;" f +free_linked_rc_edge ./timing/net_delay.c /^void free_linked_rc_edge(t_linked_rc_edge * rc_edge,$/;" f +free_linked_rt_edge ./route/route_tree_timing.c /^static void free_linked_rt_edge(t_linked_rt_edge * rt_edge) {$/;" f file: +free_list_of_pack_patterns ./pack/prepack.c /^void free_list_of_pack_patterns(INP t_pack_patterns *list_of_pack_patterns, INP int num_packing_patterns) {$/;" f +free_llist ../../libarchfpga/linkedlist.c /^void free_llist(t_llist* head) {$/;" f +free_logical_blocks ./base/read_netlist.c /^void free_logical_blocks(void) {$/;" f +free_logical_nets ./base/read_netlist.c /^void free_logical_nets(void) {$/;" f +free_lookups_and_criticalities ./place/timing_place.c /^void free_lookups_and_criticalities(float ***net_delay, t_slack * slacks) {$/;" f +free_matrix ../../libarchfpga/util.c /^void free_matrix(void *vptr, int nrmin, int nrmax, int ncmin, size_t elsize) {$/;" f +free_matrix3 ../../libarchfpga/util.c /^void free_matrix3(void *vptr, int nrmin, int nrmax, int ncmin, int ncmax,$/;" f +free_matrix4 ../../libarchfpga/util.c /^void free_matrix4(void *vptr, int nrmin, int nrmax, int ncmin, int ncmax,$/;" f +free_muxes_llist ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void free_muxes_llist(t_llist* muxes_head) {$/;" f +free_net_delay ./timing/net_delay.c /^void free_net_delay(float **net_delay,$/;" f +free_one_cb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void free_one_cb_info(t_cb* cur_cb) {$/;" f +free_one_mem_bank_info ./fpga_x2p/base/fpga_x2p_utils.c /^void free_one_mem_bank_info(t_mem_bank_info* mem_bank_info) {$/;" f +free_one_sb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void free_one_sb_info(t_sb* cur_sb) {$/;" f +free_one_scff_info ./fpga_x2p/base/fpga_x2p_utils.c /^void free_one_scff_info(t_scff_info* scff_info) {$/;" f +free_one_spice_model_grid_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void free_one_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) {$/;" f +free_one_spice_model_routing_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void free_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) {$/;" f +free_one_standalone_sram_info ./fpga_x2p/base/fpga_x2p_utils.c /^void free_one_standalone_sram_info(t_standalone_sram_info* standalone_sram_info) {$/;" f +free_options ./base/vpr_api.c /^void free_options(t_options *options) {$/;" f +free_output_file_names ./base/ReadOptions.c /^void free_output_file_names() {$/;" f +free_override_constraint ./timing/read_sdc.c /^void free_override_constraint(t_override_constraint *& constraint_array, int num_constraints) {$/;" f +free_pack_pattern ./pack/prepack.c /^static void free_pack_pattern(INOUTP t_pack_pattern_block *pattern_block, INOUTP t_pack_pattern_block **pattern_block_list) {$/;" f file: +free_parse ./base/read_blif.c /^static void free_parse(void) {$/;" f file: +free_pb ./util/vpr_utils.c /^void free_pb(t_pb *pb) {$/;" f +free_pb_data ./base/place_and_route.c /^void free_pb_data(t_pb *pb) {$/;" f +free_pb_graph ./pack/pb_type_graph.c /^static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node) {$/;" f file: +free_pb_stats ./util/vpr_utils.c /^void free_pb_stats(t_pb *pb) {$/;" f +free_pb_stats_recursive ./pack/cluster.c /^static void free_pb_stats_recursive(t_pb *pb) {$/;" f file: +free_pb_type ./base/vpr_api.c /^static void free_pb_type(t_pb_type *pb_type) {$/;" f file: +free_place_lookup_structs ./place/timing_place_lookup.c /^void free_place_lookup_structs(void) {$/;" f +free_placement_macros_structs ./place/place_macro.c /^void free_placement_macros_structs(void) {$/;" f +free_placement_structs ./place/place.c /^static void free_placement_structs($/;" f file: +free_port_pin_from_blk_pin ./util/vpr_utils.c /^void free_port_pin_from_blk_pin(void) {$/;" f +free_rc_edge_free_list ./timing/net_delay.c /^void free_rc_edge_free_list(t_linked_rc_edge * rc_edge_free_list) {$/;" f +free_rc_node ./timing/net_delay.c /^void free_rc_node(t_rc_node * rc_node,$/;" f +free_rc_node_free_list ./timing/net_delay.c /^void free_rc_node_free_list(t_rc_node * rc_node_free_list) {$/;" f +free_rc_tree ./timing/net_delay.c /^void free_rc_tree(t_rc_node * rc_root,$/;" f +free_route_structs ./route/route_common.c /^void free_route_structs() {$/;" f +free_route_tree ./route/route_tree_timing.c /^void free_route_tree(t_rt_node * rt_node) {$/;" f +free_route_tree_timing_structs ./route/route_tree_timing.c /^void free_route_tree_timing_structs(void) {$/;" f +free_routing_structs ./place/timing_place_lookup.c /^static void free_routing_structs(struct s_router_opts router_opts,$/;" f file: +free_rr_graph ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph(t_rr_graph* local_rr_graph) {$/;" f +free_rr_graph ./route/rr_graph.c /^void free_rr_graph(void) {$/;" f +free_rr_graph_heap_data ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph_heap_data(t_rr_graph* local_rr_graph,$/;" f +free_rr_graph_route_structs ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph_route_structs(t_rr_graph* local_rr_graph) { \/* [0..num_rr_nodes-1] *\/$/;" f +free_rr_graph_rr_nodes ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph_rr_nodes(t_rr_graph* local_rr_graph) {$/;" f +free_rr_graph_switch_inf ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph_switch_inf(INOUTP t_rr_graph* local_rr_graph) {$/;" f +free_rr_graph_trace_data ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph_trace_data(t_rr_graph* local_rr_graph,$/;" f +free_rr_graph_traceback ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void free_rr_graph_traceback(t_rr_graph* local_rr_graph, $/;" f +free_rr_node_indices ./route/rr_graph2.c /^void free_rr_node_indices(INP t_ivec *** L_rr_node_indices) {$/;" f +free_rr_node_route_structs ./route/route_common.c /^void free_rr_node_route_structs(void) {$/;" f +free_rt_node ./route/route_tree_timing.c /^static void free_rt_node(t_rt_node * rt_node) {$/;" f file: +free_saved_routing ./route/route_common.c /^void free_saved_routing(struct s_trace **best_routing,$/;" f +free_sb_info_array ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void free_sb_info_array(t_sb*** LL_sb_info, int LL_nx, int LL_ny) {$/;" f +free_sblock_pattern_lookup ./route/rr_graph2.c /^void free_sblock_pattern_lookup(INOUTP short *****sblock_pattern) {$/;" f +free_sdc_related_structs ./timing/read_sdc.c /^void free_sdc_related_structs(void) {$/;" f +free_seg_details ./route/rr_graph2.c /^void free_seg_details(t_seg_details * seg_details, int nodes_per_chan) {$/;" f +free_spice_model_grid_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void free_spice_model_grid_index_low_high(int num_spice_models, $/;" f +free_spice_model_routing_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void free_spice_model_routing_index_low_high(int num_spice_models, $/;" f +free_spice_tb_llist ./fpga_x2p/spice/spice_api.c /^void free_spice_tb_llist() {$/;" f file: +free_sram_orgz_info ./fpga_x2p/base/fpga_x2p_utils.c /^void free_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +free_switch_block_conn ./route/rr_graph_sbox.c /^void free_switch_block_conn(struct s_ivec ***switch_block_conn,$/;" f +free_timing_driven_route_structs ./route/route_timing.c /^void free_timing_driven_route_structs(float *pin_criticality, int *sink_order,$/;" f +free_timing_graph ./timing/path_delay.c /^void free_timing_graph(t_slack * slacks) {$/;" f +free_timing_stats ./timing/path_delay.c /^void free_timing_stats(void) {$/;" f +free_trace_data ./route/route_common.c /^static void free_trace_data(struct s_trace *tptr) {$/;" f file: +free_trace_structs ./route/route_common.c /^void free_trace_structs(void) {$/;" f +free_traceback ./route/route_common.c /^void free_traceback(int inet) {$/;" f +free_try_swap_arrays ./place/place.c /^static void free_try_swap_arrays(void) {$/;" f file: +free_type_pin_to_track_map ./route/rr_graph.c /^static void free_type_pin_to_track_map(int***** ipin_to_track_map,$/;" f file: +free_type_track_to_ipin_map ./route/rr_graph.c /^static void free_type_track_to_ipin_map(struct s_ivec**** track_to_pin_map,$/;" f file: +free_wire_L_llist ./fpga_x2p/verilog/verilog_report_timing.c /^void free_wire_L_llist(t_llist* rr_path_cnt) {$/;" f +freq ../../libarchfpga/fpga_spice_include/spice_types.h /^ float freq; $/;" m struct:s_spice_net_info +frequency ../../libarchfpga/include/physical_types.h /^ int frequency;$/;" m struct:s_segment_inf +from_block ../../libarchfpga/include/cad_types.h /^ t_pack_pattern_block *from_block;$/;" m struct:s_pack_pattern_connections +from_clb_pin_end_index ./base/vpr_types.h /^ int from_clb_pin_end_index;$/;" m struct:s_clb_to_clb_directs +from_clb_pin_start_index ./base/vpr_types.h /^ int from_clb_pin_start_index;$/;" m struct:s_clb_to_clb_directs +from_clb_type ./base/vpr_types.h /^ t_type_descriptor *from_clb_type;$/;" m struct:s_clb_to_clb_directs +from_pin ../../libarchfpga/include/cad_types.h /^ t_pb_graph_pin *from_pin;$/;" m struct:s_pack_pattern_connections +from_pin ../../libarchfpga/include/physical_types.h /^ char *from_pin;$/;" m struct:s_direct_inf +from_port ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_port* from_port;$/;" m struct:s_spice_model_tedge +from_port_pin_number ../../libarchfpga/fpga_spice_include/spice_types.h /^ int from_port_pin_number;$/;" m struct:s_spice_model_tedge +front ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_list { t_buffer_plan_node* front; } t_buffer_plan_list;$/;" m struct:s_buffer_plan_list file: +fs ./base/place_and_route.h /^ int fs; \/* at this fs *\/$/;" m struct:s_fmap_cell +fs ./base/vpr_types.h /^ int fs;$/;" m struct:s_sb +full_stats ./base/vpr_types.h /^ boolean full_stats;$/;" m struct:s_router_opts +g_MTA_area ./power/power_sizing.c /^static double g_MTA_area;$/;" v file: +g_buffer_strength_last_searched ./power/power_cmos_tech.c /^static t_power_buffer_strength_inf * g_buffer_strength_last_searched;$/;" v file: +g_clock_arch ./base/globals.c /^t_clock_arch * g_clock_arch;$/;" v +g_mux_volt_last_searched ./power/power_cmos_tech.c /^static t_power_mux_volt_inf * g_mux_volt_last_searched;$/;" v file: +g_power_arch ./power/power.c /^t_power_arch * g_power_arch;$/;" v +g_power_by_component ./power/power_components.c /^t_power_components g_power_by_component;$/;" v +g_power_commonly_used ./power/power.c /^t_power_commonly_used * g_power_commonly_used;$/;" v +g_power_output ./power/power.c /^t_power_output * g_power_output;$/;" v +g_power_searching_nmos_leakage_info ./power/power_cmos_tech.c /^t_power_nmos_leakage_inf * g_power_searching_nmos_leakage_info;$/;" v +g_power_tech ./power/power.c /^t_power_tech * g_power_tech;$/;" v +g_sdc ./timing/read_sdc.c /^t_timing_constraints * g_sdc = NULL;$/;" v +g_solution_inf ./power/power.c /^t_solution_inf g_solution_inf;$/;" v +g_transistor_last_searched ./power/power_cmos_tech.c /^static t_transistor_inf * g_transistor_last_searched;$/;" v file: +gain ./base/vpr_types.h /^ std::map gain; \/* Attraction (inverse of cost) function *\/$/;" m struct:s_pb_stats +gate_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_gate* gate_info;$/;" m struct:s_spice_model_design_tech_info +gc ./base/graphics.c /^static GC gc, gcxor, gc_menus, current_gc;$/;" v file: +gc_menus ./base/graphics.c /^static GC gc, gcxor, gc_menus, current_gc;$/;" v file: +gcxor ./base/graphics.c /^static GC gc, gcxor, gc_menus, current_gc;$/;" v file: +gen_bitstream ./base/vpr_types.h /^ boolean gen_bitstream;$/;" m struct:s_bitstream_gen_opts +gen_spice_name_tag_pb_rec ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void gen_spice_name_tag_pb_rec(t_pb* cur_pb,$/;" f +gen_spice_name_tag_phy_pb_rec ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void gen_spice_name_tag_phy_pb_rec(t_phy_pb* cur_phy_pb,$/;" f +gen_spice_name_tags_all_pbs ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void gen_spice_name_tags_all_pbs() {$/;" f +gen_spice_name_tags_all_phy_pbs ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void gen_spice_name_tags_all_phy_pbs() {$/;" f +gen_str_spice_model_structure ./fpga_x2p/base/fpga_x2p_utils.c /^char* gen_str_spice_model_structure(enum e_spice_model_structure spice_model_structure) {$/;" f +gen_verilog_grid_one_pin_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_grid_one_pin_name(int x, int y,$/;" f +gen_verilog_one_block_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_block_instance_name(int grid_x, int grid_y, int grid_z) {$/;" f +gen_verilog_one_cb_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_cb_instance_name(t_cb* cur_cb_info) {$/;" f +gen_verilog_one_cb_module_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_cb_module_name(t_cb* cur_cb_info) {$/;" f +gen_verilog_one_grid_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_grid_instance_name(int grid_x, int grid_y) {$/;" f +gen_verilog_one_grid_module_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_grid_module_name(int grid_x, int grid_y) {$/;" f +gen_verilog_one_mux_module_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_mux_module_name(t_spice_model* spice_model, $/;" f +gen_verilog_one_pb_graph_node_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_pb_graph_node_instance_name(t_pb_graph_node* cur_pb_graph_node) {$/;" f +gen_verilog_one_pb_graph_pin_full_name_in_hierarchy ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy(t_pb_graph_pin* cur_pb_graph_pin) {$/;" f +gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_grand_parent_node ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_grand_parent_node(t_pb_graph_pin* cur_pb_graph_pin) {$/;" f +gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(t_pb_graph_pin* cur_pb_graph_pin) {$/;" f +gen_verilog_one_pb_type_pin_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_pb_type_pin_name(char* prefix, $/;" f +gen_verilog_one_phy_block_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_phy_block_instance_name(t_type_ptr cur_type_ptr, $/;" f +gen_verilog_one_routing_channel_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_routing_channel_instance_name(t_rr_type chan_type,$/;" f +gen_verilog_one_routing_channel_module_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_routing_channel_module_name(t_rr_type chan_type,$/;" f +gen_verilog_one_routing_report_timing_Lwire_dir_path ./fpga_x2p/verilog/verilog_report_timing.c /^char* gen_verilog_one_routing_report_timing_Lwire_dir_path(char* report_timing_path, $/;" f +gen_verilog_one_routing_report_timing_rpt_name ./fpga_x2p/verilog/verilog_report_timing.c /^char* gen_verilog_one_routing_report_timing_rpt_name(char* report_timing_path,$/;" f +gen_verilog_one_sb_instance_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_sb_instance_name(t_sb* cur_sb_info) {$/;" f +gen_verilog_one_sb_module_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_one_sb_module_name(t_sb* cur_sb_info) {$/;" f +gen_verilog_routing_channel_one_midout_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_routing_channel_one_midout_name(t_cb* cur_cb_info,$/;" f +gen_verilog_routing_channel_one_pin_name ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_routing_channel_one_pin_name(t_rr_node* chan_rr_node,$/;" f +gen_verilog_top_module_io_port_prefix ./fpga_x2p/verilog/verilog_utils.c /^char* gen_verilog_top_module_io_port_prefix(char* global_prefix, $/;" f +generate_compact_verilog_grid_module_name ./fpga_x2p/verilog/verilog_compact_netlist.c /^char* generate_compact_verilog_grid_module_name(t_type_ptr phy_block_type,$/;" f file: +generate_compact_verilog_grid_module_name_prefix ./fpga_x2p/verilog/verilog_compact_netlist.c /^char* generate_compact_verilog_grid_module_name_prefix(t_type_ptr phy_block_type,$/;" f file: +generate_frac_lut_sram_bits ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int* generate_frac_lut_sram_bits(t_phy_pb* lut_phy_pb,$/;" f +generate_lut_sram_bits ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int* generate_lut_sram_bits(int truth_table_len,$/;" f +generate_nets_sinks_prefer_sides ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^int generate_nets_sinks_prefer_sides(int n_nets, t_net* nets,$/;" f +generate_spice_basics ./fpga_x2p/spice/spice_subckt.c /^int generate_spice_basics(char* subckt_dir, t_spice spice) {$/;" f file: +generate_spice_logic_blocks ./fpga_x2p/spice/spice_pbtypes.c /^void generate_spice_logic_blocks(char* subckt_dir,$/;" f +generate_spice_luts ./fpga_x2p/spice/spice_lut.c /^void generate_spice_luts(char* subckt_dir, $/;" f +generate_spice_muxes ./fpga_x2p/spice/spice_mux.c /^void generate_spice_muxes(char* subckt_dir,$/;" f +generate_spice_nmos_pmos ./fpga_x2p/spice/spice_subckt.c /^int generate_spice_nmos_pmos(char* subckt_dir,$/;" f +generate_spice_routing_resources ./fpga_x2p/spice/spice_routing.c /^void generate_spice_routing_resources(char* subckt_dir,$/;" f +generate_spice_rram_veriloga ./fpga_x2p/spice/spice_subckt.c /^void generate_spice_rram_veriloga(char* subckt_dir, $/;" f +generate_spice_src_des_pb_graph_pin_prefix ./fpga_x2p/spice/spice_pbtypes.c /^void generate_spice_src_des_pb_graph_pin_prefix(t_pb_graph_pin* src_pb_graph_pin,$/;" f +generate_spice_subckt_powergated_tapbuf ./fpga_x2p/spice/spice_subckt.c /^void generate_spice_subckt_powergated_tapbuf(FILE* fp, $/;" f +generate_spice_subckt_tapbuf ./fpga_x2p/spice/spice_subckt.c /^void generate_spice_subckt_tapbuf(FILE* fp, $/;" f +generate_spice_subckts ./fpga_x2p/spice/spice_subckt.c /^void generate_spice_subckts(char* subckt_dir,$/;" f +generate_spice_wires ./fpga_x2p/spice/spice_subckt.c /^void generate_spice_wires(char* subckt_dir,$/;" f +generate_string_spice_model_type ./fpga_x2p/base/fpga_x2p_utils.c /^char* generate_string_spice_model_type(enum e_spice_model_type spice_model_type) {$/;" f +generate_verilog_mem_subckt_name ./fpga_x2p/verilog/verilog_utils.c /^char* generate_verilog_mem_subckt_name(t_spice_model* spice_model, $/;" f +generate_verilog_mux_subckt_name ./fpga_x2p/verilog/verilog_utils.c /^char* generate_verilog_mux_subckt_name(t_spice_model* spice_model, $/;" f +generate_verilog_src_des_pb_graph_pin_prefix ./fpga_x2p/verilog/verilog_pbtypes.c /^void generate_verilog_src_des_pb_graph_pin_prefix(t_pb_graph_pin* src_pb_graph_pin,$/;" f +generate_verilog_subckt_name ./fpga_x2p/verilog/verilog_utils.c /^char* generate_verilog_subckt_name(t_spice_model* spice_model, $/;" f +generic_compute_matrix ./place/timing_place_lookup.c /^static void generic_compute_matrix(float ***matrix_ptr, t_type_ptr source_type,$/;" f file: +getEchoEnabled ./base/ReadOptions.c /^boolean getEchoEnabled(void) {$/;" f +getEchoFileName ./base/ReadOptions.c /^char *getEchoFileName(enum e_echo_files echo_option) {$/;" f +getOutputFileName ./base/ReadOptions.c /^char *getOutputFileName(enum e_output_files ename) {$/;" f +get_array_size_of_molecule ./pack/cluster_placement.c /^int get_array_size_of_molecule(t_pack_molecule *molecule) {$/;" f +get_average_opin_delay ./route/rr_graph_indexed_data.c /^static float get_average_opin_delay(t_ivec *** L_rr_node_indices,$/;" f file: +get_bb_from_scratch ./place/place.c /^static void get_bb_from_scratch(int inet, struct s_bb *coords,$/;" f file: +get_bidir_opin_connections ./route/rr_graph2.c /^int get_bidir_opin_connections(INP int i, INP int j, INP int ipin,$/;" f +get_bidir_track_to_chan_seg ./route/rr_graph2.c /^static int get_bidir_track_to_chan_seg(INP struct s_ivec conn_tracks,$/;" f file: +get_blif_tok ./base/read_blif.c /^static void get_blif_tok(char *buffer, int doall, boolean *done,$/;" f file: +get_blk_pin_from_port_pin ./util/vpr_utils.c /^void get_blk_pin_from_port_pin(int blk_type_index, int port,int port_pin, $/;" f +get_block_center ./base/draw.c /^static void get_block_center(int bnum, float *x, float *y) {$/;" f file: +get_cblock_trans ./route/rr_graph_area.c /^static float get_cblock_trans(int *num_inputs_to_cblock, int* switches_to_cblock,$/;" f file: +get_chan_rr_node_coorindate_in_sb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void get_chan_rr_node_coorindate_in_sb_info(t_sb cur_sb_info,$/;" f +get_chan_rr_node_end_coordinate ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void get_chan_rr_node_end_coordinate(t_rr_node* chan_rr_node,$/;" f +get_chan_rr_node_ending_cb ./fpga_x2p/verilog/verilog_tcl_utils.c /^t_cb* get_chan_rr_node_ending_cb(t_rr_node* src_rr_node, $/;" f +get_chan_rr_node_ending_sb ./fpga_x2p/verilog/verilog_tcl_utils.c /^t_sb* get_chan_rr_node_ending_sb(t_rr_node* src_rr_node, $/;" f +get_chan_rr_node_start_coordinate ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void get_chan_rr_node_start_coordinate(t_rr_node* chan_rr_node,$/;" f +get_chan_rr_nodes ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^t_rr_node** get_chan_rr_nodes(int* num_chan_rr_nodes,$/;" f +get_channel_occupancy_stats ./base/stats.c /^static void get_channel_occupancy_stats(void) {$/;" f file: +get_child_pb_for_phy_pb_graph_node ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_pb* get_child_pb_for_phy_pb_graph_node(t_pb* cur_pb, int ipb, int jpb) {$/;" f +get_class_range_for_block ./util/vpr_utils.c /^void get_class_range_for_block(INP int iblk, OUTP int *class_low,$/;" f +get_critical_path_delay ./timing/path_delay.c /^float get_critical_path_delay(void) {$/;" f +get_crossing_penalty ./fpga_x2p/clb_pin_remap/post_place_timing.c /^float get_crossing_penalty(int num_sinks) {$/;" f +get_default_spice_model ./fpga_x2p/base/fpga_x2p_utils.c /^t_spice_model* get_default_spice_model(enum e_spice_model_type default_spice_model_type,$/;" f +get_delay_normalization_fac ./route/rr_graph_indexed_data.c /^static float get_delay_normalization_fac(int nodes_per_chan,$/;" f file: +get_empty_buffer_plan_list ./mrfpga/buffer_insertion.c /^static t_buffer_plan_list get_empty_buffer_plan_list( )$/;" f file: +get_entry ./power/PowerSpicedComponent.c /^PowerCallibInputs * PowerSpicedComponent::get_entry(int num_inputs) {$/;" f class:PowerSpicedComponent +get_entry_bound ./power/PowerSpicedComponent.c /^PowerCallibInputs * PowerSpicedComponent::get_entry_bound(bool lower,$/;" f class:PowerSpicedComponent +get_entry_bound ./power/PowerSpicedComponent.c /^PowerCallibSize * PowerCallibInputs::get_entry_bound(bool lower,$/;" f class:PowerCallibInputs +get_escape_char ./timing/slre.c /^static int get_escape_char(const char **re) {$/;" f file: +get_expected_lowest_cost_primitive_for_logical_block ./pack/prepack.c /^static t_pb_graph_node *get_expected_lowest_cost_primitive_for_logical_block(INP int ilogical_block) {$/;" f file: +get_expected_lowest_cost_primitive_for_logical_block_in_pb_graph_node ./pack/prepack.c /^static t_pb_graph_node *get_expected_lowest_cost_primitive_for_logical_block_in_pb_graph_node(INP int ilogical_block, INP t_pb_graph_node *curr_pb_graph_node, OUTP float *cost) {$/;" f file: +get_expected_segs_to_target ./route/route_timing.c /^static int get_expected_segs_to_target(int inode, int target_node,$/;" f file: +get_ff_output_init_val ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int get_ff_output_init_val(t_logical_block* ff_logical_block) {$/;" f +get_first_pin ./place/timing_place_lookup.c /^static int get_first_pin(enum e_pin_type pintype, t_type_ptr type) {$/;" f file: +get_fpga_x2p_global_op_clock_ports ./fpga_x2p/base/fpga_x2p_utils.c /^void get_fpga_x2p_global_op_clock_ports(t_llist* head,$/;" f +get_free_molecule_with_most_ext_inputs_for_cluster ./pack/cluster.c /^static t_pack_molecule *get_free_molecule_with_most_ext_inputs_for_cluster($/;" f file: +get_grid_block_subckt_name ./fpga_x2p/spice/spice_pbtypes.c /^char* get_grid_block_subckt_name(int x,$/;" f +get_grid_phy_block_subckt_name ./fpga_x2p/spice/spice_pbtypes.c /^char* get_grid_phy_block_subckt_name(int x, int y, int z,$/;" f +get_grid_pin_height ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int get_grid_pin_height(int grid_x, int grid_y, int pin_index) {$/;" f +get_grid_pin_side ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int get_grid_pin_side(int grid_x, int grid_y, int pin_index) {$/;" f +get_grid_side_pin_rr_nodes ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^t_rr_node** get_grid_side_pin_rr_nodes(int* num_pin_rr_nodes,$/;" f +get_grid_side_pins ./route/rr_graph_opincb.c /^void get_grid_side_pins(int grid_x, int grid_y, $/;" f file: +get_grid_testbench_one_grid_num_sim_clock_cycles ./fpga_x2p/spice/spice_grid_testbench.c /^int get_grid_testbench_one_grid_num_sim_clock_cycles(FILE* fp, $/;" f +get_hardlogic_child_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_pb* get_hardlogic_child_pb(t_pb* cur_hardlogic_pb,$/;" f +get_hash_entry ./util/hash.c /^get_hash_entry(struct s_hash **hash_table, char *name) {$/;" f +get_hash_stats ./util/hash.c /^void get_hash_stats(struct s_hash **hash_table, char *hash_table_name){$/;" f +get_heap_head ./route/route_common.c /^get_heap_head(void) {$/;" f +get_highest_gain_molecule ./pack/cluster.c /^static t_pack_molecule *get_highest_gain_molecule($/;" f file: +get_imacro_from_iblk ./place/place_macro.c /^void get_imacro_from_iblk(int * imacro, int iblk, t_pl_macro * macros, int num_macros) {$/;" f +get_init_buffer_plan ./mrfpga/buffer_insertion.c /^static t_buffer_plan get_init_buffer_plan( int inode, int num_pins, int* isink_to_inode )$/;" f file: +get_init_buffer_plan_list ./mrfpga/buffer_insertion.c /^static t_buffer_plan_list get_init_buffer_plan_list( int inode, int num_pins, int* isink_to_inode )$/;" f file: +get_int_list_length ./mrfpga/buffer_insertion.c /^static int get_int_list_length( t_linked_int* list )$/;" f file: +get_ipin_switch_index ./route/rr_graph_opincb.c /^int get_ipin_switch_index(t_rr_node* ipin) {$/;" f file: +get_keypress_input ./base/graphics.c /^static bool get_keypress_input, get_mouse_move_input;$/;" v file: +get_length_and_bends_stats ./base/stats.c /^void get_length_and_bends_stats(void) {$/;" f +get_logical_block_output_init_val ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int get_logical_block_output_init_val(t_logical_block* cur_logical_block) {$/;" f +get_logical_block_output_vpack_net_num ./fpga_x2p/base/fpga_x2p_utils.c /^void get_logical_block_output_vpack_net_num(t_logical_block* cur_logical_block,$/;" f +get_longest_segment_length ./place/timing_place_lookup.c /^static int get_longest_segment_length($/;" f file: +get_lut_child_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_pb* get_lut_child_pb(t_pb* cur_lut_pb,$/;" f +get_lut_child_phy_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_phy_pb* get_lut_child_phy_pb(t_phy_pb* cur_lut_pb,$/;" f +get_lut_logical_block_index_with_output_vpack_net_num ./fpga_x2p/base/fpga_x2p_utils.c /^int get_lut_logical_block_index_with_output_vpack_net_num(int target_vpack_net_num) {$/;" f +get_lut_logical_block_input_pin_vpack_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_block,$/;" f +get_lut_output_init_val ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int get_lut_output_init_val(t_logical_block* lut_logical_block) {$/;" f +get_mapped_lut_pb_input_pin_vpack_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void get_mapped_lut_pb_input_pin_vpack_net_num(t_pb* lut_pb,$/;" f +get_mapped_lut_phy_pb_input_pin_vpack_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void get_mapped_lut_phy_pb_input_pin_vpack_net_num(t_phy_pb* lut_phy_pb,$/;" f +get_mapped_lut_phy_pb_output_pin ./fpga_x2p/base/fpga_x2p_lut_utils.c /^t_pb_graph_pin* get_mapped_lut_phy_pb_output_pin(t_phy_pb* lut_phy_pb, $/;" f +get_max_depth_of_pb_graph_node ./pack/cluster_feasibility_filter.c /^static int get_max_depth_of_pb_graph_node(INP t_pb_graph_node *pb_graph_node) {$/;" f file: +get_max_depth_of_pb_type ./util/vpr_utils.c /^int get_max_depth_of_pb_type(t_pb_type *pb_type) {$/;" f +get_max_nets_in_pb_type ./util/vpr_utils.c /^int get_max_nets_in_pb_type(const t_pb_type *pb_type) {$/;" f +get_max_pins_per_net ./route/route_timing.c /^static int get_max_pins_per_net(void) {$/;" f file: +get_max_primitives_in_pb_type ./util/vpr_utils.c /^int get_max_primitives_in_pb_type(t_pb_type *pb_type) {$/;" f +get_mem_bank_info_reserved_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void get_mem_bank_info_reserved_blwl(t_mem_bank_info* cur_mem_bank_info,$/;" f +get_molecule_by_num_ext_inputs ./pack/cluster.c /^static t_pack_molecule *get_molecule_by_num_ext_inputs($/;" f file: +get_molecule_for_cluster ./pack/cluster.c /^static t_pack_molecule *get_molecule_for_cluster($/;" f file: +get_molecule_gain ./pack/cluster.c /^static float get_molecule_gain(t_pack_molecule *molecule, std::map &blk_gain) {$/;" f file: +get_most_critical_seed_molecule ./pack/cluster.c /^static t_pack_molecule* get_most_critical_seed_molecule(int * indexofcrit) {$/;" f file: +get_mouse_move_input ./base/graphics.c /^static bool get_keypress_input, get_mouse_move_input;$/;" v file: +get_mrfpga_switch_type ./mrfpga/mrfpga_api.c /^void get_mrfpga_switch_type(boolean is_from_sbox,$/;" f +get_mux_default_path_id ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int get_mux_default_path_id(t_spice_model* mux_spice_model,$/;" f +get_mux_full_input_size ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int get_mux_full_input_size(t_spice_model* mux_spice_model,$/;" f +get_net_corresponding_to_pb_graph_pin ./pack/cluster.c /^static int get_net_corresponding_to_pb_graph_pin(t_pb *cur_pb,$/;" f file: +get_net_cost ./place/place.c /^static float get_net_cost(int inet, struct s_bb *bbptr) {$/;" f file: +get_net_wirelength_estimate ./place/place.c /^static double get_net_wirelength_estimate(int inet, struct s_bb *bbptr) {$/;" f file: +get_next_hash ./util/hash.c /^get_next_hash(struct s_hash **hash_table, struct s_hash_iterator *hash_iterator) {$/;" f +get_next_primitive_list ./pack/cluster_placement.c /^boolean get_next_primitive_list($/;" f +get_non_updateable_bb ./place/place.c /^static void get_non_updateable_bb(int inet, struct s_bb *bb_coord_new) {$/;" f file: +get_num_bends_and_length ./base/stats.c /^void get_num_bends_and_length(int inet, int *bends_ptr, int *len_ptr,$/;" f +get_num_conn ./base/check_netlist.c /^static int get_num_conn(int bnum) {$/;" f file: +get_opin_direct_connecions ./route/rr_graph.c /^static int get_opin_direct_connecions(int x, int y, int opin, INOUTP t_linked_edge ** edge_list_ptr, INP t_ivec *** L_rr_node_indices, $/;" f file: +get_opposite_side ./fpga_x2p/base/fpga_x2p_utils.c /^int get_opposite_side(int side){$/;" f +get_opt_float_val ./fpga_x2p/shell/read_opt.c /^float get_opt_float_val(t_opt_info* opts, char* opt_name, float default_val) {$/;" f +get_opt_int_val ./fpga_x2p/shell/read_opt.c /^int get_opt_int_val(t_opt_info* opts, char* opt_name, int default_val) {$/;" f +get_opt_val ./fpga_x2p/shell/read_opt.c /^char* get_opt_val(t_opt_info* opts, char* opt_name) {$/;" f +get_pb_graph_full_name_in_hierarchy ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^char* get_pb_graph_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node) {$/;" f +get_pb_graph_node_pin_from_block_pin ./util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_block_pin(int iblock, int ipin) {$/;" f +get_pb_graph_node_pin_from_clb_net ./util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_clb_net(int inet, int ipin) {$/;" f +get_pb_graph_node_pin_from_model_port_pin ./util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(t_model_ports *model_port, int model_pin, t_pb_graph_node *pb_graph_node) {$/;" f +get_pb_graph_node_pin_from_vpack_net ./util/vpr_utils.c /^t_pb_graph_pin* get_pb_graph_node_pin_from_vpack_net(int inet, int ipin) {$/;" f +get_pb_graph_node_wired_lut_logical_block_index ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int get_pb_graph_node_wired_lut_logical_block_index(t_pb_graph_node* cur_pb_graph_node,$/;" f +get_pb_graph_pin_from_name ./pack/pb_type_graph.c /^static t_pb_graph_pin * get_pb_graph_pin_from_name(INP const char * port_name,$/;" f file: +get_pb_graph_pin_lut_frac_level ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int get_pb_graph_pin_lut_frac_level(t_pb_graph_pin* out_pb_graph_pin) {$/;" f +get_pb_graph_pin_lut_output_mask ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int get_pb_graph_pin_lut_output_mask(t_pb_graph_pin* out_pb_graph_pin) {$/;" f +get_phy_child_pb_for_phy_pb_graph_node ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_phy_pb* get_phy_child_pb_for_phy_pb_graph_node(t_phy_pb* cur_phy_pb, $/;" f +get_port_pin_from_blk_pin ./util/vpr_utils.c /^void get_port_pin_from_blk_pin(int blk_type_index, int blk_pin, int * port,$/;" f +get_routing_seg_sdc_tmax ./fpga_x2p/verilog/verilog_sdc.c /^float get_routing_seg_sdc_tmax (t_segment_inf* cur_seg) {$/;" f +get_rr_cong_cost ./route/route_common.c /^float get_rr_cong_cost(int inode) {$/;" f +get_rr_graph_heap_head ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^t_heap * get_rr_graph_heap_head(t_rr_graph* local_rr_graph) {$/;" f +get_rr_graph_net_index_with_vpack_net ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^int get_rr_graph_net_index_with_vpack_net(t_rr_graph* local_rr_graph,$/;" f +get_rr_graph_net_vpack_net_index ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^int get_rr_graph_net_vpack_net_index(t_rr_graph* local_rr_graph,$/;" f +get_rr_graph_rr_cong_cost ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^float get_rr_graph_rr_cong_cost(t_rr_graph* local_rr_graph,$/;" f +get_rr_graph_rr_node_pack_intrinsic_cost ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^float get_rr_graph_rr_node_pack_intrinsic_cost(t_rr_graph* local_rr_graph,$/;" f +get_rr_graph_seg_start ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^int get_rr_graph_seg_start(INP t_seg_details * seg_details, INP int itrack,$/;" f +get_rr_node_index ./route/rr_graph2.c /^int get_rr_node_index(int x, int y, t_rr_type rr_type, int ptc,$/;" f +get_rr_node_index_in_cb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int get_rr_node_index_in_cb_info(t_rr_node* cur_rr_node,$/;" f +get_rr_node_index_in_sb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int get_rr_node_index_in_sb_info(t_rr_node* cur_rr_node,$/;" f +get_rr_node_net_density ./fpga_x2p/base/fpga_x2p_utils.c /^float get_rr_node_net_density(t_rr_node node) {$/;" f +get_rr_node_net_init_value ./fpga_x2p/base/fpga_x2p_utils.c /^int get_rr_node_net_init_value(t_rr_node node) {$/;" f +get_rr_node_net_probability ./fpga_x2p/base/fpga_x2p_utils.c /^float get_rr_node_net_probability(t_rr_node node) {$/;" f +get_rr_node_side_and_index_in_cb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void get_rr_node_side_and_index_in_cb_info(t_rr_node* cur_rr_node,$/;" f +get_rr_node_side_and_index_in_sb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void get_rr_node_side_and_index_in_sb_info(t_rr_node* cur_rr_node,$/;" f +get_rr_node_wire_length ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^int get_rr_node_wire_length(t_rr_node* src_rr_node) {$/;" f +get_rr_pin_draw_coords ./base/draw.c /^static void get_rr_pin_draw_coords(int inode, int iside, int ioff, float *xcen,$/;" f file: +get_sdc_tok ./timing/read_sdc.c /^static boolean get_sdc_tok(char * buf) {$/;" f file: +get_seed_logical_molecule_with_most_ext_inputs ./pack/cluster.c /^static t_pack_molecule* get_seed_logical_molecule_with_most_ext_inputs($/;" f file: +get_seg_end ./route/rr_graph2.c /^int get_seg_end(INP t_seg_details * seg_details, INP int itrack, INP int istart,$/;" f +get_seg_start ./route/rr_graph2.c /^int get_seg_start(INP t_seg_details * seg_details, INP int itrack,$/;" f +get_seg_track_counts ./route/rr_graph2.c /^get_seg_track_counts(INP int num_sets, INP int num_seg_types,$/;" f file: +get_segment_usage_stats ./route/segment_stats.c /^void get_segment_usage_stats(int num_segment, t_segment_inf * segment_inf) {$/;" f +get_serial_num ./route/route_common.c /^void get_serial_num(void) {$/;" f +get_simple_switch_block_track ./route/rr_graph_sbox.c /^int get_simple_switch_block_track(INP enum e_side from_side,$/;" f +get_simulation_time ./fpga_x2p/verilog/verilog_autocheck_top_testbench.c /^int get_simulation_time(int num_prog_clock_cycles,$/;" f file: +get_simulation_time ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^int get_simulation_time(int num_prog_clock_cycles,$/;" f file: +get_spice_model_delay_info_ports ./fpga_x2p/base/fpga_x2p_timing_utils.c /^t_spice_model_port** get_spice_model_delay_info_ports(t_spice_model* cur_spice_model, $/;" f +get_spice_model_num_tedges_per_pin ./fpga_x2p/base/fpga_x2p_timing_utils.c /^int get_spice_model_num_tedges_per_pin(t_spice_model* cur_spice_model,$/;" f +get_sram_orgz_info_mem_model ./fpga_x2p/base/fpga_x2p_utils.c /^void get_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +get_sram_orgz_info_num_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void get_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +get_sram_orgz_info_num_mem_bit ./fpga_x2p/base/fpga_x2p_utils.c /^int get_sram_orgz_info_num_mem_bit(t_sram_orgz_info* cur_sram_orgz_info) {$/;" f +get_sram_orgz_info_reserved_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void get_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +get_start_end_points_one_macro ./place/place_macro.c /^void get_start_end_points_one_macro(t_pl_macro pl_macro,$/;" f +get_std_dev ./place/place.c /^static double get_std_dev(int n, double sum_x_squared, double av_x) {$/;" f file: +get_switch_info ./pack/pack.c /^float get_switch_info(short switch_index, float &Tdel_switch, float &R_switch, float &Cout_switch) {$/;" f +get_switch_sdc_tmax ./fpga_x2p/verilog/verilog_sdc.c /^float get_switch_sdc_tmax (t_switch_inf* cur_switch_inf) {$/;" f +get_switch_type ./route/rr_graph2.c /^static void get_switch_type(boolean is_from_sbox, boolean is_to_sbox,$/;" f file: +get_timing_driven_expected_cost ./route/route_timing.c /^static float get_timing_driven_expected_cost(int inode, int target_node,$/;" f file: +get_tnode_block_and_output_net ./timing/path_delay.c /^void get_tnode_block_and_output_net(int inode, int *iblk_ptr, int *inet_ptr) {$/;" f +get_tnode_index ./timing/path_delay.c /^static inline int get_tnode_index(t_tnode * node) {$/;" f file: +get_top_of_heap_index ./util/heapsort.c /^static int get_top_of_heap_index(int *heap, float *sort_values, int heap_tail,$/;" f file: +get_track_num ./base/draw.c /^static int get_track_num(int inode, int **chanx_track, int **chany_track) {$/;" f file: +get_track_to_ipins ./route/rr_graph2.c /^int get_track_to_ipins(int seg, int chan, int track,$/;" f +get_track_to_tracks ./route/rr_graph2.c /^int get_track_to_tracks(INP int from_chan, INP int from_seg, INP int from_track,$/;" f +get_unidir_opin_connections ./route/rr_graph2.c /^int get_unidir_opin_connections(INP int chan, INP int seg, INP int Fc,$/;" f +get_unidir_track_to_chan_seg ./route/rr_graph2.c /^static int get_unidir_track_to_chan_seg(INP boolean is_end_sb,$/;" f file: +get_unused_spice_model_port_tedge ./fpga_x2p/base/fpga_x2p_timing_utils.c /^t_spice_model_tedge* get_unused_spice_model_port_tedge(t_spice_model_port* cur_port,$/;" f +get_verilog_modelsim_simulation_time_period ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^float get_verilog_modelsim_simulation_time_period(float time_unit,$/;" f file: +get_wire_L_counter_in_llist ./fpga_x2p/verilog/verilog_report_timing.c /^t_llist* get_wire_L_counter_in_llist(t_llist* rr_path_cnt, $/;" f +get_wired_lut_net_name ./fpga_x2p/base/fpga_x2p_lut_utils.c /^int get_wired_lut_net_name(t_pb_graph_node* lut_pb_graph_node,$/;" f +get_wired_lut_truth_table ./fpga_x2p/base/fpga_x2p_lut_utils.c /^char** get_wired_lut_truth_table() {$/;" f +getcolor ./base/graphics.c /^int getcolor (void) { return 0; }$/;" f +getcolor ./base/graphics.c /^int getcolor() {$/;" f +gfpga_postfix ./fpga_x2p/verilog/verilog_formal_random_top_testbench.c /^static char* gfpga_postfix = "_gfpga";$/;" v file: +gio_inout_prefix ./fpga_x2p/base/fpga_x2p_globals.c /^char* gio_inout_prefix = "gfpga_pad_";$/;" v +gl_state ./base/graphics.c /^static t_gl_state gl_state = {false, SCREEN, 0};$/;" v file: +global_clocks ./base/ReadOptions.h /^ boolean global_clocks;$/;" m struct:s_options +global_clocks ./base/vpr_types.h /^ boolean global_clocks;$/;" m struct:s_packer_opts +global_ports_head ./fpga_x2p/base/fpga_x2p_globals.c /^t_llist* global_ports_head = NULL;$/;" v +global_route_switch ./base/vpr_types.h /^ short global_route_switch;$/;" m struct:s_det_routing_arch +gr_automode ./base/draw.c /^static int gr_automode; \/* Need user input after: 0: each t, *$/;" v file: +grid ./base/globals.c /^struct s_grid_tile **grid = NULL; \/* [0..(nx+1)][0..(ny+1)] Physical block list *\/$/;" v typeref:struct:s_grid_tile +grid ./base/globals_declare.h /^struct s_grid_tile **grid;$/;" v typeref:struct:s_grid_tile +grid_backup ./place/timing_place_lookup.c /^static struct s_grid_tile **grid_backup;$/;" v typeref:struct:s_grid_tile file: +grid_conf_bits_lsb ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** grid_conf_bits_lsb;$/;" m struct:s_sram_orgz_info +grid_conf_bits_msb ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** grid_conf_bits_msb;$/;" m struct:s_sram_orgz_info +grid_index_high ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** grid_index_high;$/;" m struct:s_spice_model +grid_index_low ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** grid_index_low;$/;" m struct:s_spice_model +grid_loc_def ../../libarchfpga/include/physical_types.h /^ struct s_grid_loc_def *grid_loc_def; \/* [0..num_def-1] *\/$/;" m struct:s_type_descriptor typeref:struct:s_type_descriptor::s_grid_loc_def +grid_loc_type ../../libarchfpga/include/physical_types.h /^ enum e_grid_loc_type grid_loc_type;$/;" m struct:s_grid_loc_def typeref:enum:s_grid_loc_def::e_grid_loc_type +grid_logic_tile_area ../../libarchfpga/include/physical_types.h /^ float grid_logic_tile_area;$/;" m struct:s_arch +grid_logic_tile_area ./base/globals.c /^float grid_logic_tile_area = 0;$/;" v +grid_nx ../../libarchfpga/fpga_spice_include/spice_types.h /^ int grid_nx; \/* grid size *\/ $/;" m struct:s_sram_orgz_info +grid_ny ../../libarchfpga/fpga_spice_include/spice_types.h /^ int grid_ny;$/;" m struct:s_sram_orgz_info +grid_reserved_conf_bits ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** grid_reserved_conf_bits;$/;" m struct:s_sram_orgz_info +grid_spice_file_name_prefix ./fpga_x2p/spice/spice_globals.c /^char* grid_spice_file_name_prefix = "grid_";$/;" v +grid_spice_subckt_file_path_head ./fpga_x2p/spice/spice_globals.c /^t_llist* grid_spice_subckt_file_path_head = NULL;$/;" v +grid_verilog_file_name_prefix ./fpga_x2p/verilog/verilog_global.c /^char* grid_verilog_file_name_prefix = "grid_";$/;" v +grid_verilog_subckt_file_path_head ./fpga_x2p/verilog/verilog_global.c /^t_llist* grid_verilog_subckt_file_path_head = NULL;$/;" v +group_num ../../pcre/SRC/internal.h /^ int group_num; \/* Number of group that was called *\/$/;" m struct:recursion_info +group_size ./base/vpr_types.h /^ int group_size;$/;" m struct:s_seg_details +group_start ./base/vpr_types.h /^ int group_start;$/;" m struct:s_seg_details +hAllObjtestDC ./base/graphics.c /^hObjtestDC, hAllObjtestDC; \/* object test *\/$/;" v file: +hBackgroundDC ./base/graphics.c /^static HDC hGraphicsDC, hForegroundDC, hBackgroundDC,$/;" v file: +hButtonsWnd ./base/graphics.c /^static HWND hMainWnd, hGraphicsWnd, hButtonsWnd, hStatusWnd;$/;" v file: +hCurrentDC ./base/graphics.c /^hCurrentDC, \/* WC : double-buffer *\/$/;" v file: +hForegroundDC ./base/graphics.c /^static HDC hGraphicsDC, hForegroundDC, hBackgroundDC,$/;" v file: +hGraphicsBrush ./base/graphics.c /^static HBRUSH hGraphicsBrush, hGrayBrush;$/;" v file: +hGraphicsDC ./base/graphics.c /^static HDC hGraphicsDC, hForegroundDC, hBackgroundDC,$/;" v file: +hGraphicsFont ./base/graphics.c /^static HFONT hGraphicsFont;$/;" v file: +hGraphicsPen ./base/graphics.c /^static HPEN hGraphicsPen;$/;" v file: +hGraphicsWnd ./base/graphics.c /^static HWND hMainWnd, hGraphicsWnd, hButtonsWnd, hStatusWnd;$/;" v file: +hGrayBrush ./base/graphics.c /^static HBRUSH hGraphicsBrush, hGrayBrush;$/;" v file: +hMainWnd ./base/graphics.c /^static HWND hMainWnd, hGraphicsWnd, hButtonsWnd, hStatusWnd;$/;" v file: +hObjtestDC ./base/graphics.c /^hObjtestDC, hAllObjtestDC; \/* object test *\/$/;" v file: +hStatusWnd ./base/graphics.c /^static HWND hMainWnd, hGraphicsWnd, hButtonsWnd, hStatusWnd;$/;" v file: +h_ptr ./util/hash.h /^ struct s_hash *h_ptr;$/;" m struct:s_hash_iterator typeref:struct:s_hash_iterator::s_hash +hack_switch_to_rram ./base/SetupVPR.c /^static void hack_switch_to_rram(struct s_det_routing_arch *det_routing_arch) {$/;" f file: +has_printhandler_pre_vpr ./base/vpr_api.c /^static boolean has_printhandler_pre_vpr = FALSE;$/;" v file: +has_valid_T_arr ./timing/path_delay.c /^static inline boolean has_valid_T_arr(int inode) {$/;" f file: +has_valid_T_req ./timing/path_delay.c /^static inline boolean has_valid_T_req(int inode) {$/;" f file: +has_valid_normalized_T_arr ./timing/path_delay.c /^boolean has_valid_normalized_T_arr(int inode) {$/;" f +hash_value ./util/hash.c /^int hash_value(char *name) {$/;" f +heap ./fpga_x2p/base/fpga_x2p_types.h /^ t_heap **heap; \/* Indexed from [1..heap_size] *\/$/;" m struct:fpga_spice_rr_graph +heap ./route/route_common.c /^static struct s_heap **heap; \/* Indexed from [1..heap_size] *\/$/;" v typeref:struct:s_heap file: +heap_ch ./fpga_x2p/base/fpga_x2p_types.h /^ t_chunk heap_ch;$/;" m struct:fpga_spice_rr_graph +heap_ch ./route/route_common.c /^static t_chunk heap_ch = {NULL, 0, NULL};$/;" v file: +heap_free_head ./fpga_x2p/base/fpga_x2p_types.h /^ t_heap *heap_free_head;$/;" m struct:fpga_spice_rr_graph +heap_free_head ./route/route_common.c /^static struct s_heap *heap_free_head = NULL;$/;" v typeref:struct:s_heap file: +heap_size ./fpga_x2p/base/fpga_x2p_types.h /^ int heap_size; \/* Number of slots in the heap array *\/$/;" m struct:fpga_spice_rr_graph +heap_size ./route/route_common.c /^static int heap_size; \/* Number of slots in the heap array *\/$/;" v file: +heap_tail ./fpga_x2p/base/fpga_x2p_types.h /^ int heap_tail; \/* Index of first unused slot in the heap array *\/$/;" m struct:fpga_spice_rr_graph +heap_tail ./route/route_common.c /^static int heap_tail; \/* Index of first unused slot in the heap array *\/$/;" v file: +heapsort ./util/heapsort.c /^void heapsort(int *sort_index, float *sort_values, int nelem, int start_index) {$/;" f +height ../../libarchfpga/include/physical_types.h /^ int height;$/;" m struct:s_type_descriptor +height ./base/graphics.c /^ int height; $/;" m struct:__anon4 file: +help_opts ./fpga_x2p/shell/cmd_help.h /^t_opt_info help_opts[] = {$/;" v +highlight_blocks ./base/draw.c /^static void highlight_blocks(float x, float y) {$/;" f file: +highlight_crit_path ./base/draw.c /^static void highlight_crit_path(void (*drawscreen_ptr)(void)) {$/;" f file: +highlight_nets ./base/draw.c /^static void highlight_nets(char *message) {$/;" f file: +highlight_rr_nodes ./base/draw.c /^static void highlight_rr_nodes(float x, float y) {$/;" f file: +hill_climbing_flag ./base/ReadOptions.h /^ boolean hill_climbing_flag;$/;" m struct:s_options +hill_climbing_flag ./base/vpr_types.h /^ boolean hill_climbing_flag;$/;" m struct:s_packer_opts +hillgain ./base/vpr_types.h /^ std::map hillgain;$/;" m struct:s_pb_stats +hwnd ./base/graphics.c /^ HWND hwnd;$/;" m struct:__anon4 file: +i ./util/hash.h /^ int i;$/;" m struct:s_hash_iterator +i_ds ./power/power.h /^ float i_ds;$/;" m struct:s_power_nmos_leakage_pair +iblock ./base/vpr_types.h /^ int iblock;$/;" m struct:s_trace +icarus_simulator_flag ./fpga_x2p/verilog/verilog_global.c /^char* icarus_simulator_flag = "ICARUS_SIMULATOR"; \/\/ the flag to enable specific Verilog code in testbenches$/;" v +id_path ./base/vpr_types.h /^ int id_path;$/;" m struct:s_rr_node +identify_rr_node_driver_switch ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void identify_rr_node_driver_switch(t_det_routing_arch RoutingArch,$/;" f file: +idle_mode_name ../../libarchfpga/include/physical_types.h /^ char* idle_mode_name;$/;" m struct:s_pb_type +ilines ./base/read_blif.c /^static int ilines, olines, model_lines, endlines;$/;" v file: +in_dens ./power/power.h /^ float * in_dens; \/* Switching density of inputs *\/$/;" m struct:s_rr_node_power +in_flight ./base/vpr_types.h /^ t_cluster_placement_primitive *in_flight; \/* ptrs to primitives currently being considered *\/$/;" m struct:s_cluster_placement_stats +in_port_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* in_port_name;$/;" m struct:s_spice_model_delay_info +in_prob ./power/power.h /^ float * in_prob; \/* Static probability of inputs *\/$/;" m struct:s_rr_node_power +include_dir ./base/vpr_types.h /^ char* include_dir;$/;" m struct:s_spice_opts +include_icarus_simulator ./base/vpr_types.h /^ boolean include_icarus_simulator;$/;" m struct:s_syn_verilog_opts +include_netlist ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_netlist* include_netlist;$/;" m struct:s_spice_model +include_netlists ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_netlist* include_netlists; $/;" m struct:s_spice +include_netlists_include_user_defined_verilog_netlists ./fpga_x2p/verilog/verilog_include_netlists.c /^void include_netlists_include_user_defined_verilog_netlists(FILE* fp,$/;" f file: +include_signal_init ./base/vpr_types.h /^ boolean include_signal_init;$/;" m struct:s_syn_verilog_opts +include_timing ./base/vpr_types.h /^ boolean include_timing;$/;" m struct:s_syn_verilog_opts +included ../../libarchfpga/fpga_spice_include/spice_types.h /^ int included;$/;" m struct:s_spice_model_netlist +incremental_cost ../../libarchfpga/include/cad_types.h /^ float incremental_cost; \/* cost dependant on current status of packing *\/$/;" m struct:s_cluster_placement_primitive +index ../../libarchfpga/fpga_spice_include/spice_types.h /^ int index;$/;" m struct:s_conf_bit_info +index ../../libarchfpga/include/cad_types.h /^ int index; \/* array index for pattern*\/$/;" m struct:s_pack_patterns +index ../../libarchfpga/include/logic_types.h /^ int index; \/* indexing for array look-up *\/$/;" m struct:s_model_ports +index ../../libarchfpga/include/logic_types.h /^ int index;$/;" m struct:s_model +index ../../libarchfpga/include/physical_types.h /^ int index; \/* index of type descriptor in array (allows for index referencing) *\/$/;" m struct:s_type_descriptor +index ../../libarchfpga/include/physical_types.h /^ int index;$/;" m struct:s_mode +index ../../libarchfpga/include/physical_types.h /^ int index;$/;" m struct:s_port +index ./base/vpr_types.h /^ int index; \/* Index in array that this block can be found *\/$/;" m struct:s_logical_block +index ./base/vpr_types.h /^ int index;$/;" m struct:s_seg_details +index ./base/vpr_types.h /^ int index;$/;" m struct:s_trace +index ./route/route_common.h /^ int index;$/;" m struct:s_heap +index ./util/hash.h /^ int index;$/;" m struct:s_hash +index_in_top_tb ../../libarchfpga/fpga_spice_include/spice_types.h /^ int index_in_top_tb;$/;" m struct:s_conf_bit_info +infer_annotations ../../libarchfpga/include/physical_types.h /^ boolean infer_annotations;$/;" m struct:s_interconnect +infer_pattern ../../libarchfpga/include/physical_types.h /^ boolean infer_pattern; \/*If TRUE, infer pattern based on patterns connected to it*\/$/;" m struct:s_pb_graph_edge +init_and_check_one_sram_inf_orgz ./fpga_x2p/base/fpga_x2p_setup.c /^void init_and_check_one_sram_inf_orgz(t_sram_inf_orgz* cur_sram_inf_orgz,$/;" f file: +init_and_check_sram_inf ./fpga_x2p/base/fpga_x2p_setup.c /^void init_and_check_sram_inf(t_arch* arch,$/;" f file: +init_arch_mrfpga ../../libarchfpga/read_xml_mrfpga.c /^void init_arch_mrfpga(t_arch_mrfpga* arch_mrfpga) {$/;" f +init_buffer_inf ../../libarchfpga/read_xml_mrfpga.c /^void init_buffer_inf(t_buffer_inf* buffer_inf) {$/;" f +init_chan ./base/place_and_route.c /^void init_chan(int cfactor, t_chan_width_dist chan_width_dist) {$/;" f +init_chan_seg_detail_params ./route/rr_graph_swseg.c /^static int init_chan_seg_detail_params(INP char* chan_type,$/;" f file: +init_check_arch_pb_type_idle_and_phy_mode ./fpga_x2p/base/fpga_x2p_setup.c /^void init_check_arch_pb_type_idle_and_phy_mode(t_arch* Arch) {$/;" f file: +init_check_arch_spice_models ./fpga_x2p/base/fpga_x2p_setup.c /^void init_check_arch_spice_models(t_arch* arch,$/;" f +init_draw_coords ./base/draw.c /^void init_draw_coords(float width_val) {$/;" f +init_graphics ./base/graphics.c /^init_graphics (const char *window_name, int cindex) $/;" f +init_graphics ./base/graphics.c /^void init_graphics (const char *window_name, int cindex) { }$/;" f +init_grids_num_conf_bits ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info) {$/;" f +init_grids_num_iopads ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void init_grids_num_iopads() {$/;" f +init_grids_num_mode_bits ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void init_grids_num_mode_bits() {$/;" f +init_include_user_defined_netlists ./fpga_x2p/spice/spice_utils.c /^void init_include_user_defined_netlists(t_spice spice) {$/;" f +init_include_user_defined_verilog_netlists ./fpga_x2p/verilog/verilog_utils.c /^void init_include_user_defined_verilog_netlists(t_spice spice) {$/;" f +init_list_include_netlists ./fpga_x2p/spice/spice_api.c /^void init_list_include_netlists(t_spice* spice) { $/;" f file: +init_list_include_verilog_netlists ./fpga_x2p/verilog/verilog_utils.c /^void init_list_include_verilog_netlists(t_spice* spice) { $/;" f +init_llist_global_ports ./fpga_x2p/base/fpga_x2p_setup.c /^t_llist* init_llist_global_ports(t_spice* spice) {$/;" f file: +init_llist_verilog_and_spice_syntax_char ./fpga_x2p/base/fpga_x2p_setup.c /^t_llist* init_llist_verilog_and_spice_syntax_char() {$/;" f file: +init_logical_block_spice_model_temp_used ./fpga_x2p/spice/spice_utils.c /^void init_logical_block_spice_model_temp_used(t_spice_model* spice_model) {$/;" f +init_logical_block_spice_model_type_temp_used ./fpga_x2p/spice/spice_utils.c /^void init_logical_block_spice_model_type_temp_used(int num_spice_models, t_spice_model* spice_model,$/;" f +init_mem_bank_info ./fpga_x2p/base/fpga_x2p_utils.c /^void init_mem_bank_info(t_mem_bank_info* cur_mem_bank_info,$/;" f +init_memristor_inf ../../libarchfpga/read_xml_mrfpga.c /^void init_memristor_inf(t_memristor_inf* memristor_inf) {$/;" f +init_mux_arch_default ./power/power_util.c /^static void init_mux_arch_default(t_mux_arch * mux_arch, int levels,$/;" f file: +init_one_cb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void init_one_cb_info(t_cb* cur_cb) { $/;" f +init_one_grid_num_conf_bits ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void init_one_grid_num_conf_bits(int ix, int iy, $/;" f +init_one_grid_num_iopads ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void init_one_grid_num_iopads(int ix, int iy) {$/;" f +init_one_grid_num_mode_bits ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void init_one_grid_num_mode_bits(int ix, int iy) {$/;" f +init_one_rr_node_for_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void init_one_rr_node_for_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin,$/;" f +init_one_rr_node_pack_cost_for_phy_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void init_one_rr_node_pack_cost_for_phy_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin,$/;" f +init_one_sb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void init_one_sb_info(t_sb* cur_sb) { $/;" f +init_parse ./base/read_blif.c /^static void init_parse(int doall) {$/;" f file: +init_postscript ./base/graphics.c /^int init_postscript (const char *fname) $/;" f +init_postscript ./base/graphics.c /^int init_postscript (const char *fname) { $/;" f +init_reserved_syntax_char ./fpga_x2p/base/fpga_x2p_utils.c /^void init_reserved_syntax_char(t_reserved_syntax_char* cur_reserved_syntax_char,$/;" f +init_route_structs ./route/route_common.c /^void init_route_structs(int bb_factor) {$/;" f +init_route_tree_to_source ./route/route_tree_timing.c /^init_route_tree_to_source(int inet) {$/;" f +init_rr_graph ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void init_rr_graph(INOUTP t_rr_graph* local_rr_graph) {$/;" f +init_rr_nodes_is_parasitic_net ./fpga_x2p/base/fpga_x2p_utils.c /^void init_rr_nodes_is_parasitic_net(int LL_num_rr_nodes,$/;" f +init_rr_nodes_vpack_net_num_changed ./fpga_x2p/base/fpga_x2p_utils.c /^void init_rr_nodes_vpack_net_num_changed(int LL_num_rr_nodes,$/;" f +init_scff_info ./fpga_x2p/base/fpga_x2p_utils.c /^void init_scff_info(t_scff_info* cur_scff_info,$/;" f +init_shell_env ./fpga_x2p/shell/mini_shell.c /^void init_shell_env(t_shell_env* env) {$/;" f +init_spice_grid_testbench_globals ./fpga_x2p/spice/spice_grid_testbench.c /^void init_spice_grid_testbench_globals(t_spice spice) {$/;" f file: +init_spice_models_grid_tb_cnt ./fpga_x2p/base/fpga_x2p_utils.c /^void init_spice_models_grid_tb_cnt(int num_spice_models,$/;" f +init_spice_models_tb_cnt ./fpga_x2p/base/fpga_x2p_utils.c /^void init_spice_models_tb_cnt(int num_spice_models,$/;" f +init_spice_mux_arch ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void init_spice_mux_arch(t_spice_model* spice_model,$/;" f +init_spice_mux_testbench_globals ./fpga_x2p/spice/spice_mux_testbench.c /^static void init_spice_mux_testbench_globals(t_spice spice) {$/;" f file: +init_spice_net_info ./fpga_x2p/base/fpga_x2p_utils.c /^void init_spice_net_info(t_spice_net_info* spice_net_info) {$/;" f +init_spice_primitive_testbench_globals ./fpga_x2p/spice/spice_primitive_testbench.c /^void init_spice_primitive_testbench_globals(t_spice spice) {$/;" f file: +init_spice_routing_testbench_globals ./fpga_x2p/spice/spice_routing_testbench.c /^static void init_spice_routing_testbench_globals(t_spice spice) {$/;" f file: +init_sram_orgz_info ./fpga_x2p/base/fpga_x2p_utils.c /^void init_sram_orgz_info(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +init_sram_orgz_info_reserved_blwl ./fpga_x2p/base/fpga_x2p_bitstream_utils.c /^void init_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +init_standalone_sram_info ./fpga_x2p/base/fpga_x2p_utils.c /^void init_standalone_sram_info(t_standalone_sram_info* cur_standalone_sram_info,$/;" f +init_t ./base/vpr_types.h /^ float init_t;$/;" m struct:s_annealing_sched +init_val ../../libarchfpga/fpga_spice_include/spice_types.h /^ int init_val;$/;" m struct:s_spice_net_info +init_val ./base/vpr_types.h /^ int init_val;$/;" m struct:s_logical_block +init_world ./base/graphics.c /^init_world (float x1, float y1, float x2, float y2) $/;" f +init_world ./base/graphics.c /^void init_world (float xl, float yt, float xr, float yb) { }$/;" f +initial_placement ./place/place.c /^static void initial_placement(enum e_pad_loc_type pad_loc_type,$/;" f file: +initial_placement_blocks ./place/place.c /^static void initial_placement_blocks(int * free_locations, enum e_pad_loc_type pad_loc_type) {$/;" f file: +initial_placement_pl_macros ./place/place.c /^static void initial_placement_pl_macros(int macros_max_num_tries, int * free_locations) {$/;" f file: +initial_pres_fac ./base/ReadOptions.h /^ float initial_pres_fac;$/;" m struct:s_options +initial_pres_fac ./base/vpr_types.h /^ float initial_pres_fac;$/;" m struct:s_router_opts +initial_simulation_flag ./fpga_x2p/verilog/verilog_global.c /^char* initial_simulation_flag = "INITIAL_SIMULATION"; \/\/ the flag to enable initial functional verification$/;" v +initialized ./base/graphics.c /^ bool initialized;$/;" m struct:__anon5 file: +inner_loop_recompute_divider ./base/ReadOptions.h /^ int inner_loop_recompute_divider;$/;" m struct:s_options +inner_loop_recompute_divider ./base/vpr_types.h /^ int inner_loop_recompute_divider;$/;" m struct:s_placer_opts +inner_num ./base/vpr_types.h /^ float inner_num;$/;" m struct:s_annealing_sched +inode ./route/route_tree_timing.h /^ int inode;$/;" m struct:s_rt_node +inode ./timing/net_delay_types.h /^ int inode;$/;" m struct:s_rc_node +inode_head ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" m struct:s_buffer_plan file: +inport_link_pin ../../libarchfpga/include/cad_types.h /^ int inport_link_pin; \/* applicable pin of chain input port *\/$/;" m struct:s_model_chain_pattern +input_buffer ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_buffer* input_buffer;$/;" m struct:s_spice_model +input_edges ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_edge** input_edges; \/* [0..num_input_edges] *\/$/;" m struct:s_pb_graph_pin typeref:struct:s_pb_graph_pin::s_pb_graph_edge +input_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int* input_level; \/* [0...num_input] *\/$/;" m struct:s_spice_mux_arch +input_link_port ../../libarchfpga/include/cad_types.h /^ t_model_ports *input_link_port; \/* pointer to port of chain input *\/$/;" m struct:s_model_chain_pattern +input_net_tnodes ./base/vpr_types.h /^ struct s_tnode ***input_net_tnodes; \/* [0..num_input_ports-1][0..num_pins -1] correspnding input net tnode *\/$/;" m struct:s_logical_block typeref:struct:s_logical_block::s_tnode +input_nets ./base/vpr_types.h /^ int **input_nets; \/* [0..num_input_ports-1][0..num_port_pins-1] List of input nets connected to this logical_block. *\/$/;" m struct:s_logical_block +input_offset ../../libarchfpga/fpga_spice_include/spice_types.h /^ int* input_offset; \/* [0...num_input] *\/ $/;" m struct:s_spice_mux_arch +input_pin_class_size ../../libarchfpga/include/physical_types.h /^ int *input_pin_class_size; \/* Stores the number of pins that belong to a particular input pin class *\/$/;" m struct:s_pb_graph_node +input_pins ../../libarchfpga/include/physical_types.h /^ char * input_pins;$/;" m struct:s_pin_to_pin_annotation +input_pins ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_pin *** input_pins; \/\/ [0..num_input_ports-1][0..num_pins_per_port-1]$/;" m struct:s_interconnect_pins typeref:struct:s_interconnect_pins::s_pb_graph_pin +input_pins ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin **input_pins; \/* [0..num_input_ports-1] [0..num_port_pins-1]*\/$/;" m struct:s_pb_graph_node +input_pins ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin **input_pins;$/;" m struct:s_pb_graph_edge +input_pins_used ./base/vpr_types.h /^ int **input_pins_used; \/* [0..pb_graph_node->num_pin_classes-1][0..pin_class_size] number of input pins of this class that are used *\/$/;" m struct:s_pb_stats +input_ports_eq_auto_detect ../../libarchfpga/include/physical_types.h /^ boolean input_ports_eq_auto_detect;$/;" m struct:s_type_descriptor +input_slew_fall_time ../../libarchfpga/fpga_spice_include/spice_types.h /^ float input_slew_fall_time; $/;" m struct:s_spice_stimulate_params +input_slew_fall_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_accuracy_type input_slew_fall_type;$/;" m struct:s_spice_stimulate_params typeref:enum:s_spice_stimulate_params::e_spice_accuracy_type +input_slew_rise_time ../../libarchfpga/fpga_spice_include/spice_types.h /^ float input_slew_rise_time; $/;" m struct:s_spice_stimulate_params +input_slew_rise_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_accuracy_type input_slew_rise_type;$/;" m struct:s_spice_stimulate_params typeref:enum:s_spice_stimulate_params::e_spice_accuracy_type +input_string ../../libarchfpga/include/physical_types.h /^ char *input_string;$/;" m struct:s_interconnect +input_thres_pct_fall ../../libarchfpga/fpga_spice_include/spice_types.h /^ float input_thres_pct_fall;$/;" m struct:s_spice_meas_params +input_thres_pct_rise ../../libarchfpga/fpga_spice_include/spice_types.h /^ float input_thres_pct_rise;$/;" m struct:s_spice_meas_params +inputs ../../libarchfpga/include/logic_types.h /^ t_model_ports *inputs; \/* linked list of input\/clock ports *\/$/;" m struct:s_model +inputs_per_cluster ./base/ReadOptions.h /^ int inputs_per_cluster;$/;" m struct:s_options +insert_buffer ./mrfpga/buffer_insertion.c /^static t_buffer_plan_list insert_buffer( t_buffer_plan_list list, int inode, float C, float R, float Tdel, int num_pins )$/;" f file: +insert_buffer_plan_to_list ./mrfpga/buffer_insertion.c /^static t_buffer_plan_list insert_buffer_plan_to_list( t_buffer_plan plan, t_buffer_plan_list list ) {$/;" f file: +insert_in_edge_list ./route/rr_graph_util.c /^insert_in_edge_list(INP t_linked_edge * head, INP int edge, INP short iswitch) {$/;" f +insert_in_hash_table ./util/hash.c /^insert_in_hash_table(struct s_hash **hash_table, char *name,$/;" f +insert_in_int_list ../../libarchfpga/util.c /^insert_in_int_list(t_linked_int * head, int data,$/;" f +insert_in_int_list2 ./mrfpga/mrfpga_util.c /^t_linked_int* insert_in_int_list2 (t_linked_int *head, int data )$/;" f +insert_in_vptr_list ../../libarchfpga/util.c /^insert_in_vptr_list(struct s_linked_vptr *head, void *vptr_to_add) {$/;" f +insert_llist_node ../../libarchfpga/linkedlist.c /^t_llist* insert_llist_node(t_llist* cur) {$/;" f +insert_llist_node_before_head ../../libarchfpga/linkedlist.c /^t_llist* insert_llist_node_before_head(t_llist* old_head) {$/;" f +insert_node_to_int_list ../../libarchfpga/util.c /^insert_node_to_int_list(struct s_linked_int *head, int int_to_add) {$/;" f +insert_switch_to_buffer_list ./mrfpga/buffer_insertion.c /^static void insert_switch_to_buffer_list( t_buffer_plan_list list, struct s_switch_inf switch_inf_local)$/;" f file: +insert_switch_to_buffer_plan ./mrfpga/buffer_insertion.c /^static t_buffer_plan insert_switch_to_buffer_plan( t_buffer_plan plan, struct s_switch_inf switch_inf_local)$/;" f file: +insert_to_linked_list ./base/verilog_writer.c /^pb_list *insert_to_linked_list(t_pb *pb_new , pb_list *list)$/;" f +insert_to_linked_list_conn ./base/verilog_writer.c /^conn_list *insert_to_linked_list_conn(t_pb *driver_new , t_pb *load_new , t_pb_graph_pin *driver_pin_ , t_pb_graph_pin *load_pin_ , float path_delay , conn_list *list)$/;" f +insert_wire_to_buffer_list ./mrfpga/buffer_insertion.c /^static void insert_wire_to_buffer_list( t_buffer_plan_list list, float C,float R )$/;" f file: +insert_wire_to_buffer_plan ./mrfpga/buffer_insertion.c /^static t_buffer_plan insert_wire_to_buffer_plan( t_buffer_plan plan, float C, float R )$/;" f file: +instances ../../libarchfpga/include/logic_types.h /^ void *instances;$/;" m struct:s_model +instantiate_SDF_header ./base/verilog_writer.c /^void instantiate_SDF_header(FILE *SDF)$/;" f +instantiate_input_interconnect ./base/verilog_writer.c /^void instantiate_input_interconnect(FILE *verilog , FILE *SDF , char *clock_name)$/;" f +instantiate_interconnect ./base/verilog_writer.c /^void instantiate_interconnect(FILE *verilog , int block_num , t_pb *pb , FILE *SDF)$/;" f +instantiate_primitive_modules ./base/verilog_writer.c /^void instantiate_primitive_modules(FILE *fp, char *clock_name , FILE *SDF)$/;" f +instantiate_top_level_module ./base/verilog_writer.c /^void instantiate_top_level_module(FILE *verilog)$/;" f +instantiate_wires ./base/verilog_writer.c /^void instantiate_wires(FILE *verilog)$/;" f +int_2_binary_str ./power/power_util.c /^static void int_2_binary_str(char * binary_str, int value, int str_length) {$/;" f file: +inter_cluster_net_delay ./base/ReadOptions.h /^ float inter_cluster_net_delay;$/;" m struct:s_options +inter_cluster_net_delay ./base/vpr_types.h /^ float inter_cluster_net_delay;$/;" m struct:s_packer_opts +interconnect ../../libarchfpga/include/physical_types.h /^ t_interconnect * interconnect;$/;" m struct:s_interconnect_pins +interconnect ../../libarchfpga/include/physical_types.h /^ t_interconnect * interconnect;$/;" m struct:s_pb_graph_edge +interconnect ../../libarchfpga/include/physical_types.h /^ t_interconnect *interconnect;$/;" m struct:s_mode +interconnect_pins ../../libarchfpga/include/physical_types.h /^ t_interconnect_pins ** interconnect_pins; \/* [0..num_modes-1][0..num_interconnect_in_mode] *\/$/;" m struct:s_pb_graph_node +interconnect_power ../../libarchfpga/include/physical_types.h /^ t_interconnect_power * interconnect_power;$/;" m struct:s_interconnect +interconnect_printing ./base/verilog_writer.c /^void interconnect_printing(FILE *fp , conn_list *downhill)$/;" f +interconnect_type_name ./power/power_util.c /^char * interconnect_type_name(enum e_interconnect type) {$/;" f +intra_cluster_net_delay ./base/ReadOptions.h /^ float intra_cluster_net_delay;$/;" m struct:s_options +intra_cluster_net_delay ./base/vpr_types.h /^ float intra_cluster_net_delay;$/;" m struct:s_packer_opts +inv_capacity ./base/vpr_types.h /^ float inv_capacity;$/;" m struct:s_place_region +inv_length ./base/vpr_types.h /^ float inv_length;$/;" m struct:s_rr_indexed_data +inv_prefix ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* inv_prefix; $/;" m struct:s_spice_model_port +inv_spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* inv_spice_model;$/;" m struct:s_spice_model_port +inv_spice_model_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* inv_spice_model_name;$/;" m struct:s_spice_model_port +invalid ./base/vpr_types.h /^ t_cluster_placement_primitive *invalid; \/* ptrs to primitives that are invalid *\/$/;" m struct:s_cluster_placement_stats +invalidate_heap_entries ./route/route_common.c /^void invalidate_heap_entries(int sink_node, int ipin_node) {$/;" f +invalidate_rr_graph_heap_entries ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void invalidate_rr_graph_heap_entries(t_rr_graph* local_rr_graph, $/;" f +invalidate_screen ./base/graphics.c /^static void invalidate_screen(void)$/;" f file: +io_line ./base/read_blif.c /^static void io_line(int in_or_out, int doall, t_model *io_model) {$/;" f file: +io_nmos_subckt_name ./fpga_x2p/spice/spice_globals.c /^char* io_nmos_subckt_name = "vpr_io_nmos";$/;" v +io_pmos_subckt_name ./fpga_x2p/spice/spice_globals.c /^char* io_pmos_subckt_name = "vpr_io_pmos";$/;" v +io_vdd ../../libarchfpga/fpga_spice_include/spice_types.h /^ float io_vdd;$/;" m struct:s_spice_tech_lib +iopad_spice_model ./fpga_x2p/spice/spice_globals.c /^t_spice_model* iopad_spice_model = NULL;$/;" v +iopad_verilog_model ./fpga_x2p/verilog/verilog_global.c /^t_spice_model* iopad_verilog_model = NULL;$/;" v +ipin_mux_trans_size ../../libarchfpga/include/physical_types.h /^ float ipin_mux_trans_size;$/;" m struct:s_arch +ipin_mux_trans_size ./base/globals.c /^float ipin_mux_trans_size = 0;$/;" v +ipin_rr_node ./base/vpr_types.h /^ t_rr_node*** ipin_rr_node;$/;" m struct:s_cb +ipin_rr_node ./base/vpr_types.h /^ t_rr_node*** ipin_rr_node;$/;" m struct:s_sb +ipin_rr_node_grid_side ./base/vpr_types.h /^ int** ipin_rr_node_grid_side; \/* We need to record the side of a IPIN, because a IPIN may locate on more than one sides *\/$/;" m struct:s_cb +ipin_rr_node_grid_side ./base/vpr_types.h /^ int** ipin_rr_node_grid_side; \/* We need to record the side of a IPIN, because a IPIN may locate on more than one sides *\/$/;" m struct:s_sb +ipin_rr_nodes_vpack_net_num_changed ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^boolean ipin_rr_nodes_vpack_net_num_changed(int LL_num_rr_nodes,$/;" f file: +ipow ../../libarchfpga/util.c /^int ipow(int base, int exp) {$/;" f +isEchoFileEnabled ./base/ReadOptions.c /^boolean isEchoFileEnabled(enum e_echo_files echo_option) {$/;" f +isFixed ./base/vpr_types.h /^ boolean isFixed;$/;" m struct:s_block +is_Fc_frac ../../libarchfpga/include/physical_types.h /^ boolean *is_Fc_frac; \/* [0..num_pins-1] *\/$/;" m struct:s_type_descriptor +is_Fc_full_flex ../../libarchfpga/include/physical_types.h /^ boolean *is_Fc_full_flex; \/* [0..num_pins-1] *\/$/;" m struct:s_type_descriptor +is_accurate ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_accurate;$/;" m struct:s_arch_mrfpga +is_anchored ../../pcre/SRC/pcre.c /^is_anchored(register const uschar *code, int *options, unsigned int bracket_map,$/;" f file: +is_any_but ./timing/slre.c /^static int is_any_but(const unsigned char *p, int len, const char *s,$/;" f file: +is_any_of ./timing/slre.c /^static int is_any_of(const unsigned char *p, int len, const char *s, int *ofs) {$/;" f file: +is_block_optional ../../libarchfpga/include/cad_types.h /^ boolean *is_block_optional; \/* [0..num_blocks-1] is the block_id in this pattern mandatory or optional to form a molecule *\/$/;" m struct:s_pack_patterns +is_cb_exist ./fpga_x2p/base/fpga_x2p_utils.c /^boolean is_cb_exist(t_rr_type cb_type,$/;" f +is_cbox ./route/rr_graph2.c /^boolean is_cbox(INP int chan, INP int seg, INP int track,$/;" f +is_chain ../../libarchfpga/include/cad_types.h /^ boolean is_chain; \/* Does this pattern chain across logic blocks *\/$/;" m struct:s_pack_patterns +is_clock ../../libarchfpga/include/logic_types.h /^ boolean is_clock; \/* clock? *\/$/;" m struct:s_model_ports +is_clock ../../libarchfpga/include/physical_types.h /^ boolean is_clock;$/;" m struct:s_port +is_clock ./base/vpr_types.h /^ boolean is_clock;$/;" m struct:s_logical_block +is_config_enable ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_config_enable;$/;" m struct:s_spice_model_port +is_const_gen ./base/vpr_types.h /^ boolean is_const_gen;$/;" m struct:s_net +is_counted_repeat ../../pcre/SRC/pcre.c /^is_counted_repeat(const uschar *p, compile_data *cd)$/;" f file: +is_default ../../libarchfpga/fpga_spice_include/spice_types.h /^ int is_default;$/;" m struct:s_spice_model +is_des_rr_node_in_src_rr_node_edges ./route/pb_pin_eq_auto_detect.c /^boolean is_des_rr_node_in_src_rr_node_edges(t_rr_node* src_rr_node,$/;" f +is_done_callibration ./power/PowerSpicedComponent.c /^bool PowerSpicedComponent::is_done_callibration(void) {$/;" f class:PowerSpicedComponent +is_empty_heap ./route/route_common.c /^boolean is_empty_heap(void) {$/;" f +is_forced_connection ../../libarchfpga/include/physical_types.h /^ boolean is_forced_connection; \/* This output pin connects to one and only one input pin *\/$/;" m struct:s_pb_graph_pin +is_forced_connection ./pack/cluster_feasibility_filter.c /^static boolean is_forced_connection(INP t_pb_graph_pin *pb_graph_pin) {$/;" f file: +is_global ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_global;$/;" m struct:s_spice_model_port +is_global ./base/globals_declare.h /^boolean *is_global;$/;" v +is_global ./base/vpr_types.h /^ boolean is_global;$/;" m struct:s_net +is_global_pin ../../libarchfpga/include/physical_types.h /^ boolean *is_global_pin; \/* [0..num_pins-1] *\/$/;" m struct:s_type_descriptor +is_grid_coordinate_in_range ./fpga_x2p/base/fpga_x2p_utils.c /^boolean is_grid_coordinate_in_range(int x_min, $/;" f +is_in_heap ./base/vpr_types.h /^ boolean is_in_heap;$/;" m struct:s_rr_node +is_isolation ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_isolation;$/;" m struct:s_arch_mrfpga +is_isolation ./mrfpga/mrfpga_globals.c /^boolean is_isolation = FALSE;$/;" v +is_junction ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_junction;$/;" m struct:s_arch_mrfpga +is_junction ./mrfpga/mrfpga_globals.c /^boolean is_junction = FALSE;$/;" v +is_logical_blk_in_pb ./pack/cluster.c /^static boolean is_logical_blk_in_pb(int iblk, t_pb *pb) {$/;" f file: +is_mrFPGA ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_mrFPGA;$/;" m struct:s_arch_mrfpga +is_mrFPGA ./mrfpga/mrfpga_globals.c /^boolean is_mrFPGA = FALSE;$/;" v +is_net_in_cluster ./pack/cluster_legality.c /^static boolean is_net_in_cluster(INP int inet) {$/;" f file: +is_net_pi ./fpga_x2p/base/fpga_x2p_utils.c /^boolean is_net_pi(t_net* cur_net) {$/;" f +is_netlist_clock ./base/vpr_types.h /^ boolean is_netlist_clock; \/* Is this a netlist or virtual (external) clock? *\/$/;" m struct:s_clock +is_non_clock_global ../../libarchfpga/include/logic_types.h /^ boolean is_non_clock_global; \/* not a clock but is a special, global, control signal (eg global asynchronous reset, etc) *\/$/;" m struct:s_model_ports +is_non_clock_global ../../libarchfpga/include/physical_types.h /^ boolean is_non_clock_global;$/;" m struct:s_port +is_number ./timing/read_sdc.c /^static boolean is_number(char * ptr) {$/;" f file: +is_opin ./util/vpr_utils.c /^boolean is_opin(int ipin, t_type_ptr type) {$/;" f +is_opin_cblock_defined ../../libarchfpga/include/arch_types_mrfpga.h /^ int is_opin_cblock_defined;$/;" m struct:s_arch_mrfpga +is_opin_in_direct_list ./route/pb_pin_eq_auto_detect.c /^boolean is_opin_in_direct_list(t_type_ptr cur_type_descriptor,$/;" f +is_opt_set ./fpga_x2p/shell/read_opt.c /^boolean is_opt_set(t_opt_info* opts, char* opt_name, boolean default_val) {$/;" f +is_parasitic_net ./base/vpr_types.h /^ boolean is_parasitic_net;$/;" m struct:s_rr_node +is_pb_used_for_wiring ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node,$/;" f +is_pb_wired_lut ./fpga_x2p/base/fpga_x2p_lut_utils.c /^boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node,$/;" f +is_pin_open ./pack/cluster_legality.c /^boolean is_pin_open(int i) {$/;" f +is_primitive_pb_type ./fpga_x2p/base/fpga_x2p_utils.c /^boolean is_primitive_pb_type(t_pb_type* cur_pb_type) {$/;" f +is_prog ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_prog;$/;" m struct:s_spice_model_port +is_reset ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_reset;$/;" m struct:s_spice_model_port +is_rr_node_exist_opposite_side_in_sb_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^int is_rr_node_exist_opposite_side_in_sb_info(t_sb cur_sb_info,$/;" f +is_rr_node_to_be_disable_for_analysis ./fpga_x2p/verilog/verilog_sdc.c /^boolean is_rr_node_to_be_disable_for_analysis(t_rr_node* cur_rr_node) {$/;" f +is_sbox ./route/rr_graph2.c /^boolean is_sbox(INP int chan, INP int wire_seg, INP int sb_seg, INP int track,$/;" f +is_set ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean is_set;$/;" m struct:s_spice_model_port +is_show_pass_trans ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_show_pass_trans;$/;" m struct:s_arch_mrfpga +is_show_pass_trans ./mrfpga/mrfpga_globals.c /^boolean is_show_sram = FALSE, is_show_pass_trans = FALSE;$/;" v +is_show_sram ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_show_sram;$/;" m struct:s_arch_mrfpga +is_show_sram ./mrfpga/mrfpga_globals.c /^boolean is_show_sram = FALSE, is_show_pass_trans = FALSE;$/;" v +is_stack ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_stack;$/;" m struct:s_arch_mrfpga +is_stack ./mrfpga/mrfpga_globals.c /^boolean is_stack = FALSE;$/;" v +is_startline ../../pcre/SRC/pcre.c /^is_startline(const uschar *code, unsigned int bracket_map,$/;" f file: +is_swap2pins_match_prefer_side ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int is_swap2pins_match_prefer_side(int pin0_cur_side, int* pin0_prefer_side,$/;" f +is_type_pin_in_class ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int is_type_pin_in_class(t_type_ptr type,$/;" f +is_verilog_and_spice_syntax_conflict_char ./fpga_x2p/base/fpga_x2p_setup.c /^boolean is_verilog_and_spice_syntax_conflict_char(t_llist* LL_reserved_syntax_char_head, $/;" f file: +is_wire_buffer ../../libarchfpga/include/arch_types_mrfpga.h /^ boolean is_wire_buffer;$/;" m struct:s_arch_mrfpga +is_wire_buffer ./mrfpga/mrfpga_globals.c /^boolean is_wire_buffer = FALSE;$/;" v +is_wired_lut ./fpga_x2p/base/fpga_x2p_types.h /^ boolean* is_wired_lut; \/* Specify if this is a wired LUT (used as buffer) *\/$/;" m struct:fpga_spice_phy_pb +ispressed ./base/graphics.c /^ bool ispressed;$/;" m struct:__anon4 file: +iswitch ./base/vpr_types.h /^ short iswitch;$/;" m struct:s_trace +iswitch ./route/route_tree_timing.h /^ short iswitch;$/;" m struct:s_linked_rt_edge +iswitch ./route/rr_graph_util.h /^ short iswitch;$/;" m struct:s_linked_edge +iswitch ./timing/net_delay_types.h /^ short iswitch;$/;" m struct:s_linked_rc_edge +join_left_plan_list_into_whole ./mrfpga/buffer_insertion.c /^static t_buffer_plan_list join_left_plan_list_into_whole( t_buffer_plan_list left, t_buffer_plan_list* whole, int num_whole, t_buffer_plan_list current, int num_pins )$/;" f file: +keypress_ptr ./base/graphics.c /^static void (*keypress_ptr)(char entered_char);$/;" v file: +label ./fpga_x2p/shell/shell_types.h /^ char* label; $/;" m struct:s_cmd_category +label_incoming_wires ./route/rr_graph2.c /^label_incoming_wires(INP int chan_num, INP int seg_num, INP int sb_seg,$/;" f file: +label_wire_muxes ./route/rr_graph2.c /^label_wire_muxes(INP int chan_num, INP int seg_num,$/;" f file: +label_wire_muxes_for_balance ./route/rr_graph2.c /^label_wire_muxes_for_balance(INP int chan_num, INP int seg_num,$/;" f file: +lcc ../../pcre/SRC/internal.h /^ const uschar *lcc; \/* Points to lower casing table *\/$/;" m struct:compile_data +lcc ../../pcre/SRC/internal.h /^ const uschar *lcc; \/* Points to lower casing table *\/$/;" m struct:match_data +lcc_offset ../../pcre/SRC/internal.h 653;" d +leakage ../../libarchfpga/include/physical_types.h /^ float leakage;$/;" m struct:s_power_usage +leakage_default_mode ../../libarchfpga/include/physical_types.h /^ int leakage_default_mode; \/* Default mode for leakage analysis, if block has no set mode *\/$/;" m struct:s_pb_type_power +leakage_gate ./power/power.h /^ float leakage_gate;$/;" m struct:s_transistor_size_inf +leakage_pairs ./power/power.h /^ t_power_nmos_leakage_pair * leakage_pairs;$/;" m struct:s_power_nmos_leakage_inf +leakage_subthreshold ./power/power.h /^ float leakage_subthreshold;$/;" m struct:s_transistor_size_inf +least_slack ./base/vpr_types.h /^ float ** least_slack;$/;" m struct:s_timing_stats +legal_pos ./place/place.c /^static t_legal_pos **legal_pos = NULL; \/* [0..num_types-1][0..type_tsize - 1] *\/$/;" v file: +len ../../libarchfpga/include/ezxml.h /^ size_t len; \/* length of allocated memory for mmap, -1 for malloc *\/$/;" m struct:ezxml_root +len ./timing/slre.c /^ int len; \/\/ Substring length$/;" m struct:cap file: +length ../../libarchfpga/include/physical_types.h /^ int length;$/;" m struct:s_segment_inf +length ./base/vpr_types.h /^ int length;$/;" m struct:s_seg_details +level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int level;$/;" m struct:s_spice_model_wire_param +level ./power/power.h /^ int level; \/* Level in the full multilevel mux - 0 = primary inputs to mux *\/$/;" m struct:s_mux_node +level_restorer ./power/power.h /^ boolean level_restorer; \/* Whether the output of this mux is level restored *\/$/;" m struct:s_mux_node +levels ./power/power.h /^ int levels;$/;" m struct:s_mux_arch +lib_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* lib_name; $/;" m struct:s_spice_model_port +library_models ./base/vpr_types.h /^ t_model * library_models; \/* blif models in VPR *\/$/;" m struct:s_vpr_setup +limit_value ../../libarchfpga/util.c /^int limit_value(int cur, int max, const char *name) {$/;" f +line ../../libarchfpga/include/ezxml.h /^ int line;$/;" m struct:ezxml +line ../../libarchfpga/include/physical_types.h /^ int line;$/;" m struct:s_direct_inf +line_fuz ./base/draw.c /^static float line_fuz = 0.3;$/;" v file: +line_num ../../libarchfpga/include/physical_types.h /^ int line_num; \/* Interconnect is processed later, need to know what line number it messed up on to give proper error message *\/$/;" m struct:s_interconnect +line_num ../../libarchfpga/include/physical_types.h /^ int line_num; \/* used to report what line number this annotation is found in architecture file *\/$/;" m struct:s_pin_to_pin_annotation +line_types ./base/easygl_constants.h /^enum line_types {SOLID, DASHED};$/;" g +link_one_pb_graph_node_pin_to_phy_pb_graph_pin ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void link_one_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph_pin, $/;" f +link_pb_graph_node_pins_to_phy_pb_graph_pins ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void link_pb_graph_node_pins_to_phy_pb_graph_pins(t_pb_graph_node* cur_pb_graph_node, $/;" f +linked_f_pointer_ch ./fpga_x2p/base/fpga_x2p_types.h /^ t_chunk linked_f_pointer_ch;$/;" m struct:fpga_spice_rr_graph +linked_f_pointer_ch ./route/route_common.c /^static t_chunk linked_f_pointer_ch = {NULL, 0, NULL};$/;" v file: +linked_f_pointer_free_head ./fpga_x2p/base/fpga_x2p_types.h /^ t_linked_f_pointer *linked_f_pointer_free_head;$/;" m struct:fpga_spice_rr_graph +linked_f_pointer_free_head ./route/route_common.c /^static struct s_linked_f_pointer *linked_f_pointer_free_head = NULL;$/;" v typeref:struct:s_linked_f_pointer file: +list ../../libarchfpga/include/util.h /^ int *list;$/;" m struct:s_ivec +list_of_connectable_input_pin_ptrs ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_pin ***list_of_connectable_input_pin_ptrs; \/* [0..depth-1][0..num_connectable_primtive_input_pins-1] what input pins this output can connect to without exiting cluster at given depth *\/$/;" m struct:s_pb_graph_pin typeref:struct:s_pb_graph_pin::s_pb_graph_pin +load_best_buffer_list ./mrfpga/buffer_insertion.c /^void load_best_buffer_list( )$/;" f +load_chan_rr_indices ./route/rr_graph2.c /^static void load_chan_rr_indices(INP int nodes_per_chan, INP int chan_len,$/;" f file: +load_channel_occupancies ./base/stats.c /^static void load_channel_occupancies(int **chanx_occ, int **chany_occ) {$/;" f file: +load_clock_domain_and_clock_and_io_delay ./timing/path_delay.c /^static void load_clock_domain_and_clock_and_io_delay(boolean is_prepacked) {$/;" f file: +load_cluster_placement_stats_for_pb_graph_node ./pack/cluster_placement.c /^static void load_cluster_placement_stats_for_pb_graph_node($/;" f file: +load_constant_net_delay ./timing/net_delay.c /^void load_constant_net_delay(float **net_delay, float delay_value,$/;" f +load_critical_path_annotations ./pack/pb_type_graph_annotations.c /^static void load_critical_path_annotations(INP int line_num, $/;" f file: +load_criticalities ./place/timing_place.c /^void load_criticalities(t_slack * slacks, float crit_exponent) {$/;" f +load_default_models ./base/read_blif.c /^static void load_default_models(INP t_model *library_models,$/;" f file: +load_expected_remapped_net_delay ./fpga_x2p/clb_pin_remap/post_place_timing.c /^void load_expected_remapped_net_delay(float** net_delay, $/;" f +load_external_nets_and_cb ./base/read_netlist.c /^static void load_external_nets_and_cb(INP int L_num_blocks,$/;" f file: +load_font ./base/graphics.c /^load_font(int pointsize) $/;" f file: +load_internal_cb_nets ./base/read_netlist.c /^static void load_internal_cb_nets(INOUTP t_pb *top_level,$/;" f file: +load_internal_cb_rr_graph_net_nums ./base/read_netlist.c /^static void load_internal_cb_rr_graph_net_nums(INP t_rr_node * cur_rr_node,$/;" f file: +load_legal_placements ./place/place.c /^static void load_legal_placements() {$/;" f file: +load_list_of_connectable_input_pin_ptrs ./pack/cluster_feasibility_filter.c /^static void load_list_of_connectable_input_pin_ptrs($/;" f file: +load_net_delay_from_routing ./timing/net_delay.c /^void load_net_delay_from_routing(float **net_delay, struct s_net *nets,$/;" f +load_net_rr_terminals ./route/rr_graph.c /^void load_net_rr_terminals(t_ivec *** L_rr_node_indices) {$/;" f +load_new_path_R_upstream ./route/route_tree_timing.c /^static void load_new_path_R_upstream(t_rt_node * start_of_new_path_rt_node) {$/;" f file: +load_one_constant_net_delay ./timing/net_delay.c /^void load_one_constant_net_delay(float **net_delay, int inet,$/;" f +load_one_net_delay ./timing/net_delay.c /^void load_one_net_delay(float **net_delay, int inet, struct s_net* nets,$/;" f +load_one_pb_graph_pin_temp_net_num_from_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void load_one_pb_graph_pin_temp_net_num_from_pb(t_phy_pb* cur_pb,$/;" f +load_pack_pattern_annotations ./pack/pb_type_graph_annotations.c /^static void load_pack_pattern_annotations(INP int line_num, INOUTP t_pb_graph_node *pb_graph_node,$/;" f file: +load_pb ./base/verilog_writer.h /^ t_pb *load_pb;$/;" m struct:found_connectivity +load_pb_graph_node_temp_net_num_from_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void load_pb_graph_node_temp_net_num_from_pb(t_phy_pb* cur_pb) {$/;" f +load_pb_graph_pin_to_pin_annotations ./pack/pb_type_graph_annotations.c /^void load_pb_graph_pin_to_pin_annotations(INOUTP t_pb_graph_node *pb_graph_node) {$/;" f +load_perturbed_switch_pattern ./route/rr_graph.c /^static void load_perturbed_switch_pattern(INP t_type_ptr type,$/;" f file: +load_pin ./base/verilog_writer.h /^ t_pb_graph_pin *load_pin;$/;" m struct:found_connectivity +load_pin_class_by_depth ./pack/cluster_feasibility_filter.c /^static void load_pin_class_by_depth(INOUTP t_pb_graph_node *pb_graph_node,$/;" f file: +load_pin_classes_in_pb_graph_head ./pack/cluster_feasibility_filter.c /^void load_pin_classes_in_pb_graph_head(INOUTP t_pb_graph_node *pb_graph_node) {$/;" f +load_post_place_net_delay ./fpga_x2p/clb_pin_remap/post_place_timing.c /^void load_post_place_net_delay(float** net_delay,$/;" f +load_rc_tree_C ./timing/net_delay.c /^float load_rc_tree_C(t_rc_node * rc_node) {$/;" f +load_rc_tree_Ctotal ./mrfpga/cal_capacitance.c /^static float load_rc_tree_Ctotal (t_rc_node *rc_node) {$/;" f file: +load_rc_tree_T ./timing/net_delay.c /^void load_rc_tree_T(t_rc_node * rc_node, float T_arrival) {$/;" f +load_route_bb ./route/route_common.c /^static void load_route_bb(int bb_factor) {$/;" f file: +load_rr_graph_chan_rr_indices ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void load_rr_graph_chan_rr_indices(t_rr_graph* local_rr_graph,$/;" f +load_rr_indexed_data_T_values ./route/rr_graph_indexed_data.c /^static void load_rr_indexed_data_T_values(int index_start,$/;" f file: +load_rr_indexed_data_base_costs ./route/rr_graph_indexed_data.c /^static void load_rr_indexed_data_base_costs(int nodes_per_chan,$/;" f file: +load_rt_subtree_Tdel ./route/route_tree_timing.c /^static void load_rt_subtree_Tdel(t_rt_node * subtree_rt_root, float Tarrival) {$/;" f file: +load_sblock_pattern_lookup ./route/rr_graph2.c /^void load_sblock_pattern_lookup(INP int i, INP int j, INP int nodes_per_chan,$/;" f +load_simplified_device ./place/timing_place_lookup.c /^static void load_simplified_device(void) {$/;" f file: +load_timing_graph_net_delays ./timing/path_delay.c /^void load_timing_graph_net_delays(float **net_delay) {$/;" f +load_tnode ./timing/path_delay.c /^static void load_tnode(INP t_pb_graph_pin *pb_graph_pin, INP int iblock,$/;" f file: +load_truth_table ./base/verilog_writer.c /^char *load_truth_table(int inputs , t_pb *pb)$/;" f +load_uniform_switch_pattern ./route/rr_graph.c /^static void load_uniform_switch_pattern(INP t_type_ptr type,$/;" f file: +load_wired_lut_pbs ./fpga_x2p/base/fpga_x2p_lut_utils.c /^void load_wired_lut_pbs(t_pb* lut_pb,$/;" f +local_cross_count ./fpga_x2p/clb_pin_remap/post_place_timing.c /^static const float local_cross_count[50] = { \/* [0..49] *\/1.0, 1.0, 1.0, 1.0828, 1.1536, 1.2206, 1.2823, 1.3385, 1.3991, 1.4493, 1.4974,$/;" v file: +local_interc_factor ../../libarchfpga/include/physical_types.h /^ float local_interc_factor;$/;" m struct:s_power_arch +local_nets ./base/vpr_types.h /^ struct s_net *local_nets; \/* Records post-packing connections, valid only for top-level *\/$/;" m struct:s_pb typeref:struct:s_pb::s_net +location_map ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* location_map;$/;" m struct:s_spice_model_buffer +log_msg ./power/power_util.c /^static void log_msg(t_log * log_ptr, char * msg) {$/;" f file: +logic_block_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* logic_block_spice_file_name = "grid_header.sp";$/;" v +logic_block_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* logic_block_verilog_file_name = "logic_blocks.v";$/;" v +logical_block ./base/globals.c /^struct s_logical_block *logical_block = NULL;$/;" v typeref:struct:s_logical_block +logical_block ./base/vpr_types.h /^ int logical_block; \/* If this is a terminating pb, gives the logical (netlist) block that it contains *\/$/;" m struct:s_pb +logical_block ./fpga_x2p/base/fpga_x2p_types.h /^ int* logical_block; \/* If this is a terminating pb, gives the logical (netlist) block that it contains *\/$/;" m struct:fpga_spice_phy_pb +logical_block_input_count ./base/read_blif.c /^static int *logical_block_input_count, *logical_block_output_count;$/;" v file: +logical_block_output_count ./base/read_blif.c /^static int *logical_block_input_count, *logical_block_output_count;$/;" v file: +logical_block_ptrs ./base/vpr_types.h /^ t_logical_block **logical_block_ptrs; \/* [0..num_blocks-1] ptrs to logical blocks that implements this molecule, index on pack_pattern_block->index of pack pattern *\/$/;" m struct:s_pack_molecule +logical_block_types ./base/vpr_types.h /^enum logical_block_types {$/;" g +logical_effort_factor ../../libarchfpga/include/physical_types.h /^ float logical_effort_factor;$/;" m struct:s_power_arch +logs ./power/power.h /^ t_log * logs;$/;" m struct:s_power_output +long_trans_inf ./power/power.h /^ t_transistor_size_inf * long_trans_inf; \/* Long transistor (W=1,L=2) *\/$/;" m struct:s_transistor_inf +longest_path_only ./fpga_x2p/verilog/verilog_report_timing.c /^ boolean longest_path_only;$/;" m struct:s_trpt_opts file: +longline ../../libarchfpga/include/physical_types.h /^ boolean longline;$/;" m struct:s_segment_inf +longline ./base/vpr_types.h /^ boolean longline;$/;" m struct:s_seg_details +lookahead_input_pins_used ./base/vpr_types.h /^ int **lookahead_input_pins_used; \/* [0..pb_graph_node->num_pin_classes-1][0..pin_class_size] number of input pins of this class that are speculatively used *\/$/;" m struct:s_pb_stats +lookahead_output_pins_used ./base/vpr_types.h /^ int **lookahead_output_pins_used; \/* [0..pb_graph_node->num_pin_classes-1][0..pin_class_size] number of output pins of this class that are speculatively used *\/$/;" m struct:s_pb_stats +lookup_dump ./place/timing_place_lookup.c /^static FILE *lookup_dump; \/* If debugging mode is on, print out to$/;" v file: +loop_greedy ./timing/slre.c /^static void loop_greedy(const struct slre *r, int pc, const char *s, int len,$/;" f file: +loop_non_greedy ./timing/slre.c /^static void loop_non_greedy(const struct slre *r, int pc, const char *s,$/;" f file: +lowercase ./timing/slre.c /^static int lowercase(const char *s) {$/;" f file: +lut_frac_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int lut_frac_level;$/;" m struct:s_spice_model_port +lut_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_lut* lut_info;$/;" m struct:s_spice_model_design_tech_info +lut_input_buffer ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_buffer* lut_input_buffer;$/;" m struct:s_spice_model +lut_input_inverter ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_buffer* lut_input_inverter;$/;" m struct:s_spice_model +lut_intermediate_buffer ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_buffer* lut_intermediate_buffer;$/;" m struct:s_spice_model +lut_output_mask ../../libarchfpga/fpga_spice_include/spice_types.h /^ int* lut_output_mask;$/;" m struct:s_spice_model_port +lut_output_pb_graph_pin ./fpga_x2p/base/fpga_x2p_types.h /^ t_pb_graph_pin** lut_output_pb_graph_pin;$/;" m struct:fpga_spice_phy_pb +lut_pin_remap ./base/vpr_types.h /^ int *lut_pin_remap; \/* [0..num_lut_inputs-1] applies only to LUT primitives, stores how LUT inputs were swapped during CAD flow, $/;" m struct:s_pb +lut_pin_remap ./fpga_x2p/base/fpga_x2p_types.h /^ int *lut_pin_remap; \/* [0..num_lut_inputs-1] applies only to LUT primitives, stores how LUT inputs were swapped during CAD flow, $/;" m struct:fpga_spice_phy_pb +lut_size ./base/ReadOptions.h /^ int lut_size;$/;" m struct:s_options +lut_size ./fpga_x2p/base/fpga_x2p_types.h /^ int* lut_size;$/;" m struct:fpga_spice_phy_pb +luts_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* luts_spice_file_name = "luts.sp";$/;" v +luts_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* luts_verilog_file_name = "luts.v";$/;" v +m ../../libarchfpga/include/ezxml.h /^ char *m; \/* original xml string *\/$/;" m struct:ezxml_root +magic_number ../../pcre/SRC/internal.h /^ unsigned long int magic_number;$/;" m struct:real_pcre +main ../../libarchfpga/ezxml.c /^main(int argc,$/;" f +main ../../libarchfpga/main.c /^int main(int argc, char **argv) {$/;" f +main ../../pcre/SRC/main.c /^int main(int argc, char **argv)$/;" f +main ./main.c /^int main(int argc, char **argv) {$/;" f +main ./shell_main.c /^int main(int argc, char ** argv) {$/;" f +main main.c /^int main(int argc, char **argv) {$/;" f +main shell_main.c /^int main(int argc, char ** argv) {$/;" f +main_best_buffer_list ../../libarchfpga/include/arch_types_mrfpga.h /^ t_linked_int* main_best_buffer_list;$/;" m struct:s_arch_mrfpga +main_best_buffer_list ./mrfpga/mrfpga_globals.c /^t_linked_int* main_best_buffer_list;$/;" v +mandatory ./fpga_x2p/shell/read_opt_types.h /^ enum opt_manda mandatory;$/;" m struct:s_opt_info typeref:enum:s_opt_info::opt_manda +map_button ./base/graphics.c /^static void map_button (int bnum) $/;" f file: +map_pb_type_port_to_spice_model_ports ./fpga_x2p/base/fpga_x2p_setup.c /^int map_pb_type_port_to_spice_model_ports(t_pb_type* cur_pb_type,$/;" f file: +mapped_spice_model ./base/vpr_types.h /^ t_spice_model* mapped_spice_model;$/;" m struct:s_logical_block +mapped_spice_model_index ./base/vpr_types.h /^ int mapped_spice_model_index; \/* index of spice_model in completed FPGA netlist *\/$/;" m struct:s_logical_block +mark_and_update_partial_gain ./pack/cluster.c /^static void mark_and_update_partial_gain(int inet, enum e_gain_update gain_flag,$/;" f file: +mark_blk_pins_nets_sink_index ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void mark_blk_pins_nets_sink_index(int n_nets, t_net* nets,$/;" f +mark_constant_generators ./base/read_netlist.c /^static void mark_constant_generators(INP int L_num_blocks,$/;" f file: +mark_constant_generators_rec ./base/read_netlist.c /^static void mark_constant_generators_rec(INP t_pb *pb, INP t_rr_node *rr_graph,$/;" f file: +mark_direct_of_pins ./util/vpr_utils.c /^static void mark_direct_of_pins(int start_pin_index, int end_pin_index, int itype, $/;" f file: +mark_direct_of_ports ./util/vpr_utils.c /^static void mark_direct_of_ports (int idirect, int direct_type, char * pb_type_name, $/;" f file: +mark_ends ./route/route_common.c /^void mark_ends(int inet) {$/;" f +mark_ends_cluster ./pack/cluster_legality.c /^static void mark_ends_cluster(int inet) {$/;" f file: +mark_grid_type_pb_graph_node_pins_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void mark_grid_type_pb_graph_node_pins_temp_net_num(int x, int y) {$/;" f +mark_node_expansion_by_bin ./route/route_timing.c /^static int mark_node_expansion_by_bin(int inet, int target_node,$/;" f file: +mark_one_pb_parasitic_nets ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void mark_one_pb_parasitic_nets(t_phy_pb* cur_pb) {$/;" f +mark_pb_graph_node_clock_pins_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void mark_pb_graph_node_clock_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node,$/;" f +mark_pb_graph_node_input_pins_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void mark_pb_graph_node_input_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node,$/;" f +mark_pb_graph_node_output_pins_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void mark_pb_graph_node_output_pins_temp_net_num(t_pb_graph_node* cur_pb_graph_node,$/;" f +mark_rr_graph_ends ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void mark_rr_graph_ends(t_rr_graph* local_rr_graph, $/;" f +mark_rr_graph_sinks ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void mark_rr_graph_sinks(t_rr_graph* local_rr_graph, $/;" f +mark_vpack_net_used_in_pb ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void mark_vpack_net_used_in_pb(t_pb* cur_op_pb,$/;" f +mark_vpack_net_used_in_pb_pin ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void mark_vpack_net_used_in_pb_pin(t_pb* cur_op_pb, t_pb_graph_pin* cur_pb_graph_pin,$/;" f +marked_blocks ./base/vpr_types.h /^ int *marked_nets, *marked_blocks;$/;" m struct:s_pb_stats +marked_nets ./base/vpr_types.h /^ int *marked_nets, *marked_blocks;$/;" m struct:s_pb_stats +match ../../pcre/SRC/pcre.c /^match(register const uschar *eptr, register const uschar *ecode,$/;" f file: +match ./timing/slre.c /^static const char *match(const struct slre *r, int pc, const char *s, int len,$/;" f file: +match2 ./timing/slre.c /^static const char *match2(const struct slre *r, const char *buf, int len,$/;" f file: +match_call_count ../../pcre/SRC/internal.h /^ unsigned long int match_call_count; \/* As it says *\/$/;" m struct:match_data +match_condassert ../../pcre/SRC/pcre.c 172;" d file: +match_data ../../pcre/SRC/internal.h /^typedef struct match_data {$/;" s +match_data ../../pcre/SRC/internal.h /^} match_data;$/;" t typeref:struct:match_data +match_isgroup ../../pcre/SRC/pcre.c 173;" d file: +match_limit ../../pcre/SRC/internal.h /^ unsigned long int match_limit;\/* As it says *\/$/;" m struct:match_data +match_limit ../../pcre/SRC/pcre.h /^ unsigned long int match_limit; \/* Maximum number of calls to match() *\/$/;" m struct:pcre_extra +match_pb_types_spice_model_rec ./fpga_x2p/base/fpga_x2p_setup.c /^void match_pb_types_spice_model_rec(t_pb_type* cur_pb_type,$/;" f file: +match_pb_types_verilog_model_rec ./fpga_x2p/verilog/verilog_pbtypes.c /^void match_pb_types_verilog_model_rec(t_pb_type* cur_pb_type,$/;" f +match_ref ../../pcre/SRC/pcre.c /^match_ref(int offset, register const uschar *eptr, int length, match_data *md,$/;" f file: +match_xclass ../../pcre/SRC/pcre.c /^match_xclass(int c, const uschar *data)$/;" f file: +max ./base/graphics.c 171;" d file: +max ./mrfpga/mrfpga_util.h 6;" d +max_IPIN_fanin ./power/power.h /^ int max_IPIN_fanin;$/;" m struct:s_power_commonly_used +max_buffer_size ./power/power.h /^ int max_buffer_size;$/;" m struct:s_power_tech +max_criticality ./base/ReadOptions.h /^ float max_criticality;$/;" m struct:s_options +max_criticality ./base/vpr_types.h /^ float max_criticality;$/;" m struct:s_router_opts +max_ext_index ./pack/cluster_legality.c /^ ext_clock_rr_node_index, max_ext_index;$/;" v file: +max_index ./route/rr_graph.c /^ int max_index;$/;" m struct:s_mux_size_distribution file: +max_internal_delay ../../libarchfpga/include/physical_types.h /^ float max_internal_delay;$/;" m struct:s_pb_type +max_len_pl_macros ./place/place_macro.c /^int max_len_pl_macros(int num_pl_macros, $/;" f +max_mux_sl_size ./power/power.h /^ int max_mux_sl_size;$/;" m struct:s_power_nmos_mux_inf +max_pins_per_side ../../libarchfpga/include/arch_types_mrfpga.h /^ int max_pins_per_side;$/;" m struct:s_arch_mrfpga +max_pins_per_side ./mrfpga/mrfpga_globals.c /^int max_pins_per_side;$/;" v +max_router_iterations ./base/ReadOptions.h /^ int max_router_iterations;$/;" m struct:s_options +max_router_iterations ./base/vpr_types.h /^ int max_router_iterations;$/;" m struct:s_router_opts +max_routing_mux_size ./power/power.h /^ int max_routing_mux_size;$/;" m struct:s_power_commonly_used +max_seg_fanout ./power/power.h /^ int max_seg_fanout;$/;" m struct:s_power_commonly_used +max_seg_to_IPIN_fanout ./power/power.h /^ int max_seg_to_IPIN_fanout;$/;" m struct:s_power_commonly_used +max_seg_to_seg_fanout ./power/power.h /^ int max_seg_to_seg_fanout;$/;" m struct:s_power_commonly_used +max_sim_num_clock_cycles ./fpga_x2p/spice/spice_grid_testbench.c /^static int max_sim_num_clock_cycles = 2;$/;" v file: +max_sim_num_clock_cycles ./fpga_x2p/spice/spice_mux_testbench.c /^static int max_sim_num_clock_cycles = 2;$/;" v file: +max_sim_num_clock_cycles ./fpga_x2p/spice/spice_primitive_testbench.c /^static int max_sim_num_clock_cycles = 2;$/;" v file: +max_sim_num_clock_cycles ./fpga_x2p/spice/spice_routing_testbench.c /^static int max_sim_num_clock_cycles = 2;$/;" v file: +max_width_per_trans ./fpga_x2p/spice/spice_globals.c /^float max_width_per_trans = 5.;$/;" v +mc_params ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_mc_params mc_params;$/;" m struct:s_spice_params +mc_sim ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean mc_sim;$/;" m struct:s_spice_mc_params +meas_header_file_name ./fpga_x2p/spice/spice_globals.c /^char* meas_header_file_name = "meas_params.sp";$/;" v +meas_params ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_meas_params meas_params;$/;" m struct:s_spice_params +mem_avail ../../libarchfpga/include/util.h /^ int mem_avail; \/* number of bytes left in the current chunk *\/$/;" m struct:s_chunk +mem_bank_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_mem_bank_info* mem_bank_info; \/* Only be allocated when orgz type is memory bank *\/$/;" m struct:s_sram_orgz_info +mem_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* mem_model; \/* SPICE model of a memory bit *\/$/;" m struct:s_mem_bank_info +mem_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* mem_model; \/* SPICE model of a memory bit *\/$/;" m struct:s_scff_info +mem_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* mem_model; \/* SPICE model of a memory bit *\/$/;" m struct:s_standalone_sram_info +members ./place/place_macro.h /^ t_pl_macro_member* members;$/;" m struct:s_pl_macro +memcpy ../../pcre/SRC/internal.h 48;" d +memmove ../../pcre/SRC/internal.h 49;" d +memmove ../../pcre/SRC/internal.h 61;" d +memmove ../../pcre/SRC/internal.h 63;" d +memmove ../../pcre/SRC/internal.h 73;" d +memories_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* memories_verilog_file_name = "memories.v";$/;" v +memory_pool ./pack/cluster.c /^static struct s_molecule_link *memory_pool; \/*Declared here so I can free easily.*\/$/;" v typeref:struct:s_molecule_link file: +memristor_inf ../../libarchfpga/include/arch_types_mrfpga.h /^ t_memristor_inf memristor_inf;$/;" m struct:s_arch_mrfpga +memristor_inf ./mrfpga/mrfpga_globals.c /^t_memristor_inf memristor_inf;$/;" v +memset ../../pcre/SRC/internal.h 50;" d +menu ./base/graphics.c /^static Window toplevel, menu, textarea; \/* various windows *\/$/;" v file: +menu_font_size ./base/graphics.c /^static const int menu_font_size = 12; \/* Font for menus and dialog boxes. *\/$/;" v file: +menutext ./base/graphics.c /^static void menutext(Window win, int xc, int yc, const char *text) $/;" f file: +messagelogger ../../libarchfpga/include/util.h /^typedef unsigned char (*messagelogger)( TIO_MessageMode_t messageMode,$/;" t +messages ./power/power.h /^ char ** messages;$/;" m struct:s_log +meta_characters ./timing/slre.c /^static const char *meta_characters = "|.*+?()[\\\\";$/;" v file: +min ./base/graphics.c 174;" d file: +min ./mrfpga/mrfpga_util.h 10;" d +min_size ../../libarchfpga/include/logic_types.h /^ int min_size; \/* minimum number of pins *\/$/;" m struct:s_model_ports +min_width ../../libarchfpga/fpga_spice_include/spice_types.h /^ float min_width;$/;" m struct:s_spice_transistor_type +mode ./base/vpr_types.h /^ int mode; \/* mode that this pb is set to *\/$/;" m struct:s_pb +mode ./fpga_x2p/base/fpga_x2p_types.h /^ int mode; \/* mode that this pb is set to *\/$/;" m struct:fpga_spice_phy_pb +mode_bits ../../libarchfpga/include/physical_types.h /^ char* mode_bits; \/* Mode bits to select *\/$/;" m struct:s_pb_type +mode_bits ./fpga_x2p/base/fpga_x2p_types.h /^ char* mode_bits; \/* Mode bits for the logical block *\/$/;" m struct:fpga_spice_phy_pb +mode_power ../../libarchfpga/include/physical_types.h /^ t_mode_power * mode_power;$/;" m struct:s_mode +mode_select ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean mode_select;$/;" m struct:s_spice_model_port +model ../../libarchfpga/include/cad_types.h /^ t_model *model; \/* block associated with chain *\/$/;" m struct:s_model_chain_pattern +model ../../libarchfpga/include/physical_types.h /^ t_model *model;$/;" m struct:s_pb_type +model ./base/read_blif.c /^ t_model * model;$/;" m struct:s_model_stats file: +model ./base/read_blif.c /^static char *model = NULL;$/;" v file: +model ./base/vpr_types.h /^ t_model* model; \/* Technology-mapped type (eg. LUT, Flip-flop, memory slice, inpad, etc) *\/$/;" m struct:s_logical_block +model_library ../../libarchfpga/include/physical_types.h /^ t_model *model_library;$/;" m struct:s_arch +model_lines ./base/read_blif.c /^static int ilines, olines, model_lines, endlines;$/;" v file: +model_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* model_name;$/;" m struct:s_spice_transistor_type +model_netlist ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* model_netlist; \/* SPICE netlist provided by user *\/$/;" m struct:s_spice_model +model_pin ./base/vpr_types.h /^ int model_port, model_pin; \/* technology mapped model pin *\/$/;" m struct:s_prepacked_tnode_data +model_port ../../libarchfpga/include/physical_types.h /^ t_model_ports *model_port;$/;" m struct:s_port +model_port ./base/vpr_types.h /^ int model_port, model_pin; \/* technology mapped model pin *\/$/;" m struct:s_prepacked_tnode_data +model_port_ptr ./base/vpr_types.h /^ t_model_ports *model_port_ptr;$/;" m struct:s_prepacked_tnode_data +model_ref ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* model_ref;$/;" m struct:s_spice_tech_lib +models ../../libarchfpga/include/physical_types.h /^ t_model *models;$/;" m struct:s_arch +modelsim_autocheck_testbench_module_postfix ./fpga_x2p/verilog/verilog_global.c /^char* modelsim_autocheck_testbench_module_postfix = "_autocheck_top_tb";$/;" v +modelsim_include_user_defined_verilog_netlists ./fpga_x2p/verilog/verilog_modelsim_autodeck.c /^void modelsim_include_user_defined_verilog_netlists(FILE* fp,$/;" f file: +modelsim_ini_path ./base/vpr_types.h /^ char* modelsim_ini_path;$/;" m struct:s_syn_verilog_opts +modelsim_proc_script_name_postfix ./fpga_x2p/verilog/verilog_global.c /^char* modelsim_proc_script_name_postfix = "_proc.tcl";$/;" v +modelsim_project_name_postfix ./fpga_x2p/verilog/verilog_global.c /^char* modelsim_project_name_postfix = "_fpga_msim";$/;" v +modelsim_simulation_time_unit ./fpga_x2p/verilog/verilog_global.c /^char* modelsim_simulation_time_unit = "ms";$/;" v +modelsim_testbench_module_postfix ./fpga_x2p/verilog/verilog_global.c /^char* modelsim_testbench_module_postfix = "_top_tb";$/;" v +modelsim_top_script_name_postfix ./fpga_x2p/verilog/verilog_global.c /^char* modelsim_top_script_name_postfix = "_runsim.tcl";$/;" v +modes ../../libarchfpga/include/physical_types.h /^ t_mode *modes; \/* [0..num_modes-1] *\/$/;" m struct:s_pb_type +moleculeptr ./pack/cluster.c /^ t_pack_molecule *moleculeptr;$/;" m struct:s_molecule_link file: +mouseclick_ptr ./base/graphics.c /^static void (*mouseclick_ptr)(float x, float y);$/;" v file: +mousemove_ptr ./base/graphics.c /^static void (*mousemove_ptr)(float x, float y);$/;" v file: +moved_blocks ./place/place.c /^ t_pl_moved_block * moved_blocks;$/;" m struct:s_pl_blocks_to_be_moved file: +multilevel_mux_last_level_input_num ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit,$/;" f +mux_arch ./power/power.h /^ t_mux_arch * mux_arch;$/;" m struct:s_power_mux_info +mux_arch_fix_levels ./power/power_util.c /^void mux_arch_fix_levels(t_mux_arch * mux_arch) {$/;" f +mux_arch_max_size ./power/power.h /^ int mux_arch_max_size;$/;" m struct:s_power_mux_info +mux_basis_posfix ./fpga_x2p/spice/spice_globals.c /^char* mux_basis_posfix = "_basis";$/;" v +mux_count ./route/rr_graph.c /^ int mux_count;$/;" m struct:s_mux_size_distribution file: +mux_find_selector_values ./power/power_util.c /^boolean mux_find_selector_values(int * selector_values, t_mux_node * mux_node,$/;" f +mux_graph_head ./power/power.h /^ t_mux_node * mux_graph_head;$/;" m struct:s_mux_arch +mux_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_mux* mux_info;$/;" m struct:s_spice_model_design_tech_info +mux_info ./power/power.h /^ std::map mux_info;$/;" m struct:s_power_commonly_used +mux_num_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int mux_num_level;$/;" m struct:s_spice_model_mux +mux_size ./power/power.h /^ int mux_size;$/;" m struct:s_power_buffer_sc_levr_inf +mux_special_basis_posfix ./fpga_x2p/spice/spice_globals.c /^char* mux_special_basis_posfix = "_special_basis";$/;" v +mux_trans_size ../../libarchfpga/include/physical_types.h /^ float mux_trans_size;$/;" m struct:s_switch_inf +mux_transistor_size ../../libarchfpga/include/physical_types.h /^ float mux_transistor_size;$/;" m struct:s_power_arch +mux_voltage_inf ./power/power.h /^ t_power_mux_volt_inf * mux_voltage_inf;$/;" m struct:s_power_nmos_mux_inf +mux_voltage_pairs ./power/power.h /^ t_power_mux_volt_pair * mux_voltage_pairs;$/;" m struct:s_power_mux_volt_inf +muxes_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* muxes_spice_file_name = "muxes.sp";$/;" v +muxes_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* muxes_verilog_file_name = "muxes.v";$/;" v +my_atof_2D ./util/token.c /^void my_atof_2D(INOUTP float **matrix, INP int max_i, INP int max_j,$/;" f +my_atoi ../../libarchfpga/util.c /^int my_atoi(const char *str) {$/;" f +my_calloc ../../libarchfpga/util.c /^my_calloc(size_t nelem, size_t size) {$/;" f +my_chunk_malloc ../../libarchfpga/util.c /^my_chunk_malloc(size_t size, t_chunk *chunk_info) {$/;" f +my_decimal2binary ./fpga_x2p/base/fpga_x2p_utils.c /^int* my_decimal2binary(int decimal,$/;" f +my_fgets ../../libarchfpga/util.c /^my_fgets(char *buf, int max_size, FILE * fp) {$/;" f +my_fopen ../../libarchfpga/util.c /^my_fopen(const char *fname, const char *flag, int prompt) {$/;" f +my_frand ../../libarchfpga/util.c /^float my_frand(void) {$/;" f +my_free ../../libarchfpga/read_xml_spice_util.c /^void my_free(void* ptr) {$/;" f +my_gettime ./fpga_x2p/base/fpga_x2p_utils.c /^char* my_gettime() {$/;" f +my_irand ../../libarchfpga/util.c /^int my_irand(int imax) {$/;" f +my_itoa ./fpga_x2p/base/fpga_x2p_utils.c /^char* my_itoa(int input) {$/;" f +my_itobin ./fpga_x2p/base/fpga_x2p_utils.c /^char* my_itobin(int in_int, int bin_len) {$/;" f +my_malloc ../../libarchfpga/util.c /^my_malloc(size_t size) {$/;" f +my_malloc ./base/graphics.c /^static void *my_malloc(int ibytes) {$/;" f file: +my_realloc ../../libarchfpga/util.c /^my_realloc(void *ptr, size_t size) {$/;" f +my_realloc ./base/graphics.c /^static void *my_realloc(void *memblk, int ibytes) {$/;" f file: +my_remove_file ./fpga_x2p/base/fpga_x2p_utils.c /^void my_remove_file(char* file_path) {$/;" f +my_srandom ../../libarchfpga/util.c /^void my_srandom(int seed) {$/;" f +my_strcat ./fpga_x2p/base/fpga_x2p_utils.c /^char* my_strcat(char* str1,$/;" f +my_strcmp ./fpga_x2p/shell/shell_utils.c /^int my_strcmp(char* str1, char* str2) {$/;" f +my_strdup ../../libarchfpga/util.c /^my_strdup(const char *str) {$/;" f +my_strncpy ../../libarchfpga/util.c /^my_strncpy(char *dest, const char *src, size_t size) {$/;" f +my_strtok ../../libarchfpga/util.c /^my_strtok(char *ptr, const char *tokens, FILE * fp, char *buf) {$/;" f +name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* name;$/;" m struct:s_spice_model +name ../../libarchfpga/include/cad_types.h /^ char *name; \/* name of this chain of logic *\/$/;" m struct:s_model_chain_pattern +name ../../libarchfpga/include/cad_types.h /^ char *name; \/* name of this logic model pattern *\/$/;" m struct:s_pack_patterns +name ../../libarchfpga/include/ezxml.h /^ char *name; \/* tag name *\/$/;" m struct:ezxml +name ../../libarchfpga/include/logic_types.h /^ char *name; \/* name of this logic model *\/$/;" m struct:s_model +name ../../libarchfpga/include/logic_types.h /^ char *name; \/* name of this port *\/$/;" m struct:s_model_ports +name ../../libarchfpga/include/physical_types.h /^ char *name;$/;" m struct:s_direct_inf +name ../../libarchfpga/include/physical_types.h /^ char *name;$/;" m struct:s_interconnect +name ../../libarchfpga/include/physical_types.h /^ char *name;$/;" m struct:s_switch_inf +name ../../libarchfpga/include/physical_types.h /^ char *name;$/;" m struct:s_type_descriptor +name ../../libarchfpga/include/physical_types.h /^ char* name;$/;" m struct:s_mode +name ../../libarchfpga/include/physical_types.h /^ char* name;$/;" m struct:s_pb_type +name ../../libarchfpga/include/physical_types.h /^ char* name;$/;" m struct:s_port +name ./base/vpr_types.h /^ char * name; \/* I\/O port name with an SDC constraint *\/$/;" m struct:s_io +name ./base/vpr_types.h /^ char * name;$/;" m struct:s_clock +name ./base/vpr_types.h /^ char *name; \/* Name of this physical block *\/$/;" m struct:s_pb +name ./base/vpr_types.h /^ char *name; \/* Taken from the first vpack_net which it drives. *\/$/;" m struct:s_logical_block +name ./base/vpr_types.h /^ char *name;$/;" m struct:s_block +name ./base/vpr_types.h /^ char *name;$/;" m struct:s_net +name ./base/vpr_types.h /^ char* name;$/;" m struct:s_clb_to_clb_directs +name ./fpga_x2p/base/fpga_x2p_types.h /^ char *name; \/* Name of this physical block *\/$/;" m struct:fpga_spice_phy_pb +name ./fpga_x2p/shell/read_opt_types.h /^ char* name; \/*The name of option*\/$/;" m struct:s_opt_info +name ./fpga_x2p/shell/read_opt_types.h /^ char* name;$/;" m struct:s_cmd_info +name ./fpga_x2p/shell/shell_types.h /^ char* name;$/;" m struct:s_shell_cmd +name ./fpga_x2p/shell/shell_types.h /^ e_cmd_category name;$/;" m struct:s_cmd_category +name ./power/power.h /^ char * name;$/;" m struct:s_log +name ./timing/read_sdc.c /^ char * name;$/;" m struct:s_sdc_clock file: +name ./util/hash.h /^ char *name;$/;" m struct:s_hash +name_count ../../pcre/SRC/internal.h /^ unsigned short int name_count; \/* Number of name items *\/$/;" m struct:real_pcre +name_entry_size ../../pcre/SRC/internal.h /^ int name_entry_size; \/* Size of each entry *\/$/;" m struct:compile_data +name_entry_size ../../pcre/SRC/internal.h /^ unsigned short int name_entry_size; \/* Size of any name items; 0 => none *\/$/;" m struct:real_pcre +name_mux ../../libarchfpga/include/physical_types.h /^ char* name_mux;$/;" m struct:s_pb_graph_pin +name_mux ./base/vpr_types.h /^ char* name_mux;$/;" m struct:s_rr_node +name_table ../../pcre/SRC/internal.h /^ uschar *name_table; \/* The name\/number table *\/$/;" m struct:compile_data +name_type ./base/draw.c /^static const char *name_type[] = { "SOURCE", "SINK", "IPIN", "OPIN", "CHANX", "CHANY",$/;" v file: +names_found ../../pcre/SRC/internal.h /^ int names_found; \/* Number of entries so far *\/$/;" m struct:compile_data +nelem ../../libarchfpga/include/util.h /^ int nelem;$/;" m struct:s_ivec +net ./base/globals_declare.h /^struct s_net *net;$/;" v typeref:struct:s_net +net ./fpga_x2p/base/fpga_x2p_types.h /^ t_net** net; \/* nets to route, this is pointer to the existing nets *\/$/;" m struct:fpga_spice_rr_graph +net_cnt ./route/pb_pin_eq_auto_detect.c /^ int net_cnt;$/;" m struct:s_num_mapped_opins_stats file: +net_color ./base/draw.c /^static enum color_types *net_color, *block_color;$/;" v typeref:enum:color_types file: +net_cost ./place/place.c /^static float *net_cost = NULL, *temp_net_cost = NULL; \/* [0..num_nets-1] *\/$/;" v file: +net_delay ./place/timing_place_lookup.c /^static float **net_delay;$/;" v file: +net_delay_ch ./place/timing_place.c /^static t_chunk net_delay_ch = {NULL, 0, NULL};$/;" v file: +net_num ./base/vpr_types.h /^ int net_num;$/;" m struct:s_rr_node +net_num_in_pack ./base/vpr_types.h /^ int net_num_in_pack;$/;" m struct:s_rr_node +net_num_sinks ./fpga_x2p/base/fpga_x2p_types.h /^ int* net_num_sinks;$/;" m struct:fpga_spice_rr_graph +net_num_sources ./fpga_x2p/base/fpga_x2p_types.h /^ int* net_num_sources;$/;" m struct:fpga_spice_rr_graph +net_output_feeds_driving_block_input ./pack/cluster.c /^static int *net_output_feeds_driving_block_input;$/;" v file: +net_pin_index ./place/place.c /^static int **net_pin_index = NULL;$/;" v file: +net_power ./base/vpr_types.h /^ t_net_power * net_power;$/;" m struct:s_net +net_rr_sinks ./fpga_x2p/base/fpga_x2p_types.h /^ int **net_rr_sinks; \/* [0..num_nets-1][0..num_pins-1] *\/$/;" m struct:fpga_spice_rr_graph +net_rr_sources ./fpga_x2p/base/fpga_x2p_types.h /^ int **net_rr_sources; \/* [0..num_nets-1][0..num_pins-1] *\/$/;" m struct:fpga_spice_rr_graph +net_rr_terminals ./base/globals.c /^int **net_rr_terminals = NULL; \/* [0..num_nets-1][0..num_pins-1] *\/$/;" v +net_rr_terminals ./base/globals_declare.h /^int **net_rr_terminals; \/* [0..num_nets-1][0..num_pins-1] *\/$/;" v +net_rr_terminals ./fpga_x2p/base/fpga_x2p_types.h /^ int **net_rr_terminals; \/* [0..num_nets-1][0..num_pins-1] *\/$/;" m struct:fpga_spice_rr_graph +net_to_vpack_net_mapping ./fpga_x2p/base/fpga_x2p_types.h /^ int* net_to_vpack_net_mapping;$/;" m struct:fpga_spice_rr_graph +netlist_clocks ./timing/read_sdc.c /^char ** netlist_clocks; \/* [0..num_netlist_clocks - 1] array of names of clocks in netlist *\/$/;" v +netlist_ios ./timing/read_sdc.c /^char ** netlist_ios; \/* [0..num_netlist_clocks - 1] array of names of ios in netlist *\/$/;" v +nets ./base/vpr_types.h /^ int *nets;$/;" m struct:s_block +nets_in_cluster ./pack/cluster_legality.c /^static int *nets_in_cluster; \/* [0..num_nets_in_cluster-1] *\/$/;" v file: +nets_sink_index ./base/vpr_types.h /^ int* nets_sink_index;$/;" m struct:s_block +next ../../libarchfpga/fpga_spice_include/linkedlist.h /^ t_llist* next;$/;" m struct:s_llist +next ../../libarchfpga/include/cad_types.h /^ struct s_model_chain_pattern *next; \/* next chain (linked list) *\/$/;" m struct:s_model_chain_pattern typeref:struct:s_model_chain_pattern::s_model_chain_pattern +next ../../libarchfpga/include/cad_types.h /^ struct s_pack_pattern_connections *next;$/;" m struct:s_pack_pattern_connections typeref:struct:s_pack_pattern_connections::s_pack_pattern_connections +next ../../libarchfpga/include/ezxml.h /^ ezxml_t next; \/* next tag with same name in this section at this depth *\/$/;" m struct:ezxml +next ../../libarchfpga/include/logic_types.h /^ struct s_model *next; \/* next model (linked list) *\/$/;" m struct:s_model typeref:struct:s_model::s_model +next ../../libarchfpga/include/logic_types.h /^ struct s_model_ports *next; \/* next port *\/$/;" m struct:s_model_ports typeref:struct:s_model_ports::s_model_ports +next ../../libarchfpga/include/util.h /^ struct s_linked_int *next;$/;" m struct:s_linked_int typeref:struct:s_linked_int::s_linked_int +next ../../libarchfpga/include/util.h /^ struct s_linked_vptr *next;$/;" m struct:s_linked_vptr typeref:struct:s_linked_vptr::s_linked_vptr +next ./base/place_and_route.h /^ struct s_fmap_cell *next;$/;" m struct:s_fmap_cell typeref:struct:s_fmap_cell::s_fmap_cell +next ./base/verilog_writer.h /^ struct found_connectivity *next;$/;" m struct:found_connectivity typeref:struct:found_connectivity::found_connectivity +next ./base/verilog_writer.h /^ struct found_pins *next;$/;" m struct:found_pins typeref:struct:found_pins::found_pins +next ./base/vpr_types.h /^ struct s_linked_f_pointer *next;$/;" m struct:s_linked_f_pointer typeref:struct:s_linked_f_pointer::s_linked_f_pointer +next ./base/vpr_types.h /^ struct s_pack_molecule *next;$/;" m struct:s_pack_molecule typeref:struct:s_pack_molecule::s_pack_molecule +next ./base/vpr_types.h /^ struct s_trace *next;$/;" m struct:s_trace typeref:struct:s_trace::s_trace +next ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_node { t_buffer_plan value; struct s_buffer_plan_node* next;} t_buffer_plan_node;$/;" m struct:s_buffer_plan_node typeref:struct:s_buffer_plan_node::s_buffer_plan_node file: +next ./pack/cluster.c /^ struct s_molecule_link *next;$/;" m struct:s_molecule_link typeref:struct:s_molecule_link::s_molecule_link file: +next ./route/route_common.h /^ struct s_heap *next;$/;" m union:s_heap::__anon14 typeref:struct:s_heap::__anon14::s_heap +next ./route/route_tree_timing.h /^ struct s_rt_node *next;$/;" m union:s_rt_node::__anon16 typeref:struct:s_rt_node::__anon16::s_rt_node +next ./route/route_tree_timing.h /^ struct s_linked_rt_edge *next;$/;" m struct:s_linked_rt_edge typeref:struct:s_linked_rt_edge::s_linked_rt_edge +next ./route/rr_graph.c /^ struct s_mux *next;$/;" m struct:s_mux typeref:struct:s_mux::s_mux file: +next ./route/rr_graph.c /^ struct s_mux_size_distribution *next;$/;" m struct:s_mux_size_distribution typeref:struct:s_mux_size_distribution::s_mux_size_distribution file: +next ./route/rr_graph_util.h /^ struct s_linked_edge *next;$/;" m struct:s_linked_edge typeref:struct:s_linked_edge::s_linked_edge +next ./timing/net_delay_types.h /^ struct s_rc_node *next;$/;" m union:s_rc_node::__anon18 typeref:struct:s_rc_node::__anon18::s_rc_node +next ./timing/net_delay_types.h /^ struct s_linked_rc_edge *next;$/;" m struct:s_linked_rc_edge typeref:struct:s_linked_rc_edge::s_linked_rc_edge +next ./timing/net_delay_types.h /^ struct s_linked_rc_ptr *next;$/;" m struct:s_linked_rc_ptr typeref:struct:s_linked_rc_ptr::s_linked_rc_ptr +next ./util/hash.h /^ struct s_hash *next;$/;" m struct:s_hash typeref:struct:s_hash::s_hash +next_mem_loc_ptr ../../libarchfpga/include/util.h /^ char *next_mem_loc_ptr;\/* pointer to the first available (free) *$/;" m struct:s_chunk +next_primitive ../../libarchfpga/include/cad_types.h /^ struct s_cluster_placement_primitive *next_primitive;$/;" m struct:s_cluster_placement_primitive typeref:struct:s_cluster_placement_primitive::s_cluster_placement_primitive +nint ../../libarchfpga/include/util.h 24;" d +nmos_leakage_info ./power/power.h /^ t_power_nmos_leakage_inf * nmos_leakage_info;$/;" m struct:s_power_tech +nmos_mux_info ./power/power.h /^ t_power_nmos_mux_inf * nmos_mux_info;$/;" m struct:s_power_tech +nmos_pmos_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* nmos_pmos_spice_file_name = "nmos_pmos.sp";$/;" v +nmos_size ../../libarchfpga/fpga_spice_include/spice_types.h /^ float nmos_size;$/;" m struct:s_spice_model_pass_gate_logic +nmos_size ./power/power.h /^ float nmos_size;$/;" m struct:s_power_nmos_leakage_inf +nmos_size ./power/power.h /^ float nmos_size;$/;" m struct:s_power_nmos_mux_inf +nmos_subckt_name ./fpga_x2p/spice/spice_globals.c /^char* nmos_subckt_name = "vpr_nmos";$/;" v +node_block ./base/vpr_types.h /^ int *node_block;$/;" m struct:s_net +node_block_pin ./base/vpr_types.h /^ int *node_block_pin;$/;" m struct:s_net +node_block_port ./base/vpr_types.h /^ int *node_block_port;$/;" m struct:s_net +node_to_heap ./route/route_common.c /^void node_to_heap(int inode, float cost, int prev_node, int prev_edge,$/;" f +nominal_vdd ../../libarchfpga/fpga_spice_include/spice_types.h /^ float nominal_vdd;$/;" m struct:s_spice_tech_lib +normalized_T_arr ./base/vpr_types.h /^ float normalized_T_arr; \/* arrival time (normalized with respect to max time) *\/$/;" m struct:s_prepacked_tnode_data +normalized_slack ./base/vpr_types.h /^ float normalized_slack; \/* slack (normalized with respect to max slack) *\/$/;" m struct:s_prepacked_tnode_data +normalized_total_critical_paths ./base/vpr_types.h /^ float normalized_total_critical_paths; \/* critical path count (normalized with respect to max count) *\/$/;" m struct:s_prepacked_tnode_data +notbol ../../pcre/SRC/internal.h /^ BOOL notbol; \/* NOTBOL flag *\/$/;" m struct:match_data +notempty ../../pcre/SRC/internal.h /^ BOOL notempty; \/* Empty string match not wanted *\/$/;" m struct:match_data +noteol ../../pcre/SRC/internal.h /^ BOOL noteol; \/* NOTEOL flag *\/$/;" m struct:match_data +num_annotations ../../libarchfpga/include/physical_types.h /^ int num_annotations;$/;" m struct:s_interconnect +num_annotations ../../libarchfpga/include/physical_types.h /^ int num_annotations;$/;" m struct:s_pb_type +num_bl ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_bl; \/* Number of Bit Lines in total *\/$/;" m struct:s_mem_bank_info +num_blif_models ./base/read_blif.c /^static int num_blif_models;$/;" v file: +num_blocks ../../libarchfpga/include/cad_types.h /^ int num_blocks; \/* number of blocks in pattern *\/$/;" m struct:s_pack_patterns +num_blocks ./base/globals.c /^int num_blocks = 0;$/;" v +num_blocks ./base/globals_declare.h /^int num_nets, num_blocks;$/;" v +num_blocks ./base/vpr_types.h /^ int num_blocks; \/* number of logical blocks of molecule *\/$/;" m struct:s_pack_molecule +num_blocks ./place/place_macro.h /^ int num_blocks;$/;" m struct:s_pl_macro +num_buttons ./base/graphics.c /^static int num_buttons = 0; \/* Number of menu buttons *\/$/;" v file: +num_caps ./timing/slre.c /^ int num_caps; \/\/ Number of bracket pairs$/;" m struct:slre file: +num_cb_buffers ./power/power.h /^ int num_cb_buffers;$/;" m struct:s_power_commonly_used +num_cb_switch ../../libarchfpga/include/physical_types.h /^ int num_cb_switch;$/;" m struct:s_arch +num_cc_constraints ./base/vpr_types.h /^ int num_cc_constraints; \/* number of special-case clock-to-clock constraints overriding default, calculated, timing constraints *\/$/;" m struct:s_timing_constraints +num_cf_constraints ./base/vpr_types.h /^ int num_cf_constraints; \/* number of special-case clock-to-flipflop constraints *\/$/;" m struct:s_timing_constraints +num_child_blocks_in_pb ./base/vpr_types.h /^ int num_child_blocks_in_pb;$/;" m struct:s_pb_stats +num_class ../../libarchfpga/include/physical_types.h /^ int num_class;$/;" m struct:s_type_descriptor +num_clb2clb_directs ./base/globals.c /^int num_clb2clb_directs = 0;$/;" v +num_clock_names ./timing/read_sdc.c /^ int num_clock_names;$/;" m struct:s_sdc_exclusive_group file: +num_clock_pins ../../libarchfpga/include/physical_types.h /^ int *num_clock_pins; \/* [0..num_clock_ports - 1] *\/$/;" m struct:s_pb_graph_node +num_clock_pins ../../libarchfpga/include/physical_types.h /^ int num_clock_pins;$/;" m struct:s_pb_type +num_clock_ports ../../libarchfpga/include/physical_types.h /^ int num_clock_ports;$/;" m struct:s_pb_graph_node +num_clocks ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_clocks;$/;" m struct:s_spice_stimulate_params +num_conf_bits ./base/vpr_types.h /^ int num_conf_bits;$/;" m struct:s_pb +num_conf_bits ./fpga_x2p/base/fpga_x2p_types.h /^ int num_conf_bits;$/;" m struct:fpga_spice_phy_pb +num_conf_bits_cbx ./fpga_x2p/base/fpga_x2p_globals.c /^int** num_conf_bits_cbx = NULL;$/;" v +num_conf_bits_cby ./fpga_x2p/base/fpga_x2p_globals.c /^int** num_conf_bits_cby = NULL;$/;" v +num_conf_bits_sb ./fpga_x2p/base/fpga_x2p_globals.c /^int** num_conf_bits_sb = NULL;$/;" v +num_connectable_primtive_input_pins ../../libarchfpga/include/physical_types.h /^ int *num_connectable_primtive_input_pins; \/* [0..depth-1] number of input pins that this output pin can reach without exiting cluster at given depth *\/$/;" m struct:s_pb_graph_pin +num_constrained_clocks ./base/vpr_types.h /^ int num_constrained_clocks; \/* number of clocks with timing constraints *\/$/;" m struct:s_timing_constraints +num_constrained_inputs ./base/vpr_types.h /^ int num_constrained_inputs; \/* number of inputs with timing constraints *\/$/;" m struct:s_timing_constraints +num_constrained_outputs ./base/vpr_types.h /^ int num_constrained_outputs; \/* number of outputs with timing constraints *\/$/;" m struct:s_timing_constraints +num_critical_input_paths ./base/vpr_types.h /^ long num_critical_input_paths, num_critical_output_paths; \/* count of critical paths fanning into\/out of this tnode *\/$/;" m struct:s_prepacked_tnode_data +num_critical_output_paths ./base/vpr_types.h /^ long num_critical_input_paths, num_critical_output_paths; \/* count of critical paths fanning into\/out of this tnode *\/$/;" m struct:s_prepacked_tnode_data +num_data_input ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_data_input; \/* Inputs for multiplexing datapath signals*\/ $/;" m struct:s_spice_mux_arch +num_delay_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_delay_info;$/;" m struct:s_spice_model +num_directs ../../libarchfpga/include/physical_types.h /^ int num_directs;$/;" m struct:s_arch +num_drive_rr_nodes ./base/vpr_types.h /^ int num_drive_rr_nodes;$/;" m struct:s_rr_node +num_driver ./base/read_blif.c /^static int *num_driver, *temp_num_pins;$/;" v file: +num_drivers ../../libarchfpga/include/physical_types.h /^ int num_drivers;$/;" m struct:s_type_descriptor +num_edges ./base/vpr_types.h /^ int num_edges;$/;" m struct:s_tnode +num_edges ./base/vpr_types.h /^ short num_edges;$/;" m struct:s_rr_node +num_edges_head ./pack/pb_type_graph.c /^static struct s_linked_vptr *num_edges_head;$/;" v typeref:struct:s_linked_vptr file: +num_ext_inputs ./base/vpr_types.h /^ int num_ext_inputs; \/* number of input pins used by molecule that are not self-contained by pattern molecule matches *\/$/;" m struct:s_pack_molecule +num_ext_inputs_logical_block ./util/vpr_utils.c /^int num_ext_inputs_logical_block(int iblk) {$/;" f +num_fc_constraints ./base/vpr_types.h /^ int num_fc_constraints; \/* number of special-case flipflop-to-clock constraints *\/$/;" m struct:s_timing_constraints +num_feasible_blocks ./base/vpr_types.h /^ int num_feasible_blocks; \/* [0..num_marked_models-1] *\/$/;" m struct:s_pb_stats +num_ff_constraints ./base/vpr_types.h /^ int num_ff_constraints; \/* number of special-case flipflop-to-flipflop constraints *\/$/;" m struct:s_timing_constraints +num_global_clocks ../../libarchfpga/include/physical_types.h /^ int num_global_clocks;$/;" m struct:s_clock_arch +num_grid_loc_def ../../libarchfpga/include/physical_types.h /^ int num_grid_loc_def;$/;" m struct:s_type_descriptor +num_heap_allocated ./fpga_x2p/base/fpga_x2p_types.h /^ int num_heap_allocated;$/;" m struct:fpga_spice_rr_graph +num_heap_allocated ./route/route_common.c /^static int num_heap_allocated = 0;$/;" v file: +num_include_netlist ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_include_netlist;$/;" m struct:s_spice +num_inpads ./base/vpr_types.h /^ int num_inpads;$/;" m struct:s_pb +num_inpads ./fpga_x2p/base/fpga_x2p_types.h /^ int num_inpads;$/;" m struct:fpga_spice_phy_pb +num_input ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_input; \/* All Inputs including those connect to constant generator *\/$/;" m struct:s_spice_mux_arch +num_input_basis ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_input_basis;$/;" m struct:s_spice_mux_arch +num_input_edges ../../libarchfpga/include/physical_types.h /^ int num_input_edges;$/;" m struct:s_pb_graph_pin +num_input_last_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_input_last_level;$/;" m struct:s_spice_mux_arch +num_input_per_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int* num_input_per_level; \/* [0...num_level] *\/$/;" m struct:s_spice_mux_arch +num_input_pin_class ../../libarchfpga/include/physical_types.h /^ int num_input_pin_class; \/* number of pin classes that this input pb_graph_node has *\/$/;" m struct:s_pb_graph_node +num_input_pins ../../libarchfpga/include/physical_types.h /^ int *num_input_pins; \/* [0..num_input_ports - 1] *\/$/;" m struct:s_pb_graph_node +num_input_pins ../../libarchfpga/include/physical_types.h /^ int num_input_pins; \/* inputs not including clock pins *\/$/;" m struct:s_pb_type +num_input_pins ../../libarchfpga/include/physical_types.h /^ int num_input_pins;$/;" m struct:s_pb_graph_edge +num_input_ports ../../libarchfpga/include/physical_types.h /^ int num_input_ports;$/;" m struct:s_interconnect_power +num_input_ports ../../libarchfpga/include/physical_types.h /^ int num_input_ports;$/;" m struct:s_pb_graph_node +num_inputs ./power/PowerSpicedComponent.h /^ int num_inputs;$/;" m class:PowerCallibInputs +num_inputs ./power/power.h /^ int num_inputs; \/* Number of inputs *\/$/;" m struct:s_mux_node +num_inputs ./power/power.h /^ int num_inputs;$/;" m struct:s_mux_arch +num_inputs ./power/power.h /^ short num_inputs; \/* Number of inputs *\/$/;" m struct:s_rr_node_power +num_interconnect ../../libarchfpga/include/physical_types.h /^ int num_interconnect;$/;" m struct:s_mode +num_iopads ./base/vpr_types.h /^ int num_iopads;$/;" m struct:s_pb +num_iopads ./fpga_x2p/base/fpga_x2p_types.h /^ int num_iopads;$/;" m struct:fpga_spice_phy_pb +num_ipin_rr_nodes ./base/vpr_types.h /^ int* num_ipin_rr_nodes; \/* Switch block has some inputs that are CLB IPIN*\/$/;" m struct:s_cb +num_ipin_rr_nodes ./base/vpr_types.h /^ int* num_ipin_rr_nodes; \/* Switch block has some inputs that are CLB IPIN*\/$/;" m struct:s_sb +num_latches ./base/read_blif.c /^static int num_luts = 0, num_latches = 0, num_subckts = 0;$/;" v file: +num_leakage_pairs ./power/power.h /^ int num_leakage_pairs;$/;" m struct:s_power_nmos_leakage_inf +num_legal_pos ./place/place.c /^static int *num_legal_pos = NULL; \/* [0..num_legal_pos-1] *\/$/;" v file: +num_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_level;$/;" m struct:s_spice_mux_arch +num_levr_entries ./power/power.h /^ int num_levr_entries;$/;" m struct:s_power_buffer_strength_inf +num_linked_f_pointer_allocated ./fpga_x2p/base/fpga_x2p_types.h /^ int num_linked_f_pointer_allocated;$/;" m struct:fpga_spice_rr_graph +num_linked_f_pointer_allocated ./route/route_common.c /^static int num_linked_f_pointer_allocated = 0;$/;" v file: +num_local_nets ./base/vpr_types.h /^ int num_local_nets; \/* Records post-packing connections, valid only for top-level *\/$/;" m struct:s_pb +num_logical_blocks ./base/globals.c /^int num_logical_nets = 0, num_logical_blocks = 0;$/;" v +num_logical_blocks ./fpga_x2p/base/fpga_x2p_types.h /^ int num_logical_blocks;$/;" m struct:fpga_spice_phy_pb +num_logical_nets ./base/globals.c /^int num_logical_nets = 0, num_logical_blocks = 0;$/;" v +num_logs ./power/power.h /^ int num_logs;$/;" m struct:s_power_output +num_luts ./base/read_blif.c /^static int num_luts = 0, num_latches = 0, num_subckts = 0;$/;" v file: +num_mapped_opins ./base/vpr_types.h /^ int num_mapped_opins;$/;" m struct:s_net +num_mapped_opins ./route/pb_pin_eq_auto_detect.c /^ int num_mapped_opins;$/;" m struct:s_num_mapped_opins_stats file: +num_marked_blocks ./base/vpr_types.h /^ int num_marked_nets, num_marked_blocks;$/;" m struct:s_pb_stats +num_marked_nets ./base/vpr_types.h /^ int num_marked_nets, num_marked_blocks;$/;" m struct:s_pb_stats +num_mc_points ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_mc_points;$/;" m struct:s_spice_mc_params +num_mem_bit ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_mem_bit; \/* Number of memory bits in total *\/$/;" m struct:s_mem_bank_info +num_mem_bit ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_mem_bit; \/* Number of memory bits in total *\/$/;" m struct:s_scff_info +num_mem_bit ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_mem_bit; \/* Number of memory bits in total *\/$/;" m struct:s_standalone_sram_info +num_messages ./power/power.h /^ int num_messages;$/;" m struct:s_log +num_mode_bits ./base/vpr_types.h /^ int num_mode_bits;$/;" m struct:s_pb +num_mode_bits ./fpga_x2p/base/fpga_x2p_types.h /^ int num_mode_bits;$/;" m struct:fpga_spice_phy_pb +num_modes ../../libarchfpga/include/physical_types.h /^ int num_modes;$/;" m struct:s_pb_type +num_moved_blocks ./place/place.c /^ int num_moved_blocks;$/;" m struct:s_pl_blocks_to_be_moved file: +num_multicycles ./base/vpr_types.h /^ int num_multicycles;$/;" m struct:s_override_constraint +num_mux ../../libarchfpga/include/physical_types.h /^ int num_mux;$/;" m struct:s_interconnect +num_netlist_clocks ./timing/read_sdc.c /^int num_netlist_clocks = 0; \/* number of clocks in netlist *\/$/;" v +num_netlist_ios ./timing/read_sdc.c /^int num_netlist_ios = 0; \/* number of clocks in netlist *\/$/;" v +num_nets ./base/globals.c /^int num_nets = 0;$/;" v +num_nets ./base/globals_declare.h /^int num_nets, num_blocks;$/;" v +num_nets ./fpga_x2p/base/fpga_x2p_types.h /^ int num_nets; \/* number of nets to route *\/$/;" m struct:fpga_spice_rr_graph +num_nets_in_cluster ./pack/cluster_legality.c /^static int num_nets_in_cluster;$/;" v file: +num_nmos_leakage_info ./power/power.h /^ int num_nmos_leakage_info;$/;" m struct:s_power_tech +num_nmos_mux_info ./power/power.h /^ int num_nmos_mux_info;$/;" m struct:s_power_tech +num_normal_switch ../../libarchfpga/include/arch_types_mrfpga.h /^ short num_normal_switch;$/;" m struct:s_arch_mrfpga +num_normal_switch ./mrfpga/mrfpga_globals.c /^short num_normal_switch;$/;" v +num_opin_drivers ./base/vpr_types.h /^ int num_opin_drivers; \/* UDSD by WMF (could use "short") *\/$/;" m struct:s_rr_node +num_opin_rr_nodes ./base/vpr_types.h /^ int* num_opin_rr_nodes; \/* Connection block has some outputs that are CLB OPIN *\/$/;" m struct:s_cb +num_opin_rr_nodes ./base/vpr_types.h /^ int* num_opin_rr_nodes; \/* Connection block has some outputs that are CLB OPIN *\/$/;" m struct:s_sb +num_outpads ./base/vpr_types.h /^ int num_outpads;$/;" m struct:s_pb +num_outpads ./fpga_x2p/base/fpga_x2p_types.h /^ int num_outpads;$/;" m struct:fpga_spice_phy_pb +num_output_edges ../../libarchfpga/include/physical_types.h /^ int num_output_edges;$/;" m struct:s_pb_graph_pin +num_output_pin_class ../../libarchfpga/include/physical_types.h /^ int num_output_pin_class; \/* number of output pin classes that this pb_graph_node has *\/$/;" m struct:s_pb_graph_node +num_output_pins ../../libarchfpga/include/physical_types.h /^ int *num_output_pins; \/* [0..num_output_ports - 1] *\/$/;" m struct:s_pb_graph_node +num_output_pins ../../libarchfpga/include/physical_types.h /^ int num_output_pins;$/;" m struct:s_pb_graph_edge +num_output_pins ../../libarchfpga/include/physical_types.h /^ int num_output_pins;$/;" m struct:s_pb_type +num_output_ports ../../libarchfpga/include/physical_types.h /^ int num_output_ports;$/;" m struct:s_interconnect_power +num_output_ports ../../libarchfpga/include/physical_types.h /^ int num_output_ports;$/;" m struct:s_pb_graph_node +num_p_inputs ./base/globals.c /^int num_p_inputs = 0, num_p_outputs = 0;$/;" v +num_p_outputs ./base/globals.c /^int num_p_inputs = 0, num_p_outputs = 0;$/;" v +num_pack_patterns ../../libarchfpga/include/physical_types.h /^ int num_pack_patterns;$/;" m struct:s_pb_graph_edge +num_pb ../../libarchfpga/include/physical_types.h /^ int num_pb;$/;" m struct:s_pb_type +num_pb_type_children ../../libarchfpga/include/physical_types.h /^ int num_pb_type_children;$/;" m struct:s_mode +num_pb_types ./base/vpr_types.h /^ int num_pb_types; \/* num primitive pb_types inside complex block *\/$/;" m struct:s_cluster_placement_stats +num_pin_loc_assignments ../../libarchfpga/include/physical_types.h /^ int **num_pin_loc_assignments; \/* [0..height-1][0..3] *\/$/;" m struct:s_type_descriptor +num_pin_timing ../../libarchfpga/include/physical_types.h /^ int num_pin_timing; \/* primitive ipin to opin timing *\/$/;" m struct:s_pb_graph_pin +num_pins ../../libarchfpga/include/physical_types.h /^ int num_pins;$/;" m struct:s_class +num_pins ../../libarchfpga/include/physical_types.h /^ int num_pins;$/;" m struct:s_port +num_pins ../../libarchfpga/include/physical_types.h /^ int num_pins;$/;" m struct:s_type_descriptor +num_pins_of_net_in_pb ./base/vpr_types.h /^ std::map num_pins_of_net_in_pb;$/;" m struct:s_pb_stats +num_pins_per_port ../../libarchfpga/include/physical_types.h /^ int num_pins_per_port;$/;" m struct:s_interconnect_power +num_pl_macros ./place/place.c /^static int num_pl_macros;$/;" v file: +num_port ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_port;$/;" m struct:s_spice_model +num_ports ../../libarchfpga/include/physical_types.h /^ int num_ports;$/;" m struct:s_pb_type +num_receivers ../../libarchfpga/include/physical_types.h /^ int num_receivers;$/;" m struct:s_type_descriptor +num_reserved_conf_bits ./base/vpr_types.h /^ int num_reserved_conf_bits;$/;" m struct:s_pb +num_reserved_conf_bits ./base/vpr_types.h /^ int num_reserved_conf_bits; \/* number of reserved configuration bits *\/$/;" m struct:s_cb +num_reserved_conf_bits ./base/vpr_types.h /^ int num_reserved_conf_bits; \/* number of reserved configuration bits *\/$/;" m struct:s_sb +num_reserved_conf_bits ./fpga_x2p/base/fpga_x2p_types.h /^ int num_reserved_conf_bits;$/;" m struct:fpga_spice_phy_pb +num_rp ./place/place_stats.c /^ int num_rp[MAX_LEN];$/;" m struct:relapos_rec_s file: +num_rr_indexed_data ./base/globals.c /^int num_rr_indexed_data = 0;$/;" v +num_rr_indexed_data ./base/globals_declare.h /^int num_rr_indexed_data;$/;" v +num_rr_indexed_data ./fpga_x2p/base/fpga_x2p_types.h /^ int num_rr_indexed_data;$/;" m struct:fpga_spice_rr_graph +num_rr_nodes ./base/globals.c /^int num_rr_nodes = 0;$/;" v +num_rr_nodes ./base/globals_declare.h /^int num_rr_nodes;$/;" v +num_rr_nodes ./fpga_x2p/base/fpga_x2p_types.h /^ int num_rr_nodes;$/;" m struct:fpga_spice_rr_graph +num_sb_buffers ./power/power.h /^ int num_sb_buffers;$/;" m struct:s_power_commonly_used +num_scff ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_scff; \/* Number of Scan-chain flip-flops *\/$/;" m struct:s_scff_info +num_segment ./base/vpr_types.h /^ int num_segment;$/;" m struct:s_det_routing_arch +num_segments ../../libarchfpga/include/physical_types.h /^ int num_segments;$/;" m struct:s_arch +num_segments ./fpga_x2p/spice/spice_mux_testbench.c /^static int num_segments;$/;" v file: +num_segments ./fpga_x2p/spice/spice_routing_testbench.c /^static int num_segments;$/;" v file: +num_siblings ./base/vpr_types.h /^ int num_siblings;$/;" m struct:s_trace +num_sides ./base/vpr_types.h /^ int num_sides; \/* Should be fixed to 4 *\/$/;" m struct:s_cb +num_sides ./base/vpr_types.h /^ int num_sides; \/* Should be fixed to 4 *\/$/;" m struct:s_sb +num_sigma ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_sigma;$/;" m struct:s_spice_mc_variation_params +num_sim_clock_cycles ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_sim_clock_cycles;$/;" m struct:s_spicetb_info +num_sink ./base/vpr_types.h /^ int num_sink;$/;" m struct:s_override_constraint +num_sinks ./base/vpr_types.h /^ int num_sinks;$/;" m struct:s_net +num_size_entries ./power/power.h /^ int num_size_entries;$/;" m struct:s_transistor_inf +num_source ./base/vpr_types.h /^ int num_source;$/;" m struct:s_override_constraint +num_spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_spice_model;$/;" m struct:s_spice +num_sram ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_sram; \/* Number of SRAMs in total *\/$/;" m struct:s_standalone_sram_info +num_strengths ./power/power.h /^ int num_strengths;$/;" m struct:s_power_buffer_size_inf +num_subckts ./base/read_blif.c /^static int num_luts = 0, num_latches = 0, num_subckts = 0;$/;" v file: +num_swap_aborted ./place/place.c /^static int num_swap_aborted = 0;$/;" v file: +num_swap_accepted ./place/place.c /^static int num_swap_accepted = 0;$/;" v file: +num_swap_rejected ./place/place.c /^static int num_swap_rejected = 0;$/;" v file: +num_switch ./base/vpr_types.h /^ short num_switch;$/;" m struct:s_det_routing_arch +num_switch_inf ./fpga_x2p/base/fpga_x2p_types.h /^ int num_switch_inf;$/;" m struct:fpga_spice_rr_graph +num_switches ../../libarchfpga/include/physical_types.h /^ int num_switches;$/;" m struct:s_arch +num_swseg_pattern ../../libarchfpga/include/physical_types.h /^ int num_swseg_pattern;$/;" m struct:s_arch +num_swseg_pattern ./base/vpr_types.h /^ int num_swseg_pattern; \/*Xifan TANG: Switch Segment Pattern Support*\/$/;" m struct:s_det_routing_arch +num_tedges ../../libarchfpga/fpga_spice_include/spice_types.h /^ int* num_tedges; \/* 1-D Array, show number of tedges of each pin *\/$/;" m struct:s_spice_model_port +num_timing_nets ./timing/path_delay.c /^static int num_timing_nets = 0;$/;" v file: +num_tnode_levels ./timing/path_delay2.c /^int num_tnode_levels; \/* Number of levels in the timing graph. *\/$/;" v +num_tnodes ./timing/path_delay.c /^int num_tnodes = 0; \/* Number of nodes (pins) in the timing graph *\/$/;" v +num_trace_allocated ./fpga_x2p/base/fpga_x2p_types.h /^ int num_trace_allocated; \/* To watch for memory leaks. *\/$/;" m struct:fpga_spice_rr_graph +num_trace_allocated ./route/route_common.c /^static int num_trace_allocated = 0; \/* To watch for memory leaks. *\/$/;" v file: +num_transistor_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_transistor_type;$/;" m struct:s_spice_tech_lib +num_ts_called ./place/place.c /^static int num_ts_called = 0;$/;" v file: +num_types ./base/globals.c /^int num_types = 0;$/;" v +num_types_backup ./place/timing_place_lookup.c /^static int num_types_backup;$/;" v file: +num_used_cb_mux_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_cb_mux_tb = 0;$/;" v +num_used_cb_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_cb_tb = 0;$/;" v +num_used_grid_mux_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_grid_mux_tb = 0;$/;" v +num_used_grid_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_grid_tb = 0;$/;" v +num_used_hardlogic_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_hardlogic_tb = 0;$/;" v +num_used_io_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_io_tb = 0;$/;" v +num_used_lut_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_lut_tb = 0;$/;" v +num_used_sb_mux_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_sb_mux_tb = 0;$/;" v +num_used_sb_tb ./fpga_x2p/spice/spice_globals.c /^int num_used_sb_tb = 0;$/;" v +num_value_prop_pairs ../../libarchfpga/include/physical_types.h /^ int num_value_prop_pairs;$/;" m struct:s_pin_to_pin_annotation +num_voltage_pairs ./power/power.h /^ int num_voltage_pairs;$/;" m struct:s_power_mux_volt_inf +num_wire_drivers ./base/vpr_types.h /^ int num_wire_drivers; \/* UDSD by WMF *\/$/;" m struct:s_rr_node +num_wl ../../libarchfpga/fpga_spice_include/spice_types.h /^ int num_wl; \/* Number of Word Lines in total *\/$/;" m struct:s_mem_bank_info +nx ./base/globals.c /^int nx = 0;$/;" v +nx ./base/globals_declare.h /^int nx, ny;$/;" v +ny ./base/globals.c /^int ny = 0;$/;" v +ny ./base/globals_declare.h /^int nx, ny;$/;" v +object_end ./base/graphics.c /^void object_end() { }$/;" f +object_end ./base/graphics.c /^void object_end() {$/;" f +object_start ./base/graphics.c /^void object_start(int all) { }$/;" f +object_start ./base/graphics.c /^void object_start(int all) {$/;" f +occ ./base/vpr_types.h /^ short occ;$/;" m struct:s_rr_node +occupancy ./base/vpr_types.h /^ float occupancy;$/;" m struct:s_place_region +off ../../libarchfpga/include/ezxml.h /^ size_t off; \/* tag offset from start of parent tag character content *\/$/;" m struct:ezxml +offset ./base/vpr_types.h /^ int offset;$/;" m struct:s_grid_tile +offset_end ../../pcre/SRC/internal.h /^ int offset_end; \/* One past the end *\/$/;" m struct:match_data +offset_max ../../pcre/SRC/internal.h /^ int offset_max; \/* The maximum usable for return data *\/$/;" m struct:match_data +offset_overflow ../../pcre/SRC/internal.h /^ BOOL offset_overflow; \/* Set if too many extractions *\/$/;" m struct:match_data +offset_save ../../pcre/SRC/internal.h /^ int *offset_save; \/* Pointer to start of saved offsets *\/$/;" m struct:recursion_info +offset_vector ../../pcre/SRC/internal.h /^ int *offset_vector; \/* Offset vector *\/$/;" m struct:match_data +offset_vector ../../pcre/SRC/pcre.h /^ int *offset_vector; \/* The offset vector *\/$/;" m struct:pcre_callout_block +offsetof ../../pcre/SRC/internal.h 173;" d +old_num_rr_nodes ./base/draw.c /^static int old_num_rr_nodes = 0;$/;" v file: +olines ./base/read_blif.c /^static int ilines, olines, model_lines, endlines;$/;" v file: +op_clock_freq ../../libarchfpga/fpga_spice_include/spice_types.h /^ float op_clock_freq; \/* Operation clock frequency*\/$/;" m struct:s_spice_stimulate_params +open ../../libarchfpga/ezxml.c 58;" d file: +operator < ./power/PowerSpicedComponent.h /^ const bool operator<(const PowerCallibSize & rhs) {$/;" f class:PowerCallibSize +opin_rr_node ./base/vpr_types.h /^ t_rr_node*** opin_rr_node;$/;" m struct:s_cb +opin_rr_node ./base/vpr_types.h /^ t_rr_node*** opin_rr_node;$/;" m struct:s_sb +opin_rr_node_grid_side ./base/vpr_types.h /^ int** opin_rr_node_grid_side; \/* We need to record the side of a OPIN, because a OPIN may locate on more than one sides *\/$/;" m struct:s_cb +opin_rr_node_grid_side ./base/vpr_types.h /^ int** opin_rr_node_grid_side; \/* We need to record the side of a OPIN, because a OPIN may locate on more than one sides *\/$/;" m struct:s_sb +opin_switch ../../libarchfpga/include/physical_types.h /^ short opin_switch;$/;" m struct:s_segment_inf +opin_switch ./base/vpr_types.h /^ short opin_switch;$/;" m struct:s_seg_details +opin_to_cb ../../libarchfpga/include/physical_types.h /^ boolean opin_to_cb;$/;" m struct:s_type_descriptor +opin_to_wire_switch ./base/vpr_types.h /^ short opin_to_wire_switch; \/* mrFPGA: Xifan TANG*\/$/;" m struct:s_det_routing_arch +opt_def ./fpga_x2p/shell/read_opt_types.h /^ enum opt_default opt_def;$/;" m struct:s_opt_info typeref:enum:s_opt_info::opt_default +opt_default ./fpga_x2p/shell/read_opt_types.h /^enum opt_default {$/;" g +opt_manda ./fpga_x2p/shell/read_opt_types.h /^enum opt_manda {$/;" g +opt_val_type ./fpga_x2p/shell/read_opt_types.h /^enum opt_val_type {$/;" g +opt_with_val ./fpga_x2p/shell/read_opt_types.h /^enum opt_with_val {$/;" g +options ../../pcre/SRC/internal.h /^ unsigned long int options;$/;" m struct:real_pcre +options ../../pcre/SRC/internal.h /^ uschar options;$/;" m struct:pcre_study_data +options ./timing/slre.c /^ enum slre_option options;$/;" m struct:slre typeref:enum:slre::slre_option file: +opts ./fpga_x2p/shell/read_opt_types.h /^ t_opt_info opts[];$/;" m struct:s_cmd_info +opts ./fpga_x2p/shell/shell_types.h /^ t_opt_info* opts;$/;" m struct:s_shell_cmd +ord2utf8 ../../pcre/SRC/pcre.c /^ord2utf8(int cvalue, uschar *buffer)$/;" f file: +ordered ../../libarchfpga/include/ezxml.h /^ ezxml_t ordered; \/* next tag, same section and depth, in original order *\/$/;" m struct:ezxml +ortho_cost_index ./base/vpr_types.h /^ int ortho_cost_index;$/;" m struct:s_rr_indexed_data +out ./power/power.h /^ FILE * out;$/;" m struct:s_power_output +out_edges ./base/vpr_types.h /^ t_tedge *out_edges; \/* [0..num_edges - 1] array of edges fanning out from this tnode.$/;" m struct:s_tnode +out_file_prefix ../../libarchfpga/util.c /^char *out_file_prefix = NULL;$/;" v +out_file_prefix ./base/ReadOptions.h /^ char *out_file_prefix;$/;" m struct:s_options +out_file_prefix ./base/vpr_types.h /^ char *out_file_prefix;$/;" m struct:s_file_name_opts +out_port_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* out_port_name;$/;" m struct:s_spice_model_delay_info +outer ../../pcre/SRC/internal.h /^ struct branch_chain *outer;$/;" m struct:branch_chain typeref:struct:branch_chain::branch_chain +outport_link_pin ../../libarchfpga/include/cad_types.h /^ int outport_link_pin; \/* applicable pin of chain output port *\/$/;" m struct:s_model_chain_pattern +outputFileNames ./base/ReadOptions.c /^static char **outputFileNames = NULL;$/;" v file: +output_blif ./pack/output_blif.c /^void output_blif (t_block *clb, int num_clusters, boolean global_clocks,$/;" f +output_buffer ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_buffer* output_buffer;$/;" m struct:s_spice_model +output_clustering ./pack/output_clustering.c /^void output_clustering(t_block *clb, int num_clusters, boolean global_clocks,$/;" f +output_edges ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_edge** output_edges; \/* [0..num_output_edges] *\/$/;" m struct:s_pb_graph_pin typeref:struct:s_pb_graph_pin::s_pb_graph_edge +output_file ./base/vpr_types.h /^ char *output_file;$/;" m struct:s_packer_opts +output_link_port ../../libarchfpga/include/cad_types.h /^ t_model_ports *output_link_port; \/* pointer to port of chain output *\/$/;" m struct:s_model_chain_pattern +output_log ./power/power_util.c /^void output_log(t_log * log_ptr, FILE * fp) {$/;" f +output_logs ./power/power_util.c /^void output_logs(FILE * fp, t_log * logs, int num_logs) {$/;" f +output_net_tnodes ./base/vpr_types.h /^ struct s_tnode ***output_net_tnodes; \/* [0..num_output_ports-1][0..num_pins -1] correspnding output net tnode *\/$/;" m struct:s_logical_block typeref:struct:s_logical_block::s_tnode +output_nets ./base/vpr_types.h /^ int **output_nets; \/* [0..num_output_ports-1][0..num_port_pins-1] List of output nets connected to this logical_block. *\/$/;" m struct:s_logical_block +output_pin_class_size ../../libarchfpga/include/physical_types.h /^ int *output_pin_class_size; \/* Stores the number of pins that belong to a particular output pin class *\/$/;" m struct:s_pb_graph_node +output_pins ../../libarchfpga/include/physical_types.h /^ char * output_pins;$/;" m struct:s_pin_to_pin_annotation +output_pins ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_pin *** output_pins; \/\/ [0..num_output_ports-1][0..num_pins_per_port-1]$/;" m struct:s_interconnect_pins typeref:struct:s_interconnect_pins::s_pb_graph_pin +output_pins ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin **output_pins; \/* [0..num_output_ports-1] [0..num_port_pins-1]*\/$/;" m struct:s_pb_graph_node +output_pins ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin **output_pins;$/;" m struct:s_pb_graph_edge +output_pins_used ./base/vpr_types.h /^ int **output_pins_used; \/* [0..pb_graph_node->num_pin_classes-1][0..pin_class_size] number of output pins of this class that are used *\/$/;" m struct:s_pb_stats +output_ports_eq_auto_detect ../../libarchfpga/include/physical_types.h /^ boolean output_ports_eq_auto_detect;$/;" m struct:s_type_descriptor +output_string ../../libarchfpga/include/physical_types.h /^ char *output_string;$/;" m struct:s_interconnect +output_thres_pct_fall ../../libarchfpga/fpga_spice_include/spice_types.h /^ float output_thres_pct_fall;$/;" m struct:s_spice_meas_params +output_thres_pct_rise ../../libarchfpga/fpga_spice_include/spice_types.h /^ float output_thres_pct_rise;$/;" m struct:s_spice_meas_params +outputs ../../libarchfpga/include/logic_types.h /^ t_model_ports *outputs; \/* linked list of output ports *\/$/;" m struct:s_model +override_one_rr_node_for_top_primitive_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void override_one_rr_node_for_top_primitive_phy_pb_graph_node(INP t_pb_graph_pin* cur_pb_graph_pin,$/;" f +pack_clb_pin_remap ./base/vpr_types.h /^ boolean pack_clb_pin_remap;$/;" m struct:s_packer_opts +pack_intrinsic_cost ./base/vpr_types.h /^ float pack_intrinsic_cost;$/;" m struct:s_rr_node +pack_pattern ./base/vpr_types.h /^ t_pack_patterns *pack_pattern; \/* If this is a forced_pack molecule, pattern this molecule matches *\/$/;" m struct:s_pack_molecule +pack_pattern_indices ../../libarchfpga/include/physical_types.h /^ int *pack_pattern_indices; \/*[0..num_pack_patterns(of_edge)-1]*\/$/;" m struct:s_pb_graph_edge +pack_pattern_names ../../libarchfpga/include/physical_types.h /^ char **pack_pattern_names; \/*[0..num_pack_patterns(of_edge)-1]*\/$/;" m struct:s_pb_graph_edge +pack_route_time ./base/globals.c /^float pack_route_time = 0.;$/;" v +packed_molecules ./base/vpr_types.h /^ struct s_linked_vptr *packed_molecules; \/* List of t_pack_molecules that this logical block is a part of *\/$/;" m struct:s_logical_block typeref:struct:s_logical_block::s_linked_vptr +packer_algorithm ./base/ReadOptions.h /^ enum e_packer_algorithm packer_algorithm;$/;" m struct:s_options typeref:enum:s_options::e_packer_algorithm +packer_algorithm ./base/vpr_types.h /^ enum e_packer_algorithm packer_algorithm;$/;" m struct:s_packer_opts typeref:enum:s_packer_opts::e_packer_algorithm +pad_loc_file ./base/vpr_types.h /^ char *pad_loc_file;$/;" m struct:s_placer_opts +pad_loc_type ./base/vpr_types.h /^ enum e_pad_loc_type pad_loc_type;$/;" m struct:s_placer_opts typeref:enum:s_placer_opts::e_pad_loc_type +parasitic_net_estimation ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void parasitic_net_estimation() {$/;" f file: +parent ../../libarchfpga/include/ezxml.h /^ ezxml_t parent; \/* parent tag, NULL if current tag is root tag *\/$/;" m struct:ezxml +parent ./power/PowerSpicedComponent.h /^ PowerSpicedComponent * parent;$/;" m class:PowerCallibInputs +parent_mode ../../libarchfpga/include/physical_types.h /^ t_mode * parent_mode;$/;" m struct:s_interconnect +parent_mode ../../libarchfpga/include/physical_types.h /^ t_mode *parent_mode;$/;" m struct:s_pb_type +parent_mode_index ../../libarchfpga/include/physical_types.h /^ int parent_mode_index;$/;" m struct:s_interconnect +parent_node ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_node *parent_node;$/;" m struct:s_pb_graph_pin typeref:struct:s_pb_graph_pin::s_pb_graph_node +parent_node ./route/route_tree_timing.h /^ struct s_rt_node *parent_node;$/;" m struct:s_rt_node typeref:struct:s_rt_node::s_rt_node +parent_pb ./base/vpr_types.h /^ struct s_pb *parent_pb; \/* pointer to parent node *\/$/;" m struct:s_pb typeref:struct:s_pb::s_pb +parent_pb ./fpga_x2p/base/fpga_x2p_types.h /^ t_phy_pb *parent_pb; \/* pointer to parent node *\/$/;" m struct:fpga_spice_phy_pb +parent_pb_graph_node ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_node *parent_pb_graph_node;$/;" m struct:s_pb_graph_node typeref:struct:s_pb_graph_node::s_pb_graph_node +parent_pb_type ../../libarchfpga/include/physical_types.h /^ struct s_pb_type *parent_pb_type;$/;" m struct:s_mode typeref:struct:s_mode::s_pb_type +parent_pb_type ../../libarchfpga/include/physical_types.h /^ struct s_pb_type *parent_pb_type;$/;" m struct:s_port typeref:struct:s_port::s_pb_type +parent_pin_class ../../libarchfpga/include/physical_types.h /^ int *parent_pin_class; \/* [0..depth-1] the grouping of pins that this particular pin belongs to *\/$/;" m struct:s_pb_graph_pin +parent_spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* parent_spice_model;$/;" m struct:s_conf_bit_info +parent_spice_model_index ../../libarchfpga/fpga_spice_include/spice_types.h /^ int parent_spice_model_index;$/;" m struct:s_conf_bit_info +parent_switch ./route/route_tree_timing.h /^ short parent_switch;$/;" m struct:s_rt_node +parse_direct_pin_name ./util/vpr_utils.c /^void parse_direct_pin_name(char * src_string, int line, int * start_pin_index, $/;" f +partition ./fpga_x2p/base/quicksort.c /^int partition(int len, float* sort_value, int pivot_index) {$/;" f file: +partition_index ./fpga_x2p/base/quicksort.c /^int partition_index(int len, int* sort_index, $/;" f file: +pass_gate_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_pass_gate_logic* pass_gate_info;$/;" m struct:s_spice_model_design_tech_info +pass_gate_logic ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_pass_gate_logic* pass_gate_logic;$/;" m struct:s_spice_model +path ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* path;$/;" m struct:s_spice_model_netlist +path ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* path;$/;" m struct:s_spice_tech_lib +path_cost ./route/route_common.h /^ float path_cost;$/;" m struct:__anon15 +path_criticality ./base/vpr_types.h /^ float ** path_criticality;$/;" m struct:s_slack +pathfinder_update_cost ./route/route_common.c /^void pathfinder_update_cost(float pres_fac, float acc_fac) {$/;" f +pathfinder_update_one_cost ./route/route_common.c /^void pathfinder_update_one_cost(struct s_trace *route_segment_start,$/;" f +pathfinder_update_rr_graph_cost ./fpga_x2p/router/fpga_x2p_router.c /^void pathfinder_update_rr_graph_cost(t_rr_graph* local_rr_graph,$/;" f +pathfinder_update_rr_graph_one_cost ./fpga_x2p/router/fpga_x2p_router.c /^void pathfinder_update_rr_graph_one_cost(t_rr_graph* local_rr_graph, $/;" f +pattern_index ../../libarchfpga/include/cad_types.h /^ int pattern_index; \/* index of pattern that this block is a part of *\/$/;" m struct:s_pack_pattern_block +pattern_length ../../libarchfpga/include/physical_types.h /^ int pattern_length;$/;" m struct:s_swseg_pattern_inf +patterns ../../libarchfpga/include/physical_types.h /^ boolean* patterns;$/;" m struct:s_swseg_pattern_inf +pb ./base/verilog_writer.h /^ t_pb *pb;$/;" m struct:found_pins +pb ./base/vpr_types.h /^ t_pb *pb;$/;" m struct:s_block +pb ./base/vpr_types.h /^ t_pb* pb; \/* pb primitive that this block is packed into *\/$/;" m struct:s_logical_block +pb ./base/vpr_types.h /^ t_pb* pb;$/;" m struct:s_rr_node +pb_graph_head ../../libarchfpga/include/physical_types.h /^ t_pb_graph_node *pb_graph_head;$/;" m struct:s_type_descriptor +pb_graph_node ../../libarchfpga/include/cad_types.h /^ t_pb_graph_node *pb_graph_node;$/;" m struct:s_cluster_placement_primitive +pb_graph_node ./base/vpr_types.h /^ t_pb_graph_node *pb_graph_node; \/* pointer to pb_graph_node this pb corresponds to *\/$/;" m struct:s_pb +pb_graph_node ./fpga_x2p/base/fpga_x2p_types.h /^ t_pb_graph_node *pb_graph_node; \/* pointer to pb_graph_node this pb corresponds to *\/$/;" m struct:fpga_spice_phy_pb +pb_graph_pin ./base/vpr_types.h /^ t_pb_graph_pin *pb_graph_pin; \/* pb_graph_pin that this block is connected to *\/$/;" m struct:s_tnode +pb_graph_pin ./base/vpr_types.h /^ t_pb_graph_pin *pb_graph_pin;$/;" m struct:s_rr_node +pb_list ./base/verilog_writer.h /^}pb_list;$/;" t typeref:struct:found_pins +pb_max_internal_delay ./base/globals.c /^float pb_max_internal_delay = UNDEFINED; \/* biggest internal delay of physical block *\/$/;" v +pb_node_power ../../libarchfpga/include/physical_types.h /^ t_pb_graph_node_power * pb_node_power;$/;" m struct:s_pb_graph_node +pb_pin_density ./fpga_x2p/base/fpga_x2p_utils.c /^float pb_pin_density(t_rr_node* pb_rr_graph, $/;" f +pb_pin_init_value ./fpga_x2p/base/fpga_x2p_utils.c /^int pb_pin_init_value(t_rr_node* pb_rr_graph, $/;" f +pb_pin_net_num ./fpga_x2p/base/fpga_x2p_utils.c /^int pb_pin_net_num(t_rr_node* pb_rr_graph, $/;" f +pb_pin_probability ./fpga_x2p/base/fpga_x2p_utils.c /^float pb_pin_probability(t_rr_node* pb_rr_graph, $/;" f +pb_stats ./base/vpr_types.h /^ struct s_pb_stats *pb_stats; \/* statistics for current pb *\/$/;" m struct:s_pb typeref:struct:s_pb::s_pb_stats +pb_type ../../libarchfpga/include/cad_types.h /^ const t_pb_type *pb_type; \/* pb_type that this block is an instance of *\/$/;" m struct:s_pack_pattern_block +pb_type ../../libarchfpga/include/physical_types.h /^ struct s_pb_type *pb_type;$/;" m struct:s_pb_graph_node typeref:struct:s_pb_graph_node::s_pb_type +pb_type ../../libarchfpga/include/physical_types.h /^ struct s_pb_type *pb_type;$/;" m struct:s_type_descriptor typeref:struct:s_type_descriptor::s_pb_type +pb_type_children ../../libarchfpga/include/physical_types.h /^ struct s_pb_type *pb_type_children; \/* [0..num_child_pb_types] *\/$/;" m struct:s_mode typeref:struct:s_mode::s_pb_type +pb_type_power ../../libarchfpga/include/physical_types.h /^ t_pb_type_power * pb_type_power;$/;" m struct:s_pb_type +pb_types ../../libarchfpga/include/logic_types.h /^ struct s_linked_vptr *pb_types; \/* Physical block types that implement this model *\/$/;" m struct:s_model typeref:struct:s_model::s_linked_vptr +pbtype_max_internal_delay ./base/globals.c /^const t_pb_type *pbtype_max_internal_delay = NULL; \/* physical block type with highest internal delay *\/$/;" v +pchars ../../pcre/SRC/pcre.c /^pchars(const uschar *p, int length, BOOL is_subject, match_data *md)$/;" f file: +pcre ../../pcre/SRC/pcre.h /^typedef struct real_pcre pcre;$/;" t typeref:struct:real_pcre +pcre_callout ../../pcre/SRC/pcre.c /^int (*pcre_callout)(pcre_callout_block *) = NULL;$/;" v +pcre_callout ../../pcre/SRC/pcre.h /^PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *);$/;" v +pcre_callout_block ../../pcre/SRC/pcre.h /^typedef struct pcre_callout_block {$/;" s +pcre_callout_block ../../pcre/SRC/pcre.h /^} pcre_callout_block;$/;" t typeref:struct:pcre_callout_block +pcre_compile ../../pcre/SRC/pcre.c /^pcre_compile(const char *pattern, int options, const char **errorptr,$/;" f +pcre_config ../../pcre/SRC/pcre.c /^pcre_config(int what, void *where)$/;" f +pcre_copy_named_substring ../../pcre/SRC/get.c /^pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,$/;" f +pcre_copy_substring ../../pcre/SRC/get.c /^pcre_copy_substring(const char *subject, int *ovector, int stringcount,$/;" f +pcre_default_tables ../../pcre/SRC/chartables.h /^static unsigned char pcre_default_tables[] = {$/;" v +pcre_exec ../../pcre/SRC/pcre.c /^pcre_exec(const pcre *external_re, const pcre_extra *extra_data,$/;" f +pcre_extra ../../pcre/SRC/pcre.h /^typedef struct pcre_extra {$/;" s +pcre_extra ../../pcre/SRC/pcre.h /^} pcre_extra;$/;" t typeref:struct:pcre_extra +pcre_free ../../pcre/SRC/pcre.c /^void (*pcre_free)(void *) = free;$/;" v +pcre_free ../../pcre/SRC/pcre.h /^PCRE_DATA_SCOPE void (*pcre_free)(void *);$/;" v +pcre_free_substring ../../pcre/SRC/get.c /^pcre_free_substring(char *pointer)$/;" f +pcre_free_substring_list ../../pcre/SRC/get.c /^pcre_free_substring_list(const char **pointer)$/;" f +pcre_fullinfo ../../pcre/SRC/pcre.c /^pcre_fullinfo(const pcre *external_re, const pcre_extra *extra_data, int what,$/;" f +pcre_get_named_substring ../../pcre/SRC/get.c /^pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,$/;" f +pcre_get_stringnumber ../../pcre/SRC/get.c /^pcre_get_stringnumber(const pcre *code, const char *stringname)$/;" f +pcre_get_substring ../../pcre/SRC/get.c /^pcre_get_substring(const char *subject, int *ovector, int stringcount,$/;" f +pcre_get_substring_list ../../pcre/SRC/get.c /^pcre_get_substring_list(const char *subject, int *ovector, int stringcount,$/;" f +pcre_info ../../pcre/SRC/pcre.c /^pcre_info(const pcre *external_re, int *optptr, int *first_byte)$/;" f +pcre_malloc ../../pcre/SRC/pcre.c /^void *(*pcre_malloc)(size_t) = malloc;$/;" v +pcre_malloc ../../pcre/SRC/pcre.h /^PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t);$/;" v +pcre_memmove ../../pcre/SRC/internal.h /^pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n)$/;" f +pcre_study_data ../../pcre/SRC/internal.h /^typedef struct pcre_study_data {$/;" s +pcre_study_data ../../pcre/SRC/internal.h /^} pcre_study_data;$/;" t typeref:struct:pcre_study_data +pcre_version ../../pcre/SRC/pcre.c /^pcre_version(void)$/;" f +peak ../../libarchfpga/include/physical_types.h /^ float peak;$/;" m struct:s_chan +period ../../libarchfpga/include/physical_types.h /^ float period; \/* Period of clock *\/$/;" m struct:s_clock_network +period ./timing/read_sdc.c /^ float period;$/;" m struct:s_sdc_clock file: +pfreq ./base/vpr_types.h /^enum pfreq {$/;" g +phy_mode_pin_rotate_offset_acc ../../libarchfpga/include/physical_types.h /^ int phy_mode_pin_rotate_offset_acc; \/* The pin number will rotate by an offset unit when mapping to physical modes *\/$/;" m struct:s_port +phy_pb ./base/vpr_types.h /^ void* phy_pb;$/;" m struct:s_block +phy_pb ./base/vpr_types.h /^ void* phy_pb;$/;" m struct:s_pb +phy_pb_type ../../libarchfpga/include/physical_types.h /^ struct s_pb_type* phy_pb_type;$/;" m struct:s_pb_type typeref:struct:s_pb_type::s_pb_type +phy_pb_type_port ../../libarchfpga/include/physical_types.h /^ t_port* phy_pb_type_port;$/;" m struct:s_port +phy_pb_type_port_lsb ../../libarchfpga/include/physical_types.h /^ int phy_pb_type_port_lsb;$/;" m struct:s_port +phy_pb_type_port_msb ../../libarchfpga/include/physical_types.h /^ int phy_pb_type_port_msb;$/;" m struct:s_port +physical_mode_name ../../libarchfpga/include/physical_types.h /^ char* physical_mode_name;$/;" m struct:s_pb_type +physical_mode_num_conf_bits ../../libarchfpga/include/physical_types.h /^ int physical_mode_num_conf_bits;$/;" m struct:s_pb_type +physical_mode_num_iopads ../../libarchfpga/include/physical_types.h /^ int physical_mode_num_iopads;$/;" m struct:s_pb_type +physical_mode_num_reserved_conf_bits ../../libarchfpga/include/physical_types.h /^ int physical_mode_num_reserved_conf_bits;$/;" m struct:s_pb_type +physical_mode_pin ../../libarchfpga/include/physical_types.h /^ char* physical_mode_pin;$/;" m struct:s_port +physical_mode_pin_rotate_offset ../../libarchfpga/include/physical_types.h /^ int physical_mode_pin_rotate_offset; \/* The pin number will rotate by an offset unit when mapping to physical modes *\/$/;" m struct:s_port +physical_pb_graph_node ../../libarchfpga/include/physical_types.h /^ t_pb_graph_node* physical_pb_graph_node; \/* physical pb_graph_node *\/$/;" m struct:s_pb_graph_node +physical_pb_graph_pin ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin* physical_pb_graph_pin;$/;" m struct:s_pb_graph_pin +physical_pb_type_index_factor ../../libarchfpga/include/physical_types.h /^ float physical_pb_type_index_factor;$/;" m struct:s_pb_type +physical_pb_type_index_offset ../../libarchfpga/include/physical_types.h /^ int physical_pb_type_index_offset;$/;" m struct:s_pb_type +physical_pb_type_name ../../libarchfpga/include/physical_types.h /^ char* physical_pb_type_name;$/;" m struct:s_pb_type +pi ../../libarchfpga/include/ezxml.h /^ char ***pi; \/* processing instructions *\/$/;" m struct:ezxml_root +pic_on_screen ./base/draw.c /^static enum pic_type pic_on_screen = NO_PICTURE; \/* What do I draw? *\/$/;" v typeref:enum:pic_type file: +pic_type ./base/vpr_types.h /^enum pic_type {$/;" g +pin_and_chan_adjacent ./route/check_route.c /^static int pin_and_chan_adjacent(int pin_node, int chan_node) {$/;" f file: +pin_class ../../libarchfpga/include/physical_types.h /^ int *pin_class; \/* [0..num_pins-1] *\/$/;" m struct:s_type_descriptor +pin_class ../../libarchfpga/include/physical_types.h /^ int pin_class;$/;" m struct:s_pb_graph_pin +pin_count_in_cluster ../../libarchfpga/include/physical_types.h /^ int pin_count_in_cluster;$/;" m struct:s_pb_graph_pin +pin_count_in_cluster ./pack/pb_type_graph.c /^static int pin_count_in_cluster;$/;" v file: +pin_criticality ./place/timing_place_lookup.c /^static float *pin_criticality;$/;" v file: +pin_dens ./power/power_util.c /^float pin_dens(t_pb * pb, t_pb_graph_pin * pin) {$/;" f +pin_height ../../libarchfpga/include/physical_types.h /^ int *pin_height; \/* [0..num_pins-1] *\/$/;" m struct:s_type_descriptor +pin_index_per_side ../../libarchfpga/include/physical_types.h /^ int* pin_index_per_side;$/;" m struct:s_type_descriptor +pin_loc_assignments ../../libarchfpga/include/physical_types.h /^ char ****pin_loc_assignments; \/* [0..height-1][0..3][0..num_tokens-1][0..string_name] *\/$/;" m struct:s_type_descriptor +pin_location_distribution ../../libarchfpga/include/physical_types.h /^ enum e_pin_location_distr pin_location_distribution;$/;" m struct:s_type_descriptor typeref:enum:s_type_descriptor::e_pin_location_distr +pin_number ../../libarchfpga/include/physical_types.h /^ int pin_number;$/;" m struct:s_pb_graph_pin +pin_power ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin_power * pin_power;$/;" m struct:s_pb_graph_pin +pin_prefer_side ./base/vpr_types.h /^ int** pin_prefer_side; \/* [0..num_pins-1][0..3] *\/$/;" m struct:s_block +pin_prob ./power/power_util.c /^float pin_prob(t_pb * pb, t_pb_graph_pin * pin) {$/;" f +pin_ptc_to_side ../../libarchfpga/include/physical_types.h /^ int* pin_ptc_to_side;$/;" m struct:s_type_descriptor +pin_side_count ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int pin_side_count(int pin_side[]) {$/;" f +pin_size ./base/draw.c /^static float tile_width, pin_size;$/;" v file: +pin_timing ../../libarchfpga/include/physical_types.h /^ struct s_pb_graph_pin** pin_timing; \/* primitive ipin to opin timing *\/$/;" m struct:s_pb_graph_pin typeref:struct:s_pb_graph_pin::s_pb_graph_pin +pin_timing_del_max ../../libarchfpga/include/physical_types.h /^ float *pin_timing_del_max; \/* primitive ipin to opin timing *\/$/;" m struct:s_pb_graph_pin +pin_toggle_initialized ../../libarchfpga/include/physical_types.h /^ boolean pin_toggle_initialized;$/;" m struct:s_port_power +pinlist ../../libarchfpga/include/physical_types.h /^ int *pinlist; \/* [0..num_pins - 1] *\/$/;" m struct:s_class +pinloc ../../libarchfpga/include/physical_types.h /^ int ***pinloc; \/* [0..height-1][0..3][0..num_pins-1] *\/$/;" m struct:s_type_descriptor +pl_macros ./place/place.c /^static t_pl_macro * pl_macros = NULL;$/;" v file: +place_algorithm ./base/vpr_types.h /^ enum e_place_algorithm place_algorithm;$/;" m struct:s_placer_opts typeref:enum:s_placer_opts::e_place_algorithm +place_and_route ./base/place_and_route.c /^void place_and_route(enum e_operation operation,$/;" f +place_chan_width ./base/vpr_types.h /^ int place_chan_width;$/;" m struct:s_placer_opts +place_clb_pin_remap ./base/vpr_types.h /^ boolean place_clb_pin_remap;$/;" m struct:s_placer_opts +place_cost_exp ./base/ReadOptions.h /^ float place_cost_exp;$/;" m struct:s_options +place_cost_exp ./base/vpr_types.h /^ float place_cost_exp;$/;" m struct:s_placer_opts +place_exp_first ./base/ReadOptions.h /^ float place_exp_first;$/;" m struct:s_options +place_exp_last ./base/ReadOptions.h /^ float place_exp_last;$/;" m struct:s_options +place_freq ./base/vpr_types.h /^ enum pfreq place_freq;$/;" m struct:s_placer_opts typeref:enum:s_placer_opts::pfreq +placement_index ../../libarchfpga/include/physical_types.h /^ int placement_index;$/;" m struct:s_pb_graph_node +placement_index_in_top_node ../../libarchfpga/include/physical_types.h /^ int placement_index_in_top_node; \/* index at the top-level pb_graph node *\/$/;" m struct:s_pb_graph_node +pmos_size ../../libarchfpga/fpga_spice_include/spice_types.h /^ float pmos_size;$/;" m struct:s_spice_model_pass_gate_logic +pmos_subckt_name ./fpga_x2p/spice/spice_globals.c /^char* pmos_subckt_name = "vpr_pmos";$/;" v +pn_ratio ../../libarchfpga/fpga_spice_include/spice_types.h /^ float pn_ratio;$/;" m struct:s_spice_tech_lib +point_to_point_delay_cost ./place/place.c /^static float **point_to_point_delay_cost = NULL;$/;" v file: +point_to_point_timing_cost ./place/place.c /^static float **point_to_point_timing_cost = NULL;$/;" v file: +poly ./base/graphics.c /^ int poly[3][2]; $/;" m struct:__anon4 file: +port ../../libarchfpga/include/physical_types.h /^ t_port *port;$/;" m struct:s_pb_graph_pin +port_class ../../libarchfpga/include/physical_types.h /^ char * port_class;$/;" m struct:s_port +port_index_by_type ../../libarchfpga/include/physical_types.h /^ int port_index_by_type;$/;" m struct:s_port +port_info_initialized ../../libarchfpga/include/physical_types.h /^ boolean port_info_initialized;$/;" m struct:s_interconnect_power +port_power ../../libarchfpga/include/physical_types.h /^ t_port_power * port_power;$/;" m struct:s_port +ports ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_port* ports;$/;" m struct:s_spice_model +ports ../../libarchfpga/include/physical_types.h /^ t_port *ports; \/* [0..num_ports] *\/$/;" m struct:s_pb_type +posix_class_maps ../../pcre/SRC/pcre.c /^static const int posix_class_maps[] = {$/;" v file: +posix_name_lengths ../../pcre/SRC/pcre.c /^static const uschar posix_name_lengths[] = {$/;" v file: +posix_names ../../pcre/SRC/pcre.c /^static const char *posix_names[] = {$/;" v file: +post ../../libarchfpga/fpga_spice_include/spice_types.h /^ int post;$/;" m struct:s_spice_params +post_place_sync ./base/place_and_route.c /^void post_place_sync(INP int L_num_blocks,$/;" f +postscript ./base/graphics.c /^postscript (void (*drawscreen) (void)) $/;" f file: +power ../../libarchfpga/include/physical_types.h /^ t_power_arch * power;$/;" m struct:s_arch +power ./power/PowerSpicedComponent.h /^ float power;$/;" m class:PowerCallibSize +power_MTAs ./power/power_sizing.c /^static double power_MTAs(float W_size) {$/;" f file: +power_MTAs_L ./power/power_sizing.c /^static double power_MTAs_L(float L_size) {$/;" f file: +power_add_usage ./power/power_util.c /^void power_add_usage(t_power_usage * dest, const t_power_usage * src) {$/;" f +power_alloc_and_init_pb_pin ./power/power.c /^void power_alloc_and_init_pb_pin(t_pb_graph_pin * pin) {$/;" f +power_buffer_size ../../libarchfpga/include/physical_types.h /^ float power_buffer_size;$/;" m struct:s_switch_inf +power_buffer_size_from_logical_effort ./power/power_util.c /^float power_buffer_size_from_logical_effort(float C_load) {$/;" f +power_buffer_type ../../libarchfpga/include/physical_types.h /^ e_power_buffer_type power_buffer_type;$/;" m struct:s_switch_inf +power_calc_buffer_num_stages ./power/power_util.c /^int power_calc_buffer_num_stages(float final_stage_size,$/;" f +power_calc_buffer_size_from_Cout ./power/power_lowlevel.c /^float power_calc_buffer_size_from_Cout(float C_out) {$/;" f +power_calc_leakage_gate ./power/power_lowlevel.c /^static float power_calc_leakage_gate(e_tx_type transistor_type, float size) {$/;" f file: +power_calc_leakage_st ./power/power_lowlevel.c /^static float power_calc_leakage_st(e_tx_type transistor_type, float size) {$/;" f file: +power_calc_leakage_st_pass_transistor ./power/power_lowlevel.c /^static float power_calc_leakage_st_pass_transistor(float size, float v_ds) {$/;" f file: +power_calc_mux_v_out ./power/power_lowlevel.c /^float power_calc_mux_v_out(int num_inputs, float transistor_size, float v_in,$/;" f +power_calc_node_switching ./power/power_lowlevel.c /^float power_calc_node_switching(float capacitance, float density,$/;" f +power_calc_node_switching_v ./power/power_lowlevel.c /^static float power_calc_node_switching_v(float capacitance, float density,$/;" f file: +power_calc_transistor_capacitance ./power/power_lowlevel.c /^static void power_calc_transistor_capacitance(float *C_d, float *C_s,$/;" f file: +power_callib_period ./power/power_callibrate.h /^const float power_callib_period = 5e-9;$/;" v +power_callibrate ./power/power_callibrate.c /^void power_callibrate(void) {$/;" f +power_compare_buffer_sc_levr ./power/power_cmos_tech.c /^static int power_compare_buffer_sc_levr(const void * key_void,$/;" f file: +power_compare_buffer_strength ./power/power_cmos_tech.c /^static int power_compare_buffer_strength(const void * key_void,$/;" f file: +power_compare_leakage_pair ./power/power_cmos_tech.c /^static int power_compare_leakage_pair(const void * key_void,$/;" f file: +power_compare_transistor_size ./power/power_cmos_tech.c /^static int power_compare_transistor_size(const void * key_void,$/;" f file: +power_compare_voltage_pair ./power/power_cmos_tech.c /^static int power_compare_voltage_pair(const void * key_void,$/;" f file: +power_component_add_usage ./power/power_components.c /^void power_component_add_usage(t_power_usage * power_usage,$/;" f +power_component_get_usage ./power/power_components.c /^void power_component_get_usage(t_power_usage * power_usage,$/;" f +power_component_get_usage_sum ./power/power_components.c /^float power_component_get_usage_sum(e_power_component_type component_idx) {$/;" f +power_components_init ./power/power_components.c /^void power_components_init(void) {$/;" f +power_components_uninit ./power/power_components.c /^void power_components_uninit(void) {$/;" f +power_count_transistor_SRAM_bit ./power/power_sizing.c /^static double power_count_transistor_SRAM_bit(void) {$/;" f file: +power_count_transistors_FF ./power/power_sizing.c /^static double power_count_transistors_FF(float size) {$/;" f file: +power_count_transistors_LUT ./power/power_sizing.c /^static double power_count_transistors_LUT(int LUT_inputs,$/;" f file: +power_count_transistors_buffer ./power/power_sizing.c /^double power_count_transistors_buffer(float buffer_size) {$/;" f +power_count_transistors_connectionbox ./power/power_sizing.c /^static double power_count_transistors_connectionbox(void) {$/;" f file: +power_count_transistors_interc ./power/power_sizing.c /^static double power_count_transistors_interc(t_interconnect * interc) {$/;" f file: +power_count_transistors_inv ./power/power_sizing.c /^static double power_count_transistors_inv(float size) {$/;" f file: +power_count_transistors_levr ./power/power_sizing.c /^static double power_count_transistors_levr() {$/;" f file: +power_count_transistors_mux ./power/power_sizing.c /^static double power_count_transistors_mux(t_mux_arch * mux_arch) {$/;" f file: +power_count_transistors_mux_node ./power/power_sizing.c /^static double power_count_transistors_mux_node(t_mux_node * mux_node,$/;" f file: +power_count_transistors_pb_node ./power/power_sizing.c /^static double power_count_transistors_pb_node(t_pb_graph_node * pb_node) {$/;" f file: +power_count_transistors_primitive ./power/power_sizing.c /^static double power_count_transistors_primitive(t_pb_type * pb_type) {$/;" f file: +power_count_transistors_switchbox ./power/power_sizing.c /^static double power_count_transistors_switchbox(t_arch * arch) {$/;" f file: +power_count_transistors_trans_gate ./power/power_sizing.c /^static double power_count_transistors_trans_gate(float size) {$/;" f file: +power_estimation_method_name ./power/power.c /^static char * power_estimation_method_name($/;" f file: +power_find_buffer_sc_levr ./power/power_cmos_tech.c /^void power_find_buffer_sc_levr(t_power_buffer_sc_levr_inf ** lower,$/;" f +power_find_buffer_strength_inf ./power/power_cmos_tech.c /^void power_find_buffer_strength_inf(t_power_buffer_strength_inf ** lower,$/;" f +power_find_mux_volt_inf ./power/power_cmos_tech.c /^void power_find_mux_volt_inf(t_power_mux_volt_pair ** lower,$/;" f +power_find_nmos_leakage ./power/power_cmos_tech.c /^void power_find_nmos_leakage(t_power_nmos_leakage_inf * nmos_leakage_info,$/;" f +power_find_transistor_info ./power/power_cmos_tech.c /^boolean power_find_transistor_info(t_transistor_size_inf ** lower,$/;" f +power_gated ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean power_gated;$/;" m struct:s_spice_model_design_tech_info +power_get_mux_arch ./power/power_util.c /^t_mux_arch * power_get_mux_arch(int num_mux_inputs, float transistor_size) {$/;" f +power_init ./power/power.c /^boolean power_init(char * power_out_filepath,$/;" f +power_init_pb_pins_rec ./power/power.c /^void power_init_pb_pins_rec(t_pb_graph_node * pb_node) {$/;" f +power_log_msg ./power/power_util.c /^void power_log_msg(e_power_log_type log_type, char * msg) {$/;" f +power_lowlevel_init ./power/power_lowlevel.c /^void power_lowlevel_init() {$/;" f +power_method_inherited ../../libarchfpga/read_xml_arch_file.c /^e_power_estimation_method power_method_inherited($/;" f +power_method_is_recursive ./power/power_util.c /^boolean power_method_is_recursive(e_power_estimation_method method) {$/;" f +power_method_is_transistor_level ./power/power_util.c /^boolean power_method_is_transistor_level($/;" f +power_mux_node_max_inputs ./power/power_sizing.c /^static void power_mux_node_max_inputs(t_mux_node * mux_node,$/;" f file: +power_pb_pins_init ./power/power.c /^void power_pb_pins_init() {$/;" f +power_perc_dynamic ./power/power_util.c /^float power_perc_dynamic(t_power_usage * power_usage) {$/;" f +power_print_breakdown_component ./power/power.c /^static void power_print_breakdown_component(FILE * fp, char * name,$/;" f file: +power_print_breakdown_entry ./power/power.c /^static void power_print_breakdown_entry(FILE * fp, int indent,$/;" f file: +power_print_breakdown_pb ./power/power.c /^static void power_print_breakdown_pb(FILE * fp) {$/;" f file: +power_print_breakdown_pb_rec ./power/power.c /^static void power_print_breakdown_pb_rec(FILE * fp, t_pb_type * pb_type,$/;" f file: +power_print_breakdown_summary ./power/power.c /^static void power_print_breakdown_summary(FILE * fp) {$/;" f file: +power_print_spice_comparison ./power/power_callibrate.c /^void power_print_spice_comparison(void) {$/;" f +power_print_summary ./power/power.c /^static void power_print_summary(FILE * fp, t_vpr_setup vpr_setup) {$/;" f file: +power_print_title ./power/power_util.c /^void power_print_title(FILE * fp, char * title) {$/;" f +power_reset_pb_type ./power/power.c /^static void power_reset_pb_type(t_pb_type * pb_type) {$/;" f file: +power_reset_tile_usage ./power/power.c /^static void power_reset_tile_usage(void) {$/;" f file: +power_routing_init ./power/power.c /^void power_routing_init(t_det_routing_arch * routing_arch) {$/;" f +power_scale_usage ./power/power_util.c /^void power_scale_usage(t_power_usage * power_usage, float scale_factor) {$/;" f +power_size_pb ./power/power_sizing.c /^static void power_size_pb(void) {$/;" f file: +power_size_pb_rec ./power/power_sizing.c /^static void power_size_pb_rec(t_pb_graph_node * pb_node) {$/;" f file: +power_size_pin_buffers_and_wires ./power/power_sizing.c /^static void power_size_pin_buffers_and_wires(t_pb_graph_pin * pin,$/;" f file: +power_size_pin_to_interconnect ./power/power_sizing.c /^static void power_size_pin_to_interconnect(t_interconnect * interc,$/;" f file: +power_sizing_init ./power/power_sizing.c /^void power_sizing_init(t_arch * arch) {$/;" f +power_sum_usage ./power/power_util.c /^float power_sum_usage(t_power_usage * power_usage) {$/;" f +power_tech_init ./power/power_cmos_tech.c /^void power_tech_init(char * cmos_tech_behavior_filepath) {$/;" f +power_tech_load_xml_file ./power/power_cmos_tech.c /^void power_tech_load_xml_file(char * cmos_tech_behavior_filepath) {$/;" f +power_tech_xml_load_component ./power/power_cmos_tech.c /^static void power_tech_xml_load_component(ezxml_t parent,$/;" f file: +power_tech_xml_load_components ./power/power_cmos_tech.c /^static void power_tech_xml_load_components(ezxml_t parent) {$/;" f file: +power_tech_xml_load_multiplexer_info ./power/power_cmos_tech.c /^static void power_tech_xml_load_multiplexer_info(ezxml_t parent) {$/;" f file: +power_tech_xml_load_nmos_st_leakages ./power/power_cmos_tech.c /^static void power_tech_xml_load_nmos_st_leakages(ezxml_t parent) {$/;" f file: +power_total ./power/power.c /^e_power_ret_code power_total(float * run_time_s, t_vpr_setup vpr_setup,$/;" f +power_transistor_area ./power/power_sizing.c /^double power_transistor_area(double num_MTAs) {$/;" f +power_transistors_for_pb_node ./power/power_sizing.c /^static double power_transistors_for_pb_node(t_pb_graph_node * pb_node) {$/;" f file: +power_transistors_per_tile ./power/power_sizing.c /^static double power_transistors_per_tile(t_arch * arch) {$/;" f file: +power_uninit ./power/power.c /^boolean power_uninit(void) {$/;" f +power_usage ../../libarchfpga/include/physical_types.h /^ t_power_usage power_usage; \/* Power usage of this mode *\/$/;" m struct:s_mode_power +power_usage ../../libarchfpga/include/physical_types.h /^ t_power_usage power_usage; \/* Total power usage of this pb type *\/$/;" m struct:s_pb_type_power +power_usage ../../libarchfpga/include/physical_types.h /^ t_power_usage power_usage;$/;" m struct:s_interconnect_power +power_usage_MUX2_transmission ./power/power_lowlevel.c /^void power_usage_MUX2_transmission(t_power_usage * power_usage, float size,$/;" f +power_usage_blocks ./power/power.c /^static void power_usage_blocks(t_power_usage * power_usage) {$/;" f file: +power_usage_buf_for_callibration ./power/power_callibrate.c /^float power_usage_buf_for_callibration(int num_inputs, float transistor_size) {$/;" f +power_usage_buf_levr_for_callibration ./power/power_callibrate.c /^float power_usage_buf_levr_for_callibration(int num_inputs,$/;" f +power_usage_buffer ./power/power_components.c /^void power_usage_buffer(t_power_usage * power_usage, float size, float in_prob,$/;" f +power_usage_bufs_wires ../../libarchfpga/include/physical_types.h /^ t_power_usage power_usage_bufs_wires; \/* Power dissipated in local buffers and wire switching (Subset of total power) *\/$/;" m struct:s_pb_type_power +power_usage_clock ./power/power.c /^static void power_usage_clock(t_power_usage * power_usage,$/;" f file: +power_usage_clock_single ./power/power.c /^static void power_usage_clock_single(t_power_usage * power_usage,$/;" f file: +power_usage_ff ./power/power_components.c /^void power_usage_ff(t_power_usage * power_usage, float size, float D_prob,$/;" f +power_usage_ff_for_callibration ./power/power_callibrate.c /^float power_usage_ff_for_callibration(int num_inputs, float transistor_size) {$/;" f +power_usage_inverter ./power/power_lowlevel.c /^void power_usage_inverter(t_power_usage * power_usage, float in_dens,$/;" f +power_usage_inverter_irregular ./power/power_lowlevel.c /^void power_usage_inverter_irregular(t_power_usage * power_usage,$/;" f +power_usage_level_restorer ./power/power_lowlevel.c /^void power_usage_level_restorer(t_power_usage * power_usage,$/;" f +power_usage_local_buffers_and_wires ./power/power.c /^static void power_usage_local_buffers_and_wires(t_power_usage * power_usage,$/;" f file: +power_usage_local_interc_mux ./power/power_components.c /^void power_usage_local_interc_mux(t_power_usage * power_usage, t_pb * pb,$/;" f +power_usage_local_pin_buffer_and_wire ./power/power.c /^void power_usage_local_pin_buffer_and_wire(t_power_usage * power_usage,$/;" f +power_usage_local_pin_toggle ./power/power.c /^void power_usage_local_pin_toggle(t_power_usage * power_usage, t_pb * pb,$/;" f +power_usage_lut ./power/power_components.c /^void power_usage_lut(t_power_usage * power_usage, int lut_size,$/;" f +power_usage_lut_for_callibration ./power/power_callibrate.c /^float power_usage_lut_for_callibration(int num_inputs, float transistor_size) {$/;" f +power_usage_mux_for_callibration ./power/power_callibrate.c /^float power_usage_mux_for_callibration(int num_inputs, float transistor_size) {$/;" f +power_usage_mux_multilevel ./power/power_components.c /^void power_usage_mux_multilevel(t_power_usage * power_usage,$/;" f +power_usage_mux_rec ./power/power_components.c /^static void power_usage_mux_rec(t_power_usage * power_usage, float * out_prob,$/;" f file: +power_usage_mux_singlelevel_dynamic ./power/power_lowlevel.c /^void power_usage_mux_singlelevel_dynamic(t_power_usage * power_usage,$/;" f +power_usage_mux_singlelevel_static ./power/power_lowlevel.c /^void power_usage_mux_singlelevel_static(t_power_usage * power_usage,$/;" f +power_usage_pb ./power/power.c /^static void power_usage_pb(t_power_usage * power_usage, t_pb * pb,$/;" f file: +power_usage_primitive ./power/power.c /^static void power_usage_primitive(t_power_usage * power_usage, t_pb * pb,$/;" f file: +power_usage_routing ./power/power.c /^static void power_usage_routing(t_power_usage * power_usage,$/;" f file: +power_usage_wire ./power/power_lowlevel.c /^void power_usage_wire(t_power_usage * power_usage, float capacitance,$/;" f +power_zero_usage ./power/power_util.c /^void power_zero_usage(t_power_usage * power_usage) {$/;" f +prefer_side ./base/vpr_types.h /^ int** prefer_side; \/* [0..num_sinks][0..3] *\/$/;" m struct:s_net +prefix ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* prefix; $/;" m struct:s_spice_model_port +prefix ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* prefix; \/* Prefix when it show up in the spice netlist *\/$/;" m struct:s_spice_model +prepacked_data ./base/vpr_types.h /^ t_prepacked_tnode_data * prepacked_data;$/;" m struct:s_tnode +pres_cost ./route/route_common.h /^ float pres_cost;$/;" m struct:__anon15 +pres_fac ./pack/cluster_legality.c /^static float pres_fac;$/;" v file: +pres_fac_mult ./base/ReadOptions.h /^ float pres_fac_mult;$/;" m struct:s_options +pres_fac_mult ./base/vpr_types.h /^ float pres_fac_mult;$/;" m struct:s_router_opts +prev ../../pcre/SRC/internal.h /^ struct recursion_info *prev; \/* Previous recursion record (or NULL) *\/$/;" m struct:recursion_info typeref:struct:recursion_info::recursion_info +prev ../../pcre/SRC/pcre.c /^ struct eptrblock *prev;$/;" m struct:eptrblock typeref:struct:eptrblock::eptrblock file: +prev_edge ./base/vpr_types.h /^ int prev_edge;$/;" m struct:s_rr_node +prev_edge ./route/route_common.h /^ int prev_edge;$/;" m struct:s_heap +prev_edge ./route/route_common.h /^ short prev_edge;$/;" m struct:__anon15 +prev_edge_in_pack ./base/vpr_types.h /^ int prev_edge_in_pack;$/;" m struct:s_rr_node +prev_node ./base/vpr_types.h /^ int prev_node;$/;" m struct:s_rr_node +prev_node ./route/route_common.h /^ int prev_node;$/;" m union:s_heap::__anon14 +prev_node ./route/route_common.h /^ int prev_node;$/;" m struct:__anon15 +prev_node_in_pack ./base/vpr_types.h /^ int prev_node_in_pack; $/;" m struct:s_rr_node +prevconnectiongainincr ./base/vpr_types.h /^ std::map prevconnectiongainincr; \/* [0..num_logical_blocks-1] Prev sum to weighted sum of connections to attraction function *\/$/;" m struct:s_pb_stats +primitive_feasible ./pack/cluster.c /^static boolean primitive_feasible(int iblk, t_pb *cur_pb) {$/;" f file: +primitive_type_and_memory_feasible ./pack/cluster.c /^static boolean primitive_type_and_memory_feasible(int iblk,$/;" f file: +primitive_type_feasible ./util/vpr_utils.c /^boolean primitive_type_feasible(int iblk, const t_pb_type *cur_pb_type) {$/;" f +printClusteredNetlistStats ./base/ShowSetup.c /^void printClusteredNetlistStats() {$/;" f +print_array ./place/timing_place_lookup.c /^print_array(float **array_to_print,$/;" f file: +print_autocheck_top_testbench ./base/vpr_types.h /^ boolean print_autocheck_top_testbench;$/;" m struct:s_syn_verilog_opts +print_block_criticalities ./pack/cluster.c /^static void print_block_criticalities(const char * fname) {$/;" f file: +print_clb_placement ./place/place.c /^static void print_clb_placement(const char *fname) {$/;" f file: +print_clustering_timing_info ./timing/path_delay.c /^void print_clustering_timing_info(const char *fname) {$/;" f +print_clusters ./pack/output_blif.c /^static void print_clusters(t_block *clb, int num_clusters, FILE * fpout) {$/;" f file: +print_clusters ./pack/output_clustering.c /^static void print_clusters(t_block *clb, int num_clusters, FILE * fpout) {$/;" f file: +print_complete_net_trace ./base/vpr_api.c /^static void print_complete_net_trace(t_trace* trace, const char *file_name) {$/;" f file: +print_critical_path ./timing/path_delay.c /^void print_critical_path(const char *fname) {$/;" f +print_critical_path_node ./timing/path_delay2.c /^float print_critical_path_node(FILE * fp, t_linked_int * critical_path_node) {$/;" f +print_criticality ./timing/path_delay.c /^void print_criticality(t_slack * slacks, boolean criticality_is_normalized, const char *fname) {$/;" f +print_distribution ./route/rr_graph.c /^print_distribution(FILE * fptr,$/;" f file: +print_formal_verification_top_netlist ./base/vpr_types.h /^ boolean print_formal_verification_top_netlist;$/;" m struct:s_syn_verilog_opts +print_global_criticality_stats ./timing/path_delay.c /^static void print_global_criticality_stats(FILE * fp, float ** criticality, const char * singular_name, const char * capitalized_plural_name) {$/;" f file: +print_help ../../libarchfpga/main.c /^void print_help() {$/;" f +print_input_blif_testbench ./base/vpr_types.h /^ boolean print_input_blif_testbench;$/;" m struct:s_syn_verilog_opts +print_int_matrix3 ../../libarchfpga/util.c /^void print_int_matrix3(int ***vptr, int nrmin, int nrmax, int ncmin, int ncmax,$/;" f +print_interconnect ./pack/output_clustering.c /^static void print_interconnect(int inode, int *column, int num_tabs,$/;" f file: +print_lambda ./base/stats.c /^void print_lambda(void) {$/;" f +print_lut_remapping ./timing/path_delay.c /^void print_lut_remapping(const char *fname) {$/;" f +print_modelsim_autodeck ./base/vpr_types.h /^ boolean print_modelsim_autodeck;$/;" m struct:s_syn_verilog_opts +print_net_delay ./timing/path_delay.c /^void print_net_delay(float **net_delay, const char *fname) {$/;" f +print_net_name ./pack/output_blif.c /^static void print_net_name(int inet, int *column, FILE * fpout) {$/;" f file: +print_net_name ./pack/output_clustering.c /^static void print_net_name(int inet, int *column, int num_tabs, FILE * fpout) {$/;" f file: +print_net_opin_llist ./route/pb_pin_eq_auto_detect.c /^void print_net_opin_llist(t_llist* head) {$/;" f +print_net_opin_occupancy ./route/pb_pin_eq_auto_detect.c /^void print_net_opin_occupancy() {$/;" f +print_netlist ./pack/print_netlist.c /^void print_netlist(char *foutput, char *net_file) {$/;" f +print_open_pb_graph_node ./pack/output_clustering.c /^static void print_open_pb_graph_node(t_pb_graph_node * pb_graph_node,$/;" f file: +print_opt_info_help_desk ./fpga_x2p/shell/read_opt.c /^void print_opt_info_help_desk(t_opt_info* cur_opt_info) {$/;" f +print_pack_molecules ./pack/prepack.c /^static void print_pack_molecules(INP const char *fname,$/;" f file: +print_pb ./pack/output_blif.c /^static void print_pb(FILE *fpout, t_pb * pb, int clb_index) {$/;" f file: +print_pb ./pack/output_clustering.c /^static void print_pb(FILE *fpout, t_pb * pb, int pb_index, int tab_depth) {$/;" f file: +print_pinnum ./pack/print_netlist.c /^static void print_pinnum(FILE * fp, int pinnum) {$/;" f file: +print_place ./base/read_place.c /^void print_place(char *place_file, char *net_file, char *arch_file) {$/;" f +print_primitive ./pack/output_blif.c /^static void print_primitive(FILE *fpout, int iblk) {$/;" f file: +print_primitive_as_blif ./timing/path_delay.c /^static void print_primitive_as_blif (FILE *fpout, int iblk) {$/;" f file: +print_relative_pos_distr ./place/place_stats.c /^print_relative_pos_distr(void)$/;" f +print_report_timing_tcl ./base/vpr_types.h /^ boolean print_report_timing_tcl;$/;" m struct:s_syn_verilog_opts +print_route ./route/route_common.c /^void print_route(char *route_file) {$/;" f +print_rr_indexed_data ./route/rr_graph.c /^void print_rr_indexed_data(FILE * fp, int index) {$/;" f +print_rr_node ./route/rr_graph.c /^void print_rr_node(FILE * fp, t_rr_node * L_rr_node, int inode) {$/;" f +print_sdc_analysis ./base/vpr_types.h /^ boolean print_sdc_analysis;$/;" m struct:s_syn_verilog_opts +print_sdc_pnr ./base/vpr_types.h /^ boolean print_sdc_pnr;$/;" m struct:s_syn_verilog_opts +print_sink_delays ./place/timing_place.c /^void print_sink_delays(const char *fname) {$/;" f +print_slack ./timing/path_delay.c /^void print_slack(float ** slack, boolean slack_is_normalized, const char *fname) {$/;" f +print_spaces ./timing/path_delay.c /^static void print_spaces(FILE * fp, int num_spaces) {$/;" f file: +print_stat_memristor_buffer ./mrfpga/buffer_insertion.c /^int print_stat_memristor_buffer( char* fname, float buffer_size )$/;" f +print_stats ./pack/output_clustering.c /^static void print_stats(t_block *clb, int num_clusters) {$/;" f file: +print_string ./pack/output_blif.c /^static void print_string(const char *str_ptr, int *column, FILE * fpout) {$/;" f file: +print_string ./pack/output_clustering.c /^static void print_string(const char *str_ptr, int *column, int num_tabs, FILE * fpout) {$/;" f file: +print_tabs ./pack/output_clustering.c /^static void print_tabs(FILE *fpout, int num_tabs) {$/;" f file: +print_tabs ./util/vpr_utils.c /^void print_tabs(FILE * fpout, int num_tab) {$/;" f +print_thru_pins ./fpga_x2p/verilog/verilog_report_timing.c /^ boolean print_thru_pins;$/;" m struct:s_trpt_opts file: +print_timing_constraint_info ./timing/path_delay.c /^static void print_timing_constraint_info(const char *fname) {$/;" f file: +print_timing_graph ./timing/path_delay.c /^void print_timing_graph(const char *fname) {$/;" f +print_timing_graph_as_blif ./timing/path_delay.c /^void print_timing_graph_as_blif (const char *fname, t_model *models) {$/;" f +print_timing_stats ./timing/path_delay.c /^void print_timing_stats(void) {$/;" f +print_top_testbench ./base/vpr_types.h /^ boolean print_top_testbench;$/;" m struct:s_syn_verilog_opts +print_user_defined_template ./base/vpr_types.h /^ boolean print_user_defined_template;$/;" m struct:s_syn_verilog_opts +print_wirelen_prob_dist ./base/stats.c /^void print_wirelen_prob_dist(void) {$/;" f +priority ../../libarchfpga/include/physical_types.h /^ int priority;$/;" m struct:s_grid_loc_def +private_cmap ./base/graphics.c /^static Colormap private_cmap; \/* "None" unless a private cmap was allocated. *\/$/;" v file: +prob ../../libarchfpga/include/physical_types.h /^ float prob; \/* Static probability of net assigned to this clock *\/$/;" m struct:s_clock_network +probability ../../libarchfpga/fpga_spice_include/spice_types.h /^ float probability;$/;" m struct:s_spice_net_info +probability ./base/vpr_types.h /^ float probability;$/;" m struct:s_net_power +proc_time ./base/place_and_route.h /^ int proc_time;$/;" m struct:s_fmap_cell +proceed ./base/graphics.c /^proceed (void (*drawscreen) (void)) $/;" f file: +processComplexBlock ./base/read_netlist.c /^static void processComplexBlock(INOUTP ezxml_t Parent, INOUTP t_block *cb,$/;" f file: +processPb ./base/read_netlist.c /^static void processPb(INOUTP ezxml_t Parent, INOUTP t_pb* pb,$/;" f file: +processPorts ./base/read_netlist.c /^static void processPorts(INOUTP ezxml_t Parent, INOUTP t_pb* pb,$/;" f file: +process_arg_opt ./fpga_x2p/shell/read_opt.c /^boolean process_arg_opt(INP char** argv,$/;" f +process_constraints ./timing/path_delay.c /^static void process_constraints(void) {$/;" f file: +process_float_arg ./fpga_x2p/shell/read_opt.c /^float process_float_arg(INP char* arg) {$/;" f +process_int_arg ./fpga_x2p/shell/read_opt.c /^int process_int_arg(INP char* arg) {$/;" f +process_settings ./base/read_settings.c /^static int process_settings(ezxml_t Cur, char ** outv)$/;" f file: +process_shell_command ./fpga_x2p/shell/shell_utils.c /^void process_shell_command(char* line, t_shell_env* env) {$/;" f +process_tech_xml_load_transistor_info ./power/power_cmos_tech.c /^static void process_tech_xml_load_transistor_info(ezxml_t parent) {$/;" f file: +prog_clock_freq ../../libarchfpga/fpga_spice_include/spice_types.h /^ float prog_clock_freq; \/* Programming clock frequency, used during programming phase only *\/$/;" m struct:s_spice_stimulate_params +prop ../../libarchfpga/include/physical_types.h /^ int * prop; \/* [0..num_value_prop_pairs - 1] *\/$/;" m struct:s_pin_to_pin_annotation +propagate_clock_domain_and_skew ./timing/path_delay.c /^static void propagate_clock_domain_and_skew(int inode) {$/;" f file: +ps ./base/graphics.c /^static FILE *ps;$/;" v file: +ps_bot ./base/graphics.c /^static float ps_left, ps_right, ps_top, ps_bot; \/* Figure boundaries for *$/;" v file: +ps_cnames ./base/graphics.c /^static const char *ps_cnames[NUM_COLOR] = {"white", "black", "grey55", "grey75",$/;" v file: +ps_left ./base/graphics.c /^static float ps_left, ps_right, ps_top, ps_bot; \/* Figure boundaries for *$/;" v file: +ps_right ./base/graphics.c /^static float ps_left, ps_right, ps_top, ps_bot; \/* Figure boundaries for *$/;" v file: +ps_top ./base/graphics.c /^static float ps_left, ps_right, ps_top, ps_bot; \/* Figure boundaries for *$/;" v file: +ps_xmult ./base/graphics.c /^static float ps_xmult, ps_ymult; \/* Transformation for PostScript. *\/$/;" v file: +ps_xmult ./base/graphics.h /^ float ps_xmult, ps_ymult;$/;" m struct:__anon6 +ps_ymult ./base/graphics.c /^static float ps_xmult, ps_ymult; \/* Transformation for PostScript. *\/$/;" v file: +ps_ymult ./base/graphics.h /^ float ps_xmult, ps_ymult;$/;" m struct:__anon6 +pt_on_object ./base/graphics.c /^int pt_on_object(float x, float y) { }$/;" f +pt_on_object ./base/graphics.c /^int pt_on_object(int all, float x, float y) {$/;" f +ptc_num ./base/vpr_types.h /^ short ptc_num;$/;" m struct:s_rr_node +ptr ./timing/slre.c /^ const char *ptr; \/\/ Pointer to the substring$/;" m struct:cap file: +pwh ../../libarchfpga/fpga_spice_include/spice_types.h /^ float pwh;$/;" m struct:s_spice_net_info +pwl ../../libarchfpga/fpga_spice_include/spice_types.h /^ float pwl;$/;" m struct:s_spice_net_info +quantifier ./timing/slre.c /^static void quantifier(struct slre *r, int prev, int op) {$/;" f file: +quicksort_float ./fpga_x2p/base/quicksort.c /^void quicksort_float(int len, $/;" f +quicksort_float_index ./fpga_x2p/base/quicksort.c /^void quicksort_float_index(int len, $/;" f +quit ./base/graphics.c /^quit (void (*drawscreen) (void)) $/;" f file: +random_top_testbench_verilog_file_postfix ./fpga_x2p/verilog/verilog_global.c /^char* random_top_testbench_verilog_file_postfix = "_formal_random_top_tb.v"; $/;" v +rc_node ./timing/net_delay_types.h /^ struct s_rc_node *rc_node;$/;" m struct:s_linked_rc_ptr typeref:struct:s_linked_rc_ptr::s_rc_node +re_expand ./route/route_tree_timing.h /^ short re_expand;$/;" m struct:s_rt_node +read ../../libarchfpga/ezxml.c 59;" d file: +read_act_file ./base/vpr_types.h /^ boolean read_act_file;$/;" m struct:s_fpga_spice_opts +read_activity ./base/read_blif.c /^static void read_activity(char * activity_file) {$/;" f file: +read_and_process_blif ./base/read_blif.c /^void read_and_process_blif(char *blif_file,$/;" f +read_blif ./base/read_blif.c /^static void read_blif(char *blif_file, boolean sweep_hanging_nets_and_inputs,$/;" f file: +read_netlist ./base/read_netlist.c /^void read_netlist(INP const char *net_file, INP const t_arch *arch,$/;" f +read_options ./fpga_x2p/shell/read_opt.c /^boolean read_options(INP int argc,$/;" f +read_place ./base/read_place.c /^void read_place(INP const char *place_file, INP const char *arch_file,$/;" f +read_repeat_counts ../../pcre/SRC/pcre.c /^read_repeat_counts(const uschar *p, int *minp, int *maxp,$/;" f file: +read_sdc ./timing/read_sdc.c /^void read_sdc(t_timing_inf timing_inf) {$/;" f +read_settings ./base/ReadOptions.h /^ int read_settings;$/;" m struct:s_options +read_settings_file ./base/read_settings.c /^int read_settings_file(char * file_name, char *** outv)$/;" f +read_user_pad_loc ./base/read_place.c /^void read_user_pad_loc(char *pad_loc_file) {$/;" f +read_xml_spice ../../libarchfpga/include/physical_types.h /^ boolean read_xml_spice;$/;" m struct:s_arch +real_pcre ../../pcre/SRC/internal.h /^typedef struct real_pcre {$/;" s +real_pcre ../../pcre/SRC/internal.h /^} real_pcre;$/;" t typeref:struct:real_pcre +realloc_and_load_pb_graph_pin_ptrs_at_var ./pack/pb_type_graph.c /^static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP int line_num,$/;" f file: +reassign_rr_node_net_num_from_scratch ./route/pb_pin_eq_auto_detect.c /^void reassign_rr_node_net_num_from_scratch() {$/;" f +rec_add_pb_type_keywords_to_list ./fpga_x2p/base/fpga_x2p_setup.c /^void rec_add_pb_type_keywords_to_list(t_pb_type* cur_pb_type,$/;" f file: +rec_add_rr_graph_wired_lut_rr_edges ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void rec_add_rr_graph_wired_lut_rr_edges(INP t_pb* cur_op_pb,$/;" f +rec_add_unused_rr_graph_wired_lut_rr_edges ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void rec_add_unused_rr_graph_wired_lut_rr_edges(INP t_pb_graph_node* cur_op_pb_graph_node,$/;" f +rec_alloc_phy_pb_children ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_alloc_phy_pb_children(t_pb_graph_node* cur_pb_graph_node, $/;" f +rec_annotate_pb_type_primitive_node_physical_mode_pin ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_annotate_pb_type_primitive_node_physical_mode_pin(t_pb_type* top_pb_type,$/;" f +rec_annotate_phy_pb_type_primitive_node_physical_mode_pin ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_annotate_phy_pb_type_primitive_node_physical_mode_pin(t_pb_type* top_pb_type,$/;" f +rec_backannotate_one_pb_wired_luts_and_adapt_graph ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_backannotate_one_pb_wired_luts_and_adapt_graph(t_pb* cur_pb,$/;" f +rec_backannotate_rr_node_net_num ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_backannotate_rr_node_net_num(int LL_num_rr_nodes,$/;" f +rec_connect_rr_graph_for_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void rec_connect_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* cur_pb_graph_node, $/;" f +rec_copy_name_mux_in_node ./fpga_x2p/verilog/verilog_pbtypes.c /^void rec_copy_name_mux_in_node(t_pb_graph_node* master_node, $/;" f +rec_count_num_conf_bits_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int rec_count_num_conf_bits_pb(t_pb* cur_pb, $/;" f +rec_count_num_conf_bits_pb_type_default_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int rec_count_num_conf_bits_pb_type_default_mode(t_pb_type* cur_pb_type,$/;" f +rec_count_num_conf_bits_pb_type_physical_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type,$/;" f +rec_count_num_iopads_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_count_num_iopads_pb(t_pb* cur_pb) {$/;" f +rec_count_num_iopads_pb_type_default_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_count_num_iopads_pb_type_default_mode(t_pb_type* cur_pb_type) {$/;" f +rec_count_num_iopads_pb_type_physical_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_count_num_iopads_pb_type_physical_mode(t_pb_type* cur_pb_type) {$/;" f +rec_count_num_mode_bits_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_count_num_mode_bits_pb(t_pb* cur_pb) {$/;" f +rec_count_num_mode_bits_pb_type_default_mode ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type) {$/;" f +rec_count_rr_graph_nodes_for_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^int rec_count_rr_graph_nodes_for_phy_pb_graph_node(t_pb_graph_node* cur_pb_graph_node) {$/;" f +rec_dump_conf_bits_to_bitstream_file ./fpga_x2p/bitstream/fpga_bitstream.c /^void rec_dump_conf_bits_to_bitstream_file(FILE* fp, $/;" f file: +rec_dump_verilog_spice_model_global_ports ./fpga_x2p/verilog/verilog_utils.c /^int rec_dump_verilog_spice_model_global_ports(FILE* fp, $/;" f +rec_dump_verilog_spice_model_lib_global_ports ./fpga_x2p/verilog/verilog_utils.c /^int rec_dump_verilog_spice_model_lib_global_ports(FILE* fp, $/;" f +rec_fprint_spice_model_global_ports ./fpga_x2p/spice/spice_utils.c /^int rec_fprint_spice_model_global_ports(FILE* fp, $/;" f +rec_get_pb_graph_node_by_pb_type_and_placement_index_in_top_node ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_pb_graph_node* rec_get_pb_graph_node_by_pb_type_and_placement_index_in_top_node(t_pb_graph_node* cur_pb_graph_node, $/;" f +rec_get_pb_type_by_name ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_pb_type* rec_get_pb_type_by_name(t_pb_type* cur_pb_type, $/;" f +rec_get_phy_pb_by_name ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^t_phy_pb* rec_get_phy_pb_by_name(t_phy_pb* cur_phy_pb, $/;" f +rec_identify_pb_type_idle_mode ./fpga_x2p/base/fpga_x2p_setup.c /^void rec_identify_pb_type_idle_mode(t_pb_type* cur_pb_type) {$/;" f file: +rec_identify_pb_type_phy_mode ./fpga_x2p/base/fpga_x2p_setup.c /^void rec_identify_pb_type_phy_mode(t_pb_type* cur_pb_type) {$/;" f file: +rec_init_rr_graph_for_phy_pb_graph_node ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void rec_init_rr_graph_for_phy_pb_graph_node(INP t_pb_graph_node* cur_pb_graph_node, $/;" f +rec_link_primitive_pb_graph_node_pin_to_phy_pb_graph_pin ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_link_primitive_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_node* top_pb_graph_node,$/;" f +rec_load_unused_pb_graph_node_temp_net_num_to_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_load_unused_pb_graph_node_temp_net_num_to_pb(t_phy_pb* cur_pb) {$/;" f +rec_mark_one_pb_unused_pb_graph_node_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_mark_one_pb_unused_pb_graph_node_temp_net_num(t_phy_pb* cur_pb) {$/;" f +rec_mark_pb_graph_node_primitive_placement_index_in_top_node ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_mark_pb_graph_node_primitive_placement_index_in_top_node(t_pb_graph_node* cur_pb_graph_node) {$/;" f +rec_mark_pb_graph_node_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_mark_pb_graph_node_temp_net_num(t_pb_graph_node* cur_pb_graph_node) {$/;" f +rec_reset_pb_graph_node_rr_node_index_physical_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_reset_pb_graph_node_rr_node_index_physical_pb(t_pb_graph_node* cur_pb_graph_node) {$/;" f +rec_reset_pb_type_phy_pb_type ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_reset_pb_type_phy_pb_type(t_pb_type* cur_pb_type) {$/;" f +rec_reset_pb_type_temp_placement_index ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_reset_pb_type_temp_placement_index(t_pb_type* cur_pb_type) {$/;" f +rec_stat_pb_type_keywords ./fpga_x2p/base/fpga_x2p_setup.c /^void rec_stat_pb_type_keywords(t_pb_type* cur_pb_type,$/;" f file: +rec_stats_spice_model_global_ports ./fpga_x2p/base/fpga_x2p_utils.c /^void rec_stats_spice_model_global_ports(t_spice_model* cur_spice_model,$/;" f +rec_sync_op_pb_mapping_to_phy_pb_children ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_sync_op_pb_mapping_to_phy_pb_children(t_pb* cur_op_pb, $/;" f +rec_sync_pb_post_routing_vpack_net_num ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void rec_sync_pb_post_routing_vpack_net_num(t_pb* cur_pb) {$/;" f +rec_sync_pb_vpack_net_num_to_phy_pb_rr_graph ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void rec_sync_pb_vpack_net_num_to_phy_pb_rr_graph(t_pb* cur_op_pb,$/;" f +rec_sync_wired_lut_to_one_phy_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void rec_sync_wired_lut_to_one_phy_pb(t_pb_graph_node* cur_pb_graph_node,$/;" f +rec_sync_wired_pb_vpack_net_num_to_phy_pb_rr_graph ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void rec_sync_wired_pb_vpack_net_num_to_phy_pb_rr_graph(t_pb_graph_node* cur_pb_graph_node,$/;" f +rec_update_net_info_local_rr_node_tree ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void rec_update_net_info_local_rr_node_tree(t_pb* src_pb,$/;" f +rec_verilog_generate_sdc_disable_unused_pb_types ./fpga_x2p/verilog/verilog_sdc.c /^void rec_verilog_generate_sdc_disable_unused_pb_types(FILE* fp, $/;" f +recommend_num_sim_clock_cycle ./fpga_x2p/base/fpga_x2p_utils.c /^int recommend_num_sim_clock_cycle(float sim_window_size) {$/;" f +recompute_bb_cost ./place/place.c /^static float recompute_bb_cost(void) {$/;" f file: +recompute_crit_iter ./base/vpr_types.h /^ int recompute_crit_iter;$/;" m struct:s_placer_opts +recompute_occupancy_from_scratch ./route/check_route.c /^static void recompute_occupancy_from_scratch(t_ivec ** clb_opins_used_locally) {$/;" f file: +recompute_timing_after ./base/ReadOptions.h /^ int recompute_timing_after;$/;" m struct:s_options +recompute_timing_after ./base/vpr_types.h /^ int recompute_timing_after;$/;" m struct:s_packer_opts +recover_rr_nodes_ipin_driver_switch ./route/rr_graph_opincb.c /^void recover_rr_nodes_ipin_driver_switch() {$/;" f file: +rect_off_screen ./base/graphics.c /^rect_off_screen (float x1, float y1, float x2, float y2) $/;" f file: +recursion_info ../../pcre/SRC/internal.h /^typedef struct recursion_info {$/;" s +recursion_info ../../pcre/SRC/internal.h /^} recursion_info;$/;" t typeref:struct:recursion_info +recursive ../../pcre/SRC/internal.h /^ recursion_info *recursive; \/* Linked list of recursion data *\/$/;" m struct:match_data +redraw_screen ./base/draw.c /^static void redraw_screen() {$/;" f file: +reference_verilog_benchmark_file ./base/vpr_types.h /^ char* reference_verilog_benchmark_file;$/;" m struct:s_syn_verilog_opts +regex_match ./timing/read_sdc.c /^static boolean regex_match (char * string, char * regular_expression) {$/;" f file: +relapos_rec_s ./place/place_stats.c /^typedef struct relapos_rec_s {$/;" s file: +relapos_rec_t ./place/place_stats.c /^} relapos_rec_t;$/;" t typeref:struct:relapos_rec_s file: +relative_length ../../libarchfpga/include/physical_types.h /^ float relative_length;$/;" m union:s_port_power::__anon22 +reload_ext_net_rr_terminal_cluster ./pack/cluster_legality.c /^void reload_ext_net_rr_terminal_cluster(void) {$/;" f +reload_intra_cluster_nets ./base/vpr_api.c /^static void reload_intra_cluster_nets(t_pb *pb) {$/;" f file: +relocate ./timing/slre.c /^static void relocate(struct slre *r, int begin, int shift) {$/;" f file: +remove_llist_node ../../libarchfpga/linkedlist.c /^void remove_llist_node(t_llist* cur) { $/;" f +rename_illegal_port ./base/vpr_types.h /^ boolean rename_illegal_port; \/* Rename illegal port names that is not compatible with verilog\/SPICE syntax *\/$/;" m struct:s_fpga_spice_opts +renaming_report_postfix ./fpga_x2p/base/fpga_x2p_globals.c /^char* renaming_report_postfix = "_io_renaming.rpt";$/;" v +rep_max ../../pcre/SRC/pcre.c /^static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };$/;" v file: +rep_min ../../pcre/SRC/pcre.c /^static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };$/;" v file: +repeat ../../libarchfpga/include/physical_types.h /^ int repeat;$/;" m struct:s_grid_loc_def +report_cb_timing ./fpga_x2p/verilog/verilog_report_timing.c /^ boolean report_cb_timing;$/;" m struct:s_trpt_opts file: +report_pb_timing ./fpga_x2p/verilog/verilog_report_timing.c /^ boolean report_pb_timing;$/;" m struct:s_trpt_opts file: +report_routing_timing ./fpga_x2p/verilog/verilog_report_timing.c /^ boolean report_routing_timing;$/;" m struct:s_trpt_opts file: +report_sb_timing ./fpga_x2p/verilog/verilog_report_timing.c /^ boolean report_sb_timing;$/;" m struct:s_trpt_opts file: +report_structure ./base/graphics.c /^void report_structure(t_report *report) {$/;" f +report_structure ./base/graphics.c /^void report_structure(t_report*) { }$/;" f +report_timing_path ./base/vpr_types.h /^ char* report_timing_path;$/;" m struct:s_syn_verilog_opts +req_byte ../../pcre/SRC/internal.h /^ unsigned short int req_byte;$/;" m struct:real_pcre +req_varyopt ../../pcre/SRC/internal.h /^ int req_varyopt; \/* "After variable item" flag for reqbyte *\/$/;" m struct:compile_data +requeue_primitive ./pack/cluster_placement.c /^static void requeue_primitive($/;" f file: +res_val ../../libarchfpga/fpga_spice_include/spice_types.h /^ float res_val;$/;" m struct:s_spice_model_wire_param +reserve_locally_used_opins ./route/route_common.c /^void reserve_locally_used_opins(float pres_fac, boolean rip_up_local_opins,$/;" f +reserved_bl ../../libarchfpga/fpga_spice_include/spice_types.h /^ int reserved_bl; \/* Number of reserved BLs shared by overall RRAM circuits *\/$/;" m struct:s_mem_bank_info +reserved_syntax_char_head ./fpga_x2p/base/fpga_x2p_globals.c /^t_llist* reserved_syntax_char_head = NULL;$/;" v +reserved_wl ../../libarchfpga/fpga_spice_include/spice_types.h /^ int reserved_wl; \/* Number of reserved WLs shared by overall RRAM circuits *\/$/;" m struct:s_mem_bank_info +reset_cluster_placement_stats ./pack/cluster_placement.c /^void reset_cluster_placement_stats($/;" f +reset_common_state ./base/graphics.c /^static void reset_common_state () {$/;" f file: +reset_flags ./route/check_route.c /^static void reset_flags(int inet, boolean * connected_to_route) {$/;" f file: +reset_legalizer_for_cluster ./pack/cluster_legality.c /^void reset_legalizer_for_cluster(t_block *clb) {$/;" f +reset_lookahead_pins_used ./pack/cluster.c /^static void reset_lookahead_pins_used(t_pb *cur_pb) {$/;" f file: +reset_path_costs ./route/route_common.c /^void reset_path_costs(void) {$/;" f +reset_pin_class_scratch_pad_rec ./pack/cluster_feasibility_filter.c /^static void reset_pin_class_scratch_pad_rec($/;" f file: +reset_placement ./place/timing_place_lookup.c /^static void reset_placement(void) {$/;" f file: +reset_rr_graph_path_costs ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void reset_rr_graph_path_costs(t_rr_graph* local_rr_graph) {$/;" f +reset_rr_graph_rr_node_route_structs ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^void reset_rr_graph_rr_node_route_structs(t_rr_graph* local_rr_graph) {$/;" f +reset_rr_node_route_structs ./route/route_common.c /^void reset_rr_node_route_structs(void) {$/;" f +reset_rr_node_to_rc_node ./timing/net_delay.c /^void reset_rr_node_to_rc_node(t_linked_rc_ptr * rr_node_to_rc_node,$/;" f +reset_tried_but_unused_cluster_placements ./pack/cluster_placement.c /^void reset_tried_but_unused_cluster_placements($/;" f +reset_win32_state ./base/graphics.c /^void reset_win32_state () {$/;" f +restore_disable_timing_one_sb_output ./fpga_x2p/verilog/verilog_tcl_utils.c /^void restore_disable_timing_one_sb_output(FILE* fp, $/;" f +restore_original_device ./place/timing_place_lookup.c /^static void restore_original_device(void) {$/;" f file: +restore_routing ./route/route_common.c /^void restore_routing(struct s_trace **best_routing,$/;" f +restore_routing_cluster ./pack/cluster_legality.c /^void restore_routing_cluster(void) {$/;" f +resync_pb_graph_nodes_in_pb ./base/vpr_api.c /^static void resync_pb_graph_nodes_in_pb(t_pb_graph_node *pb_graph_node,$/;" f file: +resync_post_route_netlist ./base/vpr_api.c /^void resync_post_route_netlist() {$/;" f +ret_track_swseg_pattern ./route/rr_graph_swseg.c /^enum ret_track_swseg_pattern {$/;" g file: +reverse_llist ../../libarchfpga/linkedlist.c /^t_llist* reverse_llist(t_llist* head) {$/;" f +reverse_scaled ../../libarchfpga/include/physical_types.h /^ boolean reverse_scaled; \/* Scale by (1-prob) *\/$/;" m struct:s_port_power +revert_place_logical_block ./pack/cluster.c /^static void revert_place_logical_block(INP int iblock, INP int max_models) {$/;" f file: +rising_edge ./timing/read_sdc.c /^ float rising_edge;$/;" m struct:s_sdc_clock file: +roff ../../libarchfpga/fpga_spice_include/spice_types.h /^ float roff;$/;" m struct:s_spice_model_rram +ron ../../libarchfpga/fpga_spice_include/spice_types.h /^ float ron;$/;" m struct:s_spice_model_rram +root ./base/vpr_types.h /^ int root; \/* root index of molecule, logical_block_ptrs[root] is ptr to root logical block *\/$/;" m struct:s_pack_molecule +root_block ../../libarchfpga/include/cad_types.h /^ t_pack_pattern_block *root_block; \/* root block used by this pattern *\/$/;" m struct:s_pack_patterns +root_passes_early_filter ./pack/cluster_placement.c /^static boolean root_passes_early_filter(INP t_pb_graph_node *root, INP t_pack_molecule *molecule, INP int clb_index) {$/;" f file: +rotate_shift_swseg_pattern ./route/rr_graph_swseg.c /^boolean* rotate_shift_swseg_pattern(int pattern_length,$/;" f file: +route_bb ./fpga_x2p/base/fpga_x2p_types.h /^ t_bb *route_bb; \/* [0..num_nets-1]. Limits area in which each *\/$/;" m struct:fpga_spice_rr_graph +route_bb ./route/route_common.c /^struct s_bb *route_bb = NULL; \/* [0..num_nets-1]. Limits area in which each *\/$/;" v typeref:struct:s_bb +route_type ./base/vpr_types.h /^ enum e_route_type route_type;$/;" m struct:s_router_opts typeref:enum:s_router_opts::e_route_type +router_algorithm ./base/vpr_types.h /^ enum e_router_algorithm router_algorithm;$/;" m struct:s_router_opts typeref:enum:s_router_opts::e_router_algorithm +routing_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* routing_spice_file_name = "routing_header.sp";$/;" v +routing_spice_subckt_file_path_head ./fpga_x2p/spice/spice_globals.c /^t_llist* routing_spice_subckt_file_path_head = NULL;$/;" v +routing_stats ./base/stats.c /^void routing_stats(boolean full_stats, enum e_route_type route_type,$/;" f +routing_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* routing_verilog_file_name = "routing.v";$/;" v +routing_verilog_subckt_file_path_head ./fpga_x2p/verilog/verilog_global.c /^t_llist* routing_verilog_subckt_file_path_head = NULL;$/;" v +rr_blk_source ./base/globals.c /^int **rr_blk_source = NULL; \/* [0..(num_blocks-1)][0..(num_class-1)] *\/$/;" v +rr_blk_source ./base/globals_declare.h /^int **rr_blk_source; \/* [0..num_blocks-1][0..num_class-1] *\/$/;" v +rr_graph ./base/vpr_types.h /^ struct s_rr_node *rr_graph; \/* pointer to rr_graph connecting pbs of cluster *\/$/;" m struct:s_pb typeref:struct:s_pb::s_rr_node +rr_graph ./fpga_x2p/base/fpga_x2p_types.h /^ t_rr_graph* rr_graph;$/;" m struct:fpga_spice_phy_pb +rr_graph_externals ./route/rr_graph.c /^static void rr_graph_externals(t_timing_inf timing_inf,$/;" f file: +rr_indexed_data ./base/globals.c /^t_rr_indexed_data *rr_indexed_data = NULL; \/* [0..(num_rr_indexed_data-1)] *\/$/;" v +rr_indexed_data ./base/globals_declare.h /^t_rr_indexed_data *rr_indexed_data; \/* [0 .. num_rr_indexed_data-1] *\/$/;" v +rr_indexed_data ./fpga_x2p/base/fpga_x2p_types.h /^ t_rr_indexed_data *rr_indexed_data; \/* [0..(num_rr_indexed_data-1)] *\/$/;" m struct:fpga_spice_rr_graph +rr_mem_ch ./fpga_x2p/base/fpga_x2p_types.h /^ t_chunk rr_mem_ch;$/;" m struct:fpga_spice_rr_graph +rr_mem_ch ./pack/cluster_legality.c /^static t_chunk rr_mem_ch = {NULL, 0, NULL};$/;" v file: +rr_mem_ch ./route/rr_graph.c /^static t_chunk rr_mem_ch = {NULL, 0, NULL};$/;" v file: +rr_modified_head ./fpga_x2p/base/fpga_x2p_types.h /^ t_linked_f_pointer *rr_modified_head;$/;" m struct:fpga_spice_rr_graph +rr_modified_head ./route/route_common.c /^static struct s_linked_f_pointer *rr_modified_head = NULL;$/;" v typeref:struct:s_linked_f_pointer file: +rr_node ./base/globals.c /^t_rr_node *rr_node = NULL; \/* [0..(num_rr_nodes-1)] *\/$/;" v +rr_node ./base/globals_declare.h /^t_rr_node *rr_node; \/* [0..num_rr_nodes-1] *\/$/;" v +rr_node ./fpga_x2p/base/fpga_x2p_types.h /^ t_rr_node* rr_node;$/;" m struct:fpga_spice_rr_graph +rr_node_color ./base/draw.c /^static enum color_types *rr_node_color = NULL;$/;" v typeref:enum:color_types file: +rr_node_drive_switch_box ./fpga_x2p/base/fpga_x2p_utils.c /^int rr_node_drive_switch_box(t_rr_node* src_rr_node,$/;" f +rr_node_index_physical_pb ../../libarchfpga/include/physical_types.h /^ int rr_node_index_physical_pb; \/* rr_node in the physical pb rr_graph*\/$/;" m struct:s_pb_graph_pin +rr_node_indices ./base/globals.c /^t_ivec ***rr_node_indices = NULL;$/;" v +rr_node_indices ./base/globals_declare.h /^t_ivec ***rr_node_indices;$/;" v +rr_node_indices ./fpga_x2p/base/fpga_x2p_types.h /^ t_ivec*** rr_node_indices;$/;" m struct:fpga_spice_rr_graph +rr_node_intrinsic_cost ./pack/cluster_legality.c /^static float rr_node_intrinsic_cost(int inode) {$/;" f file: +rr_node_is_global_clb_ipin ./route/check_rr_graph.c /^static boolean rr_node_is_global_clb_ipin(int inode) {$/;" f file: +rr_node_power ./power/power.c /^static t_rr_node_power * rr_node_power;$/;" v file: +rr_node_route_inf ./fpga_x2p/base/fpga_x2p_types.h /^ t_rr_node_route_inf* rr_node_route_inf;$/;" m struct:fpga_spice_rr_graph +rr_node_route_inf ./route/route_common.c /^t_rr_node_route_inf *rr_node_route_inf = NULL; \/* [0..num_rr_nodes-1] *\/$/;" v +rr_node_to_pb_mapping ./base/vpr_types.h /^ struct s_pb **rr_node_to_pb_mapping; \/* [0..num_local_rr_nodes-1] pointer look-up of which pb this rr_node belongs based on index, NULL if pb does not exist *\/$/;" m struct:s_pb typeref:struct:s_pb::s_pb +rr_node_to_pb_mapping ./fpga_x2p/base/fpga_x2p_types.h /^ t_phy_pb **rr_node_to_pb_mapping; \/* [0..num_local_rr_nodes-1] pointer look-up of which pb this rr_node belongs based on index, NULL if pb does not exist *\/$/;" m struct:fpga_spice_phy_pb +rr_node_to_rt_node ./route/route_tree_timing.c /^static t_rt_node **rr_node_to_rt_node = NULL; \/* [0..num_rr_nodes-1] *\/$/;" v file: +rram_design_tech ./fpga_x2p/spice/spice_globals.c /^int rram_design_tech = 0;$/;" v +rram_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_rram* rram_info;$/;" m struct:s_spice_model_design_tech_info +rram_pass_tran_value ../../libarchfpga/include/arch_types_mrfpga.h /^ float rram_pass_tran_value;$/;" m struct:s_arch_mrfpga +rram_pass_tran_value ./mrfpga/mrfpga_globals.c /^float rram_pass_tran_value = 0;$/;" v +rram_variation ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_mc_variation_params rram_variation;$/;" m struct:s_spice_mc_params +rram_veriloga_file_name ./fpga_x2p/spice/spice_globals.c /^char* rram_veriloga_file_name = "rram_behavior.va";$/;" v +rt_edge_free_list ./route/route_tree_timing.c /^static t_linked_rt_edge *rt_edge_free_list = NULL;$/;" v file: +rt_node_free_list ./route/route_tree_timing.c /^static t_rt_node *rt_node_free_list = NULL;$/;" v file: +rt_node_of_sink ./place/timing_place_lookup.c /^static t_rt_node **rt_node_of_sink;$/;" v file: +run_hspice_shell_script_name ./fpga_x2p/spice/spice_run_scripts.c /^static char* run_hspice_shell_script_name = "run_hspice_sim.sh";$/;" v file: +run_parasitic_net_estimation ./fpga_x2p/base/fpga_x2p_globals.c /^boolean run_parasitic_net_estimation = TRUE;$/;" v +run_shell ./fpga_x2p/shell/mini_shell.c /^void run_shell(int argc, char ** argv) {$/;" f +run_testbench_load_extraction ./fpga_x2p/base/fpga_x2p_globals.c /^boolean run_testbench_load_extraction = TRUE;$/;" v +s ../../libarchfpga/include/ezxml.h /^ char *s; \/* start of work area *\/$/;" m struct:ezxml_root +s_TokenPair ./base/vpr_types.h /^struct s_TokenPair {$/;" s +s_annealing_sched ./base/vpr_types.h /^struct s_annealing_sched {$/;" s +s_arch ../../libarchfpga/include/physical_types.h /^struct s_arch {$/;" s +s_arch_mrfpga ../../libarchfpga/include/arch_types_mrfpga.h /^struct s_arch_mrfpga {$/;" s +s_bb ./base/vpr_types.h /^struct s_bb {$/;" s +s_bitstream_gen_opts ./base/vpr_types.h /^struct s_bitstream_gen_opts {$/;" s +s_block ./base/vpr_types.h /^struct s_block {$/;" s +s_buffer_inf ../../libarchfpga/include/arch_types_mrfpga.h /^struct s_buffer_inf { $/;" s +s_buffer_plan ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" s file: +s_buffer_plan_list ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_list { t_buffer_plan_node* front; } t_buffer_plan_list;$/;" s file: +s_buffer_plan_node ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_node { t_buffer_plan value; struct s_buffer_plan_node* next;} t_buffer_plan_node;$/;" s file: +s_cb ./base/vpr_types.h /^struct s_cb {$/;" s +s_chan ../../libarchfpga/include/physical_types.h /^typedef struct s_chan {$/;" s +s_chan_width_dist ../../libarchfpga/include/physical_types.h /^typedef struct s_chan_width_dist {$/;" s +s_chunk ../../libarchfpga/include/util.h /^typedef struct s_chunk {$/;" s +s_class ../../libarchfpga/include/physical_types.h /^struct s_class {$/;" s +s_clb_grid ../../libarchfpga/include/physical_types.h /^struct s_clb_grid {$/;" s +s_clb_to_clb_directs ./base/vpr_types.h /^typedef struct s_clb_to_clb_directs {$/;" s +s_clock ./base/vpr_types.h /^typedef struct s_clock {$/;" s +s_clock_arch ../../libarchfpga/include/physical_types.h /^struct s_clock_arch {$/;" s +s_clock_network ../../libarchfpga/include/physical_types.h /^struct s_clock_network {$/;" s +s_cluster_placement_primitive ../../libarchfpga/include/cad_types.h /^typedef struct s_cluster_placement_primitive {$/;" s +s_cluster_placement_stats ./base/vpr_types.h /^typedef struct s_cluster_placement_stats {$/;" s +s_cmd_category ./fpga_x2p/shell/shell_types.h /^struct s_cmd_category {$/;" s +s_cmd_info ./fpga_x2p/shell/read_opt_types.h /^struct s_cmd_info {$/;" s +s_conf_bit ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_conf_bit {$/;" s +s_conf_bit_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_conf_bit_info {$/;" s +s_det_routing_arch ./base/vpr_types.h /^struct s_det_routing_arch {$/;" s +s_direct_inf ../../libarchfpga/include/physical_types.h /^typedef struct s_direct_inf {$/;" s +s_file_name_opts ./base/vpr_types.h /^struct s_file_name_opts {$/;" s +s_fmap_cell ./base/place_and_route.h /^typedef struct s_fmap_cell {$/;" s +s_fpga_spice_opts ./base/vpr_types.h /^struct s_fpga_spice_opts {$/;" s +s_grid_loc_def ../../libarchfpga/include/physical_types.h /^typedef struct s_grid_loc_def {$/;" s +s_grid_tile ./base/vpr_types.h /^typedef struct s_grid_tile {$/;" s +s_hash ./util/hash.h /^struct s_hash {$/;" s +s_hash_iterator ./util/hash.h /^struct s_hash_iterator {$/;" s +s_heap ./route/route_common.h /^struct s_heap {$/;" s +s_interconnect ../../libarchfpga/include/physical_types.h /^struct s_interconnect {$/;" s +s_interconnect_pins ../../libarchfpga/include/physical_types.h /^struct s_interconnect_pins {$/;" s +s_interconnect_power ../../libarchfpga/include/physical_types.h /^struct s_interconnect_power {$/;" s +s_io ./base/vpr_types.h /^typedef struct s_io {$/;" s +s_ivec ../../libarchfpga/include/util.h /^typedef struct s_ivec {$/;" s +s_legal_pos ./place/place.c /^typedef struct s_legal_pos {$/;" s file: +s_linked_edge ./route/rr_graph_util.h /^struct s_linked_edge {$/;" s +s_linked_f_pointer ./base/vpr_types.h /^struct s_linked_f_pointer {$/;" s +s_linked_int ../../libarchfpga/include/util.h /^typedef struct s_linked_int {$/;" s +s_linked_rc_edge ./timing/net_delay_types.h /^struct s_linked_rc_edge {$/;" s +s_linked_rc_ptr ./timing/net_delay_types.h /^struct s_linked_rc_ptr {$/;" s +s_linked_rt_edge ./route/route_tree_timing.h /^struct s_linked_rt_edge {$/;" s +s_linked_vptr ../../libarchfpga/include/util.h /^typedef struct s_linked_vptr {$/;" s +s_llist ../../libarchfpga/fpga_spice_include/linkedlist.h /^struct s_llist$/;" s +s_log ./power/power.h /^struct s_log {$/;" s +s_logical_block ./base/vpr_types.h /^typedef struct s_logical_block {$/;" s +s_mem_bank_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_mem_bank_info {$/;" s +s_memristor_inf ../../libarchfpga/include/arch_types_mrfpga.h /^struct s_memristor_inf { $/;" s +s_mode ../../libarchfpga/include/physical_types.h /^struct s_mode {$/;" s +s_mode_power ../../libarchfpga/include/physical_types.h /^struct s_mode_power {$/;" s +s_model ../../libarchfpga/include/logic_types.h /^typedef struct s_model {$/;" s +s_model_chain_pattern ../../libarchfpga/include/cad_types.h /^typedef struct s_model_chain_pattern {$/;" s +s_model_ports ../../libarchfpga/include/logic_types.h /^typedef struct s_model_ports {$/;" s +s_model_stats ./base/read_blif.c /^struct s_model_stats {$/;" s file: +s_molecule_link ./pack/cluster.c /^struct s_molecule_link {$/;" s file: +s_mux ./route/rr_graph.c /^typedef struct s_mux {$/;" s file: +s_mux_arch ./power/power.h /^struct s_mux_arch {$/;" s +s_mux_node ./power/power.h /^struct s_mux_node {$/;" s +s_mux_size_distribution ./route/rr_graph.c /^typedef struct s_mux_size_distribution {$/;" s file: +s_net ./base/vpr_types.h /^typedef struct s_net {$/;" s +s_net_power ./base/vpr_types.h /^struct s_net_power {$/;" s +s_num_mapped_opins_stats ./route/pb_pin_eq_auto_detect.c /^struct s_num_mapped_opins_stats{$/;" s file: +s_opt_info ./fpga_x2p/shell/read_opt_types.h /^struct s_opt_info {$/;" s +s_options ./base/ReadOptions.h /^struct s_options {$/;" s +s_override_constraint ./base/vpr_types.h /^typedef struct s_override_constraint {$/;" s +s_pack_molecule ./base/vpr_types.h /^typedef struct s_pack_molecule {$/;" s +s_pack_pattern_block ../../libarchfpga/include/cad_types.h /^typedef struct s_pack_pattern_block {$/;" s +s_pack_pattern_connections ../../libarchfpga/include/cad_types.h /^typedef struct s_pack_pattern_connections {$/;" s +s_pack_patterns ../../libarchfpga/include/cad_types.h /^typedef struct s_pack_patterns {$/;" s +s_packer_opts ./base/vpr_types.h /^struct s_packer_opts {$/;" s +s_pb ./base/vpr_types.h /^typedef struct s_pb {$/;" s +s_pb_graph_edge ../../libarchfpga/include/physical_types.h /^struct s_pb_graph_edge {$/;" s +s_pb_graph_node ../../libarchfpga/include/physical_types.h /^struct s_pb_graph_node {$/;" s +s_pb_graph_node_power ../../libarchfpga/include/physical_types.h /^struct s_pb_graph_node_power {$/;" s +s_pb_graph_pin ../../libarchfpga/include/physical_types.h /^struct s_pb_graph_pin {$/;" s +s_pb_graph_pin_power ../../libarchfpga/include/physical_types.h /^struct s_pb_graph_pin_power {$/;" s +s_pb_stats ./base/vpr_types.h /^typedef struct s_pb_stats {$/;" s +s_pb_type ../../libarchfpga/include/physical_types.h /^struct s_pb_type {$/;" s +s_pb_type_power ../../libarchfpga/include/physical_types.h /^struct s_pb_type_power {$/;" s +s_pin_to_pin_annotation ../../libarchfpga/include/physical_types.h /^struct s_pin_to_pin_annotation {$/;" s +s_pl_blocks_to_be_moved ./place/place.c /^typedef struct s_pl_blocks_to_be_moved {$/;" s file: +s_pl_macro ./place/place_macro.h /^typedef struct s_pl_macro{$/;" s +s_pl_macro_member ./place/place_macro.h /^typedef struct s_pl_macro_member{$/;" s +s_pl_moved_block ./place/place.c /^typedef struct s_pl_moved_block {$/;" s file: +s_place_region ./base/vpr_types.h /^struct s_place_region {$/;" s +s_placer_opts ./base/vpr_types.h /^struct s_placer_opts {$/;" s +s_port ../../libarchfpga/include/physical_types.h /^struct s_port {$/;" s +s_port_power ../../libarchfpga/include/physical_types.h /^struct s_port_power {$/;" s +s_power_arch ../../libarchfpga/include/physical_types.h /^struct s_power_arch {$/;" s +s_power_breakdown ./power/power_components.h /^struct s_power_breakdown {$/;" s +s_power_buffer_sc_levr_inf ./power/power.h /^struct s_power_buffer_sc_levr_inf {$/;" s +s_power_buffer_size_inf ./power/power.h /^struct s_power_buffer_size_inf {$/;" s +s_power_buffer_strength_inf ./power/power.h /^struct s_power_buffer_strength_inf {$/;" s +s_power_commonly_used ./power/power.h /^struct s_power_commonly_used {$/;" s +s_power_mux_info ./power/power.h /^struct s_power_mux_info {$/;" s +s_power_mux_volt_inf ./power/power.h /^struct s_power_mux_volt_inf {$/;" s +s_power_mux_volt_pair ./power/power.h /^struct s_power_mux_volt_pair {$/;" s +s_power_nmos_leakage_inf ./power/power.h /^struct s_power_nmos_leakage_inf {$/;" s +s_power_nmos_leakage_pair ./power/power.h /^struct s_power_nmos_leakage_pair {$/;" s +s_power_nmos_mux_inf ./power/power.h /^struct s_power_nmos_mux_inf {$/;" s +s_power_opts ./base/vpr_types.h /^struct s_power_opts {$/;" s +s_power_output ./power/power.h /^struct s_power_output {$/;" s +s_power_tech ./power/power.h /^struct s_power_tech {$/;" s +s_power_usage ../../libarchfpga/include/physical_types.h /^struct s_power_usage {$/;" s +s_prepacked_tnode_data ./base/vpr_types.h /^typedef struct s_prepacked_tnode_data {$/;" s +s_rc_node ./timing/net_delay_types.h /^struct s_rc_node {$/;" s +s_reserved_syntax_char ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_reserved_syntax_char {$/;" s +s_router_opts ./base/vpr_types.h /^struct s_router_opts {$/;" s +s_rr_indexed_data ./base/vpr_types.h /^typedef struct s_rr_indexed_data {$/;" s +s_rr_node ./base/vpr_types.h /^struct s_rr_node {$/;" s +s_rr_node_power ./power/power.h /^struct s_rr_node_power {$/;" s +s_rt_node ./route/route_tree_timing.h /^struct s_rt_node {$/;" s +s_sb ./base/vpr_types.h /^struct s_sb {$/;" s +s_scff_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_scff_info {$/;" s +s_sdc_clock ./timing/read_sdc.c /^typedef struct s_sdc_clock {$/;" s file: +s_sdc_exclusive_group ./timing/read_sdc.c /^typedef struct s_sdc_exclusive_group {$/;" s file: +s_sdc_opts ./fpga_x2p/verilog/verilog_sdc.c /^struct s_sdc_opts {$/;" s file: +s_seg_details ./base/vpr_types.h /^typedef struct s_seg_details {$/;" s +s_segment_inf ../../libarchfpga/include/physical_types.h /^typedef struct s_segment_inf {$/;" s +s_shell_cmd ./fpga_x2p/shell/shell_types.h /^struct s_shell_cmd {$/;" s +s_shell_env ./fpga_x2p/shell/shell_types.h /^struct s_shell_env {$/;" s +s_slack ./base/vpr_types.h /^typedef struct s_slack {$/;" s +s_solution_inf ./power/power.h /^struct s_solution_inf {$/;" s +s_spice ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice {$/;" s +s_spice_mc_params ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_mc_params {$/;" s +s_spice_mc_variation_params ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_mc_variation_params {$/;" s +s_spice_meas_params ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_meas_params {$/;" s +s_spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model {$/;" s +s_spice_model_buffer ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_buffer {$/;" s +s_spice_model_delay_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_delay_info {$/;" s +s_spice_model_design_tech_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_design_tech_info {$/;" s +s_spice_model_gate ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_gate {$/;" s +s_spice_model_lut ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_lut {$/;" s +s_spice_model_mux ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_mux {$/;" s +s_spice_model_netlist ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_netlist {$/;" s +s_spice_model_pass_gate_logic ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_pass_gate_logic {$/;" s +s_spice_model_port ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_port {$/;" s +s_spice_model_rram ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_rram {$/;" s +s_spice_model_tedge ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_tedge {$/;" s +s_spice_model_wire_param ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_model_wire_param {$/;" s +s_spice_mux_arch ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_mux_arch {$/;" s +s_spice_mux_model ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_mux_model {$/;" s +s_spice_net_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_net_info {$/;" s +s_spice_opts ./base/vpr_types.h /^struct s_spice_opts {$/;" s +s_spice_params ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_params {$/;" s +s_spice_stimulate_params ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_stimulate_params {$/;" s +s_spice_tech_lib ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_tech_lib {$/;" s +s_spice_transistor_type ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spice_transistor_type {$/;" s +s_spicetb_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_spicetb_info {$/;" s +s_sram_inf ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_sram_inf {$/;" s +s_sram_inf_orgz ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_sram_inf_orgz {$/;" s +s_sram_orgz_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_sram_orgz_info {$/;" s +s_standalone_sram_info ../../libarchfpga/fpga_spice_include/spice_types.h /^struct s_standalone_sram_info {$/;" s +s_switch_inf ../../libarchfpga/include/physical_types.h /^typedef struct s_switch_inf {$/;" s +s_swseg_pattern_inf ../../libarchfpga/include/physical_types.h /^struct s_swseg_pattern_inf {$/;" s +s_syn_verilog_opts ./base/vpr_types.h /^struct s_syn_verilog_opts {$/;" s +s_tedge ./base/vpr_types.h /^typedef struct s_tedge {$/;" s +s_timing_constraints ./base/vpr_types.h /^typedef struct s_timing_constraints { \/* Container structure for all SDC timing constraints. $/;" s +s_timing_inf ../../libarchfpga/include/physical_types.h /^typedef struct s_timing_inf {$/;" s +s_timing_stats ./base/vpr_types.h /^typedef struct s_timing_stats {$/;" s +s_tnode ./base/vpr_types.h /^typedef struct s_tnode {$/;" s +s_token ./util/token.h /^struct s_token {$/;" s +s_trace ./base/vpr_types.h /^typedef struct s_trace {$/;" s +s_transistor_inf ./power/power.h /^struct s_transistor_inf {$/;" s +s_transistor_size_inf ./power/power.h /^struct s_transistor_size_inf {$/;" s +s_trpt_opts ./fpga_x2p/verilog/verilog_report_timing.c /^struct s_trpt_opts {$/;" s file: +s_type_descriptor ../../libarchfpga/include/physical_types.h /^struct s_type_descriptor \/* TODO rename this. maybe physical type descriptor or complex logic block or physical logic block*\/$/;" s +s_vpr_setup ./base/vpr_types.h /^typedef struct s_vpr_setup {$/;" s +s_wireL_cnt ./fpga_x2p/verilog/verilog_report_timing.c /^struct s_wireL_cnt {$/;" s file: +sat_blks_pins_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^int sat_blks_pins_prefer_side(int n_nets, t_net* nets, $/;" f +sat_one_blk_pins_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^int sat_one_blk_pins_prefer_side(int n_nets, t_net* nets, $/;" f +save_and_reset_routing_cluster ./pack/cluster_legality.c /^void save_and_reset_routing_cluster(void) {$/;" f +save_best_buffer_list ./mrfpga/buffer_insertion.c /^static void save_best_buffer_list( t_linked_int* best_list )$/;" f file: +save_best_timing ./mrfpga/buffer_insertion.c /^static void save_best_timing( float* sink_delay, t_linked_int* index, float* net_delay )$/;" f file: +save_cluster_solution ./pack/cluster_legality.c /^void save_cluster_solution(void) {$/;" f +save_routing ./route/route_common.c /^void save_routing(struct s_trace **best_routing,$/;" f +save_start ../../pcre/SRC/internal.h /^ const uschar *save_start; \/* Old value of md->start_match *\/$/;" m struct:recursion_info +saved_base_cost ./base/vpr_types.h /^ float saved_base_cost;$/;" m struct:s_rr_indexed_data +saved_eptr ../../pcre/SRC/pcre.c /^ const uschar *saved_eptr;$/;" m struct:eptrblock file: +saved_max ../../pcre/SRC/internal.h /^ int saved_max; \/* Number of saved offsets *\/$/;" m struct:recursion_info +saved_net_rr_terminals ./pack/cluster_legality.c /^static int **saved_net_rr_terminals;$/;" v file: +saved_num_nets_in_cluster ./pack/cluster_legality.c /^static int saved_num_nets_in_cluster;$/;" v file: +saved_xleft ./base/graphics.c /^static float saved_xleft, saved_xright, saved_ytop, saved_ybot; $/;" v file: +saved_xright ./base/graphics.c /^static float saved_xleft, saved_xright, saved_ytop, saved_ybot; $/;" v file: +saved_ybot ./base/graphics.c /^static float saved_xleft, saved_xright, saved_ytop, saved_ybot; $/;" v file: +saved_ytop ./base/graphics.c /^static float saved_xleft, saved_xright, saved_ytop, saved_ybot; $/;" v file: +sb ../../libarchfpga/include/physical_types.h /^ boolean *sb;$/;" m struct:s_segment_inf +sb ./base/vpr_types.h /^ boolean *sb;$/;" m struct:s_seg_details +sb_drive_rr_nodes ./base/vpr_types.h /^ t_rr_node** sb_drive_rr_nodes;$/;" m struct:s_rr_node +sb_drive_switches ./base/vpr_types.h /^ int* sb_drive_switches;$/;" m struct:s_rr_node +sb_index_high ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** sb_index_high;$/;" m struct:s_spice_model +sb_index_low ../../libarchfpga/fpga_spice_include/spice_types.h /^ int** sb_index_low;$/;" m struct:s_spice_model +sb_info ./base/globals.c /^t_sb** sb_info = NULL;$/;" v +sb_len ../../libarchfpga/include/physical_types.h /^ int sb_len;$/;" m struct:s_segment_inf +sb_num_drive_rr_nodes ./base/vpr_types.h /^ int sb_num_drive_rr_nodes;$/;" m struct:s_rr_node +sb_spice_file_name_prefix ./fpga_x2p/spice/spice_globals.c /^char* sb_spice_file_name_prefix = "sb_";$/;" v +sb_verilog_file_name_prefix ./fpga_x2p/verilog/verilog_global.c /^char* sb_verilog_file_name_prefix = "sb_";$/;" v +sc_levr ./power/power.h /^ float sc_levr;$/;" m struct:s_power_buffer_sc_levr_inf +sc_levr_inf ./power/power.h /^ t_power_buffer_sc_levr_inf * sc_levr_inf;$/;" m struct:s_power_buffer_strength_inf +sc_no_levr ./power/power.h /^ float sc_no_levr;$/;" m struct:s_power_buffer_strength_inf +scale_factor ./power/PowerSpicedComponent.c /^float PowerSpicedComponent::scale_factor(int num_inputs,$/;" f class:PowerSpicedComponent +scaled_by_pin ../../libarchfpga/include/physical_types.h /^ t_pb_graph_pin * scaled_by_pin;$/;" m struct:s_pb_graph_pin_power +scaled_by_port ../../libarchfpga/include/physical_types.h /^ t_port * scaled_by_port;$/;" m struct:s_port_power +scaled_by_port_pin_idx ../../libarchfpga/include/physical_types.h /^ int scaled_by_port_pin_idx;$/;" m struct:s_port_power +scan_chain_heads ./fpga_x2p/spice/spice_globals.c /^t_llist* scan_chain_heads = NULL;$/;" v +scff_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_scff_info* scff_info; \/* Only be allocated when orgz type is scan-chain *\/$/;" m struct:s_sram_orgz_info +sched_type ./base/vpr_types.h /^enum sched_type {$/;" g +scratch_pad ../../libarchfpga/include/physical_types.h /^ int scratch_pad; \/* temporary data structure useful to store traversal info *\/$/;" m struct:s_pb_graph_pin +screen_num ./base/graphics.c /^static int screen_num;$/;" v file: +sdc ./timing/read_sdc.c /^static FILE *sdc;$/;" v file: +sdc_analysis_file_name ./fpga_x2p/verilog/verilog_global.c /^char* sdc_analysis_file_name = "fpga_top_analysis.sdc";$/;" v +sdc_break_loop_file_name ./fpga_x2p/verilog/verilog_global.c /^char* sdc_break_loop_file_name = "break_loop.sdc";$/;" v +sdc_clock_period_file_name ./fpga_x2p/verilog/verilog_global.c /^char* sdc_clock_period_file_name = "clock.sdc";$/;" v +sdc_clocks ./timing/read_sdc.c /^t_sdc_clock * sdc_clocks = NULL; \/* List of clock periods and offsets from create_clock commands *\/$/;" v +sdc_constrain_cb_file_name ./fpga_x2p/verilog/verilog_global.c /^char* sdc_constrain_cb_file_name = "cb.sdc";$/;" v +sdc_constrain_routing_chan_file_name ./fpga_x2p/verilog/verilog_global.c /^char* sdc_constrain_routing_chan_file_name = "routing_channels.sdc";$/;" v +sdc_constrain_sb_file_name ./fpga_x2p/verilog/verilog_global.c /^char* sdc_constrain_sb_file_name = "sb.sdc";$/;" v +sdc_dir ./fpga_x2p/verilog/verilog_report_timing.c /^ char* sdc_dir;$/;" m struct:s_trpt_opts file: +sdc_dir ./fpga_x2p/verilog/verilog_sdc.c /^ char* sdc_dir;$/;" m struct:s_sdc_opts file: +sdc_dump_all_pb_graph_nodes ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void sdc_dump_all_pb_graph_nodes(FILE* fp,$/;" f +sdc_dump_annotation ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void sdc_dump_annotation(char* from_path, \/\/ includes the cell$/;" f +sdc_dump_cur_node_constraints ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void sdc_dump_cur_node_constraints(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +sdc_file_name ./base/vpr_types.h /^ char *sdc_file_name;$/;" m struct:s_packer_opts +sdc_rec_dump_child_pb_graph_node ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void sdc_rec_dump_child_pb_graph_node(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +sdf_DFF_delay_printing ./base/verilog_writer.c /^void sdf_DFF_delay_printing(FILE *SDF , t_pb *pb)$/;" f +sdf_LUT_delay_printing ./base/verilog_writer.c /^void sdf_LUT_delay_printing(FILE *SDF , t_pb *pb)$/;" f +search_and_add_num_mapped_opin_llist ./route/pb_pin_eq_auto_detect.c /^t_llist* search_and_add_num_mapped_opin_llist(t_llist* head, $/;" f +search_in_int_list ../../libarchfpga/util.c /^t_linked_int* search_in_int_list(t_linked_int* int_list_head, $/;" f +search_llist_tail ../../libarchfpga/linkedlist.c /^t_llist* search_llist_tail(t_llist* head) {$/;" f +search_mapped_block ./fpga_x2p/base/fpga_x2p_utils.c /^t_block* search_mapped_block(int x, int y, int z) {$/;" f +search_mux_linked_list ./fpga_x2p/base/fpga_x2p_mux_utils.c /^t_llist* search_mux_linked_list(t_llist* mux_head,$/;" f +search_swseg_pattern_seg_len ./route/rr_graph_swseg.c /^t_swseg_pattern_inf* search_swseg_pattern_seg_len(INP int num_swseg_pattern,$/;" f file: +search_tapbuf_llist_same_settings ./fpga_x2p/spice/spice_subckt.c /^int search_tapbuf_llist_same_settings(t_llist* head,$/;" f file: +seed ./base/vpr_types.h /^ int seed;$/;" m struct:s_placer_opts +seg_direction_type ../../libarchfpga/include/physical_types.h /^ enum e_directionality seg_direction_type;$/;" m struct:s_swseg_pattern_inf typeref:enum:s_swseg_pattern_inf::e_directionality +seg_index ./base/vpr_types.h /^ int seg_index;$/;" m struct:s_rr_indexed_data +seg_index_of_cblock ./route/rr_graph_util.c /^int seg_index_of_cblock(t_rr_type from_rr_type, int to_node) {$/;" f +seg_index_of_sblock ./route/rr_graph_util.c /^int seg_index_of_sblock(int from_node, int to_node) {$/;" f +seg_length ../../libarchfpga/include/physical_types.h /^ int seg_length;$/;" m struct:s_swseg_pattern_inf +seg_switch ../../libarchfpga/include/physical_types.h /^ short seg_switch;$/;" m struct:s_segment_inf +seg_switch ./base/vpr_types.h /^ short seg_switch;$/;" m struct:s_seg_details +segments ./fpga_x2p/spice/spice_mux_testbench.c /^static t_segment_inf* segments;$/;" v file: +segments ./fpga_x2p/spice/spice_routing_testbench.c /^static t_segment_inf* segments;$/;" v file: +selected_input ./power/power.h /^ short selected_input; \/* Input index that is selected *\/$/;" m struct:s_rr_node_power +setAllEchoFileEnabled ./base/ReadOptions.c /^void setAllEchoFileEnabled(boolean value) {$/;" f +setEchoEnabled ./base/ReadOptions.c /^void setEchoEnabled(boolean echo_enabled) {$/;" f +setEchoFileEnabled ./base/ReadOptions.c /^void setEchoFileEnabled(enum e_echo_files echo_option, boolean value) {$/;" f +setEchoFileName ./base/ReadOptions.c /^void setEchoFileName(enum e_echo_files echo_option, const char *name) {$/;" f +setOutputFileName ./base/ReadOptions.c /^void setOutputFileName(enum e_output_files ename, const char *name, const char *default_name) {$/;" f +set_and_balance_arrival_time ./timing/path_delay.c /^static void set_and_balance_arrival_time(int to_node, int from_node, float Tdel, boolean do_lut_input_balancing) {$/;" f file: +set_blk_net_one_sink_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^void set_blk_net_one_sink_prefer_side(int* prefer_side, \/* [0..3] array, should be allocated before *\/$/;" f +set_disable_timing_one_sb_output ./fpga_x2p/verilog/verilog_tcl_utils.c /^void set_disable_timing_one_sb_output(FILE* fp, $/;" f +set_draw_mode ./base/graphics.c /^void set_draw_mode (enum e_draw_mode draw_mode) { }$/;" f +set_draw_mode ./base/graphics.c /^void set_draw_mode (enum e_draw_mode draw_mode) {$/;" f +set_graphics_state ./base/draw.c /^void set_graphics_state(boolean show_graphics_val, int gr_automode_val,$/;" f +set_jump_offset ./timing/slre.c /^static void set_jump_offset(struct slre *r, int pc, int offset) {$/;" f file: +set_keypress_input ./base/graphics.c /^void set_keypress_input (bool enable) {$/;" f +set_keypress_input ./base/graphics.c /^void set_keypress_input (bool) { }$/;" f +set_max_pins_per_side ./base/SetupVPR.c /^static void set_max_pins_per_side() {$/;" f file: +set_mode_cluster_placement_stats ./pack/cluster_placement.c /^void set_mode_cluster_placement_stats(INP t_pb_graph_node *pb_graph_node,$/;" f +set_mouse_move_input ./base/graphics.c /^void set_mouse_move_input (bool enable) {$/;" f +set_mouse_move_input ./base/graphics.c /^void set_mouse_move_input (bool) { }$/;" f +set_one_pb_rr_node_default_prev_node_edge ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void set_one_pb_rr_node_default_prev_node_edge(t_rr_node* pb_rr_graph, $/;" f file: +set_one_pb_rr_node_net_num ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void set_one_pb_rr_node_net_num(t_rr_node* pb_rr_graph, $/;" f file: +set_pb_graph_mode ./pack/cluster_legality.c /^void set_pb_graph_mode(t_pb_graph_node *pb_graph_node, int mode, int isOn) {$/;" f +set_spice_model_counter ./fpga_x2p/base/fpga_x2p_utils.c /^void set_spice_model_counter(int num_spice_models,$/;" f +set_src_bottom_side_net_one_sink_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^void set_src_bottom_side_net_one_sink_prefer_side(int* prefer_side, $/;" f +set_src_left_side_net_one_sink_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^void set_src_left_side_net_one_sink_prefer_side(int* prefer_side, $/;" f +set_src_right_side_net_one_sink_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^void set_src_right_side_net_one_sink_prefer_side(int* prefer_side, $/;" f +set_src_top_side_net_one_sink_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^void set_src_top_side_net_one_sink_prefer_side(int* prefer_side, $/;" f +set_unroute_blk_pins_prefer_sides ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^int set_unroute_blk_pins_prefer_sides(int n_blk, t_block* blk) {$/;" f +setcolor ./base/graphics.c /^void setcolor (int cindex) $/;" f +setcolor ./base/graphics.c /^void setcolor (int cindex) { }$/;" f +setcolor ./base/graphics.c /^void setcolor (string cname) {$/;" f +setfontsize ./base/graphics.c /^void setfontsize (int pointsize) $/;" f +setfontsize ./base/graphics.c /^void setfontsize (int pointsize) { }$/;" f +setlinestyle ./base/graphics.c /^void setlinestyle (int linestyle) $/;" f +setlinestyle ./base/graphics.c /^void setlinestyle (int linestyle) { }$/;" f +setlinewidth ./base/graphics.c /^void setlinewidth (int linewidth) $/;" f +setlinewidth ./base/graphics.c /^void setlinewidth (int linewidth) { }$/;" f +setpoly ./base/graphics.c /^static void setpoly (int bnum, int xc, int yc, int r, float theta) $/;" f file: +setup_blocks_affected ./place/place.c /^static int setup_blocks_affected(int b_from, int x_to, int y_to, int z_to) {$/;" f file: +setup_chan_width ./place/timing_place_lookup.c /^static void setup_chan_width(struct s_router_opts router_opts,$/;" f file: +setup_intracluster_routing_for_logical_block ./pack/cluster_legality.c /^void setup_intracluster_routing_for_logical_block(INP int iblock,$/;" f +setup_intracluster_routing_for_molecule ./pack/cluster_legality.c /^void setup_intracluster_routing_for_molecule(INP t_pack_molecule *molecule,$/;" f +setup_junction_switch ./base/SetupVPR.c /^static void setup_junction_switch(struct s_det_routing_arch *det_routing_arch) {$/;" f file: +setup_vpr_opts ./fpga_x2p/shell/cmd_vpr_setup.h /^t_opt_info setup_vpr_opts[] = {$/;" v +sharinggain ./base/vpr_types.h /^ std::map sharinggain; \/* [0..num_logical_blocks-1]. How many nets on this logical_block are already in the pb under consideration *\/$/;" m struct:s_pb_stats +shell_cmd ./fpga_x2p/shell/shell_cmds.h /^t_shell_cmd shell_cmd[] = {$/;" v +shell_env ./fpga_x2p/shell/mini_shell.c /^t_shell_env shell_env;$/;" v +shell_execute_exit ./fpga_x2p/shell/cmd_exit.c /^void shell_execute_exit(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_fpga_bitstream ./fpga_x2p/shell/cmd_fpga_bitstream.c /^void shell_execute_fpga_bitstream(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_fpga_spice ./fpga_x2p/shell/cmd_fpga_spice.c /^void shell_execute_fpga_spice(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_fpga_verilog ./fpga_x2p/shell/cmd_fpga_verilog.c /^void shell_execute_fpga_verilog(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_fpga_x2p_setup ./fpga_x2p/shell/cmd_fpga_x2p_setup.c /^void shell_execute_fpga_x2p_setup(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_help ./fpga_x2p/shell/cmd_help.c /^void shell_execute_help(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_vpr_pack ./fpga_x2p/shell/cmd_vpr_pack.c /^void shell_execute_vpr_pack(t_shell_env* env, $/;" f +shell_execute_vpr_place_and_route ./fpga_x2p/shell/cmd_vpr_place_and_route.c /^void shell_execute_vpr_place_and_route(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_execute_vpr_setup ./fpga_x2p/shell/cmd_vpr_setup.c /^void shell_execute_vpr_setup(t_shell_env* env, $/;" f +shell_execute_vpr_versapower ./fpga_x2p/shell/cmd_vpr_power.c /^void shell_execute_vpr_versapower(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_init_vpr_place_and_route ./fpga_x2p/shell/cmd_vpr_place_and_route.c /^void shell_init_vpr_place_and_route(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_init_vpr_placer ./fpga_x2p/shell/cmd_vpr_place_and_route.c /^void shell_init_vpr_placer(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_init_vpr_router ./fpga_x2p/shell/cmd_vpr_place_and_route.c /^void shell_init_vpr_router(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_opts ./fpga_x2p/shell/mini_shell.h /^t_opt_info shell_opts[] = {$/;" v +shell_print_usage ./fpga_x2p/shell/shell_utils.c /^void shell_print_usage(t_shell_env* env) {$/;" f +shell_setup_fpga_bitstream ./fpga_x2p/shell/cmd_fpga_bitstream.c /^boolean shell_setup_fpga_bitstream(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_setup_fpga_spice ./fpga_x2p/shell/cmd_fpga_spice.c /^boolean shell_setup_fpga_spice(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_setup_fpga_verilog ./fpga_x2p/shell/cmd_fpga_verilog.c /^boolean shell_setup_fpga_verilog(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_setup_fpga_x2p_setup ./fpga_x2p/shell/cmd_fpga_x2p_setup.c /^boolean shell_setup_fpga_x2p_setup(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_setup_graphics ./fpga_x2p/shell/cmd_vpr_setup.c /^void shell_setup_graphics(t_shell_env* env, $/;" f +shell_setup_read_arch_opts ./fpga_x2p/shell/cmd_vpr_setup.c /^void shell_setup_read_arch_opts(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_setup_vpr_arch ./fpga_x2p/shell/cmd_vpr_setup.c /^void shell_setup_vpr_arch(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_setup_vpr_timing ./fpga_x2p/shell/cmd_vpr_setup.c /^void shell_setup_vpr_timing(t_shell_env* env) {$/;" f +shell_setup_vpr_versa_power ./fpga_x2p/shell/cmd_vpr_power.c /^boolean shell_setup_vpr_versa_power(t_shell_env* env, t_opt_info* opts) {$/;" f +shell_vpr_get_circuit_name ./fpga_x2p/shell/cmd_vpr_setup.c /^char* shell_vpr_get_circuit_name(char* blif_name) {$/;" f +shell_vpr_setup_default_file_names ./fpga_x2p/shell/cmd_vpr_setup.c /^void shell_vpr_setup_default_file_names(t_vpr_setup* vpr_setup, $/;" f +shell_vpr_setup_gen_one_file_name ./fpga_x2p/shell/cmd_vpr_setup.c /^char* shell_vpr_setup_gen_one_file_name(char* circuit_name,$/;" f +show_blif_stats ./base/read_blif.c /^static void show_blif_stats(t_model *user_models, t_model *library_models) {$/;" f file: +show_combinational_cycle_candidates ./timing/path_delay2.c /^static void show_combinational_cycle_candidates() {$/;" f file: +show_congestion ./base/draw.c /^static boolean show_congestion = FALSE;$/;" v file: +show_defects ./base/draw.c /^static boolean show_defects = FALSE; \/* Show defective stuff *\/$/;" v file: +show_graphics ./base/draw.c /^static boolean show_graphics; \/* Graphics enabled or not? *\/$/;" v file: +show_nets ./base/draw.c /^static boolean show_nets = FALSE; \/* Show nets of placement or routing? *\/$/;" v file: +show_opt_list ./fpga_x2p/shell/read_opt.c /^int show_opt_list(t_opt_info* cur) {$/;" f +sibling ../../libarchfpga/include/ezxml.h /^ ezxml_t sibling; \/* next tag with different name in same section and depth *\/$/;" m struct:ezxml +signal_density_weight ./base/vpr_types.h /^ float signal_density_weight;$/;" m struct:s_fpga_spice_opts +sim_clock_freq_slack ../../libarchfpga/fpga_spice_include/spice_types.h /^ float sim_clock_freq_slack;$/;" m struct:s_spice_stimulate_params +sim_num_clock_cycle ../../libarchfpga/fpga_spice_include/spice_types.h /^ int sim_num_clock_cycle; \/* Number of clock cycle in simulation *\/$/;" m struct:s_spice_meas_params +sim_results_dir_name ./fpga_x2p/spice/spice_run_scripts.c /^static char* sim_results_dir_name = "results\/";$/;" v file: +sim_temp ../../libarchfpga/fpga_spice_include/spice_types.h /^ int sim_temp; \/* Simulation Temperature*\/$/;" m struct:s_spice_params +sim_window_size ./base/vpr_types.h /^ float sim_window_size;$/;" m struct:s_fpga_spice_opts +simulator_path ./base/vpr_types.h /^ char* simulator_path;$/;" m struct:s_spice_opts +sink_delay ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" m struct:s_buffer_plan file: +sink_head ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" m struct:s_buffer_plan file: +sink_list ./base/vpr_types.h /^ char ** sink_list;$/;" m struct:s_override_constraint +sink_order ./place/timing_place_lookup.c /^static int *sink_order;$/;" v file: +size ../../libarchfpga/fpga_spice_include/spice_types.h /^ float size;$/;" m struct:s_spice_model_buffer +size ../../libarchfpga/fpga_spice_include/spice_types.h /^ int size;$/;" m struct:s_spice_model_port +size ../../libarchfpga/fpga_spice_include/spice_types.h /^ int size;$/;" m struct:s_spice_mux_model +size ../../libarchfpga/include/logic_types.h /^ int size; \/* maximum number of pins *\/$/;" m struct:s_model_ports +size ../../pcre/SRC/internal.h /^ size_t size; \/* Total that was malloced *\/$/;" m struct:pcre_study_data +size ../../pcre/SRC/internal.h /^ size_t size; \/* Total that was malloced *\/$/;" m struct:real_pcre +size ./power/power.h /^ float size;$/;" m struct:s_transistor_size_inf +size ./route/rr_graph.c /^ int size;$/;" m struct:s_mux file: +size_inf ./power/power.h /^ t_transistor_size_inf * size_inf; \/* Array of transistor sizes *\/$/;" m struct:s_transistor_inf +skip_clustering ./base/ReadOptions.h /^ boolean skip_clustering;$/;" m struct:s_options +skip_clustering ./base/vpr_types.h /^ boolean skip_clustering;$/;" m struct:s_packer_opts +slack ./base/vpr_types.h /^ float ** slack;$/;" m struct:s_slack +slew_fall ../../libarchfpga/fpga_spice_include/spice_types.h /^ float slew_fall;$/;" m struct:s_spice_net_info +slew_lower_thres_pct_fall ../../libarchfpga/fpga_spice_include/spice_types.h /^ float slew_lower_thres_pct_fall;$/;" m struct:s_spice_meas_params +slew_lower_thres_pct_rise ../../libarchfpga/fpga_spice_include/spice_types.h /^ float slew_lower_thres_pct_rise;$/;" m struct:s_spice_meas_params +slew_rise ../../libarchfpga/fpga_spice_include/spice_types.h /^ float slew_rise;$/;" m struct:s_spice_net_info +slew_upper_thres_pct_fall ../../libarchfpga/fpga_spice_include/spice_types.h /^ float slew_upper_thres_pct_fall;$/;" m struct:s_spice_meas_params +slew_upper_thres_pct_rise ../../libarchfpga/fpga_spice_include/spice_types.h /^ float slew_upper_thres_pct_rise;$/;" m struct:s_spice_meas_params +slre ./timing/slre.c /^struct slre {$/;" s file: +slre_capture ./timing/slre.h /^enum slre_capture {SLRE_STRING, SLRE_INT, SLRE_FLOAT};$/;" g +slre_match ./timing/slre.c /^const char *slre_match(enum slre_option options, const char *re,$/;" f +slre_option ./timing/slre.h /^enum slre_option {SLRE_CASE_INSENSITIVE = 1};$/;" g +snapshot_spice_model_counter ./fpga_x2p/base/fpga_x2p_utils.c /^int* snapshot_spice_model_counter(int num_spice_models,$/;" f +snapshot_sram_orgz_info ./fpga_x2p/base/fpga_x2p_utils.c /^t_sram_orgz_info* snapshot_sram_orgz_info(t_sram_orgz_info* src_sram_orgz_info) {$/;" f +snprintf ../../libarchfpga/ezxml.c 57;" d file: +sort_me ./power/PowerSpicedComponent.c /^void PowerCallibInputs::sort_me() {$/;" f class:PowerCallibInputs +sort_me ./power/PowerSpicedComponent.c /^void PowerSpicedComponent::sort_me(void) {$/;" f class:PowerSpicedComponent +sort_one_class_conflict_pins_by_low_slack ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^int* sort_one_class_conflict_pins_by_low_slack(t_block* target_blk, int class_index,$/;" f +sorted ./power/PowerSpicedComponent.h /^ bool sorted;$/;" m class:PowerCallibInputs +sorted ./power/PowerSpicedComponent.h /^ bool sorted;$/;" m class:PowerSpicedComponent +sorter_PowerCallibInputs ./power/PowerSpicedComponent.c /^bool sorter_PowerCallibInputs(PowerCallibInputs * a, PowerCallibInputs * b) {$/;" f +sorter_PowerCallibSize ./power/PowerSpicedComponent.c /^bool sorter_PowerCallibSize(PowerCallibSize * a, PowerCallibSize * b) {$/;" f +source_list ./base/vpr_types.h /^ char ** source_list; \/* Array of net names of flip-flops or clocks *\/$/;" m struct:s_override_constraint +spice ../../libarchfpga/include/physical_types.h /^ t_spice* spice;$/;" m struct:s_arch +spice_backannotate_vpr_post_route_info ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch,$/;" f +spice_cb_mux_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_cb_mux_tb_dir_name = "cb_mux_tb\/";$/;" v file: +spice_cb_mux_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_cb_mux_testbench_postfix = "_cbmux_testbench.sp";$/;" v +spice_cb_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_cb_tb_dir_name = "cb_tb\/";$/;" v file: +spice_cb_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_cb_testbench_postfix = "_cb_testbench.sp";$/;" v +spice_create_one_subckt_file ./fpga_x2p/spice/spice_utils.c /^FILE* spice_create_one_subckt_file(char* subckt_dir,$/;" f +spice_dff_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_dff_testbench_postfix = "_dff_testbench.sp";$/;" v +spice_dir ./base/ReadOptions.h /^ char* spice_dir;$/;" m struct:s_options +spice_dir ./base/vpr_types.h /^ char* spice_dir;$/;" m struct:s_spice_opts +spice_grid_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_grid_tb_dir_name = "grid_tb\/";$/;" v file: +spice_grid_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_grid_testbench_postfix = "_grid_testbench.sp";$/;" v +spice_hardlogic_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_hardlogic_tb_dir_name = "hardlogic_tb\/";$/;" v file: +spice_hardlogic_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_hardlogic_testbench_postfix = "_hardlogic_testbench.sp";$/;" v +spice_io_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_io_tb_dir_name = "io_tb\/";$/;" v file: +spice_io_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_io_testbench_postfix = "_io_testbench.sp";$/;" v +spice_lut_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_lut_tb_dir_name = "lut_tb\/";$/;" v file: +spice_lut_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_lut_testbench_postfix = "_lut_testbench.sp";$/;" v +spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* spice_model; \/\/ Xifan TANG: Spice Support$/;" m struct:s_sram_inf_orgz +spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* spice_model;$/;" m struct:s_spice_model_buffer +spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* spice_model;$/;" m struct:s_spice_model_pass_gate_logic +spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* spice_model;$/;" m struct:s_spice_model_port +spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* spice_model;$/;" m struct:s_spice_mux_model +spice_model ../../libarchfpga/include/physical_types.h /^ t_spice_model* spice_model;$/;" m struct:s_direct_inf +spice_model ../../libarchfpga/include/physical_types.h /^ t_spice_model* spice_model;$/;" m struct:s_interconnect +spice_model ../../libarchfpga/include/physical_types.h /^ t_spice_model* spice_model;$/;" m struct:s_pb_type +spice_model ../../libarchfpga/include/physical_types.h /^ t_spice_model* spice_model;$/;" m struct:s_segment_inf +spice_model ../../libarchfpga/include/physical_types.h /^ t_spice_model* spice_model;$/;" m struct:s_switch_inf +spice_model ./base/vpr_types.h /^ t_spice_model* spice_model;$/;" m struct:s_clb_to_clb_directs +spice_model_delay_type ../../libarchfpga/fpga_spice_include/spice_types.h /^enum spice_model_delay_type {$/;" g +spice_model_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* spice_model_name; \/\/ Xifan TANG: Spice Support$/;" m struct:s_sram_inf_orgz +spice_model_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* spice_model_name;$/;" m struct:s_spice_model_buffer +spice_model_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* spice_model_name;$/;" m struct:s_spice_model_pass_gate_logic +spice_model_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* spice_model_name;$/;" m struct:s_spice_model_port +spice_model_name ../../libarchfpga/include/physical_types.h /^ char* spice_model_name;$/;" m struct:s_direct_inf +spice_model_name ../../libarchfpga/include/physical_types.h /^ char* spice_model_name;$/;" m struct:s_interconnect +spice_model_name ../../libarchfpga/include/physical_types.h /^ char* spice_model_name;$/;" m struct:s_pb_type +spice_model_name ../../libarchfpga/include/physical_types.h /^ char* spice_model_name;$/;" m struct:s_segment_inf +spice_model_name ../../libarchfpga/include/physical_types.h /^ char* spice_model_name;$/;" m struct:s_switch_inf +spice_model_port ../../libarchfpga/include/physical_types.h /^ t_spice_model_port* spice_model_port;$/;" m struct:s_port +spice_model_sram_offset ../../libarchfpga/include/physical_types.h /^ int spice_model_sram_offset;$/;" m struct:s_interconnect +spice_model_sram_offset ../../libarchfpga/include/physical_types.h /^ int spice_model_sram_offset;$/;" m struct:s_pb_type +spice_models ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model* spice_models;$/;" m struct:s_spice +spice_mux_arch ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_mux_arch* spice_mux_arch;$/;" m struct:s_spice_mux_model +spice_name_tag ./base/vpr_types.h /^ char* spice_name_tag;$/;" m struct:s_pb +spice_name_tag ./fpga_x2p/base/fpga_x2p_types.h /^ char* spice_name_tag;$/;" m struct:fpga_spice_phy_pb +spice_net_info ./base/vpr_types.h /^ t_spice_net_info* spice_net_info;$/;" m struct:s_net +spice_net_info_add_density_weight ./fpga_x2p/base/fpga_x2p_setup.c /^void spice_net_info_add_density_weight(float signal_density_weight) {$/;" f file: +spice_netlist_file_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_netlist_file_postfix = ".sp";$/;" v +spice_params ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_params spice_params;$/;" m struct:s_spice +spice_pb_mux_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_pb_mux_tb_dir_name = "pb_mux_tb\/";$/;" v file: +spice_pb_mux_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_pb_mux_testbench_postfix = "_pbmux_testbench.sp";$/;" v +spice_print_cb_testbench ./fpga_x2p/spice/spice_routing_testbench.c /^void spice_print_cb_testbench(char* formatted_spice_dir,$/;" f +spice_print_grid_testbench ./fpga_x2p/spice/spice_grid_testbench.c /^void spice_print_grid_testbench(char* formatted_spice_dir,$/;" f +spice_print_headers ./fpga_x2p/spice/spice_heads.c /^void spice_print_headers(char* include_dir_path,$/;" f +spice_print_mux_testbench ./fpga_x2p/spice/spice_mux_testbench.c /^void spice_print_mux_testbench(char* formatted_spice_dir,$/;" f +spice_print_one_include_subckt_line ./fpga_x2p/spice/spice_utils.c /^void spice_print_one_include_subckt_line(FILE* fp, $/;" f +spice_print_primitive_testbench ./fpga_x2p/spice/spice_primitive_testbench.c /^void spice_print_primitive_testbench(char* formatted_spice_dir,$/;" f +spice_print_sb_testbench ./fpga_x2p/spice/spice_routing_testbench.c /^void spice_print_sb_testbench(char* formatted_spice_dir,$/;" f +spice_print_subckt_header_file ./fpga_x2p/spice/spice_utils.c /^void spice_print_subckt_header_file(t_llist* subckt_llist_head,$/;" f +spice_print_top_netlist ./fpga_x2p/spice/spice_top_netlist.c /^void spice_print_top_netlist(char* circuit_name,$/;" f +spice_reserved ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean spice_reserved;$/;" m struct:s_reserved_syntax_char +spice_sb_mux_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_sb_mux_tb_dir_name = "sb_mux_tb\/";$/;" v file: +spice_sb_mux_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_sb_mux_testbench_postfix = "_sbmux_testbench.sp";$/;" v +spice_sb_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_sb_tb_dir_name = "sb_tb\/";$/;" v file: +spice_sb_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_sb_testbench_postfix = "_sb_testbench.sp";$/;" v +spice_sim_multi_thread_num ./fpga_x2p/spice/spice_globals.c /^int spice_sim_multi_thread_num = 8;$/;" v +spice_sram_inf_orgz ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_sram_inf_orgz* spice_sram_inf_orgz;$/;" m struct:s_sram_inf +spice_tb_global_clock_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_clock_port_name = "gclock";$/;" v +spice_tb_global_config_done_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_config_done_port_name = "gconfig_done";$/;" v +spice_tb_global_gnd_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_gnd_port_name = "ggnd";$/;" v +spice_tb_global_port_inv_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_port_inv_postfix = "_inv";$/;" v +spice_tb_global_reset_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_reset_port_name = "greset";$/;" v +spice_tb_global_set_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_set_port_name = "gset";$/;" v +spice_tb_global_vdd_cb_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_cb_sram_port_name = "gvdd_sram_cbs";$/;" v +spice_tb_global_vdd_direct_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_direct_port_name = "gvdd_direct_interc";$/;" v +spice_tb_global_vdd_hardlogic_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_hardlogic_port_name = "gvdd_hardlogic";$/;" v +spice_tb_global_vdd_hardlogic_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_hardlogic_sram_port_name = "gvdd_sram_hardlogic";$/;" v +spice_tb_global_vdd_io_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_io_port_name = "gvdd_io";$/;" v +spice_tb_global_vdd_io_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_io_sram_port_name = "gvdd_sram_io";$/;" v +spice_tb_global_vdd_load_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_load_port_name = "gvdd_load";$/;" v +spice_tb_global_vdd_localrouting_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_localrouting_port_name = "gvdd_local_interc";$/;" v +spice_tb_global_vdd_localrouting_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_localrouting_sram_port_name = "gvdd_sram_local_routing";$/;" v +spice_tb_global_vdd_lut_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_lut_sram_port_name = "gvdd_sram_luts";$/;" v +spice_tb_global_vdd_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_port_name = "gvdd";$/;" v +spice_tb_global_vdd_sb_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_sb_sram_port_name = "gvdd_sram_sbs";$/;" v +spice_tb_global_vdd_sram_port_name ./fpga_x2p/spice/spice_globals.c /^char* spice_tb_global_vdd_sram_port_name = "gvdd_sram";$/;" v +spice_top_tb_dir_name ./fpga_x2p/spice/spice_api.c /^static char* spice_top_tb_dir_name = "top_tb\/";$/;" v file: +spice_top_testbench_postfix ./fpga_x2p/spice/spice_globals.c /^char* spice_top_testbench_postfix = "_top.sp";$/;" v +split_path_prog_name ./fpga_x2p/base/fpga_x2p_utils.c /^int split_path_prog_name(char* prog_path,$/;" f +spot_blk_position_in_a_macro ./place/place_macro.c /^int spot_blk_position_in_a_macro(t_pl_macro pl_macros,$/;" f +spot_int_in_array ../../libarchfpga/util.c /^int spot_int_in_array(int array_len, int* array,$/;" f +sram_bit ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_conf_bit* sram_bit;$/;" m struct:s_conf_bit_info +sram_inf ../../libarchfpga/include/physical_types.h /^ t_sram_inf sram_inf;$/;" m struct:s_arch +sram_spice_model ./fpga_x2p/spice/spice_globals.c /^t_spice_model* sram_spice_model = NULL;$/;" v +sram_spice_orgz_info ./fpga_x2p/spice/spice_globals.c /^t_sram_orgz_info* sram_spice_orgz_info = NULL;$/;" v +sram_spice_orgz_type ./fpga_x2p/spice/spice_globals.c /^enum e_sram_orgz sram_spice_orgz_type = SPICE_SRAM_STANDALONE;$/;" v typeref:enum:e_sram_orgz +sram_verilog_model ./fpga_x2p/verilog/verilog_global.c /^t_spice_model* sram_verilog_model = NULL;$/;" v +stage_gain ./power/power.h /^ float stage_gain;$/;" m struct:s_power_buffer_strength_inf +standalone ../../libarchfpga/include/ezxml.h /^ short standalone; \/* non-zero if *\/$/;" m struct:ezxml_root +standalone_sram_info ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_standalone_sram_info* standalone_sram_info; \/* Only be allocated when orgz type is standalone *\/$/;" m struct:s_sram_orgz_info +start ./base/vpr_types.h /^ int start;$/;" m struct:s_seg_details +start_bits ../../pcre/SRC/internal.h /^ uschar start_bits[32];$/;" m struct:pcre_study_data +start_code ../../pcre/SRC/internal.h /^ const uschar *start_code; \/* For use when recursing *\/$/;" m struct:match_data +start_code ../../pcre/SRC/internal.h /^ const uschar *start_code; \/* The start of the compiled code *\/$/;" m struct:compile_data +start_col ../../libarchfpga/include/physical_types.h /^ int start_col;$/;" m struct:s_grid_loc_def +start_hash_table_iterator ./util/hash.c /^struct s_hash_iterator start_hash_table_iterator(void) {$/;" f +start_match ../../pcre/SRC/internal.h /^ const uschar *start_match; \/* Start of this match attempt *\/$/;" m struct:match_data +start_match ../../pcre/SRC/pcre.h /^ int start_match; \/* Offset to start of this match attempt *\/$/;" m struct:pcre_callout_block +start_new_cluster ./pack/cluster.c /^static void start_new_cluster($/;" f file: +start_offset ../../pcre/SRC/internal.h /^ int start_offset; \/* The start offset value *\/$/;" m struct:match_data +start_seg_switch ../../libarchfpga/include/arch_types_mrfpga.h /^ short start_seg_switch;$/;" m struct:s_arch_mrfpga +start_seg_switch ./mrfpga/mrfpga_globals.c /^short start_seg_switch;$/;" v +start_subject ../../pcre/SRC/internal.h /^ const uschar *start_subject; \/* Start of the subject string *\/$/;" m struct:match_data +starting_pin_idx ./power/power.h /^ int starting_pin_idx; \/* Applicable to level 0 only, the overall mux primary input index *\/$/;" m struct:s_mux_node +starting_t ./place/place.c /^static float starting_t(float *cost_ptr, float *bb_cost_ptr,$/;" f file: +stats_lut_spice_mux ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void stats_lut_spice_mux(t_llist** muxes_head,$/;" f +stats_mux_spice_model_pb_node_rec ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void stats_mux_spice_model_pb_node_rec(t_llist** muxes_head,$/;" f +stats_mux_spice_model_pb_type_rec ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void stats_mux_spice_model_pb_type_rec(t_llist** muxes_head,$/;" f +stats_mux_verilog_model_pb_node_rec ./fpga_x2p/verilog/verilog_pbtypes.c /^void stats_mux_verilog_model_pb_node_rec(t_llist** muxes_head,$/;" f +stats_mux_verilog_model_pb_type_rec ./fpga_x2p/verilog/verilog_pbtypes.c /^void stats_mux_verilog_model_pb_type_rec(t_llist** muxes_head,$/;" f +stats_pb_graph_node_port_pin_numbers ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void stats_pb_graph_node_port_pin_numbers(t_pb_graph_node* cur_pb_graph_node,$/;" f +stats_spice_muxes ./fpga_x2p/base/fpga_x2p_mux_utils.c /^t_llist* stats_spice_muxes(int num_switches,$/;" f +stats_spice_muxes_routing_arch ./fpga_x2p/base/fpga_x2p_mux_utils.c /^void stats_spice_muxes_routing_arch(t_llist** muxes_head,$/;" f +statusMessage ./base/graphics.c /^static char statusMessage[BUFSIZE] = ""; \/* User message to display *\/$/;" v file: +std ./base/graphics.c /^using namespace std;$/;" v +std ./power/PowerSpicedComponent.c /^using namespace std;$/;" v +std ./power/power.c /^using namespace std;$/;" v +std ./power/power_cmos_tech.c /^using namespace std;$/;" v +std ./power/power_components.c /^using namespace std;$/;" v +std ./power/power_sizing.c /^using namespace std;$/;" v +std ./power/power_util.c /^using namespace std;$/;" v +stimu_header_file_name ./fpga_x2p/spice/spice_globals.c /^char* stimu_header_file_name = "stimulate_params.sp";$/;" v +stimulate_params ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_stimulate_params stimulate_params;$/;" m struct:s_spice_params +store_char_in_data ./timing/slre.c /^static void store_char_in_data(struct slre *r, int ch) {$/;" f file: +strength_inf ./power/power.h /^ t_power_buffer_strength_inf * strength_inf;$/;" m struct:s_power_buffer_size_inf +strncmp ../../pcre/SRC/internal.h 47;" d +structure ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_structure structure;$/;" m struct:s_spice_model_mux typeref:enum:s_spice_model_mux::e_spice_model_structure +structure ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_structure structure;$/;" m struct:s_spice_mux_arch typeref:enum:s_spice_mux_arch::e_spice_model_structure +structure ../../libarchfpga/include/physical_types.h /^ enum e_spice_model_structure structure;$/;" m struct:s_switch_inf typeref:enum:s_switch_inf::e_spice_model_structure +study_data ../../pcre/SRC/pcre.h /^ void *study_data; \/* Opaque data from pcre_study() *\/$/;" m struct:pcre_extra +subckt_dir ./base/vpr_types.h /^ char* subckt_dir;$/;" m struct:s_spice_opts +subject ../../pcre/SRC/pcre.h /^ const char *subject; \/* The subject being matched *\/$/;" m struct:pcre_callout_block +subject_length ../../pcre/SRC/pcre.h /^ int subject_length; \/* The length of the subject *\/$/;" m struct:pcre_callout_block +submodule_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* submodule_verilog_file_name = "sub_module.v";$/;" v +submodule_verilog_subckt_file_path_head ./fpga_x2p/verilog/verilog_global.c /^t_llist* submodule_verilog_subckt_file_path_head = NULL;$/;" v +sum_pin_class ./pack/cluster_feasibility_filter.c /^static void sum_pin_class(INOUTP t_pb_graph_node *pb_graph_node) {$/;" f file: +swap_blk_same_class_2pins ./fpga_x2p/clb_pin_remap/clb_pin_remap_util.c /^void swap_blk_same_class_2pins(t_block* target_blk, int n_nets, t_net* nets,$/;" f +swap_float ./fpga_x2p/base/quicksort.c /^void swap_float(float* int_a, float* int_b) {$/;" f file: +swap_int ./fpga_x2p/base/quicksort.c /^void swap_int(int* int_a, int* int_b) {$/;" f file: +swap_result ./place/place.c /^enum swap_result {$/;" g file: +swapped_to_empty ./place/place.c /^ int swapped_to_empty;$/;" m struct:s_pl_moved_block file: +sweep_hanging_nets_and_inputs ./base/ReadOptions.h /^ boolean sweep_hanging_nets_and_inputs;$/;" m struct:s_options +sweep_hanging_nets_and_inputs ./base/vpr_types.h /^ boolean sweep_hanging_nets_and_inputs;$/;" m struct:s_packer_opts +switch_block_type ./base/vpr_types.h /^ enum e_switch_block_type switch_block_type;$/;" m struct:s_det_routing_arch typeref:enum:s_det_routing_arch::e_switch_block_type +switch_inf ./base/globals.c /^struct s_switch_inf *switch_inf = NULL; \/* [0..(det_routing_arch.num_switch-1)] *\/$/;" v typeref:struct:s_switch_inf +switch_inf ./base/globals_declare.h /^struct s_switch_inf *switch_inf; \/* [0..det_routing_arch.num_switch-1] *\/$/;" v typeref:struct:s_switch_inf +switch_inf ./fpga_x2p/base/fpga_x2p_types.h /^ t_switch_inf* switch_inf;$/;" m struct:fpga_spice_rr_graph +switch_num_level ../../libarchfpga/include/physical_types.h /^ int switch_num_level;$/;" m struct:s_switch_inf +switches ./base/vpr_types.h /^ short *switches;$/;" m struct:s_rr_node +swseg_pattern_change_switch_type ./route/rr_graph_swseg.c /^int swseg_pattern_change_switch_type(int cur_node,$/;" f file: +swseg_patterns ../../libarchfpga/include/physical_types.h /^ t_swseg_pattern_inf* swseg_patterns;$/;" m struct:s_arch +swseg_patterns ./base/vpr_types.h /^ t_swseg_pattern_inf* swseg_patterns; \/* Xifan TANG: Switch Segment Pattern Support *\/$/;" m struct:s_vpr_setup +syn_verilog_dump_dir ./base/vpr_types.h /^ char* syn_verilog_dump_dir;$/;" m struct:s_syn_verilog_opts +sync_arch_mrfpga_globals ./mrfpga/mrfpga_api.c /^void sync_arch_mrfpga_globals(t_arch_mrfpga arch_mrfpga) {$/;" f +sync_grid_to_blocks ./util/vpr_utils.c /^void sync_grid_to_blocks(INP int L_num_blocks,$/;" f +sync_pb_graph_pin_vpack_net_num_to_phy_pb ./fpga_x2p/router/fpga_x2p_pb_rr_graph.c /^void sync_pb_graph_pin_vpack_net_num_to_phy_pb(t_rr_node* cur_op_pb_rr_graph, $/;" f +syntax_char ../../libarchfpga/fpga_spice_include/spice_types.h /^ char syntax_char;$/;" m struct:s_reserved_syntax_char +szAppName ./base/graphics.c /^static TCHAR szAppName[256], $/;" v file: +szButtonsName ./base/graphics.c /^szButtonsName[] = TEXT("VPR Buttons");$/;" v file: +szGraphicsName ./base/graphics.c /^szGraphicsName[] = TEXT("VPR Graphics"), $/;" v file: +szStatusName ./base/graphics.c /^szStatusName[] = TEXT("VPR Status"),$/;" v file: +t_arch ../../libarchfpga/include/physical_types.h /^typedef struct s_arch t_arch;$/;" t typeref:struct:s_arch +t_arch_mrfpga ../../libarchfpga/include/arch_types_mrfpga.h /^typedef struct s_arch_mrfpga t_arch_mrfpga;$/;" t typeref:struct:s_arch_mrfpga +t_bb ./base/vpr_types.h /^typedef struct s_bb t_bb;$/;" t typeref:struct:s_bb +t_bitstream_gen_opts ./base/vpr_types.h /^typedef struct s_bitstream_gen_opts t_bitstream_gen_opts;$/;" t typeref:struct:s_bitstream_gen_opts +t_block ./base/vpr_types.h /^typedef struct s_block t_block;$/;" t typeref:struct:s_block +t_buffer_inf ../../libarchfpga/include/arch_types_mrfpga.h /^typedef struct s_buffer_inf t_buffer_inf;$/;" t typeref:struct:s_buffer_inf +t_buffer_plan ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan {t_linked_int* inode_head; t_linked_int* sink_head; float* sink_delay; float C_downstream; float Tdel;} t_buffer_plan;$/;" t typeref:struct:s_buffer_plan file: +t_buffer_plan_list ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_list { t_buffer_plan_node* front; } t_buffer_plan_list;$/;" t typeref:struct:s_buffer_plan_list file: +t_buffer_plan_node ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_node { t_buffer_plan value; struct s_buffer_plan_node* next;} t_buffer_plan_node;$/;" t typeref:struct:s_buffer_plan_node file: +t_button ./base/graphics.c /^} t_button;$/;" t typeref:struct:__anon4 file: +t_button_type ./base/graphics.c /^} t_button_type;$/;" t typeref:enum:__anon3 file: +t_cb ./base/vpr_types.h /^typedef struct s_cb t_cb;$/;" t typeref:struct:s_cb +t_chan ../../libarchfpga/include/physical_types.h /^} t_chan;$/;" t typeref:struct:s_chan +t_chan_width_dist ../../libarchfpga/include/physical_types.h /^} t_chan_width_dist;$/;" t typeref:struct:s_chan_width_dist +t_chunk ../../libarchfpga/include/util.h /^} t_chunk;$/;" t typeref:struct:s_chunk +t_class ../../libarchfpga/include/physical_types.h /^typedef struct s_class t_class;$/;" t typeref:struct:s_class +t_clb_to_clb_directs ./base/vpr_types.h /^} t_clb_to_clb_directs;$/;" t typeref:struct:s_clb_to_clb_directs +t_clock ./base/vpr_types.h /^} t_clock;$/;" t typeref:struct:s_clock +t_clock_arch ../../libarchfpga/include/physical_types.h /^typedef struct s_clock_arch t_clock_arch;$/;" t typeref:struct:s_clock_arch +t_clock_network ../../libarchfpga/include/physical_types.h /^typedef struct s_clock_network t_clock_network;$/;" t typeref:struct:s_clock_network +t_cluster_placement_primitive ../../libarchfpga/include/cad_types.h /^} t_cluster_placement_primitive;$/;" t typeref:struct:s_cluster_placement_primitive +t_cluster_placement_stats ./base/vpr_types.h /^} t_cluster_placement_stats;$/;" t typeref:struct:s_cluster_placement_stats +t_cmd_category ./fpga_x2p/shell/shell_types.h /^typedef struct s_cmd_category t_cmd_category;$/;" t typeref:struct:s_cmd_category +t_cmd_info ./fpga_x2p/shell/read_opt_types.h /^typedef struct s_cmd_info t_cmd_info;$/;" t typeref:struct:s_cmd_info +t_conf_bit ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_conf_bit t_conf_bit;$/;" t typeref:struct:s_conf_bit +t_conf_bit_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_conf_bit_info t_conf_bit_info;$/;" t typeref:struct:s_conf_bit_info +t_det_routing_arch ./base/vpr_types.h /^typedef struct s_det_routing_arch t_det_routing_arch;$/;" t typeref:struct:s_det_routing_arch +t_direct_inf ../../libarchfpga/include/physical_types.h /^} t_direct_inf;$/;" t typeref:struct:s_direct_inf +t_display_type ./base/graphics.c /^} t_display_type;$/;" t typeref:enum:__anon2 file: +t_fmap_cell ./base/place_and_route.h /^} t_fmap_cell;$/;" t typeref:struct:s_fmap_cell +t_fpga_spice_opts ./base/vpr_types.h /^typedef struct s_fpga_spice_opts t_fpga_spice_opts;$/;" t typeref:struct:s_fpga_spice_opts +t_gl_state ./base/graphics.c /^} t_gl_state;$/;" t typeref:struct:__anon5 file: +t_graph_type ./route/rr_graph.h /^typedef enum e_graph_type t_graph_type;$/;" t typeref:enum:e_graph_type +t_grid_loc_def ../../libarchfpga/include/physical_types.h /^} t_grid_loc_def;$/;" t typeref:struct:s_grid_loc_def +t_grid_tile ./base/vpr_types.h /^} t_grid_tile;$/;" t typeref:struct:s_grid_tile +t_heap ./route/route_common.h /^typedef struct s_heap t_heap;$/;" t typeref:struct:s_heap +t_interconnect ../../libarchfpga/include/physical_types.h /^typedef struct s_interconnect t_interconnect;$/;" t typeref:struct:s_interconnect +t_interconnect_pins ../../libarchfpga/include/physical_types.h /^typedef struct s_interconnect_pins t_interconnect_pins;$/;" t typeref:struct:s_interconnect_pins +t_interconnect_power ../../libarchfpga/include/physical_types.h /^typedef struct s_interconnect_power t_interconnect_power;$/;" t typeref:struct:s_interconnect_power +t_io ./base/vpr_types.h /^} t_io;$/;" t typeref:struct:s_io +t_ivec ../../libarchfpga/include/util.h /^} t_ivec;$/;" t typeref:struct:s_ivec +t_legal_pos ./place/place.c /^}t_legal_pos;$/;" t typeref:struct:s_legal_pos file: +t_linked_edge ./route/rr_graph_util.h /^typedef struct s_linked_edge t_linked_edge;$/;" t typeref:struct:s_linked_edge +t_linked_f_pointer ./base/vpr_types.h /^typedef struct s_linked_f_pointer t_linked_f_pointer;$/;" t typeref:struct:s_linked_f_pointer +t_linked_int ../../libarchfpga/include/util.h /^} t_linked_int;$/;" t typeref:struct:s_linked_int +t_linked_rc_edge ./timing/net_delay_types.h /^typedef struct s_linked_rc_edge t_linked_rc_edge;$/;" t typeref:struct:s_linked_rc_edge +t_linked_rc_ptr ./timing/net_delay_types.h /^typedef struct s_linked_rc_ptr t_linked_rc_ptr;$/;" t typeref:struct:s_linked_rc_ptr +t_linked_rt_edge ./route/route_tree_timing.h /^typedef struct s_linked_rt_edge t_linked_rt_edge;$/;" t typeref:struct:s_linked_rt_edge +t_linked_vptr ../../libarchfpga/include/util.h /^} t_linked_vptr;$/;" t typeref:struct:s_linked_vptr +t_llist ../../libarchfpga/fpga_spice_include/linkedlist.h /^typedef struct s_llist t_llist;$/;" t typeref:struct:s_llist +t_log ./power/power.h /^typedef struct s_log t_log;$/;" t typeref:struct:s_log +t_logical_block ./base/vpr_types.h /^} t_logical_block;$/;" t typeref:struct:s_logical_block +t_mem_bank_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_mem_bank_info t_mem_bank_info;$/;" t typeref:struct:s_mem_bank_info +t_memristor_inf ../../libarchfpga/include/arch_types_mrfpga.h /^typedef struct s_memristor_inf t_memristor_inf;$/;" t typeref:struct:s_memristor_inf +t_mode ../../libarchfpga/include/physical_types.h /^typedef struct s_mode t_mode;$/;" t typeref:struct:s_mode +t_mode_power ../../libarchfpga/include/physical_types.h /^typedef struct s_mode_power t_mode_power;$/;" t typeref:struct:s_mode_power +t_model ../../libarchfpga/include/logic_types.h /^} t_model;$/;" t typeref:struct:s_model +t_model_chain_pattern ../../libarchfpga/include/cad_types.h /^} t_model_chain_pattern;$/;" t typeref:struct:s_model_chain_pattern +t_model_ports ../../libarchfpga/include/logic_types.h /^} t_model_ports;$/;" t typeref:struct:s_model_ports +t_mux ./route/rr_graph.c /^} t_mux;$/;" t typeref:struct:s_mux file: +t_mux_arch ./power/power.h /^typedef struct s_mux_arch t_mux_arch;$/;" t typeref:struct:s_mux_arch +t_mux_node ./power/power.h /^typedef struct s_mux_node t_mux_node;$/;" t typeref:struct:s_mux_node +t_mux_size_distribution ./route/rr_graph.c /^} t_mux_size_distribution;$/;" t typeref:struct:s_mux_size_distribution file: +t_net ./base/vpr_types.h /^} t_net;$/;" t typeref:struct:s_net +t_net_power ./base/vpr_types.h /^typedef struct s_net_power t_net_power;$/;" t typeref:struct:s_net_power +t_num_mapped_opins_stats ./route/pb_pin_eq_auto_detect.c /^typedef struct s_num_mapped_opins_stats t_num_mapped_opins_stats;$/;" t typeref:struct:s_num_mapped_opins_stats file: +t_opt_info ./fpga_x2p/shell/read_opt_types.h /^typedef struct s_opt_info t_opt_info;$/;" t typeref:struct:s_opt_info +t_options ./base/ReadOptions.h /^typedef struct s_options t_options;$/;" t typeref:struct:s_options +t_override_constraint ./base/vpr_types.h /^} t_override_constraint;$/;" t typeref:struct:s_override_constraint +t_pack_molecule ./base/vpr_types.h /^} t_pack_molecule;$/;" t typeref:struct:s_pack_molecule +t_pack_pattern_block ../../libarchfpga/include/cad_types.h /^} t_pack_pattern_block;$/;" t typeref:struct:s_pack_pattern_block +t_pack_pattern_connections ../../libarchfpga/include/cad_types.h /^} t_pack_pattern_connections;$/;" t typeref:struct:s_pack_pattern_connections +t_pack_patterns ../../libarchfpga/include/cad_types.h /^} t_pack_patterns;$/;" t typeref:struct:s_pack_patterns +t_pb ./base/vpr_types.h /^} t_pb;$/;" t typeref:struct:s_pb +t_pb_graph_edge ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_graph_edge t_pb_graph_edge;$/;" t typeref:struct:s_pb_graph_edge +t_pb_graph_node ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_graph_node t_pb_graph_node;$/;" t typeref:struct:s_pb_graph_node +t_pb_graph_node_power ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_graph_node_power t_pb_graph_node_power;$/;" t typeref:struct:s_pb_graph_node_power +t_pb_graph_pin ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_graph_pin t_pb_graph_pin;$/;" t typeref:struct:s_pb_graph_pin +t_pb_graph_pin_power ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_graph_pin_power t_pb_graph_pin_power;$/;" t typeref:struct:s_pb_graph_pin_power +t_pb_stats ./base/vpr_types.h /^} t_pb_stats;$/;" t typeref:struct:s_pb_stats +t_pb_type ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_type t_pb_type;$/;" t typeref:struct:s_pb_type +t_pb_type_power ../../libarchfpga/include/physical_types.h /^typedef struct s_pb_type_power t_pb_type_power;$/;" t typeref:struct:s_pb_type_power +t_phy_pb ./fpga_x2p/base/fpga_x2p_types.h /^typedef struct fpga_spice_phy_pb t_phy_pb;$/;" t typeref:struct:fpga_spice_phy_pb +t_pin_to_pin_annotation ../../libarchfpga/include/physical_types.h /^typedef struct s_pin_to_pin_annotation t_pin_to_pin_annotation;$/;" t typeref:struct:s_pin_to_pin_annotation +t_pl_blocks_to_be_moved ./place/place.c /^}t_pl_blocks_to_be_moved;$/;" t typeref:struct:s_pl_blocks_to_be_moved file: +t_pl_macro ./place/place_macro.h /^} t_pl_macro;$/;" t typeref:struct:s_pl_macro +t_pl_macro_member ./place/place_macro.h /^} t_pl_macro_member;$/;" t typeref:struct:s_pl_macro_member +t_pl_moved_block ./place/place.c /^}t_pl_moved_block;$/;" t typeref:struct:s_pl_moved_block file: +t_point ./base/easygl_constants.h /^} t_point; \/* Used in calls to fillpoly *\/$/;" t typeref:struct:__anon1 +t_port ../../libarchfpga/include/physical_types.h /^typedef struct s_port t_port;$/;" t typeref:struct:s_port +t_port_power ../../libarchfpga/include/physical_types.h /^typedef struct s_port_power t_port_power;$/;" t typeref:struct:s_port_power +t_power_arch ../../libarchfpga/include/physical_types.h /^typedef struct s_power_arch t_power_arch;$/;" t typeref:struct:s_power_arch +t_power_buffer_sc_levr_inf ./power/power.h /^typedef struct s_power_buffer_sc_levr_inf t_power_buffer_sc_levr_inf;$/;" t typeref:struct:s_power_buffer_sc_levr_inf +t_power_buffer_size_inf ./power/power.h /^typedef struct s_power_buffer_size_inf t_power_buffer_size_inf;$/;" t typeref:struct:s_power_buffer_size_inf +t_power_buffer_strength_inf ./power/power.h /^typedef struct s_power_buffer_strength_inf t_power_buffer_strength_inf;$/;" t typeref:struct:s_power_buffer_strength_inf +t_power_commonly_used ./power/power.h /^typedef struct s_power_commonly_used t_power_commonly_used;$/;" t typeref:struct:s_power_commonly_used +t_power_components ./power/power_components.h /^typedef struct s_power_breakdown t_power_components;$/;" t typeref:struct:s_power_breakdown +t_power_estimation_method ../../libarchfpga/include/physical_types.h /^typedef enum e_power_estimation_method_ t_power_estimation_method;$/;" t typeref:enum:e_power_estimation_method_ +t_power_mux_info ./power/power.h /^typedef struct s_power_mux_info t_power_mux_info;$/;" t typeref:struct:s_power_mux_info +t_power_mux_volt_inf ./power/power.h /^typedef struct s_power_mux_volt_inf t_power_mux_volt_inf;$/;" t typeref:struct:s_power_mux_volt_inf +t_power_mux_volt_pair ./power/power.h /^typedef struct s_power_mux_volt_pair t_power_mux_volt_pair;$/;" t typeref:struct:s_power_mux_volt_pair +t_power_nmos_leakage_inf ./power/power.h /^typedef struct s_power_nmos_leakage_inf t_power_nmos_leakage_inf;$/;" t typeref:struct:s_power_nmos_leakage_inf +t_power_nmos_leakage_pair ./power/power.h /^typedef struct s_power_nmos_leakage_pair t_power_nmos_leakage_pair;$/;" t typeref:struct:s_power_nmos_leakage_pair +t_power_nmos_leakages ./power/power.h /^typedef struct s_power_nmos_leakages t_power_nmos_leakages;$/;" t typeref:struct:s_power_nmos_leakages +t_power_nmos_mux_inf ./power/power.h /^typedef struct s_power_nmos_mux_inf t_power_nmos_mux_inf;$/;" t typeref:struct:s_power_nmos_mux_inf +t_power_opts ./base/vpr_types.h /^typedef struct s_power_opts t_power_opts;$/;" t typeref:struct:s_power_opts +t_power_output ./power/power.h /^typedef struct s_power_output t_power_output;$/;" t typeref:struct:s_power_output +t_power_tech ./power/power.h /^typedef struct s_power_tech t_power_tech;$/;" t typeref:struct:s_power_tech +t_power_usage ../../libarchfpga/include/physical_types.h /^typedef struct s_power_usage t_power_usage;$/;" t typeref:struct:s_power_usage +t_prepacked_tnode_data ./base/vpr_types.h /^} t_prepacked_tnode_data;$/;" t typeref:struct:s_prepacked_tnode_data +t_rc_node ./timing/net_delay_types.h /^typedef struct s_rc_node t_rc_node;$/;" t typeref:struct:s_rc_node +t_report ./base/graphics.h /^} t_report;$/;" t typeref:struct:__anon6 +t_reserved_syntax_char ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_reserved_syntax_char t_reserved_syntax_char;$/;" t typeref:struct:s_reserved_syntax_char +t_router_opts ./base/vpr_types.h /^typedef struct s_router_opts t_router_opts;$/;" t typeref:struct:s_router_opts +t_rr_graph ./fpga_x2p/base/fpga_x2p_types.h /^typedef struct fpga_spice_rr_graph t_rr_graph;$/;" t typeref:struct:fpga_spice_rr_graph +t_rr_indexed_data ./base/vpr_types.h /^} t_rr_indexed_data;$/;" t typeref:struct:s_rr_indexed_data +t_rr_node ./base/vpr_types.h /^typedef struct s_rr_node t_rr_node;$/;" t typeref:struct:s_rr_node +t_rr_node_power ./power/power.h /^typedef struct s_rr_node_power t_rr_node_power;$/;" t typeref:struct:s_rr_node_power +t_rr_node_route_inf ./route/route_common.h /^} t_rr_node_route_inf;$/;" t typeref:struct:__anon15 +t_rr_type ./base/vpr_types.h /^} t_rr_type;$/;" t typeref:enum:e_rr_type +t_rt_node ./route/route_tree_timing.h /^typedef struct s_rt_node t_rt_node;$/;" t typeref:struct:s_rt_node +t_sb ./base/vpr_types.h /^typedef struct s_sb t_sb;$/;" t typeref:struct:s_sb +t_scff_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_scff_info t_scff_info;$/;" t typeref:struct:s_scff_info +t_sdc_clock ./timing/read_sdc.c /^} t_sdc_clock;$/;" t typeref:struct:s_sdc_clock file: +t_sdc_exclusive_group ./timing/read_sdc.c /^} t_sdc_exclusive_group;$/;" t typeref:struct:s_sdc_exclusive_group file: +t_sdc_opts ./fpga_x2p/verilog/verilog_sdc.c /^typedef struct s_sdc_opts t_sdc_opts;$/;" t typeref:struct:s_sdc_opts file: +t_seg_details ./base/vpr_types.h /^} t_seg_details;$/;" t typeref:struct:s_seg_details +t_segment_inf ../../libarchfpga/include/physical_types.h /^} t_segment_inf;$/;" t typeref:struct:s_segment_inf +t_shell_cmd ./fpga_x2p/shell/shell_types.h /^typedef struct s_shell_cmd t_shell_cmd;$/;" t typeref:struct:s_shell_cmd +t_shell_env ./fpga_x2p/shell/shell_types.h /^typedef struct s_shell_env t_shell_env;$/;" t typeref:struct:s_shell_env +t_slack ./base/vpr_types.h /^} t_slack;$/;" t typeref:struct:s_slack +t_solution_inf ./power/power.h /^typedef struct s_solution_inf t_solution_inf;$/;" t typeref:struct:s_solution_inf +t_spice ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice t_spice;$/;" t typeref:struct:s_spice +t_spice_mc_params ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_mc_params t_spice_mc_params;$/;" t typeref:struct:s_spice_mc_params +t_spice_mc_variation_params ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_mc_variation_params t_spice_mc_variation_params;$/;" t typeref:struct:s_spice_mc_variation_params +t_spice_meas_params ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_meas_params t_spice_meas_params;$/;" t typeref:struct:s_spice_meas_params +t_spice_model ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model t_spice_model;$/;" t typeref:struct:s_spice_model +t_spice_model_buffer ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_buffer t_spice_model_buffer;$/;" t typeref:struct:s_spice_model_buffer +t_spice_model_delay_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_delay_info t_spice_model_delay_info;$/;" t typeref:struct:s_spice_model_delay_info +t_spice_model_design_tech_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_design_tech_info t_spice_model_design_tech_info;$/;" t typeref:struct:s_spice_model_design_tech_info +t_spice_model_gate ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_gate t_spice_model_gate;$/;" t typeref:struct:s_spice_model_gate +t_spice_model_lut ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_lut t_spice_model_lut;$/;" t typeref:struct:s_spice_model_lut +t_spice_model_mux ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_mux t_spice_model_mux;$/;" t typeref:struct:s_spice_model_mux +t_spice_model_netlist ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_netlist t_spice_model_netlist;$/;" t typeref:struct:s_spice_model_netlist +t_spice_model_pass_gate_logic ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_pass_gate_logic t_spice_model_pass_gate_logic;$/;" t typeref:struct:s_spice_model_pass_gate_logic +t_spice_model_port ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_port t_spice_model_port;$/;" t typeref:struct:s_spice_model_port +t_spice_model_rram ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_rram t_spice_model_rram;$/;" t typeref:struct:s_spice_model_rram +t_spice_model_tedge ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_tedge t_spice_model_tedge;$/;" t typeref:struct:s_spice_model_tedge +t_spice_model_wire_param ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_model_wire_param t_spice_model_wire_param;$/;" t typeref:struct:s_spice_model_wire_param +t_spice_mux_arch ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_mux_arch t_spice_mux_arch;$/;" t typeref:struct:s_spice_mux_arch +t_spice_mux_model ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_mux_model t_spice_mux_model;$/;" t typeref:struct:s_spice_mux_model +t_spice_net_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_net_info t_spice_net_info;$/;" t typeref:struct:s_spice_net_info +t_spice_opts ./base/vpr_types.h /^typedef struct s_spice_opts t_spice_opts;$/;" t typeref:struct:s_spice_opts +t_spice_params ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_params t_spice_params;$/;" t typeref:struct:s_spice_params +t_spice_stimulate_params ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_stimulate_params t_spice_stimulate_params;$/;" t typeref:struct:s_spice_stimulate_params +t_spice_tech_lib ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_tech_lib t_spice_tech_lib;$/;" t typeref:struct:s_spice_tech_lib +t_spice_transistor_type ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spice_transistor_type t_spice_transistor_type;$/;" t typeref:struct:s_spice_transistor_type +t_spicetb_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_spicetb_info t_spicetb_info;$/;" t typeref:struct:s_spicetb_info +t_sram_inf ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_sram_inf t_sram_inf;$/;" t typeref:struct:s_sram_inf +t_sram_inf_orgz ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_sram_inf_orgz t_sram_inf_orgz;$/;" t typeref:struct:s_sram_inf_orgz +t_sram_orgz_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_sram_orgz_info t_sram_orgz_info;$/;" t typeref:struct:s_sram_orgz_info +t_standalone_sram_info ../../libarchfpga/fpga_spice_include/spice_types.h /^typedef struct s_standalone_sram_info t_standalone_sram_info;$/;" t typeref:struct:s_standalone_sram_info +t_switch_block_type ../../libarchfpga/include/physical_types.h /^typedef enum e_switch_block_type t_switch_block_type;$/;" t typeref:enum:e_switch_block_type +t_switch_inf ../../libarchfpga/include/physical_types.h /^} t_switch_inf;$/;" t typeref:struct:s_switch_inf +t_swseg_pattern_inf ../../libarchfpga/include/physical_types.h /^typedef struct s_swseg_pattern_inf t_swseg_pattern_inf;$/;" t typeref:struct:s_swseg_pattern_inf +t_syn_verilog_opts ./base/vpr_types.h /^typedef struct s_syn_verilog_opts t_syn_verilog_opts;$/;" t typeref:struct:s_syn_verilog_opts +t_tedge ./base/vpr_types.h /^} t_tedge;$/;" t typeref:struct:s_tedge +t_timing_constraints ./base/vpr_types.h /^} t_timing_constraints;$/;" t typeref:struct:s_timing_constraints +t_timing_inf ../../libarchfpga/include/physical_types.h /^} t_timing_inf;$/;" t typeref:struct:s_timing_inf +t_timing_stats ./base/vpr_types.h /^} t_timing_stats;$/;" t typeref:struct:s_timing_stats +t_tnode ./base/vpr_types.h /^} t_tnode;$/;" t typeref:struct:s_tnode +t_token ./util/token.h /^typedef struct s_token t_token;$/;" t typeref:struct:s_token +t_trace ./base/vpr_types.h /^} t_trace;$/;" t typeref:struct:s_trace +t_transistor_inf ./power/power.h /^typedef struct s_transistor_inf t_transistor_inf;$/;" t typeref:struct:s_transistor_inf +t_transistor_size_inf ./power/power.h /^typedef struct s_transistor_size_inf t_transistor_size_inf;$/;" t typeref:struct:s_transistor_size_inf +t_trpt_opts ./fpga_x2p/verilog/verilog_report_timing.c /^typedef struct s_trpt_opts t_trpt_opts;$/;" t typeref:struct:s_trpt_opts file: +t_type_descriptor ../../libarchfpga/include/physical_types.h /^typedef struct s_type_descriptor t_type_descriptor;$/;" t typeref:struct:s_type_descriptor +t_type_ptr ../../libarchfpga/include/physical_types.h /^typedef const struct s_type_descriptor *t_type_ptr;$/;" t typeref:struct:s_type_descriptor +t_vpr_setup ./base/vpr_types.h /^} t_vpr_setup;$/;" t typeref:struct:s_vpr_setup +t_wireL_cnt ./fpga_x2p/verilog/verilog_report_timing.c /^typedef struct s_wireL_cnt t_wireL_cnt;$/;" t typeref:struct:s_wireL_cnt file: +tables ../../pcre/SRC/internal.h /^ const unsigned char *tables; \/* Pointer to tables *\/$/;" m struct:real_pcre +tables_length ../../pcre/SRC/internal.h 657;" d +tag ./fpga_x2p/shell/read_opt_types.h /^ char* tag; \/* tag of option *\/$/;" m struct:s_opt_info +tap_buf_level ../../libarchfpga/fpga_spice_include/spice_types.h /^ int tap_buf_level;$/;" m struct:s_spice_model_buffer +tapered_buf ../../libarchfpga/fpga_spice_include/spice_types.h /^ int tapered_buf; \/*Valid only when this is a buffer*\/$/;" m struct:s_spice_model_buffer +target_flag ./route/route_common.h /^ short target_flag;$/;" m struct:__anon15 +tb_cnt ../../libarchfpga/fpga_spice_include/spice_types.h /^ int tb_cnt;$/;" m struct:s_spice_model +tb_head ./fpga_x2p/spice/spice_globals.c /^t_llist* tb_head = NULL;$/;" v +tb_name ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* tb_name;$/;" m struct:s_spicetb_info +tb_num_grid ./fpga_x2p/spice/spice_grid_testbench.c /^static int tb_num_grid = 0;$/;" v file: +tb_num_primitive ./fpga_x2p/spice/spice_primitive_testbench.c /^static int tb_num_primitive = 0;$/;" v file: +td_place_exp_first ./base/vpr_types.h /^ float td_place_exp_first;$/;" m struct:s_placer_opts +td_place_exp_last ./base/vpr_types.h /^ float td_place_exp_last;$/;" m struct:s_placer_opts +tech_comp ../../libarchfpga/include/arch_types_mrfpga.h /^ enum e_tech_comp tech_comp;$/;" m struct:s_arch_mrfpga typeref:enum:s_arch_mrfpga::e_tech_comp +tech_lib ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_tech_lib tech_lib;$/;" m struct:s_spice +tech_size ./power/power.h /^ float tech_size; \/* Tech size in nm, for example 90e-9 for 90nm *\/$/;" m struct:s_power_tech +tedge ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_tedge*** tedge; \/* 3-D array, considering the each pin in this port, [pin_number][num_edges[iedge]] is an edge pointor *\/$/;" m struct:s_spice_model_port +tedge_ch ./timing/path_delay.c /^static t_chunk tedge_ch = {NULL, 0, NULL};$/;" v file: +temp_net_cost ./place/place.c /^static float *net_cost = NULL, *temp_net_cost = NULL; \/* [0..num_nets-1] *\/$/;" v file: +temp_net_num ../../libarchfpga/include/physical_types.h /^ int temp_net_num;$/;" m struct:s_pb_graph_pin +temp_num_pins ./base/read_blif.c /^static int *num_driver, *temp_num_pins;$/;" v file: +temp_placement_index ../../libarchfpga/include/physical_types.h /^ int temp_placement_index;$/;" m struct:s_pb_type +temp_point_to_point_delay_cost ./place/place.c /^static float **temp_point_to_point_delay_cost = NULL;$/;" v file: +temp_point_to_point_timing_cost ./place/place.c /^static float **temp_point_to_point_timing_cost = NULL;$/;" v file: +temp_scratch_pad ../../libarchfpga/include/physical_types.h /^ void *temp_scratch_pad; \/* temporary data, useful for keeping track of things when traversing data structure *\/$/;" m struct:s_pb_graph_node +temp_used ./base/vpr_types.h /^ int temp_used;$/;" m struct:s_logical_block +temperature ./power/power.h /^ float temperature; \/* Temp in C *\/$/;" m struct:s_power_tech +test_if_exposed ./base/graphics.c /^static Bool test_if_exposed (Display *disp, XEvent *event_ptr, XPointer dummy) $/;" f file: +testbench_cb_mux_cnt ./fpga_x2p/spice/spice_mux_testbench.c /^static int testbench_cb_mux_cnt = 0;$/;" v file: +testbench_load_cnt ./fpga_x2p/spice/spice_grid_testbench.c /^static int testbench_load_cnt = 0;$/;" v file: +testbench_load_cnt ./fpga_x2p/spice/spice_mux_testbench.c /^static int testbench_load_cnt = 0;$/;" v file: +testbench_load_cnt ./fpga_x2p/spice/spice_primitive_testbench.c /^static int testbench_load_cnt = 0;$/;" v file: +testbench_load_cnt ./fpga_x2p/spice/spice_routing_testbench.c /^static int testbench_load_cnt = 0;$/;" v file: +testbench_mux_cnt ./fpga_x2p/spice/spice_mux_testbench.c /^static int testbench_mux_cnt = 0;$/;" v file: +testbench_muxes_head ./fpga_x2p/spice/spice_mux_testbench.c /^static t_llist* testbench_muxes_head = NULL; $/;" v file: +testbench_pb_mux_cnt ./fpga_x2p/spice/spice_mux_testbench.c /^static int testbench_pb_mux_cnt = 0;$/;" v file: +testbench_sb_mux_cnt ./fpga_x2p/spice/spice_mux_testbench.c /^static int testbench_sb_mux_cnt = 0;$/;" v file: +testbench_sram_cnt ./fpga_x2p/spice/spice_mux_testbench.c /^static int testbench_sram_cnt = 0;$/;" v file: +text ./base/graphics.c /^ char text[BUTTON_TEXT_LEN]; $/;" m struct:__anon4 file: +textarea ./base/graphics.c /^static Window toplevel, menu, textarea; \/* various windows *\/$/;" v file: +tfall ../../libarchfpga/fpga_spice_include/spice_types.h /^ float tfall; \/* Fall condition: delay *\/$/;" m struct:s_spice_model_tedge +tie_break_high_fanout_net ./base/vpr_types.h /^ int tie_break_high_fanout_net; \/* If no marked candidate atoms, use this high fanout net to determine the next candidate atom *\/$/;" m struct:s_pb_stats +tile_length ./power/power.h /^ float tile_length;$/;" m struct:s_power_commonly_used +tile_width ./base/draw.c /^static float tile_width, pin_size;$/;" v file: +tile_x ./base/draw.c /^static float *tile_x, *tile_y;$/;" v file: +tile_y ./base/draw.c /^static float *tile_x, *tile_y;$/;" v file: +timing_analysis_enabled ../../libarchfpga/include/physical_types.h /^ boolean timing_analysis_enabled;$/;" m struct:s_timing_inf +timing_criticality ./base/vpr_types.h /^ float ** timing_criticality;$/;" m struct:s_slack +timing_driven ./base/ReadOptions.h /^ boolean timing_driven;$/;" m struct:s_options +timing_driven ./base/vpr_types.h /^ boolean timing_driven;$/;" m struct:s_packer_opts +timing_driven_check_net_delays ./route/route_timing.c /^static void timing_driven_check_net_delays(float **net_delay) {$/;" f file: +timing_driven_expand_neighbours ./route/route_timing.c /^static void timing_driven_expand_neighbours(struct s_heap *current, int inet,$/;" f file: +timing_driven_route_net ./route/route_timing.c /^boolean timing_driven_route_net(int inet, float pres_fac, float max_criticality,$/;" f +timing_nets ./timing/path_delay.c /^static struct s_net *timing_nets = NULL;$/;" v typeref:struct:s_net file: +timing_place_crit ./place/timing_place.c /^float **timing_place_crit; \/*available externally *\/$/;" v +timing_place_crit_ch ./place/timing_place.c /^static t_chunk timing_place_crit_ch = {NULL, 0, NULL};$/;" v file: +timing_tradeoff ./base/vpr_types.h /^ float timing_tradeoff;$/;" m struct:s_placer_opts +timinggain ./base/vpr_types.h /^ std::map timinggain; \/* [0..num_logical_blocks-1]. The timing criticality score of this logical_block. $/;" m struct:s_pb_stats +tnode ./base/vpr_types.h /^ t_tnode *tnode;$/;" m struct:s_rr_node +tnode ./timing/path_delay.c /^t_tnode *tnode = NULL; \/* [0..num_tnodes - 1] *\/$/;" v +tnodes_at_level ./timing/path_delay2.c /^struct s_ivec *tnodes_at_level;$/;" v typeref:struct:s_ivec +to_block ../../libarchfpga/include/cad_types.h /^ t_pack_pattern_block *to_block;$/;" m struct:s_pack_pattern_connections +to_clb_pin_end_index ./base/vpr_types.h /^ int to_clb_pin_end_index;$/;" m struct:s_clb_to_clb_directs +to_clb_pin_start_index ./base/vpr_types.h /^ int to_clb_pin_start_index;$/;" m struct:s_clb_to_clb_directs +to_clb_type ./base/vpr_types.h /^ t_type_descriptor *to_clb_type;$/;" m struct:s_clb_to_clb_directs +to_node ./base/vpr_types.h /^ int to_node; \/* index of node at the sink end of this edge *\/$/;" m struct:s_tedge +to_pin ../../libarchfpga/include/cad_types.h /^ t_pb_graph_pin *to_pin;$/;" m struct:s_pack_pattern_connections +to_pin ../../libarchfpga/include/physical_types.h /^ char *to_pin;$/;" m struct:s_direct_inf +to_port ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_port* to_port;$/;" m struct:s_spice_model_tedge +to_port_pin_number ../../libarchfpga/fpga_spice_include/spice_types.h /^ int to_port_pin_number;$/;" m struct:s_spice_model_tedge +toggle_congestion ./base/draw.c /^static void toggle_congestion(void (*drawscreen_ptr)(void)) {$/;" f file: +toggle_defects ./base/draw.c /^static void toggle_defects(void (*drawscreen_ptr)(void)) {$/;" f file: +toggle_nets ./base/draw.c /^static void toggle_nets(void (*drawscreen_ptr)(void)) {$/;" f file: +toggle_rr ./base/draw.c /^static void toggle_rr(void (*drawscreen_ptr)(void)) {$/;" f file: +top_backref ../../pcre/SRC/internal.h /^ int top_backref; \/* Maximum back reference *\/$/;" m struct:compile_data +top_backref ../../pcre/SRC/internal.h /^ unsigned short int top_backref;$/;" m struct:real_pcre +top_bracket ../../pcre/SRC/internal.h /^ unsigned short int top_bracket;$/;" m struct:real_pcre +top_height ./base/graphics.c /^static int top_width, top_height; \/* window size *\/$/;" v file: +top_height ./base/graphics.h /^ int top_width, top_height;$/;" m struct:__anon6 +top_netlist_addr_bl_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_addr_bl_port_name = "addr_bl";$/;" v +top_netlist_addr_wl_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_addr_wl_port_name = "addr_wl";$/;" v +top_netlist_array_bl_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_array_bl_port_name = "bl_bus";$/;" v +top_netlist_array_blb_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_array_blb_port_name = "blb_bus";$/;" v +top_netlist_array_wl_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_array_wl_port_name = "wl_bus";$/;" v +top_netlist_array_wlb_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_array_wlb_port_name = "wlb_bus";$/;" v +top_netlist_bl_data_in_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_bl_data_in_port_name = "data_in";$/;" v +top_netlist_bl_enable_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_bl_enable_port_name = "en_bl";$/;" v +top_netlist_normal_bl_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_normal_bl_port_postfix = "_bl";$/;" v +top_netlist_normal_blb_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_normal_blb_port_postfix = "_blb";$/;" v +top_netlist_normal_wl_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_normal_wl_port_postfix = "_wl";$/;" v +top_netlist_normal_wlb_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_normal_wlb_port_postfix = "_wlb";$/;" v +top_netlist_reserved_bl_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_reserved_bl_port_postfix = "_reserved_bl";$/;" v +top_netlist_reserved_wl_port_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_reserved_wl_port_postfix = "_reserved_wl";$/;" v +top_netlist_scan_chain_head_prefix ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_scan_chain_head_prefix = "sc_in";$/;" v +top_netlist_wl_enable_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_netlist_wl_enable_port_name = "en_wl";$/;" v +top_tb_clock_reg_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_clock_reg_postfix = "_reg";$/;" v +top_tb_config_done_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_config_done_port_name = "config_done";$/;" v +top_tb_inout_reg_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_inout_reg_postfix = "_reg";$/;" v +top_tb_op_clock_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_op_clock_port_name = "op_clock";$/;" v +top_tb_prog_clock_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_prog_clock_port_name = "prog_clock";$/;" v +top_tb_prog_reset_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_prog_reset_port_name = "prog_reset";$/;" v +top_tb_prog_set_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_prog_set_port_name = "prog_set";$/;" v +top_tb_reset_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_reset_port_name = "greset";$/;" v +top_tb_set_port_name ./fpga_x2p/verilog/verilog_global.c /^char* top_tb_set_port_name = "gset";$/;" v +top_testbench_verilog_file_postfix ./fpga_x2p/verilog/verilog_global.c /^char* top_testbench_verilog_file_postfix = "_top_tb.v"; \/* !!! must be consist with the modelsim_testbench_module_postfix *\/ $/;" v +top_width ./base/graphics.c /^static int top_width, top_height; \/* window size *\/$/;" v file: +top_width ./base/graphics.h /^ int top_width, top_height;$/;" m struct:__anon6 +toplevel ./base/graphics.c /^static Window toplevel, menu, textarea; \/* various windows *\/$/;" v file: +total_cb_buffer_size ./power/power.h /^ float total_cb_buffer_size;$/;" m struct:s_power_commonly_used +total_cb_mux_input_density ./fpga_x2p/spice/spice_mux_testbench.c /^static float total_cb_mux_input_density = 0.;$/;" v file: +total_pb_mux_input_density ./fpga_x2p/spice/spice_mux_testbench.c /^static float total_pb_mux_input_density = 0.;$/;" v file: +total_pb_pins ../../libarchfpga/include/physical_types.h /^ int total_pb_pins; \/* only valid for top-level *\/$/;" m struct:s_pb_graph_node +total_sb_buffer_size ./power/power.h /^ float total_sb_buffer_size;$/;" m struct:s_power_commonly_used +total_sb_mux_input_density ./fpga_x2p/spice/spice_mux_testbench.c /^static float total_sb_mux_input_density = 0.;$/;" v file: +trace_ch ./fpga_x2p/base/fpga_x2p_types.h /^ t_chunk trace_ch;$/;" m struct:fpga_spice_rr_graph +trace_ch ./route/route_common.c /^static t_chunk trace_ch = {NULL, 0, NULL};$/;" v file: +trace_free_head ./fpga_x2p/base/fpga_x2p_types.h /^ t_trace *trace_free_head;$/;" m struct:fpga_spice_rr_graph +trace_free_head ./route/route_common.c /^static struct s_trace *trace_free_head = NULL;$/;" v typeref:struct:s_trace file: +trace_head ./base/globals.c /^struct s_trace **trace_head = NULL; \/* [0..(num_nets-1)] *\/$/;" v typeref:struct:s_trace +trace_head ./base/globals_declare.h /^struct s_trace **trace_head, **trace_tail;$/;" v typeref:struct:s_trace +trace_head ./fpga_x2p/base/fpga_x2p_types.h /^ t_trace **trace_head; \/* [0..(num_nets-1)] *\/$/;" m struct:fpga_spice_rr_graph +trace_tail ./base/globals.c /^struct s_trace **trace_tail = NULL; \/* [0..(num_nets-1)] *\/$/;" v typeref:struct:s_trace +trace_tail ./base/globals_declare.h /^struct s_trace **trace_head, **trace_tail;$/;" v typeref:struct: +trace_tail ./fpga_x2p/base/fpga_x2p_types.h /^ t_trace **trace_tail; \/* [0..(num_nets-1)] *\/$/;" m struct:fpga_spice_rr_graph +trans_per_R ./route/rr_graph_area.c /^static float trans_per_R(float Rtrans, float R_minW_trans) {$/;" f file: +trans_per_buf ./route/rr_graph_area.c /^float trans_per_buf(float Rbuf, float R_minW_nmos, float R_minW_pmos) {$/;" f +trans_per_mux ./route/rr_graph_area.c /^static float trans_per_mux(int num_inputs, float trans_sram_bit,$/;" f file: +transistor_cnt ../../libarchfpga/include/physical_types.h /^ float transistor_cnt;$/;" m struct:s_interconnect_power +transistor_cnt_buffers ../../libarchfpga/include/physical_types.h /^ float transistor_cnt_buffers;$/;" m struct:s_pb_graph_node_power +transistor_cnt_interc ../../libarchfpga/include/physical_types.h /^ float transistor_cnt_interc; \/* Total transistor size of the interconnect in this pb *\/$/;" m struct:s_pb_graph_node_power +transistor_cnt_pb_children ../../libarchfpga/include/physical_types.h /^ float transistor_cnt_pb_children; \/* Total transistor size of this pb *\/$/;" m struct:s_pb_graph_node_power +transistor_size ./power/PowerSpicedComponent.h /^ float transistor_size;$/;" m class:PowerCallibSize +transistor_size ./power/power.h /^ float transistor_size;$/;" m struct:s_mux_arch +transistor_type ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* transistor_type;$/;" m struct:s_spice_tech_lib +transistor_type_name ./power/power_util.c /^char * transistor_type_name(e_tx_type type) {$/;" f +transistor_types ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_transistor_type* transistor_types;$/;" m struct:s_spice_tech_lib +transistors_per_SRAM_bit ../../libarchfpga/include/physical_types.h /^ float transistors_per_SRAM_bit;$/;" m struct:s_power_arch +translate_down ./base/graphics.c /^translate_down (void (*drawscreen) (void)) $/;" f file: +translate_left ./base/graphics.c /^translate_left (void (*drawscreen) (void)) $/;" f file: +translate_right ./base/graphics.c /^translate_right (void (*drawscreen) (void)) $/;" f file: +translate_up ./base/graphics.c /^translate_up (void (*drawscreen) (void)) $/;" f file: +traverse_clb ./base/verilog_writer.c /^pb_list *traverse_clb(t_pb *pb , pb_list *prim_list)$/;" f +traverse_linked_list ./base/verilog_writer.c /^void traverse_linked_list(pb_list *list)$/;" f +traverse_linked_list_conn ./base/verilog_writer.c /^void traverse_linked_list_conn(conn_list *list)$/;" f +tree_mux_last_level_input_num ./fpga_x2p/base/fpga_x2p_mux_utils.c /^int tree_mux_last_level_input_num(int num_level,$/;" f +tri_state_map ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* tri_state_map;$/;" m struct:s_spice_model_port +tried ./base/vpr_types.h /^ t_cluster_placement_primitive *tried; \/* ptrs to primitives that are open but current logic block unable to pack to *\/$/;" m struct:s_cluster_placement_stats +trigger_type ./base/vpr_types.h /^ char* trigger_type;$/;" m struct:s_logical_block +trise ../../libarchfpga/fpga_spice_include/spice_types.h /^ float trise; \/* Rise condition: delay *\/$/;" m struct:s_spice_model_tedge +trpt_routing_file_name ./fpga_x2p/verilog/verilog_global.c /^char* trpt_routing_file_name = "report_timing_routing.tcl";$/;" v +trpt_sb_file_name ./fpga_x2p/verilog/verilog_global.c /^char* trpt_sb_file_name = "report_timing_sb.tcl";$/;" v +truth_table ./base/vpr_types.h /^ struct s_linked_vptr *truth_table; \/* If this is a LUT (.names), then this is the logic that the LUT implements *\/$/;" m struct:s_logical_block typeref:struct:s_logical_block::s_linked_vptr +try_access_dir ./fpga_x2p/base/fpga_x2p_utils.c /^enum e_dir_err try_access_dir(char* dir_path) {$/;" f +try_access_file ./fpga_x2p/base/fpga_x2p_utils.c /^int try_access_file(char* file_path) {$/;" f +try_breadth_first_route ./route/route_breadth_first.c /^boolean try_breadth_first_route(struct s_router_opts router_opts,$/;" f +try_breadth_first_route_cluster ./pack/cluster_legality.c /^boolean try_breadth_first_route_cluster(void) {$/;" f +try_breadth_first_route_pb_rr_graph ./fpga_x2p/router/fpga_x2p_router.c /^boolean try_breadth_first_route_pb_rr_graph(t_rr_graph* local_rr_graph) {$/;" f +try_buffer_for_net ./mrfpga/buffer_insertion.c /^void try_buffer_for_net( int inet, t_rc_node** rc_node_free_list, t_linked_rc_edge** rc_edge_free_list, t_linked_rc_ptr* rr_node_to_rc_node, float* net_delay ) {$/;" f +try_buffer_for_routing ./mrfpga/buffer_insertion.c /^void try_buffer_for_routing ( float** net_delay ) {$/;" f +try_buffer_rc_tree ./mrfpga/buffer_insertion.c /^static t_buffer_plan_list try_buffer_rc_tree (t_rc_node *rc_node, int num_pins, int* isink_to_inode) {$/;" f file: +try_clb_pin_remap_after_placement ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^void try_clb_pin_remap_after_placement(t_det_routing_arch det_routing_arch,$/;" f +try_create_molecule ./pack/prepack.c /^static t_pack_molecule *try_create_molecule($/;" f file: +try_expand_molecule ./pack/prepack.c /^static boolean try_expand_molecule(INOUTP t_pack_molecule *molecule,$/;" f file: +try_pack ./pack/pack.c /^void try_pack(INP struct s_packer_opts *packer_opts, INP const t_arch * arch,$/;" f +try_pack_molecule ./pack/cluster.c /^static enum e_block_pack_status try_pack_molecule($/;" f file: +try_place ./place/place.c /^void try_place(struct s_placer_opts placer_opts,$/;" f +try_place_logical_block_rec ./pack/cluster.c /^static enum e_block_pack_status try_place_logical_block_rec($/;" f file: +try_place_macro ./place/place.c /^static int try_place_macro(int itype, int ichoice, int imacro, int * free_locations){$/;" f file: +try_place_molecule ./pack/cluster_placement.c /^static float try_place_molecule(INP t_pack_molecule *molecule,$/;" f file: +try_remap_blk_class_one_conflict_pin ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^int try_remap_blk_class_one_conflict_pin(t_block* target_blk, int class_index, int pin_index,$/;" f +try_route ./route/route_common.c /^boolean try_route(int width_fac, struct s_router_opts router_opts,$/;" f +try_sat_one_blk_pin_class_prefer_side ./fpga_x2p/clb_pin_remap/place_clb_pin_remap.c /^int try_sat_one_blk_pin_class_prefer_side(t_block* target_blk,$/;" f +try_swap ./place/place.c /^static enum swap_result try_swap(float t, float *cost, float *bb_cost, float *timing_cost,$/;" f file: +try_timing_driven_route ./route/route_timing.c /^boolean try_timing_driven_route(struct s_router_opts router_opts,$/;" f +try_update_lookahead_pins_used ./pack/cluster.c /^static void try_update_lookahead_pins_used(t_pb *cur_pb) {$/;" f file: +try_update_sram_orgz_info_reserved_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void try_update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +ts_bb_coord_new ./place/place.c /^static struct s_bb *ts_bb_coord_new = NULL;$/;" v typeref:struct:s_bb file: +ts_bb_edge_new ./place/place.c /^static struct s_bb *ts_bb_edge_new = NULL;$/;" v typeref:struct:s_bb file: +ts_nets_to_update ./place/place.c /^static int *ts_nets_to_update = NULL;$/;" v file: +tsu_tco ../../libarchfpga/include/physical_types.h /^ float tsu_tco; \/* For sequential logic elements, this is the setup time (if input) or clock-to-q time (if output) *\/$/;" m struct:s_pb_graph_pin +turn_on_off ./base/graphics.c /^static void turn_on_off (int pressed) {$/;" f file: +twisted ./base/vpr_types.h /^ boolean twisted;$/;" m struct:s_seg_details +txt ../../libarchfpga/include/ezxml.h /^ char *txt; \/* tag character content, empty string if none *\/$/;" m struct:ezxml +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_buffer_type type;$/;" m struct:s_spice_model_buffer typeref:enum:s_spice_model_buffer::e_spice_model_buffer_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_gate_type type;$/;" m struct:s_spice_model_gate typeref:enum:s_spice_model_gate::e_spice_model_gate_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_pass_gate_logic_type type;$/;" m struct:s_spice_model_pass_gate_logic typeref:enum:s_spice_model_pass_gate_logic::e_spice_model_pass_gate_logic_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_port_type type;$/;" m struct:s_spice_model_port typeref:enum:s_spice_model_port::e_spice_model_port_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_model_type type;$/;" m struct:s_spice_model typeref:enum:s_spice_model::e_spice_model_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_tech_lib_type type;$/;" m struct:s_spice_tech_lib typeref:enum:s_spice_tech_lib::e_spice_tech_lib_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_spice_trans_type type;$/;" m struct:s_spice_transistor_type typeref:enum:s_spice_transistor_type::e_spice_trans_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_sram_orgz type;$/;" m struct:s_sram_inf_orgz typeref:enum:s_sram_inf_orgz::e_sram_orgz +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_sram_orgz type;$/;" m struct:s_sram_orgz_info typeref:enum:s_sram_orgz_info::e_sram_orgz +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum e_wire_model_type type;$/;" m struct:s_spice_model_wire_param typeref:enum:s_spice_model_wire_param::e_wire_model_type +type ../../libarchfpga/fpga_spice_include/spice_types.h /^ enum spice_model_delay_type type;$/;" m struct:s_spice_model_delay_info typeref:enum:s_spice_model_delay_info::spice_model_delay_type +type ../../libarchfpga/include/physical_types.h /^ enum PORTS type;$/;" m struct:s_port typeref:enum:s_port::PORTS +type ../../libarchfpga/include/physical_types.h /^ enum e_interconnect type;$/;" m struct:s_interconnect typeref:enum:s_interconnect::e_interconnect +type ../../libarchfpga/include/physical_types.h /^ enum e_pb_graph_pin_type type; \/* Is a sequential logic element (TRUE), inpad\/outpad (TRUE), or neither (FALSE) *\/$/;" m struct:s_pb_graph_pin typeref:enum:s_pb_graph_pin::e_pb_graph_pin_type +type ../../libarchfpga/include/physical_types.h /^ enum e_pin_to_pin_annotation_type type;$/;" m struct:s_pin_to_pin_annotation typeref:enum:s_pin_to_pin_annotation::e_pin_to_pin_annotation_type +type ../../libarchfpga/include/physical_types.h /^ enum e_pin_type type;$/;" m struct:s_class typeref:enum:s_class::e_pin_type +type ../../libarchfpga/include/physical_types.h /^ enum e_stat type;$/;" m struct:s_chan typeref:enum:s_chan::e_stat +type ../../libarchfpga/include/physical_types.h /^ char* type;$/;" m struct:s_switch_inf +type ../../libarchfpga/include/physical_types.h /^ enum e_swseg_pattern_type type;$/;" m struct:s_swseg_pattern_inf typeref:enum:s_swseg_pattern_inf::e_swseg_pattern_type +type ./base/graphics.c /^ t_button_type type;$/;" m struct:__anon4 file: +type ./base/vpr_types.h /^ e_tnode_type type; \/* see the above enum *\/$/;" m struct:s_tnode +type ./base/vpr_types.h /^ enum e_pack_pattern_molecule_type type; \/* what kind of molecule is this? *\/$/;" m struct:s_pack_molecule typeref:enum:s_pack_molecule::e_pack_pattern_molecule_type +type ./base/vpr_types.h /^ enum logical_block_types type; \/* I\/O, combinational logic, or latch *\/$/;" m struct:s_logical_block typeref:enum:s_logical_block::logical_block_types +type ./base/vpr_types.h /^ enum sched_type type;$/;" m struct:s_annealing_sched typeref:enum:s_annealing_sched::sched_type +type ./base/vpr_types.h /^ t_rr_type type;$/;" m struct:s_rr_node +type ./base/vpr_types.h /^ t_type_ptr type;$/;" m struct:s_block +type ./base/vpr_types.h /^ t_type_ptr type;$/;" m struct:s_grid_tile +type ./base/vpr_types.h /^ t_rr_type type;$/;" m struct:s_cb +type ./util/token.h /^ enum e_token_type type;$/;" m struct:s_token typeref:enum:s_token::e_token_type +type_descriptors ./base/globals.c /^struct s_type_descriptor *type_descriptors = NULL;$/;" v typeref:struct:s_type_descriptor +type_descriptors_backup ./place/timing_place_lookup.c /^static t_type_descriptor *type_descriptors_backup;$/;" v file: +u ../../libarchfpga/include/ezxml.h /^ char *u; \/* UTF-8 conversion of string if original was UTF-16 *\/$/;" m struct:ezxml_root +u ./route/route_common.h /^ } u;$/;" m struct:s_heap typeref:union:s_heap::__anon14 +u ./route/route_tree_timing.h /^ } u;$/;" m struct:s_rt_node typeref:union:s_rt_node::__anon16 +u ./timing/net_delay_types.h /^ } u;$/;" m struct:s_rc_node typeref:union:s_rc_node::__anon18 +unbuf_switch ../../libarchfpga/include/physical_types.h /^ short unbuf_switch;$/;" m struct:s_swseg_pattern_inf +unbuf_switched ./base/vpr_types.h /^ int unbuf_switched; \/* Xifan TANG: Switch Segment Pattern Support*\/$/;" m struct:s_rr_node +unclustered_list_head ./pack/cluster.c /^static struct s_molecule_link *unclustered_list_head;$/;" v typeref:struct:s_molecule_link file: +unclustered_list_head_size ./pack/cluster.c /^int unclustered_list_head_size;$/;" v +unmap_button ./base/graphics.c /^static void unmap_button (int bnum) $/;" f file: +unmark_fanout_intermediate_nodes ./pack/cluster_feasibility_filter.c /^static void unmark_fanout_intermediate_nodes($/;" f file: +upbound_sim_num_clock_cycles ./fpga_x2p/spice/spice_grid_testbench.c /^static int upbound_sim_num_clock_cycles = 2;$/;" v file: +upbound_sim_num_clock_cycles ./fpga_x2p/spice/spice_mux_testbench.c /^static int upbound_sim_num_clock_cycles = 2;$/;" v file: +upbound_sim_num_clock_cycles ./fpga_x2p/spice/spice_primitive_testbench.c /^static int upbound_sim_num_clock_cycles = 2;$/;" v file: +upbound_sim_num_clock_cycles ./fpga_x2p/spice/spice_routing_testbench.c /^static int upbound_sim_num_clock_cycles = 2;$/;" v file: +updateRect ./base/graphics.c /^static RECT adjustRect, updateRect;$/;" v file: +update_bb ./place/place.c /^static void update_bb(int inet, struct s_bb *bb_coord_new,$/;" f file: +update_cluster_stats ./pack/cluster.c /^static void update_cluster_stats( INP t_pack_molecule *molecule,$/;" f file: +update_connection_gain_values ./pack/cluster.c /^static void update_connection_gain_values(int inet, int clustered_block,$/;" f file: +update_grid_pb_pins_parasitic_nets ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_grid_pb_pins_parasitic_nets() {$/;" f +update_grid_pbs_post_route_rr_graph ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_grid_pbs_post_route_rr_graph() {$/;" f +update_mem_bank_info_num_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void update_mem_bank_info_num_blwl(t_mem_bank_info* cur_mem_bank_info,$/;" f +update_mem_bank_info_num_mem_bit ./fpga_x2p/base/fpga_x2p_utils.c /^void update_mem_bank_info_num_mem_bit(t_mem_bank_info* cur_mem_bank_info,$/;" f +update_mem_bank_info_reserved_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void update_mem_bank_info_reserved_blwl(t_mem_bank_info* cur_mem_bank_info,$/;" f +update_message ./base/graphics.c /^update_message (const char *msg) $/;" f +update_message ./base/graphics.c /^void update_message (const char *msg) { }$/;" f +update_net_delays_from_route_tree ./route/route_tree_timing.c /^void update_net_delays_from_route_tree(float *net_delay,$/;" f +update_normalized_costs ./timing/path_delay.c /^static void update_normalized_costs(float criticality_denom, long max_critical_input_paths,$/;" f file: +update_one_grid_pack_net_num ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_one_grid_pack_net_num(int x, int y) {$/;" f +update_one_grid_pb_pins_parasitic_nets ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_one_grid_pb_pins_parasitic_nets(int ix, int iy) {$/;" f +update_one_io_grid_pack_net_num ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_one_io_grid_pack_net_num(int x, int y) {$/;" f +update_one_spice_model_grid_index_high ./fpga_x2p/base/fpga_x2p_utils.c /^void update_one_spice_model_grid_index_high(int x, int y, $/;" f +update_one_spice_model_grid_index_low ./fpga_x2p/base/fpga_x2p_utils.c /^void update_one_spice_model_grid_index_low(int x, int y, $/;" f +update_one_spice_model_routing_index_high ./fpga_x2p/base/fpga_x2p_utils.c /^void update_one_spice_model_routing_index_high(int x, int y, t_rr_type chan_type,$/;" f +update_one_spice_model_routing_index_low ./fpga_x2p/base/fpga_x2p_utils.c /^void update_one_spice_model_routing_index_low(int x, int y, t_rr_type chan_type,$/;" f +update_one_unused_grid_output_pins_parasitic_nets ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_one_unused_grid_output_pins_parasitic_nets(int ix, int iy) {$/;" f +update_one_used_grid_pb_pins_parasitic_nets ./fpga_x2p/base/fpga_x2p_backannotate_utils.c /^void update_one_used_grid_pb_pins_parasitic_nets(t_phy_pb* cur_pb,$/;" f +update_pb_graph_node_temp_net_num_to_pb ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void update_pb_graph_node_temp_net_num_to_pb(t_pb_graph_node* cur_pb_graph_node,$/;" f +update_pb_vpack_net_num_from_temp_net_num ./fpga_x2p/base/fpga_x2p_pbtypes_utils.c /^void update_pb_vpack_net_num_from_temp_net_num(t_phy_pb* cur_pb, $/;" f +update_primitive_cost_or_status ./pack/cluster_placement.c /^static void update_primitive_cost_or_status(INP t_pb_graph_node *pb_graph_node,$/;" f file: +update_ps_transform ./base/graphics.c /^update_ps_transform (void) $/;" f file: +update_rlim ./place/place.c /^static void update_rlim(float *rlim, float success_rat) {$/;" f file: +update_route_tree ./route/route_tree_timing.c /^update_route_tree(struct s_heap * hptr) {$/;" f +update_rr_base_costs ./route/route_timing.c /^static void update_rr_base_costs(int inet, float largest_criticality) {$/;" f file: +update_rr_graph_traceback ./fpga_x2p/base/fpga_x2p_rr_graph_utils.c /^t_trace* update_rr_graph_traceback(t_rr_graph* local_rr_graph,$/;" f +update_rr_nodes_driver_switch ./route/rr_graph_swseg.c /^void update_rr_nodes_driver_switch(enum e_directionality directionality) {$/;" f +update_scff_info_num_mem_bit ./fpga_x2p/base/fpga_x2p_utils.c /^void update_scff_info_num_mem_bit(t_scff_info* cur_scff_info,$/;" f +update_screen ./base/draw.c /^void update_screen(int priority, char *msg, enum pic_type pic_on_screen_val,$/;" f +update_slacks ./timing/path_delay.c /^static void update_slacks(t_slack * slacks, int source_clock_domain, int sink_clock_domain, float criticality_denom,$/;" f file: +update_spice_models_grid_index_high ./fpga_x2p/base/fpga_x2p_utils.c /^void update_spice_models_grid_index_high(int x, int y, $/;" f +update_spice_models_grid_index_low ./fpga_x2p/base/fpga_x2p_utils.c /^void update_spice_models_grid_index_low(int x, int y, $/;" f +update_spice_models_routing_index_high ./fpga_x2p/base/fpga_x2p_utils.c /^void update_spice_models_routing_index_high(int x, int y, t_rr_type chan_type,$/;" f +update_spice_models_routing_index_low ./fpga_x2p/base/fpga_x2p_utils.c /^void update_spice_models_routing_index_low(int x, int y, t_rr_type chan_type, $/;" f +update_sram_orgz_info_mem_model ./fpga_x2p/base/fpga_x2p_utils.c /^void update_sram_orgz_info_mem_model(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +update_sram_orgz_info_num_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void update_sram_orgz_info_num_blwl(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +update_sram_orgz_info_num_mem_bit ./fpga_x2p/base/fpga_x2p_utils.c /^void update_sram_orgz_info_num_mem_bit(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +update_sram_orgz_info_reserved_blwl ./fpga_x2p/base/fpga_x2p_utils.c /^void update_sram_orgz_info_reserved_blwl(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +update_standalone_sram_info_num_mem_bit ./fpga_x2p/base/fpga_x2p_utils.c /^void update_standalone_sram_info_num_mem_bit(t_standalone_sram_info* cur_standalone_sram_info,$/;" f +update_t ./place/place.c /^static void update_t(float *t, float std_dev, float rlim, float success_rat,$/;" f file: +update_td_cost ./place/place.c /^static void update_td_cost(void) {$/;" f file: +update_timing_gain_values ./pack/cluster.c /^static void update_timing_gain_values(int inet, int clustered_block,$/;" f file: +update_total_gain ./pack/cluster.c /^static void update_total_gain(float alpha, float beta, boolean timing_driven,$/;" f file: +update_traceback ./route/route_common.c /^update_traceback(struct s_heap *hptr, int inet) {$/;" f +update_transform ./base/graphics.c /^update_transform (void) $/;" f file: +update_unbuffered_ancestors_C_downstream ./route/route_tree_timing.c /^update_unbuffered_ancestors_C_downstream(t_rt_node * start_of_new_path_rt_node) {$/;" f file: +update_win ./base/graphics.c /^update_win (int x[2], int y[2], void (*drawscreen)(void)) $/;" f file: +update_wire_L_counter_in_llist ./fpga_x2p/verilog/verilog_report_timing.c /^void update_wire_L_counter_in_llist(t_llist* rr_path_cnt, $/;" f +usage ./base/vpr_types.h /^ int usage;$/;" m struct:s_grid_tile +uschar ../../pcre/SRC/internal.h /^typedef unsigned char uschar;$/;" t +use_default_timing_constraints ./timing/read_sdc.c /^static void use_default_timing_constraints(void) {$/;" f file: +used ../../libarchfpga/include/logic_types.h /^ int used;$/;" m struct:s_model +used_input_pins ./base/vpr_types.h /^ int used_input_pins; \/* Number of used input pins *\/$/;" m struct:s_logical_block +user_defined_template_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* user_defined_template_verilog_file_name = "user_defined_templates.v";$/;" v +user_models ./base/vpr_types.h /^ t_model * user_models; \/* blif models defined by the user *\/$/;" m struct:s_vpr_setup +utf8 ../../pcre/SRC/internal.h /^ BOOL utf8; \/* UTF8 flag *\/$/;" m struct:match_data +utf8_table1 ../../pcre/SRC/pcre.c /^static int utf8_table1[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};$/;" v file: +utf8_table2 ../../pcre/SRC/pcre.c /^static int utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};$/;" v file: +utf8_table3 ../../pcre/SRC/pcre.c /^static int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};$/;" v file: +utf8_table4 ../../pcre/SRC/pcre.c /^static uschar utf8_table4[] = {$/;" v file: +v_ds ./power/power.h /^ float v_ds;$/;" m struct:s_power_nmos_leakage_pair +v_in ./power/power.h /^ float v_in;$/;" m struct:s_power_mux_volt_pair +v_out_max ./power/power.h /^ float v_out_max;$/;" m struct:s_power_mux_volt_pair +v_out_min ./power/power.h /^ float v_out_min;$/;" m struct:s_power_mux_volt_pair +val ../../libarchfpga/fpga_spice_include/spice_types.h /^ int val; \/* binary value to be writtent: either 0 or 1 *\/$/;" m struct:s_conf_bit +val ./fpga_x2p/shell/read_opt_types.h /^ char* val; \/*The value*\/$/;" m struct:s_opt_info +val_type ./fpga_x2p/shell/read_opt_types.h /^ enum opt_val_type val_type; $/;" m struct:s_opt_info typeref:enum:s_opt_info::opt_val_type +valid ../../libarchfpga/include/cad_types.h /^ boolean valid;$/;" m struct:s_cluster_placement_primitive +valid ./base/vpr_types.h /^ boolean valid; \/* Whether or not this molecule is still valid *\/$/;" m struct:s_pack_molecule +valid_primitives ./base/vpr_types.h /^ t_cluster_placement_primitive **valid_primitives; \/* [0..num_pb_types-1] ptrs to linked list of valid primitives, for convenience, each linked list head is empty *\/$/;" m struct:s_cluster_placement_stats +value ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* value; $/;" m struct:s_spice_model_delay_info +value ../../libarchfpga/include/physical_types.h /^ char ** value; \/* [0..num_value_prop_pairs - 1] *\/$/;" m struct:s_pin_to_pin_annotation +value ./mrfpga/buffer_insertion.c /^typedef struct s_buffer_plan_node { t_buffer_plan value; struct s_buffer_plan_node* next;} t_buffer_plan_node;$/;" m struct:s_buffer_plan_node file: +variation_on ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean variation_on;$/;" m struct:s_spice_mc_variation_params +verify_binary_search ./base/vpr_types.h /^ boolean verify_binary_search;$/;" m struct:s_router_opts +verilog_compact_generate_fake_xy_for_io_border_side ./fpga_x2p/verilog/verilog_top_netlist_utils.c /^void verilog_compact_generate_fake_xy_for_io_border_side(int border_side, $/;" f +verilog_config_peripheral_prefix ./fpga_x2p/verilog/verilog_global.c /^char* verilog_config_peripheral_prefix = "config_peripheral";$/;" v +verilog_convert_port_type_to_string ./fpga_x2p/verilog/verilog_utils.c /^char* verilog_convert_port_type_to_string(enum e_spice_model_port_type port_type) {$/;" f +verilog_create_one_subckt_file ./fpga_x2p/verilog/verilog_utils.c /^FILE* verilog_create_one_subckt_file(char* subckt_dir,$/;" f +verilog_default_signal_init_value ./fpga_x2p/verilog/verilog_global.c /^int verilog_default_signal_init_value = 0;$/;" v +verilog_determine_src_chan_coordinate_switch_box ./fpga_x2p/verilog/verilog_routing.c /^void verilog_determine_src_chan_coordinate_switch_box(t_rr_node* src_rr_node,$/;" f +verilog_find_interc_fan_in_des_pb_graph_pin ./fpga_x2p/verilog/verilog_pbtypes.c /^void verilog_find_interc_fan_in_des_pb_graph_pin(t_pb_graph_pin* des_pb_graph_pin,$/;" f +verilog_find_pb_graph_pin_in_edges_interc_type ./fpga_x2p/verilog/verilog_pbtypes.c /^enum e_interconnect verilog_find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin) {$/;" f +verilog_formal_verification_preproc_flag ./fpga_x2p/verilog/verilog_global.c /^char* verilog_formal_verification_preproc_flag = "ENABLE_FORMAL_VERIFICATION"; \/\/ the flag to enable formal verification during compilation$/;" v +verilog_generate_one_report_timing_sb_to_cb ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_one_report_timing_sb_to_cb(FILE* fp,$/;" f +verilog_generate_one_report_timing_sb_to_sb ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_one_report_timing_sb_to_sb(FILE* fp,$/;" f +verilog_generate_one_report_timing_within_sb ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_one_report_timing_within_sb(FILE* fp,$/;" f +verilog_generate_one_routing_segmental_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_one_routing_segmental_report_timing(FILE* fp, $/;" f +verilog_generate_one_routing_wire_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_one_routing_wire_report_timing(FILE* fp, $/;" f +verilog_generate_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_report_timing(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_report_timing_one_sb_ending_segments ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_report_timing_one_sb_ending_segments(FILE* fp, $/;" f +verilog_generate_report_timing_one_sb_thru_segments ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_report_timing_one_sb_thru_segments(FILE* fp, $/;" f +verilog_generate_routing_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_routing_report_timing(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_routing_wires_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_routing_wires_report_timing(FILE* fp, $/;" f +verilog_generate_sb_report_timing ./fpga_x2p/verilog/verilog_report_timing.c /^void verilog_generate_sb_report_timing(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_analysis ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_analysis(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_break_loop_mux ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_break_loop_mux(FILE* fp,$/;" f +verilog_generate_sdc_break_loop_sb ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_break_loop_sb(FILE* fp,$/;" f +verilog_generate_sdc_break_loop_sram ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_break_loop_sram(FILE* fp, $/;" f +verilog_generate_sdc_break_loops ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_break_loops(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_clock_period ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_clock_period(t_sdc_opts sdc_opts) {$/;" f +verilog_generate_sdc_constrain_cbs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_cbs(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_constrain_one_cb ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_one_cb(FILE* fp,$/;" f +verilog_generate_sdc_constrain_one_cb_path ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_one_cb_path(FILE* fp,$/;" f +verilog_generate_sdc_constrain_one_chan ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_one_chan(FILE* fp, $/;" f +verilog_generate_sdc_constrain_one_sb_mux ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_one_sb_mux(FILE* fp,$/;" f +verilog_generate_sdc_constrain_one_sb_path ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_one_sb_path(FILE* fp,$/;" f +verilog_generate_sdc_constrain_pb_types ./fpga_x2p/verilog/verilog_sdc_pb_types.c /^void verilog_generate_sdc_constrain_pb_types(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_constrain_routing_channels ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_routing_channels(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_constrain_sbs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_constrain_sbs(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_generate_sdc_disable_global_ports ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_global_ports(FILE* fp) {$/;" f +verilog_generate_sdc_disable_one_unused_block ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_one_unused_block(FILE* fp,$/;" f +verilog_generate_sdc_disable_one_unused_cb ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_one_unused_cb(FILE* fp, $/;" f +verilog_generate_sdc_disable_one_unused_chan ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_one_unused_chan(FILE* fp, $/;" f +verilog_generate_sdc_disable_one_unused_grid ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_one_unused_grid(FILE* fp,$/;" f +verilog_generate_sdc_disable_sram_orgz ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_sram_orgz(FILE* fp, $/;" f +verilog_generate_sdc_disable_unused_cbs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_cbs(FILE* fp,$/;" f +verilog_generate_sdc_disable_unused_cbs_muxs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp) {$/;" f +verilog_generate_sdc_disable_unused_grids ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_grids(FILE* fp, $/;" f +verilog_generate_sdc_disable_unused_grids_muxs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_grids_muxs(FILE* fp,$/;" f +verilog_generate_sdc_disable_unused_routing_channels ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_routing_channels(FILE* fp, $/;" f +verilog_generate_sdc_disable_unused_sbs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_sbs(FILE* fp,$/;" f +verilog_generate_sdc_disable_unused_sbs_muxs ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp, int LL_nx, int LL_ny) {$/;" f +verilog_generate_sdc_input_output_delays ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_input_output_delays(FILE* fp,$/;" f +verilog_generate_sdc_pnr ./fpga_x2p/verilog/verilog_sdc.c /^void verilog_generate_sdc_pnr(t_sram_orgz_info* cur_sram_orgz_info,$/;" f +verilog_get_grid_block_subckt_name ./fpga_x2p/verilog/verilog_pbtypes.c /^char* verilog_get_grid_block_subckt_name(int x, int y, int z,$/;" f +verilog_get_grid_phy_block_subckt_name ./fpga_x2p/verilog/verilog_pbtypes.c /^char* verilog_get_grid_phy_block_subckt_name(int x, int y, int z,$/;" f +verilog_get_grid_side_pin_rr_nodes ./fpga_x2p/verilog/verilog_routing.c /^t_rr_node** verilog_get_grid_side_pin_rr_nodes(int* num_pin_rr_nodes,$/;" f +verilog_include_defines_preproc_file ./fpga_x2p/verilog/verilog_utils.c /^void verilog_include_defines_preproc_file(FILE* fp, $/;" f +verilog_include_simulation_defines_file ./fpga_x2p/verilog/verilog_utils.c /^void verilog_include_simulation_defines_file(FILE* fp, $/;" f +verilog_mem_posfix ./fpga_x2p/verilog/verilog_global.c /^char* verilog_mem_posfix = "_mem";$/;" v +verilog_mux_basis_posfix ./fpga_x2p/verilog/verilog_global.c /^char* verilog_mux_basis_posfix = "_basis";$/;" v +verilog_mux_special_basis_posfix ./fpga_x2p/verilog/verilog_global.c /^char* verilog_mux_special_basis_posfix = "_special_basis";$/;" v +verilog_netlist ../../libarchfpga/fpga_spice_include/spice_types.h /^ char* verilog_netlist; \/* Verilog netlist provided by user *\/$/;" m struct:s_spice_model +verilog_netlist_file_postfix ./fpga_x2p/verilog/verilog_global.c /^char* verilog_netlist_file_postfix = ".v";$/;" v +verilog_reserved ../../libarchfpga/fpga_spice_include/spice_types.h /^ boolean verilog_reserved;$/;" m struct:s_reserved_syntax_char +verilog_signal_init_preproc_flag ./fpga_x2p/verilog/verilog_global.c /^char* verilog_signal_init_preproc_flag = "ENABLE_SIGNAL_INITIALIZATION"; \/\/ the flag to enable signal initialization during compilation$/;" v +verilog_sim_timescale ./fpga_x2p/verilog/verilog_global.c /^float verilog_sim_timescale = 1e-9; \/\/ Verilog Simulation time scale (minimum time unit) : 1ns$/;" v +verilog_sram_inf_orgz ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_sram_inf_orgz* verilog_sram_inf_orgz;$/;" m struct:s_sram_inf +verilog_timing_preproc_flag ./fpga_x2p/verilog/verilog_global.c /^char* verilog_timing_preproc_flag = "ENABLE_TIMING"; \/\/ the flag to enable timing definition during compilation$/;" v +verilog_top_postfix ./fpga_x2p/verilog/verilog_global.c /^char* verilog_top_postfix = "_top.v";$/;" v +verilog_writer ./base/verilog_writer.c /^void verilog_writer(void)$/;" f +version ../../pcre/SRC/pcre.h /^ int version; \/* Identifies version of block *\/$/;" m struct:pcre_callout_block +view_mux_size_distribution ./route/rr_graph.c /^view_mux_size_distribution(t_ivec *** L_rr_node_indices,$/;" f file: +visited ./power/power.h /^ boolean visited; \/* When traversing netlist, need to track whether the node has been processed *\/$/;" m struct:s_rr_node_power +vpack_net ./base/globals.c /^struct s_net *vpack_net = NULL;$/;" v typeref:struct:s_net +vpack_net_num ./base/vpr_types.h /^ int vpack_net_num;$/;" m struct:s_rr_node +vpack_net_num_changed ./base/vpr_types.h /^ boolean vpack_net_num_changed;$/;" m struct:s_rr_node +vpack_to_clb_net_mapping ./base/globals.c /^int *vpack_to_clb_net_mapping = NULL; \/* [0..num_vpack_nets - 1] *\/$/;" v +vpr_alloc_and_load_output_file_names ./base/vpr_api.c /^void vpr_alloc_and_load_output_file_names(const char* default_name) {$/;" f +vpr_check_arch ./base/vpr_api.c /^void vpr_check_arch(INP t_arch Arch, INP boolean TimingEnabled) {$/;" f +vpr_check_options ./base/vpr_api.c /^void vpr_check_options(INP t_options Options, INP boolean TimingEnabled) {$/;" f +vpr_check_setup ./base/vpr_api.c /^void vpr_check_setup(INP enum e_operation Operation,$/;" f +vpr_crit_path_delay ../../libarchfpga/fpga_spice_include/spice_types.h /^ float vpr_crit_path_delay; \/* Reference operation clock frequency *\/$/;" m struct:s_spice_stimulate_params +vpr_fpga_bitstream_generator ./fpga_x2p/bitstream/fpga_bitstream.c /^void vpr_fpga_bitstream_generator(t_vpr_setup vpr_setup,$/;" f +vpr_fpga_generate_bitstream ./fpga_x2p/bitstream/fpga_bitstream.c /^void vpr_fpga_generate_bitstream(t_vpr_setup vpr_setup,$/;" f +vpr_fpga_spice ./fpga_x2p/spice/spice_api.c /^void vpr_fpga_spice(t_vpr_setup vpr_setup,$/;" f +vpr_fpga_verilog ./fpga_x2p/verilog/verilog_api.c /^void vpr_fpga_verilog(t_vpr_setup vpr_setup,$/;" f +vpr_fpga_x2p_tool_suites ./fpga_x2p/base/fpga_x2p_api.c /^void vpr_fpga_x2p_tool_suites(t_vpr_setup vpr_setup,$/;" f +vpr_free_all ./base/vpr_api.c /^void vpr_free_all(INOUTP t_arch Arch, INOUTP t_options options,$/;" f +vpr_free_vpr_data_structures ./base/vpr_api.c /^void vpr_free_vpr_data_structures(INOUTP t_arch Arch, INOUTP t_options options,$/;" f +vpr_get_output_file_name ./base/vpr_api.c /^char *vpr_get_output_file_name(enum e_output_files ename) {$/;" f +vpr_init ./base/vpr_api.c /^void vpr_init(INP int argc, INP char **argv, OUTP t_options *options,$/;" f +vpr_init_file_handler ./base/vpr_api.c /^void vpr_init_file_handler() {$/;" f +vpr_init_pre_place_and_route ./base/vpr_api.c /^void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) {$/;" f +vpr_pack ./base/vpr_api.c /^void vpr_pack(INP t_vpr_setup vpr_setup, INP t_arch arch) {$/;" f +vpr_pack_opts ./fpga_x2p/shell/cmd_vpr_pack.h /^t_opt_info vpr_pack_opts[] = {$/;" v +vpr_place_and_route ./base/vpr_api.c /^void vpr_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch arch) {$/;" f +vpr_place_and_route_opts ./fpga_x2p/shell/cmd_vpr_place_and_route.h /^t_opt_info vpr_place_and_route_opts[] = {$/;" v +vpr_power_estimation ./base/vpr_api.c /^void vpr_power_estimation(t_vpr_setup vpr_setup, t_arch Arch) {$/;" f +vpr_print_title ./base/vpr_api.c /^void vpr_print_title(void) {$/;" f +vpr_print_usage ./base/vpr_api.c /^void vpr_print_usage(void) {$/;" f +vpr_printf ../../libarchfpga/util.c /^messagelogger vpr_printf = PrintHandlerMessage;$/;" v +vpr_read_and_process_blif ./base/vpr_api.c /^void vpr_read_and_process_blif(INP char *blif_file,$/;" f +vpr_read_options ./base/vpr_api.c /^void vpr_read_options(INP int argc, INP char **argv, OUTP t_options * options) {$/;" f +vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture ./base/vpr_api.c /^t_trace* vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture($/;" f +vpr_run_interactive_mode ./fpga_x2p/shell/mini_shell.c /^void vpr_run_interactive_mode() {$/;" f +vpr_run_script_mode ./fpga_x2p/shell/mini_shell.c /^void vpr_run_script_mode(char* script_file_name) {$/;" f +vpr_set_output_file_name ./base/vpr_api.c /^void vpr_set_output_file_name(enum e_output_files ename, const char *name,$/;" f +vpr_setup ./fpga_x2p/shell/shell_types.h /^ t_vpr_setup vpr_setup;$/;" m struct:s_shell_env +vpr_setup_vpr ./base/vpr_api.c /^void vpr_setup_vpr(INP t_options *Options, INP boolean TimingEnabled,$/;" f +vpr_shell_prefix ./fpga_x2p/shell/mini_shell.c /^char* vpr_shell_prefix = "VPR7-OpenFPGA> ";$/;" v +vpr_show_setup ./base/vpr_api.c /^void vpr_show_setup(INP t_options options, INP t_vpr_setup vpr_setup) {$/;" f +vpr_to_phy_track ./route/rr_graph2.c /^static int vpr_to_phy_track(INP int itrack, INP int chan_num, INP int seg_num,$/;" f file: +vpr_versapower_opts ./fpga_x2p/shell/cmd_vpr_power.h /^t_opt_info vpr_versapower_opts[] = {$/;" v +watch_edges ./route/rr_graph.c /^void watch_edges(int inode, t_linked_edge * edge_list_head) {$/;" f +which_button ./base/graphics.c /^static int which_button (Window win) $/;" f file: +width ../../libarchfpga/include/physical_types.h /^ float width;$/;" m struct:s_chan +width ./base/graphics.c /^ int width; $/;" m struct:__anon4 file: +win ./base/graphics.c /^ Window win; $/;" m struct:__anon4 file: +win32_colors ./base/graphics.c /^static const COLORREF win32_colors[NUM_COLOR] = { RGB(255, 255, 255),$/;" v file: +win32_drain_message_queue ./base/graphics.c /^void win32_drain_message_queue () {$/;" f +win32_line_styles ./base/graphics.c /^static const int win32_line_styles[2] = { PS_SOLID, PS_DASH };$/;" v file: +windowAdjustFlag ./base/graphics.c /^static int windowAdjustFlag = 0, adjustButton = -1;$/;" v file: +wire ../../libarchfpga/include/physical_types.h /^ } wire;$/;" m struct:s_port_power typeref:union:s_port_power::__anon22 +wire_buffer_inf ../../libarchfpga/include/arch_types_mrfpga.h /^ t_buffer_inf wire_buffer_inf;$/;" m struct:s_arch_mrfpga +wire_buffer_inf ./mrfpga/mrfpga_globals.c /^t_buffer_inf wire_buffer_inf;$/;" v +wire_param ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_model_wire_param* wire_param;$/;" m struct:s_spice_model +wire_switch ../../libarchfpga/include/physical_types.h /^ short wire_switch;$/;" m struct:s_segment_inf +wire_switch ./base/vpr_types.h /^ short wire_switch;$/;" m struct:s_seg_details +wire_to_ipin_switch ./base/vpr_types.h /^ short wire_to_ipin_switch;$/;" m struct:s_det_routing_arch +wire_type ../../libarchfpga/include/physical_types.h /^ e_power_wire_type wire_type;$/;" m struct:s_port_power +wire_variation ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_spice_mc_variation_params wire_variation;$/;" m struct:s_spice_mc_params +wirelength ./base/place_and_route.h /^ int wirelength; \/* corresponding wirelength of successful routing at wneed *\/$/;" m struct:s_fmap_cell +wires_spice_file_name ./fpga_x2p/spice/spice_globals.c /^char* wires_spice_file_name = "wires.sp";$/;" v +wires_verilog_file_name ./fpga_x2p/verilog/verilog_global.c /^char* wires_verilog_file_name = "wires.v";$/;" v +with_val ./fpga_x2p/shell/read_opt_types.h /^ enum opt_with_val with_val;$/;" m struct:s_opt_info typeref:enum:s_opt_info::opt_with_val +wl ../../libarchfpga/fpga_spice_include/spice_types.h /^ t_conf_bit* wl;$/;" m struct:s_conf_bit_info +wneed ./base/place_and_route.h /^ int wneed; \/* need wneed to route *\/$/;" m struct:s_fmap_cell +wprog_reset_nmos ../../libarchfpga/fpga_spice_include/spice_types.h /^ float wprog_reset_nmos;$/;" m struct:s_spice_model_rram +wprog_reset_pmos ../../libarchfpga/fpga_spice_include/spice_types.h /^ float wprog_reset_pmos;$/;" m struct:s_spice_model_rram +wprog_set_nmos ../../libarchfpga/fpga_spice_include/spice_types.h /^ float wprog_set_nmos;$/;" m struct:s_spice_model_rram +wprog_set_pmos ../../libarchfpga/fpga_spice_include/spice_types.h /^ float wprog_set_pmos;$/;" m struct:s_spice_model_rram +write ../../libarchfpga/ezxml.c 60;" d file: +write_formality_script ./fpga_x2p/verilog/verilog_formality_autodeck.c /^void write_formality_script (t_syn_verilog_opts fpga_verilog_opts,$/;" f +write_include_netlists ./fpga_x2p/verilog/verilog_include_netlists.c /^void write_include_netlists (char* src_dir_formatted,$/;" f +x ./base/easygl_constants.h /^ float x; $/;" m struct:__anon1 +x ./base/vpr_types.h /^ int x;$/;" m struct:s_block +x ./base/vpr_types.h /^ int x;$/;" m struct:s_cb +x ./base/vpr_types.h /^ int x;$/;" m struct:s_sb +x ./place/place.c /^ int x;$/;" m struct:s_legal_pos file: +x_offset ../../libarchfpga/include/physical_types.h /^ int x_offset;$/;" m struct:s_direct_inf +x_offset ./base/vpr_types.h /^ int x_offset;$/;" m struct:s_clb_to_clb_directs +x_offset ./place/place_macro.h /^ int x_offset;$/;" m struct:s_pl_macro_member +x_rr_node_left ./base/draw.c /^static float *x_rr_node_left = NULL;$/;" v file: +x_rr_node_right ./base/draw.c /^static float *x_rr_node_right = NULL;$/;" v file: +xcoord ./base/graphics.c /^static int xcoord (float worldx) $/;" f file: +xdiv ./base/graphics.c /^static float xdiv, ydiv;$/;" v file: +xhigh ./base/vpr_types.h /^ short xhigh;$/;" m struct:s_rr_node +xleft ./base/graphics.c /^ int xleft; $/;" m struct:__anon4 file: +xleft ./base/graphics.c /^static float xleft, xright, ytop, ybot; \/* world coordinates *\/$/;" v file: +xleft ./base/graphics.h /^ float xleft, xright, ytop, ybot;$/;" m struct:__anon6 +xlow ./base/vpr_types.h /^ short xlow;$/;" m struct:s_rr_node +xmax ./base/vpr_types.h /^ int xmax;$/;" m struct:s_bb +xmin ./base/vpr_types.h /^ int xmin;$/;" m struct:s_bb +xml ../../libarchfpga/include/ezxml.h /^ struct ezxml xml; \/* is a super-struct built on top of ezxml struct *\/$/;" m struct:ezxml_root typeref:struct:ezxml_root::ezxml +xmult ./base/graphics.c /^static float xmult, ymult; \/* Transformation factors *\/$/;" v file: +xmult ./base/graphics.h /^ float xmult, ymult;$/;" m struct:__anon6 +xnew ./place/place.c /^ int xnew;$/;" m struct:s_pl_moved_block file: +xold ./place/place.c /^ int xold;$/;" m struct:s_pl_moved_block file: +xpeak ../../libarchfpga/include/physical_types.h /^ float xpeak;$/;" m struct:s_chan +xright ./base/graphics.c /^static float xleft, xright, ytop, ybot; \/* world coordinates *\/$/;" v file: +xright ./base/graphics.h /^ float xleft, xright, ytop, ybot;$/;" m struct:__anon6 +y ./base/easygl_constants.h /^ float y;$/;" m struct:__anon1 +y ./base/vpr_types.h /^ int y;$/;" m struct:s_block +y ./base/vpr_types.h /^ int y;$/;" m struct:s_cb +y ./base/vpr_types.h /^ int y;$/;" m struct:s_sb +y ./place/place.c /^ int y;$/;" m struct:s_legal_pos file: +y_offset ../../libarchfpga/include/physical_types.h /^ int y_offset;$/;" m struct:s_direct_inf +y_offset ./base/vpr_types.h /^ int y_offset;$/;" m struct:s_clb_to_clb_directs +y_offset ./place/place_macro.h /^ int y_offset; $/;" m struct:s_pl_macro_member +y_rr_node_bottom ./base/draw.c /^static float *y_rr_node_bottom = NULL;$/;" v file: +y_rr_node_top ./base/draw.c /^static float *y_rr_node_top = NULL;$/;" v file: +ybot ./base/graphics.c /^static float xleft, xright, ytop, ybot; \/* world coordinates *\/$/;" v file: +ybot ./base/graphics.h /^ float xleft, xright, ytop, ybot;$/;" m struct:__anon6 +ycoord ./base/graphics.c /^static int ycoord (float worldy) $/;" f file: +ydiv ./base/graphics.c /^static float xdiv, ydiv;$/;" v file: +yhigh ./base/vpr_types.h /^ short yhigh;$/;" m struct:s_rr_node +ylow ./base/vpr_types.h /^ short ylow;$/;" m struct:s_rr_node +ymax ./base/vpr_types.h /^ int ymax;$/;" m struct:s_bb +ymin ./base/vpr_types.h /^ int ymin;$/;" m struct:s_bb +ymult ./base/graphics.c /^static float xmult, ymult; \/* Transformation factors *\/$/;" v file: +ymult ./base/graphics.h /^ float xmult, ymult;$/;" m struct:__anon6 +ynew ./place/place.c /^ int ynew;$/;" m struct:s_pl_moved_block file: +yold ./place/place.c /^ int yold;$/;" m struct:s_pl_moved_block file: +ytop ./base/graphics.c /^ int ytop;$/;" m struct:__anon4 file: +ytop ./base/graphics.c /^static float xleft, xright, ytop, ybot; \/* world coordinates *\/$/;" v file: +ytop ./base/graphics.h /^ float xleft, xright, ytop, ybot;$/;" m struct:__anon6 +z ./base/vpr_types.h /^ int z; \/* For IPIN, source, and sink nodes, helps identify which location this rr_node belongs to *\/$/;" m struct:s_rr_node +z ./base/vpr_types.h /^ int z;$/;" m struct:s_block +z ./place/place.c /^ int z;$/;" m struct:s_legal_pos file: +z_offset ../../libarchfpga/include/physical_types.h /^ int z_offset;$/;" m struct:s_direct_inf +z_offset ./base/vpr_types.h /^ int z_offset;$/;" m struct:s_clb_to_clb_directs +z_offset ./place/place_macro.h /^ int z_offset;$/;" m struct:s_pl_macro_member +zero_one_spice_model_grid_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void zero_one_spice_model_grid_index_low_high(t_spice_model* cur_spice_model) {$/;" f +zero_one_spice_model_routing_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void zero_one_spice_model_routing_index_low_high(t_spice_model* cur_spice_model) {$/;" f +zero_spice_model_grid_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void zero_spice_model_grid_index_low_high(int num_spice_models, $/;" f +zero_spice_models_cnt ./fpga_x2p/base/fpga_x2p_utils.c /^void zero_spice_models_cnt(int num_spice_models, t_spice_model* spice_model) {$/;" f +zero_spice_models_routing_index_low_high ./fpga_x2p/base/fpga_x2p_utils.c /^void zero_spice_models_routing_index_low_high(int num_spice_models, $/;" f +znew ./place/place.c /^ int znew;$/;" m struct:s_pl_moved_block file: +zold ./place/place.c /^ int zold;$/;" m struct:s_pl_moved_block file: +zoom_fit ./base/graphics.c /^zoom_fit (void (*drawscreen) (void)) $/;" f file: +zoom_in ./base/graphics.c /^zoom_in (void (*drawscreen) (void)) $/;" f file: +zoom_out ./base/graphics.c /^zoom_out (void (*drawscreen) (void)) $/;" f file: diff --git a/vpr7_x2p/vpr/SRC/util/vpr_utils.c b/vpr7_x2p/vpr/SRC/util/vpr_utils.c index fed0d2f78..99fd4b92f 100755 --- a/vpr7_x2p/vpr/SRC/util/vpr_utils.c +++ b/vpr7_x2p/vpr/SRC/util/vpr_utils.c @@ -247,6 +247,12 @@ boolean primitive_type_feasible(int iblk, const t_pb_type *cur_pb_type) { return FALSE; } + /* Xifan Tang: return false if this primitive is disabled in the packing */ + if (TRUE == cur_pb_type->parent_mode->disabled_in_packing) { + return FALSE; + } + /* END */ + /* check if ports are big enough */ port = logical_block[iblk].model->inputs; second_pass = FALSE; diff --git a/vpr7_x2p/vpr/SpiceNetlists/adder.sp b/vpr7_x2p/vpr/SpiceNetlists/adder.sp new file mode 100644 index 000000000..fd6799f76 --- /dev/null +++ b/vpr7_x2p/vpr/SpiceNetlists/adder.sp @@ -0,0 +1,30 @@ +* Sub Circuit +* 1-Bit Full-Adder circuit netlist +.subckt adder inA inB Cin Cout Sumout svdd sgnd size=1 +X01 nd1 inA svdd svdd vpr_pmos W='size*beta*wp' L='pl' +X02 nd1 inB svdd svdd vpr_pmos W='size*beta*wp' L='pl' +X03 nd2 inB nd1 svdd vpr_pmos W='size*beta*wp' L='pl' +X04 nco inA nd2 svdd vpr_pmos W='size*beta*wp' L='pl' +X05 nco Cin nd1 svdd vpr_pmos W='size*beta*wp' L='pl' +X06 nco Cin nd3 sgnd vpr_nmos W='size*wn' L='nl' +X07 nd3 inA sgnd sgnd vpr_nmos W='size*wn' L='nl' +X08 nd3 inB sgnd sgnd vpr_nmos W='size*wn' L='nl' +X09 nco inA nd4 sgnd vpr_nmos W='size*wn' L='nl' +X10 nd4 inB sgnd sgnd vpr_nmos W='size*wn' L='nl' +Xo1 nco Cout svdd sgnd inv size='size' +X11 nd5 inA svdd svdd vpr_pmos W='size*beta*wp' L='pl' +X12 nd5 inB svdd svdd vpr_pmos W='size*beta*wp' L='pl' +X13 nd5 Cin svdd svdd vpr_pmos W='size*beta*wp' L='pl' +X14 nd6 inA nd5 svdd vpr_pmos W='size*beta*wp' L='pl' +X15 nd7 inB nd6 svdd vpr_pmos W='size*beta*wp' L='pl' +X16 ndS Cin nd7 svdd vpr_pmos W='size*beta*wp' L='pl' +X23 nds nco nd5 svdd vpr_pmos W='size*beta*wp' L='pl' +X24 nds nco nd8 sgnd vpr_nmos W='size*wn' L='nl' +X17 nd8 inA sgnd sgnd vpr_nmos W='size*wn' L='nl' +X18 nd8 inB sgnd sgnd vpr_nmos W='size*wn' L='nl' +X19 nd8 Cin sgnd sgnd vpr_nmos W='size*wn' L='nl' +X20 ndS Cin nd9 sgnd vpr_nmos W='size*wn' L='nl' +X21 nd9 inA n10 sgnd vpr_nmos W='size*wn' L='nl' +X22 n10 inB sgnd sgnd vpr_nmos W='size*wn' L='nl' +Xo2 nds Sumout svdd sgnd inv size='size' +.eom diff --git a/vpr7_x2p/vpr/SpiceNetlists/gate.sp b/vpr7_x2p/vpr/SpiceNetlists/gate.sp new file mode 100644 index 000000000..a97316d56 --- /dev/null +++ b/vpr7_x2p/vpr/SpiceNetlists/gate.sp @@ -0,0 +1,16 @@ +* Sub Circuit +* OR2 gate +.subckt or2 in0 in1 out svdd sgnd size=1 +Xp0 ntwk_n0 in0 svdd svdd vpr_pmos L=pl W='size*beta*wp' +Xp1 ntwk_n0 in1 ntwk_n1 svdd vpr_pmos L=pl W='size*beta*wp' +Xn0 ntwk_n1 in0 sgnd sgnd vpr_nmos L=nl W='wn*size' +Xn1 ntwk_n1 in1 sgnd sgnd vpr_nmos L=nl W='wn*size' +.eom + +* AND2 gate +.subckt and2 in0 in1 out svdd sgnd size=1 +Xp0 ntwk_n0 in0 svdd svdd vpr_pmos L=pl W='wp*size*beta' +Xp1 ntwk_n0 in1 svdd svdd vpr_pmos L=pl W='wp*size*beta' +Xn0 ntwk_n0 in0 ntwk_n1 sgnd vpr_nmos L=nl W='wn*size' +Xn1 ntwk_n1 in1 sgnd sgnd vpr_nmos L=nl W='wn*size' +.eom diff --git a/vpr7_x2p/vpr/VerilogNetlists/adder.v b/vpr7_x2p/vpr/VerilogNetlists/adder.v new file mode 100644 index 000000000..a9519b941 --- /dev/null +++ b/vpr7_x2p/vpr/VerilogNetlists/adder.v @@ -0,0 +1,19 @@ +//------ Module: sram6T_blwl -----// +//------ Verilog file: sram.v -----// +//------ Author: Xifan TANG -----// +module adder( +input [0:0] a, // Input a +input [0:0] b, // Input b +input [0:0] cin, // Input cin +output [0:0] cout, // Output carry +output [0:0] sumout // Output sum +); +wire[1:0] int_calc; + +assign int_calc = a + b + cin; +assign cout = int_calc[1]; +assign sumout = int_calc[0]; +// assign sumout = a ^ b ^ cin; +// assign cout = a & b + a & cin + b & cin; +endmodule + diff --git a/vpr7_x2p/vpr/VerilogNetlists/ff.v b/vpr7_x2p/vpr/VerilogNetlists/ff.v deleted file mode 100644 index d88e1f289..000000000 --- a/vpr7_x2p/vpr/VerilogNetlists/ff.v +++ /dev/null @@ -1,100 +0,0 @@ -//----------------------------------------------------- -// Design Name : static_dff -// File Name : ff.v -// Function : D flip-flop with asyn reset and set -// Coder : Xifan TANG -//----------------------------------------------------- -module static_dff ( -/* Global ports go first */ -input set, // set input -input reset, // Reset input -input clk, // Clock Input -/* Local ports follow */ -input D, // Data Input -output Q // Q output -); -//------------Internal Variables-------- -reg q_reg; - -//-------------Code Starts Here--------- -always @ ( posedge clk or reset or set) -if (reset) begin - q_reg <= 1'b0; -end else if (set) begin - q_reg <= 1'b1; -end else begin - q_reg <= D; -end - -// Wire q_reg to Q -assign Q = q_reg; - -endmodule //End Of Module static_dff - -//----------------------------------------------------- -// Design Name : scan_chain_dff -// File Name : ff.v -// Function : D flip-flop with asyn reset and set -// Coder : Xifan TANG -//----------------------------------------------------- -module sc_dff ( -/* Global ports go first */ -input set, // set input -input reset, // Reset input -input clk, // Clock Input -/* Local ports follow */ -input D, // Data Input -output Q, // Q output -output Qb // Q output -); -//------------Internal Variables-------- -reg q_reg; - -//-------------Code Starts Here--------- -always @ ( posedge clk or reset or set) -if (reset) begin - q_reg <= 1'b0; -end else if (set) begin - q_reg <= 1'b1; -end else begin - q_reg <= D; -end - -// Wire q_reg to Q -assign Q = q_reg; -assign Qb = ~Q; - -endmodule //End Of Module static_dff - -//----------------------------------------------------- -// Design Name : scan_chain_dff compact -// File Name : ff.v -// Function : Scan-chain D flip-flop without reset and set -// Coder : Xifan TANG -//----------------------------------------------------- -module sc_dff_compact ( -/* Global ports go first */ -input reset, // Reset input -input clk, // Clock Input -input clkb, // Clock Input -/* Local ports follow */ -input D, // Data Input -output Q, // Q output -output Qb // Q output -); -//------------Internal Variables-------- -reg q_reg; - -//-------------Code Starts Here--------- -always @ ( posedge clk or reset) -if (reset) begin - q_reg <= 1'b0; -end else begin - q_reg <= D; -end - -// Wire q_reg to Q -assign Q = q_reg; -assign Qb = ~Q; - -endmodule //End Of Module static_dff diff --git a/vpr7_x2p/vpr/VerilogNetlists/io.v b/vpr7_x2p/vpr/VerilogNetlists/io.v index e3468c370..42b4d0a48 100644 --- a/vpr7_x2p/vpr/VerilogNetlists/io.v +++ b/vpr7_x2p/vpr/VerilogNetlists/io.v @@ -6,8 +6,8 @@ input zin, // Set output to be Z input dout, // Data output output din, // Data input inout pad, // bi-directional pad -input direction, // enable signal to control direction of iopad -input direction_inv // enable signal to control direction of iopad +input direction // enable signal to control direction of iopad +//input direction_inv // enable signal to control direction of iopad ); //----- when direction enabled, the signal is propagated from pad to din assign din = direction ? pad : 1'bz; diff --git a/vpr7_x2p/vpr/VerilogNetlists/sram.v b/vpr7_x2p/vpr/VerilogNetlists/sram.v deleted file mode 100644 index c0b4777d1..000000000 --- a/vpr7_x2p/vpr/VerilogNetlists/sram.v +++ /dev/null @@ -1,99 +0,0 @@ -//------ Module: sram6T_blwl -----// -//------ Verilog file: sram.v -----// -//------ Author: Xifan TANG -----// -module sram6T_blwl( -//input read, -//input nequalize, -input din, // Data input -output dout, // Data output -output doutb, // Data output -input bl, // Bit line control signal -input wl, // Word line control signal -input blb // Inverted Bit line control signal -); - //----- local variable need to be registered - reg a; - - //----- when wl is enabled, we can read in data from bl - always @(bl, wl) - begin - //----- Cases to program internal memory bit - //----- case 1: bl = 1, wl = 1, a -> 0 - if ((1'b1 == bl)&&(1'b1 == wl)) begin - a <= 1'b1; - end - //----- case 2: bl = 0, wl = 1, a -> 0 - if ((1'b0 == bl)&&(1'b1 == wl)) begin - a <= 1'b0; - end - end - -`ifdef INITIALIZATION - initial begin - $signal_force("a", "0", 0, 1, , 1); - end -`endif - - - // dout is short-wired to din - assign dout = a; - //---- doutb is always opposite to dout - assign doutb = ~dout; -endmodule - -module sram6T_rram( -input read, -input nequalize, -input din, // Data input -output dout, // Data output -output doutb, // Data output -// !!! Port bit position should start from LSB to MSB -// Follow this convention for BL/WLs in each module! -input [0:2] bl, // Bit line control signal -input [0:2] wl// Word line control signal -); - //----- local variable need to be registered - //----- Modeling two RRAMs - reg r0, r1; - - always @(bl[0], wl[2]) - begin - //----- Cases to program r0 - //----- case 1: bl[0] = 1, wl[2] = 1, r0 -> 0 - if ((1'b1 == bl[0])&&(1'b1 == wl[2])) begin - r0 <= 0; - end - end - - always @(bl[2], wl[0]) - begin - //----- case 2: bl[2] = 1, wl[0] = 1, r0 -> 1 - if ((1'b1 == bl[2])&&(1'b1 == wl[0])) begin - r0 <= 1; - end - end - - always @(bl[1], wl[2]) - begin - //----- Cases to program r1 - //----- case 1: bl[1] = 1, wl[2] = 1, r0 -> 0 - if ((1'b1 == bl[1])&&(1'b1 == wl[2])) begin - r1 <= 0; - end - end - - always @( bl[2], wl[1]) - begin - //----- case 2: bl[2] = 1, wl[1] = 1, r0 -> 1 - if ((1'b1 == bl[2])&&(1'b1 == wl[1])) begin - r1 <= 1; - end - end - - // dout is r0 AND r1 - assign dout = r0 | (~r1); - - //---- doutb is always opposite to dout - assign doutb = ~dout; - -endmodule diff --git a/vpr7_x2p/vpr/go.sh b/vpr7_x2p/vpr/go.sh deleted file mode 100755 index 8675efd4a..000000000 --- a/vpr7_x2p/vpr/go.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -echo "#################################################" -echo "The current shell environment is the following:" -echo $0 -echo "#################################################" - -# Example of how to run vprset circuit_name = pip_add -#set circuit_name = pip_add -set circuit_name = sync_4bits_add -set circuit_blif = ${PWD}/Circuits/${circuit_name}.blif -set arch_file = ${PWD}/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml -set arch_file_template = ${PWD}/ARCH/k6_N10_scan_chain_template.xml -set circuit_act = ${PWD}/Circuits/${circuit_name}.act -set circuit_verilog = ${PWD}/Circuits/${circuit_name}.v -set spice_output = ${PWD}/spice_demo -set verilog_output = ${PWD}/verilog_demo -set modelsim_ini = /uusoc/facility/cad_tools/Mentor/modelsim10.7b/modeltech/modelsim.ini -set openfpga_path = ${PWD}/../.. - -# Make sure a clean start -rm -rf ${spice_output} -rm -rf ${verilog_output} - -echo "*******************************" -echo "THIS SCRIPT NEEDS TO BE SOURCED" -echo "source ./go.sh" -echo "*******************************" - -sed "s:OPENFPGAPATH:${openfpga_path}:g" ${arch_file_template} > ${arch_file} - -# Pack, place, and route a heterogeneous FPGA -# Packing uses the AAPack algorithm -./vpr ${arch_file} ${circuit_blif} --full_stats --nodisp --activity_file ${circuit_act} --route_chan_width 30 --fpga_spice --fpga_spice_rename_illegal_port --fpga_spice_dir ${spice_output} --fpga_spice_print_top_testbench --fpga_spice_print_grid_testbench --fpga_spice_print_cb_testbench --fpga_spice_print_sb_testbench --fpga_spice_print_lut_testbench --fpga_spice_print_hardlogic_testbench --fpga_spice_print_pb_mux_testbench --fpga_spice_print_cb_mux_testbench --fpga_spice_print_sb_mux_testbench --fpga_verilog --fpga_verilog_dir ${verilog_output} --fpga_verilog_print_top_testbench --fpga_verilog_print_top_auto_testbench ${circuit_verilog} --fpga_verilog_print_modelsim_autodeck --fpga_verilog_modelsim_ini_path ${modelsim_ini} --fpga_verilog_include_timing --fpga_verilog_init_sim - diff --git a/vpr7_x2p/vpr/go_fpga_spice.sh b/vpr7_x2p/vpr/go_fpga_spice.sh new file mode 100755 index 000000000..e4091f945 --- /dev/null +++ b/vpr7_x2p/vpr/go_fpga_spice.sh @@ -0,0 +1,32 @@ +#! /bin/csh -f +# Example of how to run vpr + +# Set variables +# For FPGA-Verilog ONLY +set spice_output_dirname = sram_fpga_hetero +set spice_output_dirpath = $PWD +# VPR critical inputs +#set arch_xml_file = ARCH/k6_N10_MD_tsmc40nm_chain_TT.xml +#set arch_xml_file = ARCH/ed_dev.xml +set arch_xml_file = ARCH/k6_N10_SC_tsmc40nm_chain_TT.xml +#set arch_xml_file = ARCH/k6_N10_SC_tsmc40nm_chain_TT_yosys.xml +#set arch_xml_file = ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml +set blif_file = Circuits/s298_prevpr.blif +set act_file = Circuits/s298_prevpr.act +#set blif_file = Circuits/simple_gates_prevpr.blif +#set act_file = Circuits/simple_gates_prevpr.act +set vpr_route_chan_width = 100 + +# Step A: Make sure a clean start +# Recompile if needed +#make clean +#make -j32 +# Remove previous designs +rm -rf $spice_output_dirpath/$spice_output_dirname + +# Run VPR +#valgrind +./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_spice --fpga_spice_dir $spice_output_dirpath/$spice_output_dirname --fpga_x2p_rename_illegal_port --fpga_spice_print_top_testbench --fpga_spice_print_lut_testbench --fpga_spice_print_hardlogic_testbench --fpga_spice_print_io_testbench --fpga_spice_print_pb_mux_testbench --fpga_spice_print_cb_mux_testbench --fpga_spice_print_sb_mux_testbench --fpga_spice_print_cb_testbench --fpga_spice_print_sb_testbench --fpga_spice_print_grid_testbench + + + diff --git a/vpr7_x2p/vpr/go_fpga_verilog.sh b/vpr7_x2p/vpr/go_fpga_verilog.sh new file mode 100755 index 000000000..0226049e9 --- /dev/null +++ b/vpr7_x2p/vpr/go_fpga_verilog.sh @@ -0,0 +1,42 @@ +#! /bin/csh -f +# Example of how to run vpr + +# Set variables +# For FPGA-Verilog ONLY +set verilog_output_dirname = sram_fpga_hetero +set verilog_output_dirpath = /var/tmp/xtang/vpr7 +set modelsim_ini_file = /uusoc/facility/cad_tools/Mentor/modelsim10.7b/modeltech/modelsim.ini +# VPR critical inputs +#set arch_xml_file = ARCH/k6_N10_MD_tsmc40nm_chain_TT.xml +#set arch_xml_file = ARCH/k8_N10_SC_tsmc40nm_chain_TT_stratixIV_lookalike.xml +set arch_xml_file = ARCH/k8_N10_sram_chain_FC_tsmc40_stratix4_auto.xml +#set arch_xml_file = ARCH/ed_stdcell.xml +#set arch_xml_file = ARCH/k6_N10_sram_chain_FC_tsmc40.xml +#set arch_xml_file = ARCH/k6_N10_SC_tsmc40nm_chain_TT.xml +#set arch_xml_file = ARCH/k6_N10_SC_tsmc40nm_chain_TT_yosys.xml +#set arch_xml_file = ARCH/k6_N10_sram_chain_SC_gf130_2x2.xml +#set verilog_reference = ${PWD}/Circuits/alu4_K6_N10_ace.v +#set blif_file = Circuits/shiftReg.blif +#set act_file = Circuits/shiftReg.act +set blif_file = Circuits/simple_gates_prevpr.blif +set act_file = Circuits/simple_gates_prevpr.act +set verilog_reference = ${PWD}/Circuits/s298_prevpr.v +#set blif_file = Circuits/frisc.blif +#set act_file = Circuits/frisc.act +#set blif_file = Circuits/elliptic.blif +#set act_file = Circuits/elliptic.act +set vpr_route_chan_width = 200 + +# Step A: Make sure a clean start +# Recompile if needed +#make clean +#make -j32 +# Remove previous designs +rm -rf $verilog_output_dirpath/$verilog_output_dirname + +# Run VPR +#valgrind +./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_modelsim_autodeck $modelsim_ini_file --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis #--fpga_verilog_print_report_timing_tcl + + + diff --git a/vpr7_x2p/vpr/picorv.sh b/vpr7_x2p/vpr/picorv.sh deleted file mode 100755 index 72ff44e56..000000000 --- a/vpr7_x2p/vpr/picorv.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# Example of how to run vpr - -# Pack, place, and route a heterogeneous FPGA -# Packing uses the AAPack algorithm -./vpr picorv/arch.xml picorv/picorv.blif --full_stats --nodisp --activity_file picorv/picorv.act --route_chan_width 30 --fpga_spice --fpga_spice_rename_illegal_port --fpga_spice_dir ./spice_test_picorv --fpga_spice_print_top_testbench --fpga_spice_print_grid_testbench --fpga_spice_print_cb_testbench --fpga_spice_print_sb_testbench --fpga_spice_print_lut_testbench --fpga_spice_print_hardlogic_testbench --fpga_spice_print_pb_mux_testbench --fpga_spice_print_cb_mux_testbench --fpga_spice_print_sb_mux_testbench --fpga_verilog --fpga_verilog_dir ./verilog_test_picorv --fpga_verilog_print_top_testbench - - - diff --git a/vpr7_x2p/vpr/picorv/arch.xml b/vpr7_x2p/vpr/picorv/arch.xml deleted file mode 100644 index e2d3abe3d..000000000 --- a/vpr7_x2p/vpr/picorv/arch.xml +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 1 1 1 - 1 1 1 1 - - - - 1 1 1 - 1 1 - - - - 1 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - io.outpad io.inpad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - 127e-12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -