Skip to content

Commit

Permalink
Merge pull request #89 from LNIS-Projects/dev
Browse files Browse the repository at this point in the history
Regression test & architecture updates
  • Loading branch information
LNIS-Projects authored Sep 22, 2020
2 parents 9a995d1 + aa5f5fc commit fba8dbe
Show file tree
Hide file tree
Showing 47 changed files with 1,559 additions and 64 deletions.
5 changes: 4 additions & 1 deletion .travis/fpga_verilog_reg_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ echo -e "FPGA-Verilog Feature Tests";
echo -e "Testing Verilog generation for LUTs: a single mode LUT6 FPGA using micro benchmarks";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/lut_design/single_mode --debug --show_thread_logs

echo -e "Testing Verilog generation for LUTs: simple fracturable LUT4 ";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/lut_design/frac_lut4 --debug --show_thread_logs

echo -e "Testing Verilog generation for LUTs: simple fracturable LUT6 ";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/lut_design/frac_lut --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/lut_design/frac_lut6 --debug --show_thread_logs

echo -e "Testing Verilog generation for LUTs: LUT6 with intermediate buffers";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/lut_design/intermediate_buffer --debug --show_thread_logs
Expand Down
92 changes: 89 additions & 3 deletions openfpga/src/repack/repack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,73 @@
/* begin namespace openfpga */
namespace openfpga {

/***************************************************************************************
* Try to find sink pb graph pins through walking through the fan-out edges from
* the source pb graph pin
* Only the sink meeting the following requirements can be considered:
* - All the fan-out edges between the source and sink are from direct interconnection
* - sink is an input of a primitive pb_type
*
* Note:
* - If there is a fan-out of the current source pb graph pin is not a direct interconnection
* the direct search should stop.
* - This function is designed for pb graph without local routing
* For example: direct connection between root pb graph node to the LUT pb graph node
*
* root pb_graph_node
* +-----------------------------------------
* | Intermediate pb_graph_node
* | +----------------------------------
* | | primitive pb_graph_node
* | | +-------------------------
* I[0] ---->+------>+------->|I[0] LUT
*
* - This function is designed for passing wires inside pb graph
*
* root pb_graph_node
* +------------------------------+
* | Intermediate pb_graph_node |
* | +-------------+ |
* | | | |
* | | | |
* I[0]----->+------>+--- ... ---->+------->+------>O[0]
*
***************************************************************************************/
static
bool rec_direct_search_sink_pb_graph_pins(const t_pb_graph_pin* source_pb_pin,
std::vector<t_pb_graph_pin*>& sink_pb_pins) {

std::vector<t_pb_graph_pin*> sink_pb_pins_to_search;

for (int iedge = 0; iedge < source_pb_pin->num_output_edges; ++iedge) {
if (DIRECT_INTERC != source_pb_pin->output_edges[iedge]->interconnect->type) {
return false;
}
for (int ipin = 0; ipin < source_pb_pin->output_edges[iedge]->num_output_pins; ++ipin) {
t_pb_graph_pin* cand_sink_pb_pin = source_pb_pin->output_edges[iedge]->output_pins[ipin];
if ( (true == is_primitive_pb_type(cand_sink_pb_pin->parent_node->pb_type))
&& (IN_PORT == cand_sink_pb_pin->port->type)) {
sink_pb_pins.push_back(cand_sink_pb_pin);
} else if ( (true == cand_sink_pb_pin->parent_node->is_root())
&& (OUT_PORT == cand_sink_pb_pin->port->type)) {
sink_pb_pins.push_back(cand_sink_pb_pin);
} else {
sink_pb_pins_to_search.push_back(cand_sink_pb_pin);
}
}
}

for (t_pb_graph_pin* sink_pb_pin : sink_pb_pins_to_search) {
bool direct_search_status = rec_direct_search_sink_pb_graph_pins(sink_pb_pin, sink_pb_pins);
if (false == direct_search_status) {
return false;
}
}

/* Reach here, we succeed. */
return true;
}

/***************************************************************************************
* Try find all the sink pins which is mapped to a routing trace in the context of pb route
* This function uses a recursive walk-through over the pb_route
Expand Down Expand Up @@ -133,13 +200,32 @@ void rec_find_routed_sink_pb_graph_pins(const t_pb* pb,
static
std::vector<t_pb_graph_pin*> find_routed_pb_graph_pins_atom_net(const t_pb* pb,
const t_pb_graph_pin* source_pb_pin,
const t_pb_graph_pin* packing_source_pb_pin,
const AtomNetId& atom_net_id,
const VprDeviceAnnotation& device_annotation,
const std::map<const t_pb_graph_pin*, AtomNetId>& pb_pin_mapped_nets,
t_pb_graph_pin** pb_graph_pin_lookup_from_index) {
std::vector<t_pb_graph_pin*> sink_pb_pins;

rec_find_routed_sink_pb_graph_pins(pb, source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index, sink_pb_pins);
/* Try to directly search for sink pb_pins from the source_pb_pin,
* which is the actual source pin to be routed from
* Note that the packing source_pb_pin is the source pin considered by
* VPR packer, but may not be the actual source!!!
*/
if (true == source_pb_pin->parent_node->is_root()) {
bool direct_search_status = rec_direct_search_sink_pb_graph_pins(source_pb_pin, sink_pb_pins);
if (true == direct_search_status) {
VTR_ASSERT(!sink_pb_pins.empty());
/* We have find through direct searching, return now */
return sink_pb_pins;
}

/* Cannot find through direct searching, reset results */
VTR_ASSERT_SAFE(false == direct_search_status);
sink_pb_pins.clear();
}

rec_find_routed_sink_pb_graph_pins(pb, packing_source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index, sink_pb_pins);

return sink_pb_pins;
}
Expand Down Expand Up @@ -339,7 +425,7 @@ void add_lb_router_nets(LbRouter& lb_router,
VTR_ASSERT(nullptr != packing_source_pb_pin);

/* Find all the sink pins in the pb_route, we walk through the input pins and find the pin */
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, packing_source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index);
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, source_pb_pin, packing_source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index);
std::vector<LbRRNodeId> sink_lb_rr_nodes = find_lb_net_physical_sink_lb_rr_nodes(lb_rr_graph, sink_pb_graph_pins, device_annotation);
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());

Expand Down Expand Up @@ -404,7 +490,7 @@ void add_lb_router_nets(LbRouter& lb_router,
VTR_ASSERT(AtomNetId::INVALID() != atom_net_id);

/* Find all the sink pins in the pb_route */
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index);
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, physical_source_pb_pin, source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index);

std::vector<LbRRNodeId> sink_lb_rr_nodes = find_lb_net_physical_sink_lb_rr_nodes(lb_rr_graph, sink_pb_graph_pins, device_annotation);
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --device ${OPENFPGA_VPR_DEVICE_LAYOUT}

# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}

# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}

# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges

# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml

# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose

# 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 #--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.xml --format xml

# 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 --include_signal_init --support_icarus_simulator --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_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --explicit_port_mapping

# Write the SDC files for PnR backend
# - Turn on every options here
write_pnr_sdc --file ./SDC

# Write SDC to disable timing for configure ports
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc

# Write the SDC to run timing analysis for a mapped FPGA fabric
write_analysis_sdc --file ./SDC_analysis

# Finish and exit OpenFPGA
exit

# Note :
# To run verification at the end of the flow maintain source in ./SRC directory
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --device ${OPENFPGA_VPR_DEVICE_LAYOUT}

# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --device ${OPENFPGA_VPR_DEVICE_LAYOUT}

# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --device ${OPENFPGA_VPR_DEVICE_LAYOUT}

# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
Expand Down
Loading

0 comments on commit fba8dbe

Please sign in to comment.