diff --git a/docs/source/manual/file_formats/clock_network.rst b/docs/source/manual/file_formats/clock_network.rst index 60cd10eff..fba5c3ef2 100644 --- a/docs/source/manual/file_formats/clock_network.rst +++ b/docs/source/manual/file_formats/clock_network.rst @@ -28,7 +28,7 @@ The entry point of a clock tree must be at a valid connection block. - + @@ -213,19 +213,26 @@ where clock spine ``spine0`` will drive another clock spine ``spine1`` at (1, 1) For each switch point, outputs of neighbouring programmable blocks are allowed to drive the spine at next level, through syntax ``internal_driver``. -.. option:: tile_pin="" +.. option:: from_pin="" Define the pin of a programmable block as an internal driver to a clock network. The pin must be a valid pin defined in the VPR architecture description file. +.. option:: to_pin="" + + Define the source pin of a clock network. The pin must be a valid pin of the global ports defined in the tile_annotation part of OpenFPGA architecture description file. + For example, .. code-block:: xml - - - - - + + + + + + + + where the clock routing can be driven at (x=1,y=1) by the output pins ``O[0:3]`` of tile ``clb`` in a VPR architecture description file: @@ -298,7 +305,7 @@ For example, .. code-block:: xml - + diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst index 2bf9e4ccb..ab27eeceb 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst @@ -132,7 +132,7 @@ Clock signals will be auto-detected and routed based on pin constraints which ar Specify the *Pin Constraints File* (PCF) when the clock network contains multiple clock pins. For example, ``-pin_constraints_file pin_constraints.xml``. Strongly recommend for multi-clock network. See detailed file format about :ref:`file_format_pin_constraints_file`. -.. note:: If there is a global net, e.g., ``clk`` or ``reset``, which will be driven by an internal resource, it should also be defined in the PCF file. + .. note:: If there is a global net, e.g., ``clk`` or ``reset``, which will be driven by an internal resource, it should also be defined in the PCF file. .. option:: --disable_unused_trees diff --git a/libs/libclkarchopenfpga/arch/example_internal_drivers.xml b/libs/libclkarchopenfpga/arch/example_internal_drivers.xml index 6215ba443..d6435523c 100644 --- a/libs/libclkarchopenfpga/arch/example_internal_drivers.xml +++ b/libs/libclkarchopenfpga/arch/example_internal_drivers.xml @@ -2,10 +2,10 @@ - + - + diff --git a/libs/libclkarchopenfpga/src/base/clock_network.cpp b/libs/libclkarchopenfpga/src/base/clock_network.cpp index bd02259b7..e989e88f4 100644 --- a/libs/libclkarchopenfpga/src/base/clock_network.cpp +++ b/libs/libclkarchopenfpga/src/base/clock_network.cpp @@ -360,10 +360,16 @@ ClockNetwork::spine_switch_point_internal_drivers( return spine_switch_internal_drivers_[spine_id][size_t(switch_point_id)]; } -std::string ClockNetwork::internal_driver_port( +std::string ClockNetwork::internal_driver_from_pin( const ClockInternalDriverId& int_driver_id) const { VTR_ASSERT(valid_internal_driver_id(int_driver_id)); - return internal_driver_ports_[int_driver_id]; + return internal_driver_from_pins_[int_driver_id]; +} + +BasicPort ClockNetwork::internal_driver_to_pin( + const ClockInternalDriverId& int_driver_id) const { + VTR_ASSERT(valid_internal_driver_id(int_driver_id)); + return internal_driver_to_pins_[int_driver_id]; } std::vector ClockNetwork::tree_taps( @@ -514,9 +520,6 @@ std::vector ClockNetwork::tree_flatten_tap_to_ports( std::string flatten_tile_str = tile_info.get_name() + "[" + std::to_string(tile_idx) + "]"; for (size_t& pin_idx : pin_info.pins()) { - if (pin_idx != size_t(clk_pin_id)) { - continue; - } std::string flatten_pin_str = pin_info.get_name() + "[" + std::to_string(pin_idx) + "]"; flatten_taps.push_back(flatten_tile_str + "." + flatten_pin_str); @@ -526,10 +529,30 @@ std::vector ClockNetwork::tree_flatten_tap_to_ports( return flatten_taps; } -std::vector ClockNetwork::flatten_internal_driver_port( - const ClockInternalDriverId& int_driver_id) const { +std::vector ClockNetwork::flatten_internal_driver_from_pin( + const ClockInternalDriverId& int_driver_id, + const ClockTreePinId& clk_pin_id) const { std::vector flatten_taps; - std::string tap_name = internal_driver_port(int_driver_id); + BasicPort des_pin = internal_driver_to_pin(int_driver_id); + if (!des_pin.is_valid()) { + VTR_LOG_ERROR( + "Invalid internal driver destination port name '%s' whose index is not " + "valid\n", + des_pin.to_verilog_string().c_str()); + exit(1); + } + if (des_pin.get_width() != 1) { + VTR_LOG_ERROR( + "Invalid internal driver destination port name '%s' whose width is not " + "1\n", + des_pin.to_verilog_string().c_str()); + exit(1); + } + if (des_pin.get_lsb() != size_t(clk_pin_id)) { + return flatten_taps; + } + + std::string tap_name = internal_driver_from_pin(int_driver_id); StringToken tokenizer(tap_name); std::vector pin_tokens = tokenizer.split("."); if (pin_tokens.size() != 2) { @@ -768,12 +791,16 @@ ClockSwitchPointId ClockNetwork::add_spine_switch_point( ClockInternalDriverId ClockNetwork::add_spine_switch_point_internal_driver( const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id, - const std::string& int_driver_port) { + const std::string& int_driver_from_port, + const std::string& int_driver_to_port) { VTR_ASSERT(valid_spine_id(spine_id)); VTR_ASSERT(valid_spine_switch_point_id(spine_id, switch_point_id)); + /* Parse ports */ + PortParser to_pin_parser(int_driver_to_port); /* Find any existing id for the driver port */ for (ClockInternalDriverId int_driver_id : internal_driver_ids_) { - if (internal_driver_ports_[int_driver_id] == int_driver_port) { + if (internal_driver_from_pins_[int_driver_id] == int_driver_from_port && + internal_driver_to_pins_[int_driver_id] == to_pin_parser.port()) { spine_switch_internal_drivers_[spine_id][size_t(switch_point_id)] .push_back(int_driver_id); return int_driver_id; @@ -783,7 +810,8 @@ ClockInternalDriverId ClockNetwork::add_spine_switch_point_internal_driver( ClockInternalDriverId int_driver_id = ClockInternalDriverId(internal_driver_ids_.size()); internal_driver_ids_.push_back(int_driver_id); - internal_driver_ports_.push_back(int_driver_port); + internal_driver_from_pins_.push_back(int_driver_from_port); + internal_driver_to_pins_.push_back(to_pin_parser.port()); spine_switch_internal_drivers_[spine_id][size_t(switch_point_id)].push_back( int_driver_id); return int_driver_id; diff --git a/libs/libclkarchopenfpga/src/base/clock_network.h b/libs/libclkarchopenfpga/src/base/clock_network.h index ffec611df..2f1a09592 100644 --- a/libs/libclkarchopenfpga/src/base/clock_network.h +++ b/libs/libclkarchopenfpga/src/base/clock_network.h @@ -135,9 +135,12 @@ class ClockNetwork { std::vector spine_switch_point_internal_drivers( const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) const; - std::string internal_driver_port( + std::string internal_driver_from_pin( const ClockInternalDriverId& int_driver_id) const; - std::vector flatten_internal_driver_port( + std::vector flatten_internal_driver_from_pin( + const ClockInternalDriverId& int_driver_id, + const ClockTreePinId& clk_pin_id) const; + BasicPort internal_driver_to_pin( const ClockInternalDriverId& int_driver_id) const; /* Return the original list of tap pins that is in storage; useful for parsers @@ -222,7 +225,8 @@ class ClockNetwork { const vtr::Point& coord); ClockInternalDriverId add_spine_switch_point_internal_driver( const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id, - const std::string& internal_driver_port); + const std::string& internal_driver_from_port, + const std::string& internal_driver_to_port); ClockTapId add_tree_tap(const ClockTreeId& tree_id, const BasicPort& from_port, const std::string& to_port); @@ -317,7 +321,8 @@ class ClockNetwork { /* Basic Information about internal drivers */ vtr::vector internal_driver_ids_; - vtr::vector internal_driver_ports_; + vtr::vector internal_driver_from_pins_; + vtr::vector internal_driver_to_pins_; /* Basic information about tap */ vtr::vector tap_ids_; vtr::vector tap_from_ports_; diff --git a/libs/libclkarchopenfpga/src/io/clock_network_xml_constants.h b/libs/libclkarchopenfpga/src/io/clock_network_xml_constants.h index a63141870..65e828573 100644 --- a/libs/libclkarchopenfpga/src/io/clock_network_xml_constants.h +++ b/libs/libclkarchopenfpga/src/io/clock_network_xml_constants.h @@ -25,7 +25,9 @@ constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME = "switch_point"; constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_NODE_NAME = "internal_driver"; constexpr const char* - XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_TILE_PIN = "tile_pin"; + XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_FROM_PIN = "from_pin"; +constexpr const char* + XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_TO_PIN = "to_pin"; constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_TAP = "tap"; constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_X = "x"; constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_Y = "y"; diff --git a/libs/libclkarchopenfpga/src/io/read_xml_clock_network.cpp b/libs/libclkarchopenfpga/src/io/read_xml_clock_network.cpp index c56b152fd..46f74641d 100644 --- a/libs/libclkarchopenfpga/src/io/read_xml_clock_network.cpp +++ b/libs/libclkarchopenfpga/src/io/read_xml_clock_network.cpp @@ -163,13 +163,19 @@ static void read_xml_clock_spine_switch_point_internal_driver( "Invalid id of a clock spine!\n"); } - std::string int_driver_port_name = + std::string int_driver_from_port_name = get_attribute( xml_int_driver, - XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_TILE_PIN, loc_data) + XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_FROM_PIN, loc_data) + .as_string(); + std::string int_driver_to_port_name = + get_attribute(xml_int_driver, + XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_TO_PIN, + loc_data) .as_string(); clk_ntwk.add_spine_switch_point_internal_driver(spine_id, switch_point_id, - int_driver_port_name); + int_driver_from_port_name, + int_driver_to_port_name); } /******************************************************************** diff --git a/libs/libclkarchopenfpga/src/io/write_xml_clock_network.cpp b/libs/libclkarchopenfpga/src/io/write_xml_clock_network.cpp index e36ed9ed8..1d9937141 100644 --- a/libs/libclkarchopenfpga/src/io/write_xml_clock_network.cpp +++ b/libs/libclkarchopenfpga/src/io/write_xml_clock_network.cpp @@ -126,8 +126,13 @@ static int write_xml_clock_spine_switch_point( openfpga::write_tab_to_file(fp, 4); fp << "<" << XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_NODE_NAME; write_xml_attribute( - fp, XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_TILE_PIN, - clk_ntwk.internal_driver_port(int_driver_id).c_str()); + fp, XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_FROM_PIN, + clk_ntwk.internal_driver_from_pin(int_driver_id).c_str()); + write_xml_attribute( + fp, XML_CLOCK_SPINE_SWITCH_POINT_INTERNAL_DRIVER_ATTRIBUTE_TO_PIN, + clk_ntwk.internal_driver_to_pin(int_driver_id) + .to_verilog_string() + .c_str()); fp << "/>" << "\n"; } diff --git a/openfpga/src/annotation/append_clock_rr_graph.cpp b/openfpga/src/annotation/append_clock_rr_graph.cpp index d051634db..3552cdc33 100644 --- a/openfpga/src/annotation/append_clock_rr_graph.cpp +++ b/openfpga/src/annotation/append_clock_rr_graph.cpp @@ -590,11 +590,12 @@ static void try_find_and_add_clock_opin2track_node( std::vector& opin_nodes, const DeviceGrid& grids, const RRGraphView& rr_graph_view, const size_t& layer, const vtr::Point& grid_coord, const e_side& pin_side, - const ClockNetwork& clk_ntwk, const ClockInternalDriverId& int_driver_id) { + const ClockNetwork& clk_ntwk, const ClockTreePinId& clk_pin, + const ClockInternalDriverId& int_driver_id) { t_physical_tile_type_ptr grid_type = grids.get_physical_type( t_physical_tile_loc(grid_coord.x(), grid_coord.y(), layer)); for (std::string tap_pin_name : - clk_ntwk.flatten_internal_driver_port(int_driver_id)) { + clk_ntwk.flatten_internal_driver_from_pin(int_driver_id, clk_pin)) { /* tap pin name could be 'io[5:5].a2f[0]' */ int grid_pin_idx = find_physical_tile_pin_index(grid_type, tap_pin_name); if (grid_pin_idx == grid_type->num_pins) { @@ -635,7 +636,7 @@ static void try_find_and_add_clock_opin2track_node( static std::vector find_clock_opin2track_node( const DeviceGrid& grids, const RRGraphView& rr_graph_view, const size_t& layer, const vtr::Point& sb_coord, - const ClockNetwork& clk_ntwk, + const ClockNetwork& clk_ntwk, const ClockTreePinId& clk_pin, const std::vector& int_driver_ids) { std::vector opin_nodes; /* Find opins from @@ -658,9 +659,9 @@ static std::vector find_clock_opin2track_node( vtr::Point grid_coord = grid_coords[igrid]; for (e_side grid_side : grid_sides[igrid]) { for (ClockInternalDriverId int_driver_id : int_driver_ids) { - try_find_and_add_clock_opin2track_node(opin_nodes, grids, rr_graph_view, - layer, grid_coord, grid_side, - clk_ntwk, int_driver_id); + try_find_and_add_clock_opin2track_node( + opin_nodes, grids, rr_graph_view, layer, grid_coord, grid_side, + clk_ntwk, clk_pin, int_driver_id); } } } @@ -709,7 +710,7 @@ static int add_rr_graph_opin2clk_edges( clk_ntwk.spine_switch_point_internal_drivers(ispine, switch_point_id); for (RRNodeId src_node : find_clock_opin2track_node( - grids, rr_graph_view, layer, src_coord, clk_ntwk, + grids, rr_graph_view, layer, src_coord, clk_ntwk, ipin, int_driver_ids)) { /* Create edges */ VTR_ASSERT(rr_graph_view.valid_node(des_node)); diff --git a/openfpga/src/annotation/openfpga_annotate_routing.cpp b/openfpga/src/annotation/openfpga_annotate_routing.cpp index cfbb064ef..489c80986 100644 --- a/openfpga/src/annotation/openfpga_annotate_routing.cpp +++ b/openfpga/src/annotation/openfpga_annotate_routing.cpp @@ -21,7 +21,8 @@ namespace openfpga { *******************************************************************/ vtr::vector annotate_rr_node_global_net( const DeviceContext& device_ctx, const ClusteredNetlist& cluster_nlist, - const PlacementContext& placement_ctx, const bool& verbose) { + const PlacementContext& placement_ctx, + const VprClusteringAnnotation& clustering_annotation, const bool& verbose) { vtr::vector rr_node_nets; size_t counter = 0; @@ -42,10 +43,56 @@ vtr::vector annotate_rr_node_global_net( ClusterBlockId block_id = cluster_nlist.pin_block(pin_id); t_block_loc blk_loc = get_block_loc(block_id, false); int phy_pin = placement_ctx.physical_pins[pin_id]; + t_physical_tile_type_ptr phy_tile = device_ctx.grid.get_physical_type( + t_physical_tile_loc(blk_loc.loc.x, blk_loc.loc.y, 0)); + int node_pin_num = phy_tile->num_pins; + /* Note that the phy_pin may not reflect the actual pin index at the + * top-level physical tile type. It could be one of the random pin to the + * same pin class. So here, we have to find an exact match of the pin + * index from the clustering results! */ + int subtile_idx = blk_loc.loc.sub_tile; + auto logical_block = cluster_nlist.block_type(block_id); + for (int j = 0; j < logical_block->pb_type->num_pins; j++) { + /* Find the net mapped to this pin in clustering results*/ + ClusterNetId cluster_net_id = cluster_nlist.block_net(block_id, j); + /* Get the actual net id because it may be renamed during routing */ + if (true == clustering_annotation.is_net_renamed(block_id, j)) { + cluster_net_id = clustering_annotation.net(block_id, j); + } + /* Bypass unmatched pins */ + if (cluster_net_id != net_id) { + continue; + } + int curr_pin_num = get_physical_pin_at_sub_tile_location( + phy_tile, logical_block, subtile_idx, j); + if (phy_tile->pin_class[curr_pin_num] != phy_tile->pin_class[phy_pin]) { + continue; + } + node_pin_num = curr_pin_num; + break; + } + VTR_ASSERT(node_pin_num < phy_tile->num_pins); + t_rr_type rr_pin_type = IPIN; + if (phy_tile->class_inf[phy_tile->pin_class[node_pin_num]].type == + RECEIVER) { + rr_pin_type = IPIN; + } else if (phy_tile->class_inf[phy_tile->pin_class[node_pin_num]].type == + DRIVER) { + rr_pin_type = OPIN; + } else { + VTR_LOG_ERROR( + "When annotating global net '%s', invalid rr node pin type for '%s' " + "pin '%d'\n", + cluster_nlist.net_name(net_id).c_str(), phy_tile->name, node_pin_num); + exit(1); + } std::vector curr_rr_nodes = rr_graph.node_lookup().find_nodes_at_all_sides( - layer, blk_loc.loc.x, blk_loc.loc.y, IPIN, phy_pin); + layer, blk_loc.loc.x, blk_loc.loc.y, rr_pin_type, node_pin_num); for (RRNodeId curr_rr_node : curr_rr_nodes) { + VTR_LOGV(verbose, "on '%s' pin '%d'\n", + cluster_nlist.net_name(net_id).c_str(), phy_tile->name, + node_pin_num); rr_node_nets[curr_rr_node] = net_id; counter++; } diff --git a/openfpga/src/annotation/openfpga_annotate_routing.h b/openfpga/src/annotation/openfpga_annotate_routing.h index dc5d28db3..8c9f0e40a 100644 --- a/openfpga/src/annotation/openfpga_annotate_routing.h +++ b/openfpga/src/annotation/openfpga_annotate_routing.h @@ -5,6 +5,7 @@ * Include header files that are required by function declaration *******************************************************************/ #include "openfpga_context.h" +#include "vpr_clustering_annotation.h" #include "vpr_context.h" #include "vpr_routing_annotation.h" @@ -17,7 +18,8 @@ namespace openfpga { vtr::vector annotate_rr_node_global_net( const DeviceContext& device_ctx, const ClusteredNetlist& cluster_nlist, - const PlacementContext& placement_ctx, const bool& verbose); + const PlacementContext& placement_ctx, + const VprClusteringAnnotation& clustering_annotation, const bool& verbose); void annotate_vpr_rr_node_nets(const DeviceContext& device_ctx, const ClusteringContext& clustering_ctx, diff --git a/openfpga/src/annotation/route_clock_rr_graph.cpp b/openfpga/src/annotation/route_clock_rr_graph.cpp index 207b83d0e..a0e57bda5 100644 --- a/openfpga/src/annotation/route_clock_rr_graph.cpp +++ b/openfpga/src/annotation/route_clock_rr_graph.cpp @@ -472,6 +472,7 @@ static int route_clock_tree_rr_graph( *******************************************************************/ int route_clock_rr_graph( VprRoutingAnnotation& vpr_routing_annotation, + const VprClusteringAnnotation& vpr_clustering_annotation, const DeviceContext& vpr_device_ctx, const ClusteredNetlist& cluster_nlist, const PlacementContext& vpr_place_ctx, const RRClockSpatialLookup& clk_rr_lookup, const ClockNetwork& clk_ntwk, @@ -510,7 +511,7 @@ int route_clock_rr_graph( /* Build rr_node-to-net mapping for global nets */ vtr::vector rr_node_gnets = annotate_rr_node_global_net(vpr_device_ctx, cluster_nlist, vpr_place_ctx, - verbose); + vpr_clustering_annotation, verbose); /* Route spines one by one */ for (auto itree : clk_ntwk.trees()) { diff --git a/openfpga/src/annotation/route_clock_rr_graph.h b/openfpga/src/annotation/route_clock_rr_graph.h index 2bd4ec178..1c37bc8b6 100644 --- a/openfpga/src/annotation/route_clock_rr_graph.h +++ b/openfpga/src/annotation/route_clock_rr_graph.h @@ -7,6 +7,7 @@ #include "clock_network.h" #include "pin_constraints.h" #include "rr_clock_spatial_lookup.h" +#include "vpr_clustering_annotation.h" #include "vpr_context.h" #include "vpr_routing_annotation.h" @@ -19,6 +20,7 @@ namespace openfpga { int route_clock_rr_graph( VprRoutingAnnotation& vpr_routing_annotation, + const VprClusteringAnnotation& vpr_clustering_annotation, const DeviceContext& vpr_device_ctx, const ClusteredNetlist& cluster_nlist, const PlacementContext& vpr_place_ctx, const RRClockSpatialLookup& clk_rr_lookup, const ClockNetwork& clk_ntwk, diff --git a/openfpga/src/base/openfpga_link_arch_template.h b/openfpga/src/base/openfpga_link_arch_template.h index bb061de09..9898d5f75 100644 --- a/openfpga/src/base/openfpga_link_arch_template.h +++ b/openfpga/src/base/openfpga_link_arch_template.h @@ -232,7 +232,8 @@ int route_clock_rr_graph_template(T& openfpga_ctx, const Command& cmd, } return route_clock_rr_graph( - openfpga_ctx.mutable_vpr_routing_annotation(), g_vpr_ctx.device(), + openfpga_ctx.mutable_vpr_routing_annotation(), + openfpga_ctx.vpr_clustering_annotation(), g_vpr_ctx.device(), g_vpr_ctx.clustering().clb_nlist, g_vpr_ctx.placement(), openfpga_ctx.clock_rr_lookup(), openfpga_ctx.clock_arch(), pin_constraints, cmd_context.option_enable(cmd, opt_disable_unused_trees), diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 5c1c703e2..3e47c6a16 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -65,6 +65,10 @@ static void print_verilog_preconfig_top_module_ports( /* The block may be renamed as it contains special characters which violate * Verilog syntax */ if (true == netlist_annotation.is_block_renamed(atom_blk)) { + VTR_LOG( + "Replace pin name '%s' with '%s' as it is renamed to comply verilog " + "syntax\n", + block_name.c_str(), netlist_annotation.block_name(atom_blk).c_str()); block_name = netlist_annotation.block_name(atom_blk); } /* For output block, remove the prefix which is added by VPR */ @@ -445,8 +449,8 @@ int print_verilog_preconfig_top_module( /* Connect FPGA top module global ports to constant or benchmark global * signals! */ status = print_verilog_preconfig_top_module_connect_global_ports( - fp, module_manager, core_module, pin_constraints, global_ports, - benchmark_clock_port_names, + fp, module_manager, core_module, pin_constraints, atom_ctx, + netlist_annotation, global_ports, benchmark_clock_port_names, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); if (CMD_EXEC_FATAL_ERROR == status) { return status; diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp index 944506c89..0073ab46d 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp @@ -57,6 +57,7 @@ void print_verilog_preconfig_top_module_internal_wires( int print_verilog_preconfig_top_module_connect_global_ports( std::fstream &fp, const ModuleManager &module_manager, const ModuleId &top_module, const PinConstraints &pin_constraints, + const AtomContext &atom_ctx, const VprNetlistAnnotation &netlist_annotation, const FabricGlobalPortInfo &fabric_global_ports, const std::vector &benchmark_clock_port_names, const std::string &port_postfix) { @@ -121,7 +122,27 @@ int print_verilog_preconfig_top_module_connect_global_ports( } clock_name_to_connect = benchmark_clock_port_names[pin_id]; } - + /* The clock name must be a valid primary input. Otherwise, it could be + * a signal generated by internal logics, e.g., clb */ + AtomBlockId atom_blk = atom_ctx.nlist.find_block(clock_name_to_connect); + if ((AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk))) { + VTR_LOG( + "Global net '%s' is not a primary input of the netlist (which " + "could a signal generated by internal logic). Will not wire it to " + "any FPGA primary input pin\n", + clock_name_to_connect.c_str()); + continue; + } + /* The block may be renamed as it contains special characters which + * violate Verilog syntax */ + if (true == netlist_annotation.is_block_renamed(atom_blk)) { + VTR_LOG( + "Replace pin name '%s' with '%s' as it is renamed to comply " + "verilog syntax\n", + clock_name_to_connect.c_str(), + netlist_annotation.block_name(atom_blk).c_str()); + clock_name_to_connect = netlist_annotation.block_name(atom_blk); + } BasicPort benchmark_clock_pin(clock_name_to_connect, 1); print_verilog_wire_connection(fp, module_clock_pin, benchmark_clock_pin, false); @@ -151,6 +172,27 @@ int print_verilog_preconfig_top_module_connect_global_ports( */ if ((false == pin_constraints.unconstrained_net(constrained_net_name)) && (false == pin_constraints.unmapped_net(constrained_net_name))) { + /* The clock name must be a valid primary input. Otherwise, it could be + * a signal generated by internal logics, e.g., clb */ + AtomBlockId atom_blk = atom_ctx.nlist.find_block(constrained_net_name); + if ((AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk))) { + VTR_LOG( + "Global net '%s' is not a primary input of the netlist (which " + "could a signal generated by internal logic). Will not wire it to " + "any FPGA primary input pin\n", + constrained_net_name.c_str()); + continue; + } + /* The block may be renamed as it contains special characters which + * violate Verilog syntax */ + if (true == netlist_annotation.is_block_renamed(atom_blk)) { + VTR_LOG( + "Replace pin name '%s' with '%s' as it is renamed to comply " + "verilog syntax\n", + constrained_net_name.c_str(), + netlist_annotation.block_name(atom_blk).c_str()); + constrained_net_name = netlist_annotation.block_name(atom_blk); + } BasicPort benchmark_pin(constrained_net_name, 1); print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, false); diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h index 55c85eadd..20ae797e2 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h @@ -35,6 +35,7 @@ void print_verilog_preconfig_top_module_internal_wires( int print_verilog_preconfig_top_module_connect_global_ports( std::fstream &fp, const ModuleManager &module_manager, const ModuleId &top_module, const PinConstraints &pin_constraints, + const AtomContext &atom_ctx, const VprNetlistAnnotation &netlist_annotation, const FabricGlobalPortInfo &fabric_global_ports, const std::vector &benchmark_clock_port_names, const std::string &port_postfix); diff --git a/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp index 30018e400..0f4978c60 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp @@ -90,8 +90,9 @@ int print_verilog_testbench_io_connection( /* Connect FPGA top module global ports to constant or benchmark global * signals! */ status = print_verilog_preconfig_top_module_connect_global_ports( - fp, module_manager, core_module, pin_constraints, global_ports, - benchmark_clock_port_names, std::string()); + fp, module_manager, core_module, pin_constraints, atom_ctx, + netlist_annotation, global_ports, benchmark_clock_port_names, + std::string()); if (CMD_EXEC_FATAL_ERROR == status) { return status; } diff --git a/openfpga_flow/benchmarks/micro_benchmark/clk_cond/clk_cond.v b/openfpga_flow/benchmarks/micro_benchmark/clk_cond/clk_cond.v new file mode 100644 index 000000000..d939c7ab3 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/clk_cond/clk_cond.v @@ -0,0 +1,21 @@ +///////////////////////////////////////// +// Functionality: A locally generated clock signal which is to test clock network with internal drivers +// Author: Xifan Tang +//////////////////////////////////////// +`timescale 1ns / 1ps + +module clk_cond(clk_i, clk_cond_i, d_i, q_o); + +input wire clk_cond_i; +input wire clk_i; +input wire d_i; +output reg q_o; + +wire int_clk; +assign int_clk = clk_cond_i & clk_i; + +always @(posedge int_clk) begin + q_o <= d_i; +end + +endmodule diff --git a/openfpga_flow/benchmarks/micro_benchmark/clk_on_lut/clk_on_lut.v b/openfpga_flow/benchmarks/micro_benchmark/clk_on_lut/clk_on_lut.v new file mode 100644 index 000000000..80814e49b --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/clk_on_lut/clk_on_lut.v @@ -0,0 +1,21 @@ +///////////////////////////////////////// +// Functionality: A register driven by a combinational logic with clk signal +// Author: Xifan Tang +//////////////////////////////////////// +`timescale 1ns / 1ps + +module clk_on_lut(a, b, q, out, clk); + +input wire clk; +input wire a; +input wire b; +output reg q; +output wire out; + +always @(posedge clk) begin + q <= a; +end + +assign out = b & clk; + +endmodule diff --git a/openfpga_flow/benchmarks/micro_benchmark/rst_and_clk_on_lut/rst_and_clk_on_lut.v b/openfpga_flow/benchmarks/micro_benchmark/rst_and_clk_on_lut/rst_and_clk_on_lut.v new file mode 100644 index 000000000..598d41dcf --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/rst_and_clk_on_lut/rst_and_clk_on_lut.v @@ -0,0 +1,29 @@ +///////////////////////////////////////// +// Functionality: A register driven by a combinational logic with reset signal +// Author: Xifan Tang +//////////////////////////////////////// +`timescale 1ns / 1ps + +module rst_and_clk_on_lut(a, b, c, q, out0, out1, clk, rst); + +input wire rst; +input wire clk; +input wire a; +input wire b; +input wire c; +output reg q; +output wire out0; +output wire out1; + +always @(posedge rst or posedge clk) begin + if (rst) begin + q <= 0; + end else begin + q <= a; + end +end + +assign out0 = b & ~rst; +assign out1 = c & ~clk; + +endmodule diff --git a/openfpga_flow/benchmarks/micro_benchmark/rst_cond/rst_cond.v b/openfpga_flow/benchmarks/micro_benchmark/rst_cond/rst_cond.v new file mode 100644 index 000000000..fba40f3a7 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/rst_cond/rst_cond.v @@ -0,0 +1,26 @@ +///////////////////////////////////////// +// Functionality: A locally generated reset signal which is to test clock network with internal drivers +// Author: Xifan Tang +//////////////////////////////////////// +`timescale 1ns / 1ps + +module rst_cond(rst_i, rst_cond_i, clk_i, d_i, q_o); + +input wire rst_cond_i; +input wire rst_i; +input wire clk_i; +input wire d_i; +output reg q_o; + +wire int_rst; +assign int_rst = rst_cond_i & rst_i; + +always @(posedge int_rst or posedge clk_i) begin + if (int_rst) begin + q_o <= 0; + end else begin + q_o <= d_i; + end +end + +endmodule diff --git a/openfpga_flow/openfpga_shell_scripts/example_clkntwk_int_driver_no_ace_script.openfpga b/openfpga_flow/openfpga_shell_scripts/example_clkntwk_int_driver_no_ace_script.openfpga new file mode 100644 index 000000000..489162d11 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/example_clkntwk_int_driver_no_ace_script.openfpga @@ -0,0 +1,76 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} \ + --clock_modeling ideal \ + --device ${OPENFPGA_VPR_DEVICE_LAYOUT} \ + --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} \ + --read_vpr_constraints ${OPENFPGA_VPR_CONSTRAINT_FILE} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Read OpenFPGA clock architecture +read_openfpga_clock_arch -f ${OPENFPGA_CLOCK_ARCH_FILE} + +# Append clock network to vpr's routing resource graph +append_clock_rr_graph + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --sort_gsb_chan_node_in_edges + +# Route clock based on clock network definition +route_clock_rr_graph ${OPENFPGA_ROUTE_CLOCK_OPTIONS} --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing #--verbose + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack --design_constraints ${OPENFPGA_REPACK_CONSTRAINTS_FILE} #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_TESTBENCH_PORT_MAPPING} --include_signal_init --bitstream fabric_bitstream.bit --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} +write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC ${OPENFPGA_VERILOG_TESTBENCH_PORT_MAPPING} --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} +write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_TESTBENCH_PORT_MAPPING} --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 0f3abd81d..85e0d9bfd 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -240,6 +240,7 @@ run-task basic_tests/clock_network/homo_2clock_2layer $@ run-task basic_tests/clock_network/homo_2clock_2layer_disable_unused $@ run-task basic_tests/clock_network/homo_2clock_2layer_disable_unused_tree $@ run-task basic_tests/clock_network/homo_1clock_1reset_2layer $@ +run-task basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut $@ run-task basic_tests/clock_network/homo_1clock_1reset_2layer_syntax $@ run-task basic_tests/clock_network/homo_1clock_1reset_2layer_disable_unused_spines $@ run-task basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver $@ diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer/config/task.conf b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer/config/task.conf index 04489c15e..554a53d64 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer/config/task.conf @@ -21,7 +21,7 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_ openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml openfpga_repack_constraints_file=${PATH:TASK_DIR}/config/repack_pin_constraints.xml openfpga_vpr_device_layout=2x2 -openfpga_vpr_route_chan_width=40 +openfpga_vpr_route_chan_width=32 openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer.xml openfpga_verilog_testbench_port_mapping=--explicit_port_mapping openfpga_route_clock_options= diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_disable_unused_spines/config/task.conf b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_disable_unused_spines/config/task.conf index f0fe1b077..622f0328e 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_disable_unused_spines/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_disable_unused_spines/config/task.conf @@ -21,7 +21,7 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_ openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml openfpga_repack_constraints_file=${PATH:TASK_DIR}/config/repack_pin_constraints.xml openfpga_vpr_device_layout=2x2 -openfpga_vpr_route_chan_width=40 +openfpga_vpr_route_chan_width=32 openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer.xml openfpga_verilog_testbench_port_mapping=--explicit_port_mapping openfpga_route_clock_options=--disable_unused_spines diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver_clk.xml similarity index 82% rename from openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver.xml rename to openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver_clk.xml index c88e8ccd4..481e88a60 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver.xml +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver_clk.xml @@ -1,17 +1,17 @@ - + - + - + - + - + @@ -20,6 +20,8 @@ + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver_rst.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver_rst.xml new file mode 100644 index 000000000..a89b25a17 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/clk_arch_1clk_1rst_2layer_int_driver_rst.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_clk_cond.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_clk_cond.xml new file mode 100644 index 000000000..903c4bfac --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_clk_cond.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_rst_cond.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_rst_cond.xml new file mode 100644 index 000000000..55e49733f --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_rst_cond.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/task.conf b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/task.conf index 70565880f..a4841a1ae 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/task.conf @@ -16,22 +16,23 @@ timeout_each_job = 3*60 fpga_flow=yosys_vpr [OpenFPGA_SHELL] -openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_clkntwk_no_ace_script.openfpga +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_clkntwk_int_driver_no_ace_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_Ntwk1clk1rst2lvl_cc_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml openfpga_repack_constraints_file=${PATH:TASK_DIR}/config/repack_pin_constraints.xml openfpga_vpr_device_layout=2x2 -openfpga_vpr_route_chan_width=40 +openfpga_vpr_route_chan_width=32 openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer_int_driver.xml openfpga_verilog_testbench_port_mapping=--explicit_port_mapping openfpga_route_clock_options= +openfpga_vpr_constraint_file=${PATH:TASK_DIR}/config/vpr_constraint_clk_cond.xml [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml [BENCHMARKS] -bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v -bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_resetb/counter.v +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/clk_cond/clk_cond.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/rst_cond/rst_cond.v [SYNTHESIS_PARAM] # Yosys script parameters @@ -41,13 +42,15 @@ bench_read_verilog_options_common = -nolatches bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys -bench0_top = counter -bench0_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_reset.xml -bench0_openfpga_verilog_testbench_port_mapping= +bench0_top = clk_cond +bench0_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_clk_cond.xml +bench0_openfpga_vpr_constraint_file=${PATH:TASK_DIR}/config/vpr_constraint_clk_cond.xml +bench0_openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer_int_driver_clk.xml -bench1_top = counter -bench1_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_resetb.xml -bench1_openfpga_verilog_testbench_port_mapping= +bench1_top = rst_cond +bench1_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_rst_cond.xml +bench1_openfpga_vpr_constraint_file=${PATH:TASK_DIR}/config/vpr_constraint_rst_cond.xml +bench1_openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer_int_driver_rst.xml [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/vpr_constraint_clk_cond.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/vpr_constraint_clk_cond.xml new file mode 100644 index 000000000..f9b30b022 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/vpr_constraint_clk_cond.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/vpr_constraint_rst_cond.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/vpr_constraint_rst_cond.xml new file mode 100644 index 000000000..3c6f27aef --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/vpr_constraint_rst_cond.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/clk_arch_1clk_1rst_2layer.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/clk_arch_1clk_1rst_2layer.xml new file mode 100644 index 000000000..b91512914 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/clk_arch_1clk_1rst_2layer.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_clk.xml similarity index 82% rename from openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_reset.xml rename to openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_clk.xml index 3788a1411..f0b871511 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_reset.xml +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_clk.xml @@ -2,7 +2,7 @@ - + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_resetb.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_rst.xml similarity index 76% rename from openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_resetb.xml rename to openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_rst.xml index 1311926f5..15df5148e 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_internal_driver/config/pin_constraints_resetb.xml +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_rst.xml @@ -2,7 +2,7 @@ - + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_rst_and_clk.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_rst_and_clk.xml new file mode 100644 index 000000000..15df5148e --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/pin_constraints_rst_and_clk.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/repack_pin_constraints.xml b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/repack_pin_constraints.xml new file mode 100644 index 000000000..06a125111 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/repack_pin_constraints.xml @@ -0,0 +1,4 @@ + + + + diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/task.conf b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/task.conf new file mode 100644 index 000000000..a3d9b1a48 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_on_lut/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = false +spice_output=false +verilog_output=true +timeout_each_job = 3*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_clkntwk_no_ace_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_Ntwk1clk1rst2lvl_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_repack_constraints_file=${PATH:TASK_DIR}/config/repack_pin_constraints.xml +openfpga_vpr_device_layout=2x2 +openfpga_vpr_route_chan_width=32 +openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer.xml +openfpga_verilog_testbench_port_mapping=--explicit_port_mapping +openfpga_route_clock_options= + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/rst_on_lut/rst_on_lut.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/clk_on_lut/clk_on_lut.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/rst_and_clk_on_lut/rst_and_clk_on_lut.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_sim.v +bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_map.v +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = rst_on_lut +bench0_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_rst.xml + +bench1_top = clk_on_lut +bench1_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_clk.xml + +bench2_top = rst_and_clk_on_lut +bench2_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints_rst_and_clk.xml + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_syntax/config/task.conf b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_syntax/config/task.conf index 04489c15e..554a53d64 100644 --- a/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_syntax/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/clock_network/homo_1clock_1reset_2layer_syntax/config/task.conf @@ -21,7 +21,7 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_ openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml openfpga_repack_constraints_file=${PATH:TASK_DIR}/config/repack_pin_constraints.xml openfpga_vpr_device_layout=2x2 -openfpga_vpr_route_chan_width=40 +openfpga_vpr_route_chan_width=32 openfpga_clock_arch_file=${PATH:TASK_DIR}/config/clk_arch_1clk_1rst_2layer.xml openfpga_verilog_testbench_port_mapping=--explicit_port_mapping openfpga_route_clock_options= diff --git a/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml b/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml index 013466e5c..b105149b1 100644 --- a/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml @@ -107,11 +107,12 @@ + - - clb.reset clb.clk clb.O[4:7] clb.I[6:11] - clb.O[0:3] clb.I[0:5] + + clb.reset clb.clk clb.O[0:3] clb.I[0:5] + clb.O[4:7] clb.I[6:11]