diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index 283b1de39..43173e64b 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -21,6 +21,7 @@ #include "rr_gsb_utils.h" #include "openfpga_physical_tile_utils.h" #include "openfpga_device_grid_utils.h" +#include "openfpga_rr_graph_utils.h" #include "module_manager_utils.h" #include "build_routing_module_utils.h" @@ -123,7 +124,7 @@ void add_top_module_nets_connect_grids_and_sb(ModuleManager& module_manager, int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(grid_type_descriptor, src_grid_pin_index); VTR_ASSERT(OPEN != subtile_index && subtile_index < grid_type_descriptor->capacity); std::string src_grid_port_name = generate_grid_port_name(src_grid_pin_width, src_grid_pin_height, subtile_index, - rr_graph.node_side(rr_gsb.get_opin_node(side_manager.get_side(), inode)), + get_rr_graph_single_node_side(rr_graph, rr_gsb.get_opin_node(side_manager.get_side(), inode)), src_grid_pin_info); ModulePortId src_grid_port_id = module_manager.find_module_port(src_grid_module, src_grid_port_name); VTR_ASSERT(true == module_manager.valid_module_port_id(src_grid_module, src_grid_port_id)); @@ -133,7 +134,7 @@ void add_top_module_nets_connect_grids_and_sb(ModuleManager& module_manager, vtr::Point sink_sb_port_coord(rr_graph.node_xlow(module_sb.get_opin_node(side_manager.get_side(), inode)), rr_graph.node_ylow(module_sb.get_opin_node(side_manager.get_side(), inode))); std::string sink_sb_port_name = generate_sb_module_grid_port_name(side_manager.get_side(), - rr_graph.node_side(module_sb.get_opin_node(side_manager.get_side(), inode)), + get_rr_graph_single_node_side(rr_graph, module_sb.get_opin_node(side_manager.get_side(), inode)), grids, vpr_device_annotation, rr_graph, @@ -271,11 +272,11 @@ void add_top_module_nets_connect_grids_and_sb_with_duplicated_pins(ModuleManager std::string src_grid_port_name; if (0. == find_physical_tile_pin_Fc(grid_type_descriptor, src_grid_pin_index)) { src_grid_port_name = generate_grid_port_name(src_grid_pin_width, src_grid_pin_height, subtile_index, - rr_graph.node_side(rr_gsb.get_opin_node(side_manager.get_side(), inode)), + get_rr_graph_single_node_side(rr_graph, rr_gsb.get_opin_node(side_manager.get_side(), inode)), src_grid_pin_info); } else { src_grid_port_name = generate_grid_duplicated_port_name(src_grid_pin_width, src_grid_pin_height, subtile_index, - rr_graph.node_side(rr_gsb.get_opin_node(side_manager.get_side(), inode)), + get_rr_graph_single_node_side(rr_graph, rr_gsb.get_opin_node(side_manager.get_side(), inode)), src_grid_pin_info, sb_side2postfix_map[side_manager.get_side()]); } ModulePortId src_grid_port_id = module_manager.find_module_port(src_grid_module, src_grid_port_name); @@ -286,7 +287,7 @@ void add_top_module_nets_connect_grids_and_sb_with_duplicated_pins(ModuleManager vtr::Point sink_sb_port_coord(rr_graph.node_xlow(module_sb.get_opin_node(side_manager.get_side(), inode)), rr_graph.node_ylow(module_sb.get_opin_node(side_manager.get_side(), inode))); std::string sink_sb_port_name = generate_sb_module_grid_port_name(side_manager.get_side(), - rr_graph.node_side(module_sb.get_opin_node(side_manager.get_side(), inode)), + get_rr_graph_single_node_side(rr_graph, module_sb.get_opin_node(side_manager.get_side(), inode)), grids, vpr_device_annotation, rr_graph, @@ -447,7 +448,7 @@ void add_top_module_nets_connect_grids_and_cb(ModuleManager& module_manager, int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(grid_type_descriptor, sink_grid_pin_index); VTR_ASSERT(OPEN != subtile_index && subtile_index < grid_type_descriptor->capacity); std::string sink_grid_port_name = generate_grid_port_name(sink_grid_pin_width, sink_grid_pin_height, subtile_index, - rr_graph.node_side(rr_gsb.get_ipin_node(cb_ipin_side, inode)), + get_rr_graph_single_node_side(rr_graph, rr_gsb.get_ipin_node(cb_ipin_side, inode)), sink_grid_pin_info); ModulePortId sink_grid_port_id = module_manager.find_module_port(sink_grid_module, sink_grid_port_name); VTR_ASSERT(true == module_manager.valid_module_port_id(sink_grid_module, sink_grid_port_id)); @@ -748,23 +749,33 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana int grid_pin_start_index = physical_tile->num_pins; t_physical_tile_port physical_tile_port; physical_tile_port.num_pins = 0; - for (const t_physical_tile_port& tile_port : physical_tile->ports) { - if (std::string(tile_port.name) == tile_port_to_connect.get_name()) { - BasicPort ref_tile_port(tile_port.name, tile_port.num_pins); - /* Port size must match!!! */ - if (false == ref_tile_port.contained(tile_port_to_connect)) { - VTR_LOG_ERROR("Tile annotation '%s' port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!", - tile_annotation.global_port_name(tile_global_port).c_str(), - tile_port_to_connect.get_name().c_str(), - tile_port_to_connect.get_lsb(), - tile_port_to_connect.get_msb(), - ref_tile_port.get_name().c_str(), - ref_tile_port.get_lsb(), - ref_tile_port.get_msb()); - return CMD_EXEC_FATAL_ERROR; + bool found_tile_port = false; + /* TODO: This part may be buggy. Need to investigate how sub tile organize information. + * For example, how the ports are indexed in each sub tile which is repeated a few time (capacity > 1) */ + for (const t_sub_tile& sub_tile : physical_tile->sub_tiles) { + for (const t_physical_tile_port& tile_port : sub_tile.ports) { + if (std::string(tile_port.name) == tile_port_to_connect.get_name()) { + BasicPort ref_tile_port(tile_port.name, tile_port.num_pins); + /* Port size must match!!! */ + if (false == ref_tile_port.contained(tile_port_to_connect)) { + VTR_LOG_ERROR("Tile annotation '%s' port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!", + tile_annotation.global_port_name(tile_global_port).c_str(), + tile_port_to_connect.get_name().c_str(), + tile_port_to_connect.get_lsb(), + tile_port_to_connect.get_msb(), + ref_tile_port.get_name().c_str(), + ref_tile_port.get_lsb(), + ref_tile_port.get_msb()); + return CMD_EXEC_FATAL_ERROR; + } + grid_pin_start_index = tile_port.absolute_first_pin_index; + physical_tile_port = tile_port; + found_tile_port = true; + break; } - grid_pin_start_index = tile_port.absolute_first_pin_index; - physical_tile_port = tile_port; + } + /* Found the port, exit early */ + if (found_tile_port) { break; } } @@ -778,8 +789,6 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); size_t grid_instance = grid_instance_ids[grid_coordinate.x()][grid_coordinate.y()]; - VTR_ASSERT(1 == physical_tile->equivalent_sites.size()); - /* Ensure port width is in range */ BasicPort src_port = module_manager.module_port(top_module, top_module_port); VTR_ASSERT(src_port.get_width() == tile_port_to_connect.get_width()); @@ -793,38 +802,41 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana } /* A tile may consist of multiple subtile, connect to all the pins from sub tiles */ - for (int iz = 0; iz < physical_tile->capacity; ++iz) { - for (size_t pin_id = tile_port_to_connect.get_lsb(); pin_id < tile_port_to_connect.get_msb() + 1; ++pin_id) { - /* TODO: This should be replaced by using a pin mapping data structure from physical tile! */ - int grid_pin_index = grid_pin_start_index + iz * physical_tile->equivalent_sites[0]->pb_type->num_pins + pin_id; - /* Find the module pin */ - size_t grid_pin_width = physical_tile->pin_width_offset[grid_pin_index]; - size_t grid_pin_height = physical_tile->pin_height_offset[grid_pin_index]; - std::vector pin_sides = find_physical_tile_pin_side(physical_tile, grid_pin_index, border_side); + for (const t_sub_tile& sub_tile : physical_tile->sub_tiles) { + VTR_ASSERT(1 == sub_tile.equivalent_sites.size()); + for (int iz = 0; iz < sub_tile.capacity.total(); ++iz) { + for (size_t pin_id = tile_port_to_connect.get_lsb(); pin_id < tile_port_to_connect.get_msb() + 1; ++pin_id) { + /* TODO: This should be replaced by using a pin mapping data structure from physical tile! */ + int grid_pin_index = grid_pin_start_index + iz * sub_tile.equivalent_sites[0]->pb_type->num_pins + pin_id; + /* Find the module pin */ + size_t grid_pin_width = physical_tile->pin_width_offset[grid_pin_index]; + size_t grid_pin_height = physical_tile->pin_height_offset[grid_pin_index]; + std::vector pin_sides = find_physical_tile_pin_side(physical_tile, grid_pin_index, border_side); - BasicPort grid_pin_info = vpr_device_annotation.physical_tile_pin_port_info(physical_tile, grid_pin_index); - VTR_ASSERT(true == grid_pin_info.is_valid()); - int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(physical_tile, grid_pin_index); - VTR_ASSERT(OPEN != subtile_index && subtile_index < physical_tile->capacity); + BasicPort grid_pin_info = vpr_device_annotation.physical_tile_pin_port_info(physical_tile, grid_pin_index); + VTR_ASSERT(true == grid_pin_info.is_valid()); + int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(physical_tile, grid_pin_index); + VTR_ASSERT(OPEN != subtile_index && subtile_index < physical_tile->capacity); - /* Build nets */ - for (const e_side& pin_side : pin_sides) { - std::string grid_port_name = generate_grid_port_name(grid_pin_width, grid_pin_height, subtile_index, - pin_side, - grid_pin_info); - ModulePortId grid_port_id = module_manager.find_module_port(grid_module, grid_port_name); - VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module, grid_port_id)); + /* Build nets */ + for (const e_side& pin_side : pin_sides) { + std::string grid_port_name = generate_grid_port_name(grid_pin_width, grid_pin_height, subtile_index, + pin_side, + grid_pin_info); + ModulePortId grid_port_id = module_manager.find_module_port(grid_module, grid_port_name); + VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module, grid_port_id)); - VTR_ASSERT(1 == module_manager.module_port(grid_module, grid_port_id).get_width()); + VTR_ASSERT(1 == module_manager.module_port(grid_module, grid_port_id).get_width()); - ModuleNetId net = create_module_source_pin_net(module_manager, top_module, - top_module, 0, - top_module_port, src_port.pins()[sink2src_pin_map[pin_id]]); - VTR_ASSERT(ModuleNetId::INVALID() != net); - - /* Configure the net sink */ - BasicPort sink_port = module_manager.module_port(grid_module, grid_port_id); - module_manager.add_module_net_sink(top_module, net, grid_module, grid_instance, grid_port_id, sink_port.pins()[0]); + ModuleNetId net = create_module_source_pin_net(module_manager, top_module, + top_module, 0, + top_module_port, src_port.pins()[sink2src_pin_map[pin_id]]); + VTR_ASSERT(ModuleNetId::INVALID() != net); + + /* Configure the net sink */ + BasicPort sink_port = module_manager.module_port(grid_module, grid_port_id); + module_manager.add_module_net_sink(top_module, net, grid_module, grid_instance, grid_port_id, sink_port.pins()[0]); + } } } } diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 465f93bcb..518cfccff 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -708,8 +708,8 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager, * it as a mode under a */ for (size_t z = 0; z < place_annotation.grid_blocks(grid_coord).size(); ++z) { - VTR_ASSERT(1 == grid_type->equivalent_sites.size()); - for (t_logical_block_type_ptr lb_type : grid_type->equivalent_sites) { + VTR_ASSERT(1 == grid_type->sub_tiles[z].equivalent_sites.size()); + for (t_logical_block_type_ptr lb_type : grid_type->sub_tiles[z].equivalent_sites) { /* Bypass empty pb_graph */ if (nullptr == lb_type->pb_graph_head) { continue; diff --git a/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp b/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp index bb65f3757..ecbd79d0b 100644 --- a/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp +++ b/openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp @@ -477,8 +477,8 @@ void print_analysis_sdc_disable_pb_block_unused_resources(std::fstream& fp, VTR_ASSERT(false == physical_pb.empty()); } - VTR_ASSERT(1 == grid_type->equivalent_sites.size()); - t_pb_graph_node* pb_graph_head = grid_type->equivalent_sites[0]->pb_graph_head; + VTR_ASSERT(1 == grid_type->sub_tiles[grid_z].equivalent_sites.size()); + t_pb_graph_node* pb_graph_head = grid_type->sub_tiles[grid_z].equivalent_sites[0]->pb_graph_head; VTR_ASSERT(nullptr != pb_graph_head); /* Find an unique name to the pb instance in this grid diff --git a/openfpga/src/fpga_sdc/analysis_sdc_routing_writer.cpp b/openfpga/src/fpga_sdc/analysis_sdc_routing_writer.cpp index 80793ee80..040a792aa 100644 --- a/openfpga/src/fpga_sdc/analysis_sdc_routing_writer.cpp +++ b/openfpga/src/fpga_sdc/analysis_sdc_routing_writer.cpp @@ -15,6 +15,7 @@ #include "openfpga_reserved_words.h" #include "openfpga_naming.h" +#include "openfpga_rr_graph_utils.h" #include "build_routing_module_utils.h" #include "sdc_writer_utils.h" @@ -131,7 +132,7 @@ void print_analysis_sdc_disable_cb_unused_resources(std::fstream& fp, RRNodeId ipin_node = rr_gsb.get_ipin_node(cb_ipin_side, inode); /* Find the MUX instance that drives the IPIN! */ - std::string mux_instance_name = generate_cb_mux_instance_name(CONNECTION_BLOCK_MUX_INSTANCE_PREFIX, rr_graph.node_side(ipin_node), inode, std::string("")); + std::string mux_instance_name = generate_cb_mux_instance_name(CONNECTION_BLOCK_MUX_INSTANCE_PREFIX, get_rr_graph_single_node_side(rr_graph, ipin_node), inode, std::string("")); mux_instance_to_net_map[mux_instance_name] = atom_ctx.lookup.atom_net(routing_annotation.rr_node_net(ipin_node)); if (false == is_rr_node_to_be_disable_for_analysis(routing_annotation, ipin_node)) { @@ -390,7 +391,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp, const RRNodeId& opin_node = rr_gsb.get_opin_node(side_manager.get_side(), inode); std::string port_name = generate_sb_module_grid_port_name(side_manager.get_side(), - rr_graph.node_side(opin_node), + get_rr_graph_single_node_side(rr_graph, opin_node), grids, device_annotation, rr_graph, @@ -403,7 +404,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp, const RRNodeId& unique_mirror_opin_node = unique_mirror.get_opin_node(side_manager.get_side(), inode); port_name = generate_sb_module_grid_port_name(side_manager.get_side(), - rr_graph.node_side(unique_mirror_opin_node), + get_rr_graph_single_node_side(rr_graph, unique_mirror_opin_node), grids, device_annotation, rr_graph, @@ -458,7 +459,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp, const RRNodeId& opin_node = rr_gsb.get_opin_node(side_manager.get_side(), inode); std::string port_name = generate_sb_module_grid_port_name(side_manager.get_side(), - rr_graph.node_side(opin_node), + get_rr_graph_single_node_side(rr_graph, opin_node), grids, device_annotation, rr_graph, @@ -471,7 +472,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp, const RRNodeId& unique_mirror_opin_node = unique_mirror.get_opin_node(side_manager.get_side(), inode); port_name = generate_sb_module_grid_port_name(side_manager.get_side(), - rr_graph.node_side(unique_mirror_opin_node), + get_rr_graph_single_node_side(rr_graph, unique_mirror_opin_node), grids, device_annotation, rr_graph, diff --git a/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp b/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp index 9061142d9..aae71c2a9 100644 --- a/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp +++ b/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp @@ -117,7 +117,7 @@ void print_analysis_sdc_io_delays(std::fstream& fp, /* Find the index of the mapped GPIO in top-level FPGA fabric */ size_t io_index = io_location_map.io_index(place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.x, place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.y, - place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.z, + place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.sub_tile, module_io_port.get_name()); if (size_t(-1) == io_index) { diff --git a/openfpga/src/fpga_sdc/pnr_sdc_grid_writer.cpp b/openfpga/src/fpga_sdc/pnr_sdc_grid_writer.cpp index 37e9cc5a6..8d945003e 100644 --- a/openfpga/src/fpga_sdc/pnr_sdc_grid_writer.cpp +++ b/openfpga/src/fpga_sdc/pnr_sdc_grid_writer.cpp @@ -536,31 +536,51 @@ void print_pnr_sdc_constrain_grid_timing(const PnrSdcOption& options, continue; } - VTR_ASSERT(1 == physical_tile.equivalent_sites.size()); - t_pb_graph_node* pb_graph_head = physical_tile.equivalent_sites[0]->pb_graph_head; - if (nullptr == pb_graph_head) { - continue; - } + for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) { + VTR_ASSERT(1 == sub_tile.equivalent_sites.size()); + t_pb_graph_node* pb_graph_head = sub_tile.equivalent_sites[0]->pb_graph_head; + if (nullptr == pb_graph_head) { + continue; + } - if (true == is_io_type(&physical_tile)) { - /* Special for I/O block: - * We will search the grids and see where the I/O blocks are located: - * - If a I/O block locates on border sides of FPGA fabric: - * i.e., one or more from {TOP, RIGHT, BOTTOM, LEFT}, - * we will generate one module for each border side - * - If a I/O block locates in the center of FPGA fabric: - * we will generate one module with NUM_SIDES (same treatment as regular grids) - */ - std::set io_type_sides = find_physical_io_tile_located_sides(device_ctx.grid, - &physical_tile); + if (true == is_io_type(&physical_tile)) { + /* Special for I/O block: + * We will search the grids and see where the I/O blocks are located: + * - If a I/O block locates on border sides of FPGA fabric: + * i.e., one or more from {TOP, RIGHT, BOTTOM, LEFT}, + * we will generate one module for each border side + * - If a I/O block locates in the center of FPGA fabric: + * we will generate one module with NUM_SIDES (same treatment as regular grids) + */ + std::set io_type_sides = find_physical_io_tile_located_sides(device_ctx.grid, + &physical_tile); - /* Generate the grid module name */ - for (const e_side& io_type_side : io_type_sides) { + /* Generate the grid module name */ + for (const e_side& io_type_side : io_type_sides) { + std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), + std::string(physical_tile.name), + is_io_type(&physical_tile), + io_type_side); + /* Find the module Id */ + ModuleId grid_module = module_manager.find_module(grid_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); + + std::string module_path = format_dir_path(root_path + grid_module_name); + module_path = format_dir_path(module_path + generate_physical_block_instance_name(pb_graph_head->pb_type, pb_graph_head->placement_index)); + + rec_print_pnr_sdc_constrain_pb_graph_timing(options, + module_path, + module_manager, + device_annotation, + pb_graph_head); + } + } else { + /* For CLB and heterogenenous blocks */ std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), std::string(physical_tile.name), is_io_type(&physical_tile), - io_type_side); + NUM_SIDES); /* Find the module Id */ ModuleId grid_module = module_manager.find_module(grid_module_name); VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); @@ -574,24 +594,6 @@ void print_pnr_sdc_constrain_grid_timing(const PnrSdcOption& options, device_annotation, pb_graph_head); } - } else { - /* For CLB and heterogenenous blocks */ - std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), - std::string(physical_tile.name), - is_io_type(&physical_tile), - NUM_SIDES); - /* Find the module Id */ - ModuleId grid_module = module_manager.find_module(grid_module_name); - VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); - - std::string module_path = format_dir_path(root_path + grid_module_name); - module_path = format_dir_path(module_path + generate_physical_block_instance_name(pb_graph_head->pb_type, pb_graph_head->placement_index)); - - rec_print_pnr_sdc_constrain_pb_graph_timing(options, - module_path, - module_manager, - device_annotation, - pb_graph_head); } } } diff --git a/openfpga/src/fpga_sdc/pnr_sdc_routing_writer.cpp b/openfpga/src/fpga_sdc/pnr_sdc_routing_writer.cpp index df6320d46..fd03159e4 100644 --- a/openfpga/src/fpga_sdc/pnr_sdc_routing_writer.cpp +++ b/openfpga/src/fpga_sdc/pnr_sdc_routing_writer.cpp @@ -92,7 +92,7 @@ void print_pnr_sdc_constrain_sb_mux_timing(std::fstream& fp, for (const RREdgeId& edge : rr_graph.node_configurable_in_edges(output_rr_node)) { /* Get the switch delay */ const RRSwitchId& driver_switch = rr_graph.edge_switch(edge); - switch_delays[module_input_ports[edge_counter]] = find_pnr_sdc_switch_tmax(rr_graph.get_switch(driver_switch)); + switch_delays[module_input_ports[edge_counter]] = find_pnr_sdc_switch_tmax(rr_graph.rr_switch_inf(driver_switch)); edge_counter++; } @@ -368,7 +368,7 @@ void print_pnr_sdc_constrain_cb_mux_timing(std::fstream& fp, for (const RREdgeId& edge : rr_graph.node_configurable_in_edges(output_rr_node)) { /* Get the switch delay */ const RRSwitchId& driver_switch = rr_graph.edge_switch(edge); - switch_delays[module_input_ports[edge_counter]] = find_pnr_sdc_switch_tmax(rr_graph.get_switch(driver_switch)); + switch_delays[module_input_ports[edge_counter]] = find_pnr_sdc_switch_tmax(rr_graph.rr_switch_inf(driver_switch)); edge_counter++; } @@ -477,8 +477,8 @@ void print_pnr_sdc_constrain_cb_timing(const PnrSdcOption& options, * TODO: Should consider multi-level RC delay models * where the number of levels are defined by users */ - float routing_segment_delay = rr_graph.get_segment(segment_id).Rmetal - * rr_graph.get_segment(segment_id).Cmetal; + float routing_segment_delay = rr_graph.rr_segments(segment_id).Rmetal + * rr_graph.rr_segments(segment_id).Cmetal; /* If we have a zero-delay path to contrain, we will skip unless users want so */ if ( (false == constrain_zero_delay_paths) diff --git a/openfpga/src/fpga_sdc/sdc_hierarchy_writer.cpp b/openfpga/src/fpga_sdc/sdc_hierarchy_writer.cpp index 49214aaa3..e7f23917d 100644 --- a/openfpga/src/fpga_sdc/sdc_hierarchy_writer.cpp +++ b/openfpga/src/fpga_sdc/sdc_hierarchy_writer.cpp @@ -295,31 +295,59 @@ void print_pnr_sdc_grid_hierarchy(const std::string& sdc_dir, continue; } - VTR_ASSERT(1 == physical_tile.equivalent_sites.size()); - t_pb_graph_node* pb_graph_head = physical_tile.equivalent_sites[0]->pb_graph_head; - if (nullptr == pb_graph_head) { - continue; - } + for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) { + VTR_ASSERT(1 == sub_tile.equivalent_sites.size()); + t_pb_graph_node* pb_graph_head = sub_tile.equivalent_sites[0]->pb_graph_head; + if (nullptr == pb_graph_head) { + continue; + } - if (true == is_io_type(&physical_tile)) { - /* Special for I/O block: - * We will search the grids and see where the I/O blocks are located: - * - If a I/O block locates on border sides of FPGA fabric: - * i.e., one or more from {TOP, RIGHT, BOTTOM, LEFT}, - * we will generate one module for each border side - * - If a I/O block locates in the center of FPGA fabric: - * we will generate one module with NUM_SIDES (same treatment as regular grids) - */ - std::set io_type_sides = find_physical_io_tile_located_sides(device_ctx.grid, - &physical_tile); + if (true == is_io_type(&physical_tile)) { + /* Special for I/O block: + * We will search the grids and see where the I/O blocks are located: + * - If a I/O block locates on border sides of FPGA fabric: + * i.e., one or more from {TOP, RIGHT, BOTTOM, LEFT}, + * we will generate one module for each border side + * - If a I/O block locates in the center of FPGA fabric: + * we will generate one module with NUM_SIDES (same treatment as regular grids) + */ + std::set io_type_sides = find_physical_io_tile_located_sides(device_ctx.grid, + &physical_tile); - /* Generate the grid module name */ - for (const e_side& io_type_side : io_type_sides) { + /* Generate the grid module name */ + for (const e_side& io_type_side : io_type_sides) { + std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), + std::string(physical_tile.name), + is_io_type(&physical_tile), + io_type_side); + /* Find the module Id */ + ModuleId grid_module = module_manager.find_module(grid_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); + + fp << "- " << grid_module_name << ":" << "\n"; + + /* Go through all the instance */ + for (const size_t& instance_id : module_manager.child_module_instances(top_module, grid_module)) { + std::string grid_instance_name = module_manager.instance_name(top_module, grid_module, instance_id); + fp << " "; + fp << "- " << grid_instance_name << ":" << "\n"; + + rec_print_pnr_sdc_grid_pb_graph_hierarchy(fp, + 2, + module_manager, + grid_module, + device_annotation, + pb_graph_head); + } + fp << "\n"; + } + } else { + /* For CLB and heterogenenous blocks */ std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), std::string(physical_tile.name), is_io_type(&physical_tile), - io_type_side); + NUM_SIDES); /* Find the module Id */ ModuleId grid_module = module_manager.find_module(grid_module_name); VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); @@ -340,36 +368,7 @@ void print_pnr_sdc_grid_hierarchy(const std::string& sdc_dir, pb_graph_head); } fp << "\n"; - } - } else { - /* For CLB and heterogenenous blocks */ - std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), - std::string(physical_tile.name), - is_io_type(&physical_tile), - NUM_SIDES); - /* Find the module Id */ - ModuleId grid_module = module_manager.find_module(grid_module_name); - VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); - - fp << "- " << grid_module_name << ":" << "\n"; - - /* Go through all the instance */ - for (const size_t& instance_id : module_manager.child_module_instances(top_module, grid_module)) { - std::string grid_instance_name = module_manager.instance_name(top_module, grid_module, instance_id); - fp << " "; - fp << "- " << grid_instance_name << ":" << "\n"; - - rec_print_pnr_sdc_grid_pb_graph_hierarchy(fp, - 2, - module_manager, - grid_module, - device_annotation, - pb_graph_head); - } - - fp << "\n"; - } } diff --git a/openfpga/src/fpga_sdc/sdc_writer_naming.h b/openfpga/src/fpga_sdc/sdc_writer_naming.h index 17126f98b..58cfdac8c 100644 --- a/openfpga/src/fpga_sdc/sdc_writer_naming.h +++ b/openfpga/src/fpga_sdc/sdc_writer_naming.h @@ -4,21 +4,21 @@ /* begin namespace openfpga */ namespace openfpga { -constexpr char* SDC_FILE_NAME_POSTFIX = ".sdc"; +constexpr const char* SDC_FILE_NAME_POSTFIX = ".sdc"; -constexpr char* SDC_GLOBAL_PORTS_FILE_NAME = "global_ports.sdc"; -constexpr char* SDC_BENCHMARK_ANALYSIS_FILE_NAME= "fpga_top_analysis.sdc"; -constexpr char* SDC_DISABLE_CONFIG_MEM_OUTPUTS_FILE_NAME = "disable_configurable_memory_outputs.sdc"; -constexpr char* SDC_DISABLE_MUX_OUTPUTS_FILE_NAME = "disable_routing_multiplexer_outputs.sdc"; -constexpr char* SDC_DISABLE_SB_OUTPUTS_FILE_NAME = "disable_sb_outputs.sdc"; -constexpr char* SDC_CB_FILE_NAME = "cb.sdc"; +constexpr const char* SDC_GLOBAL_PORTS_FILE_NAME = "global_ports.sdc"; +constexpr const char* SDC_BENCHMARK_ANALYSIS_FILE_NAME= "fpga_top_analysis.sdc"; +constexpr const char* SDC_DISABLE_CONFIG_MEM_OUTPUTS_FILE_NAME = "disable_configurable_memory_outputs.sdc"; +constexpr const char* SDC_DISABLE_MUX_OUTPUTS_FILE_NAME = "disable_routing_multiplexer_outputs.sdc"; +constexpr const char* SDC_DISABLE_SB_OUTPUTS_FILE_NAME = "disable_sb_outputs.sdc"; +constexpr const char* SDC_CB_FILE_NAME = "cb.sdc"; -constexpr char* SDC_GRID_HIERARCHY_FILE_NAME = "grid_hierarchy.txt"; -constexpr char* SDC_SB_HIERARCHY_FILE_NAME = "sb_hierarchy.txt"; -constexpr char* SDC_CBX_HIERARCHY_FILE_NAME = "cbx_hierarchy.txt"; -constexpr char* SDC_CBY_HIERARCHY_FILE_NAME = "cby_hierarchy.txt"; +constexpr const char* SDC_GRID_HIERARCHY_FILE_NAME = "grid_hierarchy.txt"; +constexpr const char* SDC_SB_HIERARCHY_FILE_NAME = "sb_hierarchy.txt"; +constexpr const char* SDC_CBX_HIERARCHY_FILE_NAME = "cbx_hierarchy.txt"; +constexpr const char* SDC_CBY_HIERARCHY_FILE_NAME = "cby_hierarchy.txt"; -constexpr char* SDC_ANALYSIS_FILE_NAME = "fpga_top_analysis.sdc"; +constexpr const char* SDC_ANALYSIS_FILE_NAME = "fpga_top_analysis.sdc"; } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_constants.h b/openfpga/src/fpga_verilog/verilog_constants.h index 3c164feee..75e8c3c68 100644 --- a/openfpga/src/fpga_verilog/verilog_constants.h +++ b/openfpga/src/fpga_verilog/verilog_constants.h @@ -3,47 +3,47 @@ /* global parameters for dumping synthesizable verilog */ -constexpr char* VERILOG_NETLIST_FILE_POSTFIX = ".v"; +constexpr const char* VERILOG_NETLIST_FILE_POSTFIX = ".v"; constexpr float VERILOG_SIM_TIMESCALE = 1e-9; // Verilog Simulation time scale (minimum time unit) : 1ns -constexpr char* VERILOG_TIMING_PREPROC_FLAG = "ENABLE_TIMING"; // the flag to enable timing definition during compilation -constexpr char* MODELSIM_SIMULATION_TIME_UNIT = "ms"; +constexpr const char* VERILOG_TIMING_PREPROC_FLAG = "ENABLE_TIMING"; // the flag to enable timing definition during compilation +constexpr const char* MODELSIM_SIMULATION_TIME_UNIT = "ms"; -constexpr char* FABRIC_INCLUDE_VERILOG_NETLIST_FILE_NAME = "fabric_netlists.v"; -constexpr char* TOP_VERILOG_TESTBENCH_INCLUDE_NETLIST_FILE_NAME_POSTFIX = "_include_netlists.v"; -constexpr char* VERILOG_TOP_POSTFIX = "_top.v"; -constexpr char* FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX = "_top_formal_verification.v"; -constexpr char* TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_top_tb.v"; /* !!! must be consist with the modelsim_testbench_module_postfix */ -constexpr char* AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_autocheck_top_tb.v"; /* !!! must be consist with the modelsim_autocheck_testbench_module_postfix */ -constexpr char* RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_formal_random_top_tb.v"; -constexpr char* DEFINES_VERILOG_FILE_NAME = "fpga_defines.v"; -constexpr char* SUBMODULE_VERILOG_FILE_NAME = "sub_module.v"; -constexpr char* LOGIC_BLOCK_VERILOG_FILE_NAME = "logic_blocks.v"; -constexpr char* LUTS_VERILOG_FILE_NAME = "luts.v"; -constexpr char* ROUTING_VERILOG_FILE_NAME = "routing.v"; -constexpr char* MUX_PRIMITIVES_VERILOG_FILE_NAME = "mux_primitives.v"; -constexpr char* MUXES_VERILOG_FILE_NAME = "muxes.v"; -constexpr char* LOCAL_ENCODER_VERILOG_FILE_NAME = "local_encoder.v"; -constexpr char* ARCH_ENCODER_VERILOG_FILE_NAME = "arch_encoder.v"; -constexpr char* MEMORIES_VERILOG_FILE_NAME = "memories.v"; -constexpr char* SHIFT_REGISTER_BANKS_VERILOG_FILE_NAME = "shift_register_banks.v"; -constexpr char* WIRES_VERILOG_FILE_NAME = "wires.v"; -constexpr char* ESSENTIALS_VERILOG_FILE_NAME = "inv_buf_passgate.v"; -constexpr char* CONFIG_PERIPHERAL_VERILOG_FILE_NAME = "config_peripherals.v"; -constexpr char* USER_DEFINED_TEMPLATE_VERILOG_FILE_NAME = "user_defined_templates.v"; +constexpr const char* FABRIC_INCLUDE_VERILOG_NETLIST_FILE_NAME = "fabric_netlists.v"; +constexpr const char* TOP_VERILOG_TESTBENCH_INCLUDE_NETLIST_FILE_NAME_POSTFIX = "_include_netlists.v"; +constexpr const char* VERILOG_TOP_POSTFIX = "_top.v"; +constexpr const char* FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX = "_top_formal_verification.v"; +constexpr const char* TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_top_tb.v"; /* !!! must be consist with the modelsim_testbench_module_postfix */ +constexpr const char* AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_autocheck_top_tb.v"; /* !!! must be consist with the modelsim_autocheck_testbench_module_postfix */ +constexpr const char* RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_formal_random_top_tb.v"; +constexpr const char* DEFINES_VERILOG_FILE_NAME = "fpga_defines.v"; +constexpr const char* SUBMODULE_VERILOG_FILE_NAME = "sub_module.v"; +constexpr const char* LOGIC_BLOCK_VERILOG_FILE_NAME = "logic_blocks.v"; +constexpr const char* LUTS_VERILOG_FILE_NAME = "luts.v"; +constexpr const char* ROUTING_VERILOG_FILE_NAME = "routing.v"; +constexpr const char* MUX_PRIMITIVES_VERILOG_FILE_NAME = "mux_primitives.v"; +constexpr const char* MUXES_VERILOG_FILE_NAME = "muxes.v"; +constexpr const char* LOCAL_ENCODER_VERILOG_FILE_NAME = "local_encoder.v"; +constexpr const char* ARCH_ENCODER_VERILOG_FILE_NAME = "arch_encoder.v"; +constexpr const char* MEMORIES_VERILOG_FILE_NAME = "memories.v"; +constexpr const char* SHIFT_REGISTER_BANKS_VERILOG_FILE_NAME = "shift_register_banks.v"; +constexpr const char* WIRES_VERILOG_FILE_NAME = "wires.v"; +constexpr const char* ESSENTIALS_VERILOG_FILE_NAME = "inv_buf_passgate.v"; +constexpr const char* CONFIG_PERIPHERAL_VERILOG_FILE_NAME = "config_peripherals.v"; +constexpr const char* USER_DEFINED_TEMPLATE_VERILOG_FILE_NAME = "user_defined_templates.v"; -constexpr char* VERILOG_MUX_BASIS_POSTFIX = "_basis"; -constexpr char* VERILOG_MEM_POSTFIX = "_mem"; +constexpr const char* VERILOG_MUX_BASIS_POSTFIX = "_basis"; +constexpr const char* VERILOG_MEM_POSTFIX = "_mem"; -constexpr char* SB_VERILOG_FILE_NAME_PREFIX = "sb_"; -constexpr char* LOGICAL_MODULE_VERILOG_FILE_NAME_PREFIX = "logical_tile_"; -constexpr char* GRID_VERILOG_FILE_NAME_PREFIX = "grid_"; +constexpr const char* SB_VERILOG_FILE_NAME_PREFIX = "sb_"; +constexpr const char* LOGICAL_MODULE_VERILOG_FILE_NAME_PREFIX = "logical_tile_"; +constexpr const char* GRID_VERILOG_FILE_NAME_PREFIX = "grid_"; -constexpr char* FORMAL_VERIFICATION_TOP_MODULE_POSTFIX = "_top_formal_verification"; -constexpr char* FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX = "_fm"; -constexpr char* FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME = "U0_formal_verification"; +constexpr const char* FORMAL_VERIFICATION_TOP_MODULE_POSTFIX = "_top_formal_verification"; +constexpr const char* FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX = "_fm"; +constexpr const char* FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME = "U0_formal_verification"; -constexpr char* FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX = "_top_formal_verification_random_tb"; +constexpr const char* FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX = "_top_formal_verification_random_tb"; #define VERILOG_DEFAULT_SIGNAL_INIT_VALUE 0 diff --git a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp index d044064c8..ac7bed10b 100644 --- a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp @@ -33,14 +33,14 @@ namespace openfpga { /******************************************************************** * Local variables used only in this file *******************************************************************/ -constexpr char* FPGA_PORT_POSTFIX = "_gfpga"; -constexpr char* BENCHMARK_PORT_POSTFIX = "_bench"; -constexpr char* CHECKFLAG_PORT_POSTFIX = "_flag"; -constexpr char* DEFAULT_CLOCK_NAME = "clk"; -constexpr char* BENCHMARK_INSTANCE_NAME = "REF_DUT"; -constexpr char* FPGA_INSTANCE_NAME = "FPGA_DUT"; -constexpr char* ERROR_COUNTER = "nb_error"; -constexpr char* FORMAL_TB_SIM_START_PORT_NAME = "sim_start"; +constexpr const char* FPGA_PORT_POSTFIX = "_gfpga"; +constexpr const char* BENCHMARK_PORT_POSTFIX = "_bench"; +constexpr const char* CHECKFLAG_PORT_POSTFIX = "_flag"; +constexpr const char* DEFAULT_CLOCK_NAME = "clk"; +constexpr const char* BENCHMARK_INSTANCE_NAME = "REF_DUT"; +constexpr const char* FPGA_INSTANCE_NAME = "FPGA_DUT"; +constexpr const char* ERROR_COUNTER = "nb_error"; +constexpr const char* FORMAL_TB_SIM_START_PORT_NAME = "sim_start"; /******************************************************************** * Print the module ports for the Verilog testbench diff --git a/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp b/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp index 9ed82a131..7f85918a7 100644 --- a/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp +++ b/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp @@ -136,7 +136,7 @@ void print_verilog_simulation_info(const std::string& ini_fname, /* Find the index of the mapped GPIO in top-level FPGA fabric */ size_t io_index = io_location_map.io_index(place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.x, place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.y, - place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.z, + place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.sub_tile, module_io_port.get_name()); if (size_t(-1) == io_index) { diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index e566c8fb7..bfa53df80 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -314,7 +314,7 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, /* Find the index of the mapped GPIO in top-level FPGA fabric */ size_t temp_io_index = io_location_map.io_index(place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.x, place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.y, - place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.z, + place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.sub_tile, module_io_port.get_name()); /* Bypass invalid index (not mapped to this GPIO port) */ diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench_constants.h b/openfpga/src/fpga_verilog/verilog_top_testbench_constants.h index 5dbb83003..61aab06ac 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench_constants.h +++ b/openfpga/src/fpga_verilog/verilog_top_testbench_constants.h @@ -4,38 +4,38 @@ /* begin namespace openfpga */ namespace openfpga { -constexpr char* TOP_TESTBENCH_REFERENCE_INSTANCE_NAME = "REF_DUT"; -constexpr char* TOP_TESTBENCH_FPGA_INSTANCE_NAME = "FPGA_DUT"; -constexpr char* TOP_TESTBENCH_SHARED_INPUT_POSTFIX = "_shared_input"; -constexpr char* TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX = "_benchmark"; -constexpr char* TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX = "_fpga"; +constexpr const char* TOP_TESTBENCH_REFERENCE_INSTANCE_NAME = "REF_DUT"; +constexpr const char* TOP_TESTBENCH_FPGA_INSTANCE_NAME = "FPGA_DUT"; +constexpr const char* TOP_TESTBENCH_SHARED_INPUT_POSTFIX = "_shared_input"; +constexpr const char* TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX = "_benchmark"; +constexpr const char* TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX = "_fpga"; -constexpr char* TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX = "_flag"; +constexpr const char* TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX = "_flag"; -constexpr char* TOP_TESTBENCH_PROG_TASK_NAME = "prog_cycle_task"; +constexpr const char* TOP_TESTBENCH_PROG_TASK_NAME = "prog_cycle_task"; -constexpr char* TOP_TESTBENCH_SIM_START_PORT_NAME = "sim_start"; +constexpr const char* TOP_TESTBENCH_SIM_START_PORT_NAME = "sim_start"; -constexpr char* TOP_TESTBENCH_ERROR_COUNTER = "nb_error"; +constexpr const char* TOP_TESTBENCH_ERROR_COUNTER = "nb_error"; -constexpr char* TOP_TB_RESET_PORT_NAME = "__greset__"; -constexpr char* TOP_TB_SET_PORT_NAME = "__gset__"; -constexpr char* TOP_TB_PROG_RESET_PORT_NAME = "__prog_reset__"; -constexpr char* TOP_TB_PROG_SET_PORT_NAME = "__prog_set_"; -constexpr char* TOP_TB_CONFIG_DONE_PORT_NAME = "__config_done__"; -constexpr char* TOP_TB_OP_CLOCK_PORT_NAME = "__op_clock__"; -constexpr char* TOP_TB_OP_CLOCK_PORT_PREFIX = "__operating_clk_"; -constexpr char* TOP_TB_PROG_CLOCK_PORT_NAME = "__prog_clock__"; -constexpr char* TOP_TB_INOUT_REG_POSTFIX = "_reg__"; -constexpr char* TOP_TB_CLOCK_REG_POSTFIX = "_reg__"; -constexpr char* TOP_TB_BITSTREAM_LENGTH_VARIABLE = "BITSTREAM_LENGTH"; -constexpr char* TOP_TB_BITSTREAM_WIDTH_VARIABLE = "BITSTREAM_WIDTH"; -constexpr char* TOP_TB_BITSTREAM_MEM_REG_NAME = "bit_mem"; -constexpr char* TOP_TB_BITSTREAM_INDEX_REG_NAME = "bit_index"; -constexpr char* TOP_TB_BITSTREAM_ITERATOR_REG_NAME = "ibit"; -constexpr char* TOP_TB_BITSTREAM_SKIP_FLAG_REG_NAME = "skip_bits"; +constexpr const char* TOP_TB_RESET_PORT_NAME = "__greset__"; +constexpr const char* TOP_TB_SET_PORT_NAME = "__gset__"; +constexpr const char* TOP_TB_PROG_RESET_PORT_NAME = "__prog_reset__"; +constexpr const char* TOP_TB_PROG_SET_PORT_NAME = "__prog_set_"; +constexpr const char* TOP_TB_CONFIG_DONE_PORT_NAME = "__config_done__"; +constexpr const char* TOP_TB_OP_CLOCK_PORT_NAME = "__op_clock__"; +constexpr const char* TOP_TB_OP_CLOCK_PORT_PREFIX = "__operating_clk_"; +constexpr const char* TOP_TB_PROG_CLOCK_PORT_NAME = "__prog_clock__"; +constexpr const char* TOP_TB_INOUT_REG_POSTFIX = "_reg__"; +constexpr const char* TOP_TB_CLOCK_REG_POSTFIX = "_reg__"; +constexpr const char* TOP_TB_BITSTREAM_LENGTH_VARIABLE = "BITSTREAM_LENGTH"; +constexpr const char* TOP_TB_BITSTREAM_WIDTH_VARIABLE = "BITSTREAM_WIDTH"; +constexpr const char* TOP_TB_BITSTREAM_MEM_REG_NAME = "bit_mem"; +constexpr const char* TOP_TB_BITSTREAM_INDEX_REG_NAME = "bit_index"; +constexpr const char* TOP_TB_BITSTREAM_ITERATOR_REG_NAME = "ibit"; +constexpr const char* TOP_TB_BITSTREAM_SKIP_FLAG_REG_NAME = "skip_bits"; -constexpr char* AUTOCHECK_TOP_TESTBENCH_VERILOG_MODULE_POSTFIX = "_autocheck_top_tb"; +constexpr const char* AUTOCHECK_TOP_TESTBENCH_VERILOG_MODULE_POSTFIX = "_autocheck_top_tb"; } /* end namespace openfpga */ diff --git a/openfpga/src/mux_lib/mux_library_builder.cpp b/openfpga/src/mux_lib/mux_library_builder.cpp index 599914de8..dca8823b0 100644 --- a/openfpga/src/mux_lib/mux_library_builder.cpp +++ b/openfpga/src/mux_lib/mux_library_builder.cpp @@ -29,7 +29,7 @@ namespace openfpga { * found in the global routing architecture *******************************************************************/ static -void build_routing_arch_mux_library(const DeviceContext& vpr_device_ctx, +void build_routing_arch_mux_library(const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const VprDeviceAnnotation& vpr_device_annotation, MuxLibrary& mux_lib) { @@ -39,31 +39,32 @@ void build_routing_arch_mux_library(const DeviceContext& vpr_device_ctx, * for the rest is a switch box */ /* Count the sizes of muliplexers in routing architecture */ - for (const RRNodeId& node : vpr_device_ctx.rr_graph.nodes()) { - switch (vpr_device_ctx.rr_graph.node_type(node)) { + for (const RRNodeId& node : rr_graph.nodes()) { + switch (rr_graph.node_type(node)) { case IPIN: case CHANX: case CHANY: { /* Have to consider the fan_in only, it is a connection block (multiplexer)*/ - if ( (0 == vpr_device_ctx.rr_graph.node_in_edges(node).size()) - || (1 == vpr_device_ctx.rr_graph.node_in_edges(node).size()) ) { + if ( (0 == rr_graph.node_in_edges(node).size()) + || (1 == rr_graph.node_in_edges(node).size()) ) { break; } /* Find the circuit_model for multiplexers in connection blocks */ - std::vector driver_switches = get_rr_graph_driver_switches(vpr_device_ctx.rr_graph, node); + std::vector driver_switches = get_rr_graph_driver_switches(rr_graph, node); VTR_ASSERT(1 == driver_switches.size()); const CircuitModelId& rr_switch_circuit_model = vpr_device_annotation.rr_switch_circuit_model(driver_switches[0]); /* we should select a circuit model for the routing resource switch */ if (CircuitModelId::INVALID() == rr_switch_circuit_model) { - VTR_LOG_ERROR("Unable to find the circuit mode for rr_switch '%s'!\n", - vpr_device_ctx.rr_graph.get_switch(driver_switches[0]).name); - vpr_device_ctx.rr_graph.print_node(node); + VTR_LOG_ERROR("Unable to find the circuit model for rr_switch '%s'!\n", + rr_graph.rr_switch_inf(driver_switches[0]).name); + VTR_LOG("Node type: %s\n", rr_graph.node_type_string(node)); + VTR_LOG("Node coordinate: %s\n", rr_graph.node_coordinate_to_string(node)); exit(1); } VTR_ASSERT(CircuitModelId::INVALID() != rr_switch_circuit_model); /* Add the mux to mux_library */ - mux_lib.add_mux(circuit_lib, rr_switch_circuit_model, vpr_device_ctx.rr_graph.node_in_edges(node).size()); + mux_lib.add_mux(circuit_lib, rr_switch_circuit_model, rr_graph.node_in_edges(node).size()); break; } default: @@ -206,7 +207,7 @@ MuxLibrary build_device_mux_library(const DeviceContext& vpr_device_ctx, MuxLibrary mux_lib; /* Step 1: We should check the multiplexer spice models defined in routing architecture.*/ - build_routing_arch_mux_library(vpr_device_ctx, openfpga_ctx.arch().circuit_lib, + build_routing_arch_mux_library(vpr_device_ctx.rr_graph, openfpga_ctx.arch().circuit_lib, openfpga_ctx.vpr_device_annotation(), mux_lib); diff --git a/openfpga/src/tile_direct/build_tile_direct.cpp b/openfpga/src/tile_direct/build_tile_direct.cpp index 5e33bc502..361b3bb4d 100644 --- a/openfpga/src/tile_direct/build_tile_direct.cpp +++ b/openfpga/src/tile_direct/build_tile_direct.cpp @@ -90,13 +90,38 @@ std::vector find_physical_tile_pin_id(t_physical_tile_type_ptr physical_ std::vector pin_ids; /* Walk through the port of the tile */ - for (const t_physical_tile_port& physical_tile_port : physical_tile->ports) { - if (std::string(physical_tile_port.name) != tile_port.get_name()) { - continue; - } - /* If the wanted port is invalid, it assumes that we want the full port */ - if (false == tile_port.is_valid()) { - for (int ipin = 0; ipin < physical_tile_port.num_pins; ++ipin) { + for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) { + for (const t_physical_tile_port& physical_tile_port : sub_tile.ports) { + if (std::string(physical_tile_port.name) != tile_port.get_name()) { + continue; + } + /* If the wanted port is invalid, it assumes that we want the full port */ + if (false == tile_port.is_valid()) { + for (int ipin = 0; ipin < physical_tile_port.num_pins; ++ipin) { + int pin_id = physical_tile_port.absolute_first_pin_index + ipin; + VTR_ASSERT(pin_id < physical_tile->num_pins); + /* Check if the pin is located on the wanted side */ + if (true == is_pin_locate_at_physical_tile_side(physical_tile, + pin_width_offset, + pin_height_offset, + pin_id, pin_side)) { + pin_ids.push_back(pin_id); + } + } + continue; + } + /* Find the LSB and MSB of the pin */ + VTR_ASSERT_SAFE(true == tile_port.is_valid()); + BasicPort ref_port(physical_tile_port.name, physical_tile_port.num_pins); + if (false == ref_port.contained(tile_port)) { + VTR_LOG_ERROR("Defined direct port '%s[%lu:%lu]' is out of range for physical port '%s[%lu:%lu]'!\n", + tile_port.get_name().c_str(), + tile_port.get_lsb(), tile_port.get_msb(), + ref_port.get_name().c_str(), + ref_port.get_lsb(), ref_port.get_msb()); + exit(1); + } + for (const size_t& ipin : tile_port.pins()) { int pin_id = physical_tile_port.absolute_first_pin_index + ipin; VTR_ASSERT(pin_id < physical_tile->num_pins); /* Check if the pin is located on the wanted side */ @@ -104,33 +129,10 @@ std::vector find_physical_tile_pin_id(t_physical_tile_type_ptr physical_ pin_width_offset, pin_height_offset, pin_id, pin_side)) { + pin_ids.push_back(pin_id); } } - continue; - } - /* Find the LSB and MSB of the pin */ - VTR_ASSERT_SAFE(true == tile_port.is_valid()); - BasicPort ref_port(physical_tile_port.name, physical_tile_port.num_pins); - if (false == ref_port.contained(tile_port)) { - VTR_LOG_ERROR("Defined direct port '%s[%lu:%lu]' is out of range for physical port '%s[%lu:%lu]'!\n", - tile_port.get_name().c_str(), - tile_port.get_lsb(), tile_port.get_msb(), - ref_port.get_name().c_str(), - ref_port.get_lsb(), ref_port.get_msb()); - exit(1); - } - for (const size_t& ipin : tile_port.pins()) { - int pin_id = physical_tile_port.absolute_first_pin_index + ipin; - VTR_ASSERT(pin_id < physical_tile->num_pins); - /* Check if the pin is located on the wanted side */ - if (true == is_pin_locate_at_physical_tile_side(physical_tile, - pin_width_offset, - pin_height_offset, - pin_id, pin_side)) { - - pin_ids.push_back(pin_id); - } } } diff --git a/openfpga/src/utils/check_tile_annotation.cpp b/openfpga/src/utils/check_tile_annotation.cpp index df209644d..e5d732a03 100644 --- a/openfpga/src/utils/check_tile_annotation.cpp +++ b/openfpga/src/utils/check_tile_annotation.cpp @@ -119,68 +119,70 @@ int check_tile_annotation_conflicts_with_physical_tile(const TileAnnotation& til found_matched_physical_tile++; /* Must found a valid port where both port name and port size must match!!! */ - for (const t_physical_tile_port& tile_port : physical_tile.ports) { - if (std::string(tile_port.name) != required_tile_port.get_name()) { - continue; + for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) { + for (const t_physical_tile_port& tile_port : sub_tile.ports) { + if (std::string(tile_port.name) != required_tile_port.get_name()) { + continue; + } + + BasicPort ref_tile_port(tile_port.name, tile_port.num_pins); + /* Port size must be in range!!! */ + if (false == ref_tile_port.contained(required_tile_port)) { + VTR_LOG_ERROR("Tile annotation port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!", + required_tile_port.get_name().c_str(), + required_tile_port.get_lsb(), + required_tile_port.get_msb(), + ref_tile_port.get_name().c_str(), + ref_tile_port.get_lsb(), + ref_tile_port.get_msb()); + num_err++; + continue; + } + + + /* Check if port property matches */ + int grid_pin_index = tile_port.absolute_first_pin_index; + + if (tile_port.is_clock != tile_annotation.global_port_is_clock(tile_global_port)) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match physical tile port %s.%s in clock property (one is defined as clock while the other is not)!\n", + required_tile_name.c_str(), + required_tile_port.get_name().c_str(), + required_tile_port.get_lsb(), + required_tile_port.get_msb(), + tile_annotation.global_port_name(tile_global_port).c_str(), + physical_tile.name, tile_port.name); + num_err++; + } + + if ((false == tile_port.is_clock) + && (false == tile_port.is_non_clock_global)) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but is not defined as a non-clock global port!\n", + required_tile_name.c_str(), + required_tile_port.get_name().c_str(), + required_tile_port.get_lsb(), + required_tile_port.get_msb(), + tile_annotation.global_port_name(tile_global_port).c_str(), + physical_tile.name, tile_port.name); + num_err++; + } + + float pin_Fc = find_physical_tile_pin_Fc(&physical_tile, grid_pin_index); + if (0. != pin_Fc) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but its Fc is not zero '%g' !\n", + required_tile_name.c_str(), + required_tile_port.get_name().c_str(), + required_tile_port.get_lsb(), + required_tile_port.get_msb(), + tile_annotation.global_port_name(tile_global_port).c_str(), + physical_tile.name, tile_port.name, pin_Fc); + + } + + found_matched_physical_tile_port++; } - - BasicPort ref_tile_port(tile_port.name, tile_port.num_pins); - /* Port size must be in range!!! */ - if (false == ref_tile_port.contained(required_tile_port)) { - VTR_LOG_ERROR("Tile annotation port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!", - required_tile_port.get_name().c_str(), - required_tile_port.get_lsb(), - required_tile_port.get_msb(), - ref_tile_port.get_name().c_str(), - ref_tile_port.get_lsb(), - ref_tile_port.get_msb()); - num_err++; - continue; - } - - - /* Check if port property matches */ - int grid_pin_index = tile_port.absolute_first_pin_index; - - if (tile_port.is_clock != tile_annotation.global_port_is_clock(tile_global_port)) { - VTR_LOGF_ERROR(__FILE__, __LINE__, - "Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match physical tile port %s.%s in clock property (one is defined as clock while the other is not)!\n", - required_tile_name.c_str(), - required_tile_port.get_name().c_str(), - required_tile_port.get_lsb(), - required_tile_port.get_msb(), - tile_annotation.global_port_name(tile_global_port).c_str(), - physical_tile.name, tile_port.name); - num_err++; - } - - if ((false == tile_port.is_clock) - && (false == tile_port.is_non_clock_global)) { - VTR_LOGF_ERROR(__FILE__, __LINE__, - "Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but is not defined as a non-clock global port!\n", - required_tile_name.c_str(), - required_tile_port.get_name().c_str(), - required_tile_port.get_lsb(), - required_tile_port.get_msb(), - tile_annotation.global_port_name(tile_global_port).c_str(), - physical_tile.name, tile_port.name); - num_err++; - } - - float pin_Fc = find_physical_tile_pin_Fc(&physical_tile, grid_pin_index); - if (0. != pin_Fc) { - VTR_LOGF_ERROR(__FILE__, __LINE__, - "Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but its Fc is not zero '%g' !\n", - required_tile_name.c_str(), - required_tile_port.get_name().c_str(), - required_tile_port.get_lsb(), - required_tile_port.get_msb(), - tile_annotation.global_port_name(tile_global_port).c_str(), - physical_tile.name, tile_port.name, pin_Fc); - - } - - found_matched_physical_tile_port++; } } diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 885eb58fe..e1d6d03cf 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 885eb58feef2d0fb6789cff017803e032bc3ee82 +Subproject commit e1d6d03cf5954e31f34049ddace7689630993a36