Merge pull request #94 from LNIS-Projects/dev

[OpenFPGA Tool] Bug fix in creating auto-generated cells using lib_name
This commit is contained in:
Laboratory for Nano Integrated Systems (LNIS) 2020-09-25 22:28:24 -06:00 committed by GitHub
commit c8d4be65e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 188 additions and 73 deletions

View File

@ -256,8 +256,16 @@ void rename_primitive_module_port_names(ModuleManager& module_manager,
/* We only care about user-defined models */
if ( (true == circuit_lib.model_verilog_netlist(model).empty())
&& (true == circuit_lib.model_spice_netlist(model).empty()) ) {
/* Exception circuit models as primitive cells
* - Inverter, buffer, pass-gate logic, logic gate
* which should be renamed even when auto-generated
*/
if ( (CIRCUIT_MODEL_INVBUF != circuit_lib.model_type(model))
&& (CIRCUIT_MODEL_PASSGATE != circuit_lib.model_type(model))
&& (CIRCUIT_MODEL_GATE != circuit_lib.model_type(model)) ) {
continue;
}
}
/* Skip Routing channel wire models because they need a different name. Do it later */
if (CIRCUIT_MODEL_CHAN_WIRE == circuit_lib.model_type(model)) {
continue;

View File

@ -43,7 +43,7 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
print_verilog_comment(fp, std::string("----- Verilog codes of a power-gated inverter -----"));
/* Create a sensitive list */
fp << "\treg " << circuit_lib.port_prefix(output_port) << "_reg;" << std::endl;
fp << "\treg " << circuit_lib.port_lib_name(output_port) << "_reg;" << std::endl;
fp << "\talways @(";
/* Power-gate port first*/
@ -52,10 +52,10 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
if (false == circuit_lib.port_is_config_enable(power_gate_port)) {
continue;
}
fp << circuit_lib.port_prefix(power_gate_port);
fp << circuit_lib.port_lib_name(power_gate_port);
fp << ", ";
}
fp << circuit_lib.port_prefix(input_port) << ") begin" << std::endl;
fp << circuit_lib.port_lib_name(input_port) << ") begin" << std::endl;
/* Dump the case of power-gated */
fp << "\t\tif (";
@ -79,14 +79,14 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
fp << "~";
}
fp << circuit_lib.port_prefix(power_gate_port) << "[" << power_gate_pin << "])";
fp << circuit_lib.port_lib_name(power_gate_port) << "[" << power_gate_pin << "])";
port_cnt++; /* Update port counter*/
}
}
fp << ") begin" << std::endl;
fp << "\t\t\tassign " << circuit_lib.port_prefix(output_port) << "_reg = ";
fp << "\t\t\tassign " << circuit_lib.port_lib_name(output_port) << "_reg = ";
/* Branch on the type of inverter/buffer:
* 1. If this is an inverter or an tapered(multi-stage) buffer with odd number of stages,
@ -101,12 +101,12 @@ void print_verilog_power_gated_invbuf_body(std::fstream& fp,
fp << "~";
}
fp << circuit_lib.port_prefix(input_port) << ";" << std::endl;
fp << circuit_lib.port_lib_name(input_port) << ";" << std::endl;
fp << "\t\tend else begin" << std::endl;
fp << "\t\t\tassign " << circuit_lib.port_prefix(output_port) << "_reg = 1'bz;" << std::endl;
fp << "\t\t\tassign " << circuit_lib.port_lib_name(output_port) << "_reg = 1'bz;" << std::endl;
fp << "\t\tend" << std::endl;
fp << "\tend" << std::endl;
fp << "\tassign " << circuit_lib.port_prefix(output_port) << " = " << circuit_lib.port_prefix(output_port) << "_reg;" << std::endl;
fp << "\tassign " << circuit_lib.port_lib_name(output_port) << " = " << circuit_lib.port_lib_name(output_port) << "_reg;" << std::endl;
}
/************************************************
@ -124,7 +124,7 @@ void print_verilog_invbuf_body(std::fstream& fp,
print_verilog_comment(fp, std::string("----- Verilog codes of a regular inverter -----"));
fp << "\tassign " << circuit_lib.port_prefix(output_port) << " = (" << circuit_lib.port_prefix(input_port) << " === 1'bz)? $random : ";
fp << "\tassign " << circuit_lib.port_lib_name(output_port) << " = (" << circuit_lib.port_lib_name(input_port) << " === 1'bz)? $random : ";
/* Branch on the type of inverter/buffer:
* 1. If this is an inverter or an tapered(multi-stage) buffer with odd number of stages,
@ -139,7 +139,7 @@ void print_verilog_invbuf_body(std::fstream& fp,
fp << "~";
}
fp << circuit_lib.port_prefix(input_port) << ";" << std::endl;
fp << circuit_lib.port_lib_name(input_port) << ";" << std::endl;
}
/************************************************
@ -264,8 +264,8 @@ void print_verilog_passgate_module(const ModuleManager& module_manager,
/* Dump logics: we propagate input to the output when the gate is '1'
* the input is blocked from output when the gate is '0'
*/
fp << "\tassign " << circuit_lib.port_prefix(output_ports[0]) << " = ";
fp << circuit_lib.port_prefix(input_ports[1]) << " ? " << circuit_lib.port_prefix(input_ports[0]);
fp << "\tassign " << circuit_lib.port_lib_name(output_ports[0]) << " = ";
fp << circuit_lib.port_lib_name(input_ports[1]) << " ? " << circuit_lib.port_lib_name(input_ports[0]);
fp << " : 1'bz;" << std::endl;
/* Print timing info */
@ -311,7 +311,7 @@ void print_verilog_and_or_gate_body(std::fstream& fp,
for (const auto& output_port : output_ports) {
for (const auto& output_pin : circuit_lib.pins(output_port)) {
BasicPort output_port_info(circuit_lib.port_prefix(output_port), output_pin, output_pin);
BasicPort output_port_info(circuit_lib.port_lib_name(output_port), output_pin, output_pin);
fp << "\tassign " << generate_verilog_port(VERILOG_PORT_CONKT, output_port_info);
fp << " = ";
@ -323,7 +323,7 @@ void print_verilog_and_or_gate_body(std::fstream& fp,
fp << " " << gate_verilog_operator << " ";
}
BasicPort input_port_info(circuit_lib.port_prefix(input_port), input_pin, input_pin);
BasicPort input_port_info(circuit_lib.port_lib_name(input_port), input_pin, input_pin);
fp << generate_verilog_port(VERILOG_PORT_CONKT, input_port_info);
/* Increment the counter for port */
@ -395,10 +395,10 @@ void print_verilog_mux2_gate_body(std::fstream& fp,
* the third input is the select port
*/
fp << "\tassign ";
BasicPort out_port_info(circuit_lib.port_prefix(output_ports[0]), 0, 0);
BasicPort sel_port_info(circuit_lib.port_prefix(input_ports[2]), 0, 0);
BasicPort in0_port_info(circuit_lib.port_prefix(input_ports[0]), 0, 0);
BasicPort in1_port_info(circuit_lib.port_prefix(input_ports[1]), 0, 0);
BasicPort out_port_info(circuit_lib.port_lib_name(output_ports[0]), 0, 0);
BasicPort sel_port_info(circuit_lib.port_lib_name(input_ports[2]), 0, 0);
BasicPort in0_port_info(circuit_lib.port_lib_name(input_ports[0]), 0, 0);
BasicPort in1_port_info(circuit_lib.port_lib_name(input_ports[1]), 0, 0);
fp << generate_verilog_port(VERILOG_PORT_CONKT, out_port_info);
fp << " = ";

View File

@ -178,21 +178,34 @@ void print_verilog_top_testbench_memory_bank_port(std::fstream& fp,
fp << generate_verilog_port(VERILOG_PORT_REG, wl_addr_port) << ";" << std::endl;
/* Print the data-input port for the frame-based decoder here */
print_verilog_comment(fp, std::string("---- Data input port for frame-based decoder -----"));
print_verilog_comment(fp, std::string("---- Data input port for memory decoders -----"));
ModulePortId din_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_DATA_IN_PORT_NAME));
BasicPort din_port = module_manager.module_port(top_module, din_port_id);
fp << generate_verilog_port(VERILOG_PORT_REG, din_port) << ";" << std::endl;
/* Wire the INVERTED configuration done signal to the enable signal !!! */
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoder to inverted configuration done signal -----"));
/* Generate enable signal waveform here:
* which is a 90 degree phase shift than the programming clock
*/
print_verilog_comment(fp, std::string("---- Wire enable port of memory decoders -----"));
ModulePortId en_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_ENABLE_PORT_NAME));
BasicPort en_port = module_manager.module_port(top_module, en_port_id);
BasicPort en_register_port(std::string(en_port.get_name() + std::string(TOP_TB_CLOCK_REG_POSTFIX)), 1);
BasicPort config_done_port(std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1);
fp << generate_verilog_port(VERILOG_PORT_WIRE, en_port) << ";" << std::endl;
print_verilog_wire_connection(fp, en_port, config_done_port, true);
fp << generate_verilog_port(VERILOG_PORT_REG, en_register_port) << ";" << std::endl;
write_tab_to_file(fp, 1);
fp << "assign ";
fp << generate_verilog_port(VERILOG_PORT_CONKT, en_port);
fp << "= ";
fp << "~" << generate_verilog_port(VERILOG_PORT_CONKT, en_register_port);
fp << " & ";
fp << "~" << generate_verilog_port(VERILOG_PORT_CONKT, config_done_port);
fp << ";" << std::endl;
}
@ -201,8 +214,6 @@ void print_verilog_top_testbench_memory_bank_port(std::fstream& fp,
*******************************************************************/
static
void print_verilog_top_testbench_frame_decoder_port(std::fstream& fp,
const ConfigProtocol& config_protocol,
const CircuitLibrary& circuit_lib,
const ModuleManager& module_manager,
const ModuleId& top_module) {
/* Validate the file stream */
@ -223,33 +234,28 @@ void print_verilog_top_testbench_frame_decoder_port(std::fstream& fp,
BasicPort din_port = module_manager.module_port(top_module, din_port_id);
fp << generate_verilog_port(VERILOG_PORT_REG, din_port) << ";" << std::endl;
/* Wire the INVERTED configuration done signal to the enable signal !!! */
/* Generate enable signal waveform here:
* which is a 90 degree phase shift than the programming clock
*/
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoders -----"));
ModulePortId en_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_ENABLE_PORT_NAME));
BasicPort en_port = module_manager.module_port(top_module, en_port_id);
BasicPort en_register_port(std::string(en_port.get_name() + std::string(TOP_TB_CLOCK_REG_POSTFIX)), 1);
/* Find the circuit model of configurable memory
* Spot its BL port and generate stimuli based on BL port's attribute:
* - If the BL port is triggered by edge, use the inverted programming clock signal
* - If the BL port is a regular port, use the inverted configuration done signal
*/
const CircuitModelId& mem_model = config_protocol.memory_model();
VTR_ASSERT(true == circuit_lib.valid_model_id(mem_model));
std::vector<CircuitPortId> mem_model_bl_ports = circuit_lib.model_ports_by_type(mem_model, CIRCUIT_MODEL_PORT_BL);
VTR_ASSERT(1 == mem_model_bl_ports.size());
if (true == circuit_lib.port_is_edge_triggered(mem_model_bl_ports[0])) {
VTR_ASSERT_SAFE(false == circuit_lib.port_is_edge_triggered(mem_model_bl_ports[0]));
BasicPort prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME), 1);
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoder to inverted programming clock signal -----"));
fp << generate_verilog_port(VERILOG_PORT_WIRE, en_port) << ";" << std::endl;
print_verilog_wire_connection(fp, en_port, prog_clock_port, true);
} else {
BasicPort config_done_port(std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1);
print_verilog_comment(fp, std::string("---- Wire enable port of frame-based decoder to inverted configuration done signal -----"));
fp << generate_verilog_port(VERILOG_PORT_WIRE, en_port) << ";" << std::endl;
print_verilog_wire_connection(fp, en_port, config_done_port, true);
}
fp << generate_verilog_port(VERILOG_PORT_REG, en_register_port) << ";" << std::endl;
write_tab_to_file(fp, 1);
fp << "assign ";
fp << generate_verilog_port(VERILOG_PORT_CONKT, en_port);
fp << "= ";
fp << "~" << generate_verilog_port(VERILOG_PORT_CONKT, en_register_port);
fp << " & ";
fp << "~" << generate_verilog_port(VERILOG_PORT_CONKT, config_done_port);
fp << ";" << std::endl;
}
/********************************************************************
@ -258,7 +264,6 @@ void print_verilog_top_testbench_frame_decoder_port(std::fstream& fp,
static
void print_verilog_top_testbench_config_protocol_port(std::fstream& fp,
const ConfigProtocol& config_protocol,
const CircuitLibrary& circuit_lib,
const ModuleManager& module_manager,
const ModuleId& top_module) {
switch(config_protocol.type()) {
@ -272,7 +277,7 @@ void print_verilog_top_testbench_config_protocol_port(std::fstream& fp,
print_verilog_top_testbench_memory_bank_port(fp, module_manager, top_module);
break;
case CONFIG_MEM_FRAME_BASED:
print_verilog_top_testbench_frame_decoder_port(fp, config_protocol, circuit_lib,
print_verilog_top_testbench_frame_decoder_port(fp,
module_manager, top_module);
break;
default:
@ -525,7 +530,6 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
const VprNetlistAnnotation& netlist_annotation,
const std::vector<std::string>& clock_port_names,
const ConfigProtocol& config_protocol,
const CircuitLibrary& circuit_lib,
const std::string& circuit_name){
/* Validate the file stream */
valid_file_stream(fp);
@ -599,7 +603,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
fp << generate_verilog_port(VERILOG_PORT_REG, set_port) << ";" << std::endl;
/* Configuration ports depend on the organization of SRAMs */
print_verilog_top_testbench_config_protocol_port(fp, config_protocol, circuit_lib,
print_verilog_top_testbench_config_protocol_port(fp, config_protocol,
module_manager, top_module);
/* Create a clock port if the benchmark have one but not in the default name!
@ -816,9 +820,7 @@ void print_verilog_top_testbench_load_bitstream_task_memory_bank(std::fstream& f
/* Validate the file stream */
valid_file_stream(fp);
ModulePortId en_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_ENABLE_PORT_NAME));
BasicPort en_port = module_manager.module_port(top_module, en_port_id);
BasicPort prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME), 1);
ModulePortId bl_addr_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_BL_ADDRESS_PORT_NAME));
@ -851,7 +853,7 @@ void print_verilog_top_testbench_load_bitstream_task_memory_bank(std::fstream& f
fp << generate_verilog_port(VERILOG_PORT_INPUT, wl_addr_value) << ";" << std::endl;
fp << generate_verilog_port(VERILOG_PORT_INPUT, din_value) << ";" << std::endl;
fp << "\tbegin" << std::endl;
fp << "\t\t@(posedge " << generate_verilog_port(VERILOG_PORT_CONKT, en_port) << ");" << std::endl;
fp << "\t\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ");" << std::endl;
fp << "\t\t\t";
fp << generate_verilog_port(VERILOG_PORT_CONKT, bl_addr_port);
@ -898,9 +900,7 @@ void print_verilog_top_testbench_load_bitstream_task_frame_decoder(std::fstream&
/* Validate the file stream */
valid_file_stream(fp);
ModulePortId en_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_ENABLE_PORT_NAME));
BasicPort en_port = module_manager.module_port(top_module, en_port_id);
BasicPort prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME), 1);
ModulePortId addr_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_ADDRESS_PORT_NAME));
@ -926,7 +926,7 @@ void print_verilog_top_testbench_load_bitstream_task_frame_decoder(std::fstream&
fp << generate_verilog_port(VERILOG_PORT_INPUT, addr_value) << ";" << std::endl;
fp << generate_verilog_port(VERILOG_PORT_INPUT, din_value) << ";" << std::endl;
fp << "\tbegin" << std::endl;
fp << "\t\t@(posedge " << generate_verilog_port(VERILOG_PORT_CONKT, en_port) << ");" << std::endl;
fp << "\t\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ");" << std::endl;
fp << "\t\t\t";
fp << generate_verilog_port(VERILOG_PORT_CONKT, addr_port);
@ -1113,6 +1113,49 @@ void print_verilog_top_testbench_generic_stimulus(std::fstream& fp,
fp << std::endl;
}
/********************************************************************
* Print input stimuli for configuration protocol
* include:
* - memory bank
* 1. the enable signal
* - frame-based
* 1. the enable signal
*******************************************************************/
static
void print_verilog_top_testbench_configuration_protocol_stimulus(std::fstream& fp,
const e_config_protocol_type& config_protocol_type,
const ModuleManager& module_manager,
const ModuleId& top_module,
const float& prog_clock_period,
const float& timescale) {
/* Validate the file stream */
valid_file_stream(fp);
/* Branch on the type of configuration protocol */
switch (config_protocol_type) {
case CONFIG_MEM_STANDALONE:
break;
case CONFIG_MEM_SCAN_CHAIN:
break;
case CONFIG_MEM_MEMORY_BANK:
case CONFIG_MEM_FRAME_BASED: {
ModulePortId en_port_id = module_manager.find_module_port(top_module,
std::string(DECODER_ENABLE_PORT_NAME));
BasicPort en_port = module_manager.module_port(top_module, en_port_id);
BasicPort en_register_port(std::string(en_port.get_name() + std::string(TOP_TB_CLOCK_REG_POSTFIX)), 1);
print_verilog_comment(fp, std::string("---- Generate enable signal waveform -----"));
print_verilog_shifted_clock_stimuli(fp, en_register_port,
0.25 * prog_clock_period / timescale,
0.5 * prog_clock_period / timescale, 0);
break;
}
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid SRAM organization type!\n");
exit(1);
}
}
/********************************************************************
* Print stimulus for a FPGA fabric with a flatten memory (standalone) configuration protocol
* We will load the bitstream in the second clock cycle, right after the first reset cycle
@ -1711,7 +1754,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
/* Start of testbench */
print_verilog_top_testbench_ports(fp, module_manager, top_module,
atom_ctx, netlist_annotation, clock_port_names,
config_protocol, circuit_lib,
config_protocol,
circuit_name);
/* Find the clock period */
@ -1731,6 +1774,13 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
op_clock_period,
VERILOG_SIM_TIMESCALE);
/* Generate stimuli for programming interface */
print_verilog_top_testbench_configuration_protocol_stimulus(fp,
config_protocol.type(),
module_manager, top_module,
prog_clock_period,
VERILOG_SIM_TIMESCALE);
/* Identify the stimulus for global reset/set for programming purpose:
* - If only reset port is seen we turn on Reset
* - If only set port is seen we turn on Reset

View File

@ -1294,6 +1294,57 @@ void print_verilog_pulse_stimuli(std::fstream& fp,
fp << std::endl;
}
/********************************************************************
* Print stimuli for a clock pulse generation
* This function supports the delay at the beginning of the waveform
*
* |<-- Initial delay -->|<--- pulse width --->|
* +------ flip_value
* |
* initial_value --------------------------------------------+
*
*******************************************************************/
void print_verilog_shifted_clock_stimuli(std::fstream& fp,
const BasicPort& port,
const float& initial_delay,
const float& pulse_width,
const size_t& initial_value) {
/* Validate the file stream */
VTR_ASSERT(true == valid_file_stream(fp));
/* Config_done signal: indicate when configuration is finished */
fp << "initial" << std::endl;
write_tab_to_file(fp, 1);
fp << "begin" << std::endl;
write_tab_to_file(fp, 1);
std::vector<size_t> initial_values(port.get_width(), initial_value);
write_tab_to_file(fp, 1);
fp << generate_verilog_port_constant_values(port, initial_values);
fp << ";" << std::endl;
write_tab_to_file(fp, 2);
fp << "#" << std::setprecision(10) << initial_delay;
fp << ";" << std::endl;
write_tab_to_file(fp, 2);
fp << "forever ";
fp << generate_verilog_port(VERILOG_PORT_CONKT, port);
fp << " = ";
fp << "#" << std::setprecision(10) << pulse_width;
fp << " ~" << generate_verilog_port(VERILOG_PORT_CONKT, port);
fp << ";" << std::endl;
write_tab_to_file(fp, 1);
fp << "end" << std::endl;
/* Print an empty line as splitter */
fp << std::endl;
}
/********************************************************************
* Print stimuli for a pulse generation
* This function supports multiple signal switching under different pulse width

View File

@ -161,6 +161,12 @@ void print_verilog_formal_verification_mux_sram_ports_wiring(std::fstream& fp,
const size_t& num_conf_bits,
const BasicPort& fm_config_bus);
void print_verilog_shifted_clock_stimuli(std::fstream& fp,
const BasicPort& port,
const float& initial_delay,
const float& pulse_width,
const size_t& initial_value);
void print_verilog_pulse_stimuli(std::fstream& fp,
const BasicPort& port,
const size_t& initial_value,

View File

@ -2,7 +2,7 @@
- Architecture independent bitstream
- Author: Xifan TANG
- Organization: University of Utah
- Date: Thu Sep 24 20:16:32 2020
- Date: Fri Sep 25 21:30:07 2020
-->
<bitstream_block name="fpga_top" hierarchy_level="0">
@ -1286,20 +1286,20 @@
</hierarchy>
<bitstream>
<bit memory_port="mem_out[0]" value="1"/>
<bit memory_port="mem_out[1]" value="1"/>
<bit memory_port="mem_out[1]" value="0"/>
<bit memory_port="mem_out[2]" value="1"/>
<bit memory_port="mem_out[3]" value="1"/>
<bit memory_port="mem_out[3]" value="0"/>
<bit memory_port="mem_out[4]" value="1"/>
<bit memory_port="mem_out[5]" value="1"/>
<bit memory_port="mem_out[5]" value="0"/>
<bit memory_port="mem_out[6]" value="1"/>
<bit memory_port="mem_out[7]" value="1"/>
<bit memory_port="mem_out[8]" value="1"/>
<bit memory_port="mem_out[7]" value="0"/>
<bit memory_port="mem_out[8]" value="0"/>
<bit memory_port="mem_out[9]" value="0"/>
<bit memory_port="mem_out[10]" value="1"/>
<bit memory_port="mem_out[10]" value="0"/>
<bit memory_port="mem_out[11]" value="0"/>
<bit memory_port="mem_out[12]" value="1"/>
<bit memory_port="mem_out[12]" value="0"/>
<bit memory_port="mem_out[13]" value="0"/>
<bit memory_port="mem_out[14]" value="1"/>
<bit memory_port="mem_out[14]" value="0"/>
<bit memory_port="mem_out[15]" value="0"/>
</bitstream>
</bitstream_block>

View File

@ -84,10 +84,10 @@
<device_technology device_model_name="logic"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="input" prefix="in" lib_name="A" size="1"/>
<port type="input" prefix="sel" lib_name="S" size="1"/>
<port type="input" prefix="selb" lib_name="SI" size="1"/>
<port type="output" prefix="out" lib_name="Y" size="1"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>