add wire module generation and simplify Verilog generation for wires
This commit is contained in:
parent
c076da9bab
commit
3cf7950bc1
|
@ -14,6 +14,7 @@
|
||||||
#include "build_decoder_modules.h"
|
#include "build_decoder_modules.h"
|
||||||
#include "build_mux_modules.h"
|
#include "build_mux_modules.h"
|
||||||
#include "build_lut_modules.h"
|
#include "build_lut_modules.h"
|
||||||
|
#include "build_wire_modules.h"
|
||||||
#include "build_module_graph.h"
|
#include "build_module_graph.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -90,7 +91,8 @@ ModuleManager build_device_module_graph(const t_vpr_setup& vpr_setup,
|
||||||
/* Build LUT modules */
|
/* Build LUT modules */
|
||||||
build_lut_modules(module_manager, arch.spice->circuit_lib);
|
build_lut_modules(module_manager, arch.spice->circuit_lib);
|
||||||
|
|
||||||
/* TODO: Build wire modules */
|
/* Build wire modules */
|
||||||
|
build_wire_modules(module_manager, arch.spice->circuit_lib, L_segment_vec);
|
||||||
|
|
||||||
/* TODO: Build memory modules */
|
/* TODO: Build memory modules */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/***********************************************
|
||||||
|
* This file includes functions to generate
|
||||||
|
* Verilog submodules for wires.
|
||||||
|
**********************************************/
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
|
||||||
|
/* Device-level header files */
|
||||||
|
#include "module_manager.h"
|
||||||
|
#include "module_manager_utils.h"
|
||||||
|
#include "physical_types.h"
|
||||||
|
#include "vpr_types.h"
|
||||||
|
|
||||||
|
/* FPGA-X2P context header files */
|
||||||
|
#include "spice_types.h"
|
||||||
|
#include "fpga_x2p_naming.h"
|
||||||
|
#include "fpga_x2p_utils.h"
|
||||||
|
|
||||||
|
/* FPGA-Verilog context header files */
|
||||||
|
#include "verilog_global.h"
|
||||||
|
#include "build_wire_modules.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Print a Verilog module of a regular wire segment
|
||||||
|
* Regular wire, which is 1-input and 1-output
|
||||||
|
* This type of wires are used in the local routing architecture
|
||||||
|
* +------+
|
||||||
|
* input --->| wire |---> output
|
||||||
|
* +------+
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void build_wire_module(ModuleManager& module_manager,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& wire_model) {
|
||||||
|
/* Find the input port, output port*/
|
||||||
|
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(wire_model, SPICE_MODEL_PORT_INPUT, true);
|
||||||
|
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(wire_model, SPICE_MODEL_PORT_OUTPUT, true);
|
||||||
|
std::vector<CircuitPortId> global_ports = circuit_lib.model_global_ports_by_type(wire_model, SPICE_MODEL_PORT_INPUT, true, true);
|
||||||
|
|
||||||
|
/* Makre sure the port size is what we want */
|
||||||
|
VTR_ASSERT (1 == input_ports.size());
|
||||||
|
VTR_ASSERT (1 == output_ports.size());
|
||||||
|
VTR_ASSERT (1 == circuit_lib.port_size(input_ports[0]));
|
||||||
|
VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0]));
|
||||||
|
|
||||||
|
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||||
|
add_circuit_model_to_module_manager(module_manager, circuit_lib, wire_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Build module of a routing track wire segment
|
||||||
|
* Routing track wire, which is 1-input and dual output
|
||||||
|
* This type of wires are used in the global routing architecture.
|
||||||
|
* One of the output is wired to another Switch block multiplexer,
|
||||||
|
* while the mid-output is wired to a Connection block multiplexer.
|
||||||
|
*
|
||||||
|
* | CLB |
|
||||||
|
* +------------+
|
||||||
|
* ^
|
||||||
|
* |
|
||||||
|
* +------------------------------+
|
||||||
|
* | Connection block multiplexer |
|
||||||
|
* +------------------------------+
|
||||||
|
* ^
|
||||||
|
* | mid-output +--------------
|
||||||
|
* +--------------------+ |
|
||||||
|
* input --->| Routing track wire |--------->| Switch Block
|
||||||
|
* +--------------------+ output |
|
||||||
|
* +--------------
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void build_routing_wire_module(ModuleManager& module_manager,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& wire_model,
|
||||||
|
const std::string& wire_subckt_name) {
|
||||||
|
/* Find the input port, output port*/
|
||||||
|
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(wire_model, SPICE_MODEL_PORT_INPUT, true);
|
||||||
|
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(wire_model, SPICE_MODEL_PORT_OUTPUT, true);
|
||||||
|
|
||||||
|
/* Make sure the port size is what we want */
|
||||||
|
VTR_ASSERT (1 == input_ports.size());
|
||||||
|
VTR_ASSERT (1 == output_ports.size());
|
||||||
|
VTR_ASSERT (1 == circuit_lib.port_size(input_ports[0]));
|
||||||
|
VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0]));
|
||||||
|
|
||||||
|
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||||
|
ModuleId wire_module = add_circuit_model_to_module_manager(module_manager, circuit_lib, wire_model, wire_subckt_name);
|
||||||
|
|
||||||
|
/* Add a mid-output port to the module */
|
||||||
|
BasicPort module_mid_output_port(generate_segment_wire_mid_output_name(circuit_lib.port_lib_name(output_ports[0])), circuit_lib.port_size(output_ports[0]));
|
||||||
|
module_manager.add_port(wire_module, module_mid_output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* This function will only create wire modules with a number of
|
||||||
|
* ports that are defined by users.
|
||||||
|
* It will NOT insert any internal logic, which should be handled
|
||||||
|
* by Verilog/SPICE writers
|
||||||
|
*******************************************************************/
|
||||||
|
void build_wire_modules(ModuleManager& module_manager,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
std::vector<t_segment_inf> routing_segments) {
|
||||||
|
/* Print Verilog models for regular wires*/
|
||||||
|
for (const auto& wire_model : circuit_lib.models_by_type(SPICE_MODEL_WIRE)) {
|
||||||
|
/* Bypass user-defined circuit models */
|
||||||
|
if ( (!circuit_lib.model_spice_netlist(wire_model).empty())
|
||||||
|
&& (!circuit_lib.model_verilog_netlist(wire_model).empty()) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
build_wire_module(module_manager, circuit_lib, wire_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& seg : routing_segments) {
|
||||||
|
VTR_ASSERT( CircuitModelId::INVALID() != seg.circuit_model);
|
||||||
|
VTR_ASSERT( SPICE_MODEL_CHAN_WIRE == circuit_lib.model_type(seg.circuit_model));
|
||||||
|
/* Bypass user-defined circuit models */
|
||||||
|
if ( (!circuit_lib.model_spice_netlist(seg.circuit_model).empty())
|
||||||
|
&& (!circuit_lib.model_verilog_netlist(seg.circuit_model).empty()) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Give a unique name for subckt of wire_model of segment,
|
||||||
|
* circuit_model name is unique, and segment id is unique as well
|
||||||
|
*/
|
||||||
|
std::string segment_wire_subckt_name = generate_segment_wire_subckt_name(circuit_lib.model_name(seg.circuit_model), &seg - &routing_segments[0]);
|
||||||
|
|
||||||
|
/* Print a Verilog module */
|
||||||
|
build_routing_wire_module(module_manager, circuit_lib, seg.circuit_model, segment_wire_subckt_name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/***********************************************
|
||||||
|
* Header file for verilog_wire.cpp
|
||||||
|
**********************************************/
|
||||||
|
|
||||||
|
#ifndef BUILD_WIRE_MODULES_H
|
||||||
|
#define BUILD_WIRE_MODULES_H
|
||||||
|
|
||||||
|
/* Include other header files which are dependency on the function declared below */
|
||||||
|
#include <vector>
|
||||||
|
#include "physical_types.h"
|
||||||
|
#include "vpr_types.h"
|
||||||
|
|
||||||
|
#include "circuit_library.h"
|
||||||
|
#include "module_manager.h"
|
||||||
|
|
||||||
|
void build_wire_modules(ModuleManager& module_manager,
|
||||||
|
const CircuitLibrary& circuit_lib,
|
||||||
|
std::vector<t_segment_inf> routing_segments);
|
||||||
|
|
||||||
|
#endif
|
|
@ -54,22 +54,23 @@ void print_verilog_wire_module(ModuleManager& module_manager,
|
||||||
VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0]));
|
VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0]));
|
||||||
|
|
||||||
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||||
ModuleId module_id = add_circuit_model_to_module_manager(module_manager, circuit_lib, wire_model);
|
ModuleId wire_module = module_manager.find_module(circuit_lib.model_name(wire_model));
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(wire_module));
|
||||||
|
|
||||||
/* dump module definition + ports */
|
/* dump module definition + ports */
|
||||||
print_verilog_module_declaration(fp, module_manager, module_id);
|
print_verilog_module_declaration(fp, module_manager, wire_module);
|
||||||
/* Finish dumping ports */
|
/* Finish dumping ports */
|
||||||
|
|
||||||
/* Print the internal logic of Verilog module */
|
/* Print the internal logic of Verilog module */
|
||||||
/* Find the input port of the module */
|
/* Find the input port of the module */
|
||||||
ModulePortId module_input_port_id = module_manager.find_module_port(module_id, circuit_lib.port_lib_name(input_ports[0]));
|
ModulePortId module_input_port_id = module_manager.find_module_port(wire_module, circuit_lib.port_lib_name(input_ports[0]));
|
||||||
VTR_ASSERT(ModulePortId::INVALID() != module_input_port_id);
|
VTR_ASSERT(ModulePortId::INVALID() != module_input_port_id);
|
||||||
BasicPort module_input_port = module_manager.module_port(module_id, module_input_port_id);
|
BasicPort module_input_port = module_manager.module_port(wire_module, module_input_port_id);
|
||||||
|
|
||||||
/* Find the output port of the module */
|
/* Find the output port of the module */
|
||||||
ModulePortId module_output_port_id = module_manager.find_module_port(module_id, circuit_lib.port_lib_name(output_ports[0]));
|
ModulePortId module_output_port_id = module_manager.find_module_port(wire_module, circuit_lib.port_lib_name(output_ports[0]));
|
||||||
VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
|
VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
|
||||||
BasicPort module_output_port = module_manager.module_port(module_id, module_output_port_id);
|
BasicPort module_output_port = module_manager.module_port(wire_module, module_output_port_id);
|
||||||
|
|
||||||
/* Print wire declaration for the inputs and outputs */
|
/* Print wire declaration for the inputs and outputs */
|
||||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, module_input_port) << ";" << std::endl;
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, module_input_port) << ";" << std::endl;
|
||||||
|
@ -130,26 +131,28 @@ void print_verilog_routing_wire_module(ModuleManager& module_manager,
|
||||||
VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0]));
|
VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0]));
|
||||||
|
|
||||||
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||||
ModuleId module_id = add_circuit_model_to_module_manager(module_manager, circuit_lib, wire_model, wire_subckt_name);
|
ModuleId wire_module = module_manager.find_module(wire_subckt_name);
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(wire_module));
|
||||||
|
|
||||||
/* Add a mid-output port to the module */
|
/* Add a mid-output port to the module */
|
||||||
BasicPort module_mid_output_port(generate_segment_wire_mid_output_name(circuit_lib.port_lib_name(output_ports[0])), circuit_lib.port_size(output_ports[0]));
|
BasicPort module_mid_output_port(generate_segment_wire_mid_output_name(circuit_lib.port_lib_name(output_ports[0])), circuit_lib.port_size(output_ports[0]));
|
||||||
module_manager.add_port(module_id, module_mid_output_port, ModuleManager::MODULE_OUTPUT_PORT);
|
ModulePortId module_mid_output_port_id = module_manager.find_module_port(wire_module, module_mid_output_port.get_name());
|
||||||
|
VTR_ASSERT(ModulePortId::INVALID() != module_mid_output_port_id);
|
||||||
|
|
||||||
/* dump module definition + ports */
|
/* dump module definition + ports */
|
||||||
print_verilog_module_declaration(fp, module_manager, module_id);
|
print_verilog_module_declaration(fp, module_manager, wire_module);
|
||||||
/* Finish dumping ports */
|
/* Finish dumping ports */
|
||||||
|
|
||||||
/* Print the internal logic of Verilog module */
|
/* Print the internal logic of Verilog module */
|
||||||
/* Find the input port of the module */
|
/* Find the input port of the module */
|
||||||
ModulePortId module_input_port_id = module_manager.find_module_port(module_id, circuit_lib.port_lib_name(input_ports[0]));
|
ModulePortId module_input_port_id = module_manager.find_module_port(wire_module, circuit_lib.port_lib_name(input_ports[0]));
|
||||||
VTR_ASSERT(ModulePortId::INVALID() != module_input_port_id);
|
VTR_ASSERT(ModulePortId::INVALID() != module_input_port_id);
|
||||||
BasicPort module_input_port = module_manager.module_port(module_id, module_input_port_id);
|
BasicPort module_input_port = module_manager.module_port(wire_module, module_input_port_id);
|
||||||
|
|
||||||
/* Find the output port of the module */
|
/* Find the output port of the module */
|
||||||
ModulePortId module_output_port_id = module_manager.find_module_port(module_id, circuit_lib.port_lib_name(output_ports[0]));
|
ModulePortId module_output_port_id = module_manager.find_module_port(wire_module, circuit_lib.port_lib_name(output_ports[0]));
|
||||||
VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
|
VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
|
||||||
BasicPort module_output_port = module_manager.module_port(module_id, module_output_port_id);
|
BasicPort module_output_port = module_manager.module_port(wire_module, module_output_port_id);
|
||||||
|
|
||||||
/* Print wire declaration for the inputs and outputs */
|
/* Print wire declaration for the inputs and outputs */
|
||||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, module_input_port) << ";" << std::endl;
|
fp << generate_verilog_port(VERILOG_PORT_WIRE, module_input_port) << ";" << std::endl;
|
||||||
|
|
Loading…
Reference in New Issue