diff --git a/openfpga/src/fpga_spice/spice_submodule.cpp b/openfpga/src/fpga_spice/spice_submodule.cpp index 7fd5564be..26b166a59 100644 --- a/openfpga/src/fpga_spice/spice_submodule.cpp +++ b/openfpga/src/fpga_spice/spice_submodule.cpp @@ -26,10 +26,10 @@ namespace openfpga { * Top-level function to generate primitive modules: * 1. Transistor wrapper * 2. Logic gates: AND/OR, inverter, buffer and transmission-gate/pass-transistor - * 3. TODO: Routing multiplexers + * 3. Routing multiplexers * 4. TODO: Local encoders for routing multiplexers * 5. Wires - * 6. TODO: Configuration memory blocks + * 6. Configuration memory blocks ********************************************************************/ int print_spice_submodule(NetlistManager& netlist_manager, const ModuleManager& module_manager, @@ -77,6 +77,8 @@ int print_spice_submodule(NetlistManager& netlist_manager, return CMD_EXEC_FATAL_ERROR; } + /* TODO: local decoders for routing multiplexers */ + /* Routing multiplexers */ status = print_spice_submodule_muxes(netlist_manager, module_manager, @@ -112,6 +114,8 @@ int print_spice_submodule(NetlistManager& netlist_manager, return CMD_EXEC_FATAL_ERROR; } + /* TODO: architecture decoders */ + return status; } diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 7f4c0d9b7..d02ced128 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -33,7 +33,7 @@ namespace openfpga { - /******************************************************************** +/******************************************************************** * A top-level function of FPGA-Verilog which focuses on fabric Verilog generation * This function will generate * - primitive modules required by the full fabric @@ -52,97 +52,93 @@ namespace openfpga * The only exception now is the user-defined modules. * We should think clearly about how to handle them for both Verilog and SPICE generators! ********************************************************************/ - void fpga_fabric_verilog(ModuleManager &module_manager, - NetlistManager &netlist_manager, - const CircuitLibrary &circuit_lib, - const MuxLibrary &mux_lib, - const DecoderLibrary &decoder_lib, - const DeviceContext &device_ctx, - const VprDeviceAnnotation &device_annotation, - const DeviceRRGSB &device_rr_gsb, - const FabricVerilogOption &options) - { +void fpga_fabric_verilog(ModuleManager &module_manager, + NetlistManager &netlist_manager, + const CircuitLibrary &circuit_lib, + const MuxLibrary &mux_lib, + const DecoderLibrary &decoder_lib, + const DeviceContext &device_ctx, + const VprDeviceAnnotation &device_annotation, + const DeviceRRGSB &device_rr_gsb, + const FabricVerilogOption &options) { - vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n"); + vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n"); - std::string src_dir_path = format_dir_path(options.output_directory()); + std::string src_dir_path = format_dir_path(options.output_directory()); - /* Create directories */ - create_directory(src_dir_path); + /* Create directories */ + create_directory(src_dir_path); - /* Sub directory under SRC directory to contain all the primitive block netlists */ - std::string submodule_dir_path = src_dir_path + std::string(DEFAULT_SUBMODULE_DIR_NAME); - create_directory(submodule_dir_path); + /* Sub directory under SRC directory to contain all the primitive block netlists */ + std::string submodule_dir_path = src_dir_path + std::string(DEFAULT_SUBMODULE_DIR_NAME); + create_directory(submodule_dir_path); - /* Sub directory under SRC directory to contain all the logic block netlists */ - std::string lb_dir_path = src_dir_path + std::string(DEFAULT_LB_DIR_NAME); - create_directory(lb_dir_path); + /* Sub directory under SRC directory to contain all the logic block netlists */ + std::string lb_dir_path = src_dir_path + std::string(DEFAULT_LB_DIR_NAME); + create_directory(lb_dir_path); - /* Sub directory under SRC directory to contain all the routing block netlists */ - std::string rr_dir_path = src_dir_path + std::string(DEFAULT_RR_DIR_NAME); - create_directory(rr_dir_path); + /* Sub directory under SRC directory to contain all the routing block netlists */ + std::string rr_dir_path = src_dir_path + std::string(DEFAULT_RR_DIR_NAME); + create_directory(rr_dir_path); - /* Print Verilog files containing preprocessing flags */ - print_verilog_preprocessing_flags_netlist(std::string(src_dir_path), - options); + /* Print Verilog files containing preprocessing flags */ + print_verilog_preprocessing_flags_netlist(std::string(src_dir_path), + options); - /* Generate primitive Verilog modules, which are corner stones of FPGA fabric - * Note that this function MUST be called before Verilog generation of - * core logic (i.e., logic blocks and routing resources) !!! - * This is because that this function will add the primitive Verilog modules to - * the module manager. - * Without the modules in the module manager, core logic generation is not possible!!! - */ - print_verilog_submodule(module_manager, netlist_manager, - mux_lib, decoder_lib, circuit_lib, - submodule_dir_path, - options); + /* Generate primitive Verilog modules, which are corner stones of FPGA fabric + * Note that this function MUST be called before Verilog generation of + * core logic (i.e., logic blocks and routing resources) !!! + * This is because that this function will add the primitive Verilog modules to + * the module manager. + * Without the modules in the module manager, core logic generation is not possible!!! + */ + print_verilog_submodule(module_manager, netlist_manager, + mux_lib, decoder_lib, circuit_lib, + submodule_dir_path, + options); - /* Generate routing blocks */ - if (true == options.compress_routing()) - { - print_verilog_unique_routing_modules(netlist_manager, - const_cast(module_manager), - device_rr_gsb, - rr_dir_path, - options.explicit_port_mapping()); - } - else - { - VTR_ASSERT(false == options.compress_routing()); - print_verilog_flatten_routing_modules(netlist_manager, - const_cast(module_manager), - device_rr_gsb, - rr_dir_path, - options.explicit_port_mapping()); - } - - /* Generate grids */ - print_verilog_grids(netlist_manager, - const_cast(module_manager), - device_ctx, device_annotation, - lb_dir_path, - options.explicit_port_mapping(), - options.verbose_output()); - - /* Generate FPGA fabric */ - print_verilog_top_module(netlist_manager, - const_cast(module_manager), - src_dir_path, - options.explicit_port_mapping()); - - /* Generate an netlist including all the fabric-related netlists */ - print_fabric_include_netlist(const_cast(netlist_manager), - src_dir_path, - circuit_lib); - - /* Given a brief stats on how many Verilog modules have been written to files */ - VTR_LOGV(options.verbose_output(), - "Written %lu Verilog modules in total\n", - module_manager.num_modules()); + /* Generate routing blocks */ + if (true == options.compress_routing()) { + print_verilog_unique_routing_modules(netlist_manager, + const_cast(module_manager), + device_rr_gsb, + rr_dir_path, + options.explicit_port_mapping()); + } else { + VTR_ASSERT(false == options.compress_routing()); + print_verilog_flatten_routing_modules(netlist_manager, + const_cast(module_manager), + device_rr_gsb, + rr_dir_path, + options.explicit_port_mapping()); } - /******************************************************************** + /* Generate grids */ + print_verilog_grids(netlist_manager, + const_cast(module_manager), + device_ctx, device_annotation, + lb_dir_path, + options.explicit_port_mapping(), + options.verbose_output()); + + /* Generate FPGA fabric */ + print_verilog_top_module(netlist_manager, + const_cast(module_manager), + src_dir_path, + options.explicit_port_mapping()); + + /* Generate an netlist including all the fabric-related netlists */ + print_fabric_include_netlist(const_cast(netlist_manager), + src_dir_path, + circuit_lib); + + /* Given a brief stats on how many Verilog modules have been written to files */ + VTR_LOGV(options.verbose_output(), + "Written %lu Verilog modules in total\n", + module_manager.num_modules()); +} + +/******************************************************************** * A top-level function of FPGA-Verilog which focuses on fabric Verilog generation * This function will generate * - A wrapper module, which encapsulate the FPGA module in a Verilog module which have the same port as the input benchmark @@ -151,100 +147,95 @@ namespace openfpga * This testbench is created for quick verification and formal verification purpose. * - Verilog netlist including preprocessing flags and all the Verilog netlists that have been generated ********************************************************************/ - void fpga_verilog_testbench(const ModuleManager &module_manager, - const BitstreamManager &bitstream_manager, - const FabricBitstream &fabric_bitstream, - const AtomContext &atom_ctx, - const PlacementContext &place_ctx, - const IoLocationMap &io_location_map, - const VprNetlistAnnotation &netlist_annotation, - const CircuitLibrary &circuit_lib, - const SimulationSetting &simulation_setting, - const e_config_protocol_type &config_protocol_type, - const VerilogTestbenchOption &options) - { +void fpga_verilog_testbench(const ModuleManager &module_manager, + const BitstreamManager &bitstream_manager, + const FabricBitstream &fabric_bitstream, + const AtomContext &atom_ctx, + const PlacementContext &place_ctx, + const IoLocationMap &io_location_map, + const VprNetlistAnnotation &netlist_annotation, + const CircuitLibrary &circuit_lib, + const SimulationSetting &simulation_setting, + const e_config_protocol_type &config_protocol_type, + const VerilogTestbenchOption &options) { - vtr::ScopedStartFinishTimer timer("Write Verilog testbenches for FPGA fabric\n"); + vtr::ScopedStartFinishTimer timer("Write Verilog testbenches for FPGA fabric\n"); - std::string src_dir_path = format_dir_path(options.output_directory()); + std::string src_dir_path = format_dir_path(options.output_directory()); - std::string netlist_name = atom_ctx.nlist.netlist_name(); + std::string netlist_name = atom_ctx.nlist.netlist_name(); - /* Create directories */ - create_directory(src_dir_path); + /* Create directories */ + create_directory(src_dir_path); - /* TODO: check if this works here. This function was in fabric generator */ - print_verilog_simulation_preprocessing_flags(std::string(src_dir_path), - options); + /* TODO: check if this works here. This function was in fabric generator */ + print_verilog_simulation_preprocessing_flags(std::string(src_dir_path), + options); - /* Collect global ports from the circuit library: - * TODO: should we place this in the OpenFPGA context? - */ - std::vector global_ports = find_circuit_library_global_ports(circuit_lib); + /* Collect global ports from the circuit library: + * TODO: should we place this in the OpenFPGA context? + */ + std::vector global_ports = find_circuit_library_global_ports(circuit_lib); - /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and pre-configured testbench for verification */ - if (true == options.print_formal_verification_top_netlist()) - { - std::string formal_verification_top_netlist_file_path = src_dir_path + netlist_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX); - print_verilog_preconfig_top_module(module_manager, bitstream_manager, - circuit_lib, global_ports, - atom_ctx, place_ctx, io_location_map, - netlist_annotation, - netlist_name, - formal_verification_top_netlist_file_path, - options.explicit_port_mapping()); - } - - if (true == options.print_preconfig_top_testbench()) - { - /* Generate top-level testbench using random vectors */ - std::string random_top_testbench_file_path = src_dir_path + netlist_name + std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); - print_verilog_random_top_testbench(netlist_name, - random_top_testbench_file_path, - atom_ctx, - netlist_annotation, - simulation_setting, - options.explicit_port_mapping()); - } - - /* Generate full testbench for verification, including configuration phase and operating phase */ - if (true == options.print_top_testbench()) - { - std::string top_testbench_file_path = src_dir_path + netlist_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); - print_verilog_top_testbench(module_manager, - bitstream_manager, fabric_bitstream, - config_protocol_type, - circuit_lib, global_ports, - atom_ctx, place_ctx, io_location_map, - netlist_annotation, - netlist_name, - top_testbench_file_path, - simulation_setting, - options.fast_configuration(), - options.explicit_port_mapping()); - } - - /* Generate exchangeable files which contains simulation settings */ - if (true == options.print_simulation_ini()) - { - std::string simulation_ini_file_name = options.simulation_ini_path(); - VTR_ASSERT(true != options.simulation_ini_path().empty()); - print_verilog_simulation_info(simulation_ini_file_name, - netlist_name, - src_dir_path, - atom_ctx, place_ctx, io_location_map, - module_manager, - config_protocol_type, - bitstream_manager.num_bits(), - simulation_setting.num_clock_cycles(), - simulation_setting.programming_clock_frequency(), - simulation_setting.operating_clock_frequency()); - } - - /* Generate a Verilog file including all the netlists that have been generated */ - print_include_netlists(src_dir_path, - netlist_name, - options.reference_benchmark_file_path()); + /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and pre-configured testbench for verification */ + if (true == options.print_formal_verification_top_netlist()) { + std::string formal_verification_top_netlist_file_path = src_dir_path + netlist_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX); + print_verilog_preconfig_top_module(module_manager, bitstream_manager, + circuit_lib, global_ports, + atom_ctx, place_ctx, io_location_map, + netlist_annotation, + netlist_name, + formal_verification_top_netlist_file_path, + options.explicit_port_mapping()); } + if (true == options.print_preconfig_top_testbench()) { + /* Generate top-level testbench using random vectors */ + std::string random_top_testbench_file_path = src_dir_path + netlist_name + std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); + print_verilog_random_top_testbench(netlist_name, + random_top_testbench_file_path, + atom_ctx, + netlist_annotation, + simulation_setting, + options.explicit_port_mapping()); + } + + /* Generate full testbench for verification, including configuration phase and operating phase */ + if (true == options.print_top_testbench()) { + std::string top_testbench_file_path = src_dir_path + netlist_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); + print_verilog_top_testbench(module_manager, + bitstream_manager, fabric_bitstream, + config_protocol_type, + circuit_lib, global_ports, + atom_ctx, place_ctx, io_location_map, + netlist_annotation, + netlist_name, + top_testbench_file_path, + simulation_setting, + options.fast_configuration(), + options.explicit_port_mapping()); + } + + /* Generate exchangeable files which contains simulation settings */ + if (true == options.print_simulation_ini()) { + std::string simulation_ini_file_name = options.simulation_ini_path(); + VTR_ASSERT(true != options.simulation_ini_path().empty()); + print_verilog_simulation_info(simulation_ini_file_name, + netlist_name, + src_dir_path, + atom_ctx, place_ctx, io_location_map, + module_manager, + config_protocol_type, + bitstream_manager.num_bits(), + simulation_setting.num_clock_cycles(), + simulation_setting.programming_clock_frequency(), + simulation_setting.operating_clock_frequency()); + } + + /* Generate a Verilog file including all the netlists that have been generated */ + print_include_netlists(src_dir_path, + netlist_name, + options.reference_benchmark_file_path()); +} + } /* end namespace openfpga */