diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 1a350d56..5f499842 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -2402,23 +2402,34 @@ LibertyReader::makeTimingArcs(const char *from_port_name, else { // bus -> bus if (timing->isOneToOne()) { - if (static_cast(from_port_iter.size()) == to_port->size()) { - LibertyPortMemberIterator to_iter(to_port); - while (from_port_iter.hasNext() && to_iter.hasNext()) { - LibertyPort *from_port_bit = from_port_iter.next(); - LibertyPort *to_port_bit = to_iter.next(); - if (from_port_bit->direction()->isOutput()) - libWarn(1215, timing->line(), "timing group from output port."); - builder_.makeTimingArcs(cell_, from_port_bit, to_port_bit, - related_out_port, timing->attrs(), - timing->line()); - } - } - else + int from_size = from_port_iter.size(); + int to_size = to_port->size(); + LibertyPortMemberIterator to_port_iter(to_port); + // warn about different sizes + if (from_size != to_size) libWarn(1216, timing->line(), "timing port %s and related port %s are different sizes.", from_port_name, to_port->name()); + // align to/from iterators for one-to-one mapping + while (from_size > to_size) { + from_size--; + from_port_iter.next(); + } + while (to_size > from_size) { + to_size--; + to_port_iter.next(); + } + // make timing arcs + while (from_port_iter.hasNext() && to_port_iter.hasNext()) { + LibertyPort *from_port_bit = from_port_iter.next(); + LibertyPort *to_port_bit = to_port_iter.next(); + if (from_port_bit->direction()->isOutput()) + libWarn(1215, timing->line(), "timing group from output port."); + builder_.makeTimingArcs(cell_, from_port_bit, to_port_bit, + related_out_port, timing->attrs(), + timing->line()); + } } else { while (from_port_iter.hasNext()) { diff --git a/test/liberty_arcs_one2one.lib b/test/liberty_arcs_one2one.lib new file mode 100644 index 00000000..7eebe107 --- /dev/null +++ b/test/liberty_arcs_one2one.lib @@ -0,0 +1,93 @@ +library (one_to_one_mismatched_width) { + delay_model : "table_lookup"; + simulation : false; + capacitive_load_unit (1,pF); + leakage_power_unit : "1pW"; + current_unit : "1A"; + pulling_resistance_unit : "1kohm"; + time_unit : "1ns"; + voltage_unit : "1v"; + library_features : "report_delay_calculation"; + input_threshold_pct_rise : 50; + input_threshold_pct_fall : 50; + output_threshold_pct_rise : 50; + output_threshold_pct_fall : 50; + slew_lower_threshold_pct_rise : 30; + slew_lower_threshold_pct_fall : 30; + slew_upper_threshold_pct_rise : 70; + slew_upper_threshold_pct_fall : 70; + slew_derate_from_library : 1.0; + nom_process : 1.0; + nom_temperature : 85.0; + nom_voltage : 0.75; + type (bus8) { + base_type : "array"; + data_type : "bit"; + bit_width : 8; + bit_from : 7; + bit_to : 0; + } + type (bus4) { + base_type : "array"; + data_type : "bit"; + bit_width : 4; + bit_from : 3; + bit_to : 0; + } + + cell (inv_8_to_4) { + bus (A) { + capacitance : 1; + bus_type : "bus8"; + direction : "input"; + } + bus (Y) { + function : "!A"; + bus_type : "bus4"; + direction : "output"; + timing () { + related_pin : "A"; + cell_rise (scalar) { + values ("1"); + } + cell_fall (scalar) { + values ("1"); + } + rise_transition (scalar) { + values ("1"); + } + fall_transition (scalar) { + values ("1"); + } + } + } + } + + cell (inv_4_to_8) { + bus (A) { + capacitance : 1; + bus_type : "bus4"; + direction : "input"; + } + bus (Y) { + function : "!A"; + bus_type : "bus8"; + direction : "output"; + timing () { + related_pin : "A"; + cell_rise (scalar) { + values ("1"); + } + cell_fall (scalar) { + values ("1"); + } + rise_transition (scalar) { + values ("1"); + } + fall_transition (scalar) { + values ("1"); + } + } + } + } +} \ No newline at end of file diff --git a/test/liberty_arcs_one2one.ok b/test/liberty_arcs_one2one.ok new file mode 100644 index 00000000..22d298ef --- /dev/null +++ b/test/liberty_arcs_one2one.ok @@ -0,0 +1,220 @@ +Warning: liberty_arcs_one2one.lib line 48, timing port A and related port Y are different sizes. +Warning: liberty_arcs_one2one.lib line 76, timing port A and related port Y are different sizes. +TEST 1: +Startpoint: a[0] (input port clocked by clk) +Endpoint: y[0] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[0] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[0] (inv_8_to_4) + 0.00 1.00 ^ y[0] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +Startpoint: a[1] (input port clocked by clk) +Endpoint: y[1] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[1] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[1] (inv_8_to_4) + 0.00 1.00 ^ y[1] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +Startpoint: a[2] (input port clocked by clk) +Endpoint: y[2] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[2] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[2] (inv_8_to_4) + 0.00 1.00 ^ y[2] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +Startpoint: a[3] (input port clocked by clk) +Endpoint: y[3] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[3] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[3] (inv_8_to_4) + 0.00 1.00 ^ y[3] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +TEST 2: +Startpoint: a[0] (input port clocked by clk) +Endpoint: y[0] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[0] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[0] (inv_4_to_8) + 0.00 1.00 ^ y[0] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +Startpoint: a[1] (input port clocked by clk) +Endpoint: y[1] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[1] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[1] (inv_4_to_8) + 0.00 1.00 ^ y[1] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +Startpoint: a[2] (input port clocked by clk) +Endpoint: y[2] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[2] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[2] (inv_4_to_8) + 0.00 1.00 ^ y[2] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + +Startpoint: a[3] (input port clocked by clk) +Endpoint: y[3] (output port clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 v a[3] (in) + 1.00 1.00 ^ partial_wide_inv_cell/Y[3] (inv_4_to_8) + 0.00 1.00 ^ y[3] (out) + 1.00 data arrival time + + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 clock reconvergence pessimism + 0.00 0.00 output external delay + 0.00 data required time +--------------------------------------------------------- + 0.00 data required time + -1.00 data arrival time +--------------------------------------------------------- + -1.00 slack (VIOLATED) + + diff --git a/test/liberty_arcs_one2one.tcl b/test/liberty_arcs_one2one.tcl new file mode 100644 index 00000000..38bac255 --- /dev/null +++ b/test/liberty_arcs_one2one.tcl @@ -0,0 +1,17 @@ +read_liberty liberty_arcs_one2one.lib + +puts "TEST 1:" +read_verilog liberty_arcs_one2one_1.v +link_design liberty_arcs_one2one_1 +create_clock -name clk -period 0 +set_input_delay -clock clk 0 [all_inputs] +set_output_delay -clock clk 0 [all_outputs] +report_checks -group_count 5 + +puts "TEST 2:" +read_verilog liberty_arcs_one2one_2.v +link_design liberty_arcs_one2one_2 +create_clock -name clk -period 0 +set_input_delay -clock clk 0 [all_inputs] +set_output_delay -clock clk 0 [all_outputs] +report_checks -group_count 5 diff --git a/test/liberty_arcs_one2one_1.v b/test/liberty_arcs_one2one_1.v new file mode 100644 index 00000000..46d11e2a --- /dev/null +++ b/test/liberty_arcs_one2one_1.v @@ -0,0 +1,13 @@ +// Liberty file test: one-to-one mapping with mismatched bit widths +// Should generate warning but still create timing arcs between bits with same index +module liberty_arcs_one2one_1 ( + input wire [7:0] a, + output wire [3:0] y +); + + inv_8_to_4 partial_wide_inv_cell ( + .A(a), + .Y(y) + ); + +endmodule \ No newline at end of file diff --git a/test/liberty_arcs_one2one_2.v b/test/liberty_arcs_one2one_2.v new file mode 100644 index 00000000..8bc66fad --- /dev/null +++ b/test/liberty_arcs_one2one_2.v @@ -0,0 +1,13 @@ +// Liberty file test: one-to-one mapping with mismatched bit widths +// Should generate warning but still create timing arcs between bits with same index +module liberty_arcs_one2one_2 ( + input wire [3:0] a, + output wire [7:0] y +); + + inv_4_to_8 partial_wide_inv_cell ( + .A(a), + .Y(y) + ); + +endmodule \ No newline at end of file diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index 8fde713d..5ecca193 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -124,6 +124,7 @@ record_example_tests { record_sta_tests { prima3 verilog_attribute + liberty_arcs_one2one } define_test_group fast [group_tests all]