This use case shows how to use Gates On the Fly to fix datapath bugs. Datapath is much more complex than control logic, and manually fixing datapath bugs is more difficult than fixing control logic bugs. In this case, an ECO flow is described to fix datapath bugs by Gates On the Fly.
This is a variable coefficients FIR filter with 6 taps. A bug is introduced by missing the rounding logic.
Figure 1 Variable coefficients FIR filter
... parameter WIDTH = 20; parameter WC = 5; always @(*) data_dly0 = i_data; always @(posedge clk) begin data_dly1 <= data_dly0; data_dly2 <= data_dly1; data_dly3 <= data_dly2; data_dly4 <= data_dly3; data_dly5 <= data_dly4; end wire signed [WIDTH:0] preadd0 = data_dly0 + data_dly5; wire signed [WIDTH:0] preadd1 = data_dly1 + data_dly4; wire signed [WIDTH:0] preadd2 = data_dly2 + data_dly3; wire signed [WIDTH+WC:0] m0 = preadd0 * c0; wire signed [WIDTH+WC:0] m1 = preadd1 * c1; wire signed [WIDTH+WC:0] m2 = preadd2 * c2; wire signed [WIDTH+WC+2:0] product = m0 + m1 + m2; // Round logic is missed in the following line wire [WIDTH+WC+2:0] rproduct = product; // '+16' part is to add the rounding logic //wire [WIDTH+WC+2:0] rproduct = product + 16; wire [WIDTH-3:0] sat_out; saturate #(.BW_IN(WIDTH+1), .BW_OUT(WIDTH-2)) u_saturate(.sat_in(rproduct[WIDTH+5:5]), .sat_out(sat_out[WIDTH-3:0])); reg [WIDTH-3:0] pout; always @(posedge clk) pout <= sat_out; ...
The implementation netlist with bug is saved in 'imp_fir.v'.
Synthesize the RTL code with ECO changes with the same constraint and save the result to 'ref_fir.v'.
Logic Equivalence Check is run on 'imp_fir.v' vs 'ref_fir.v'. The result shows '\pout_reg[0] ' to '\pout_reg[17] ' registers have mismatches.
A GofCall Perl script is created to read in the implementation netlist and reference netlist, 'fix_desing' API finds and fixes the non-equivalent modules.
The initial logic cone has 708 gates. GOF adds 19 gates into the logic to fix the bug.
Replacing the whole logic cone 708 gates would cause big disturbance in back end flow and in post-mask flow it's impossible to find enough spare gates
# GofCall ECO script, run_dpath_eco.pl use strict; undo_eco; # Discard previous ECO operations # Setup ECO name setup_eco("dpath_eco"); read_library("art.90nm.lib"); # Read in standard library read_design("-ref", "ref_fir.v"); # Read in the Reference Netlist read_design("-imp", "imp_fir.v"); # Read in the implementation Netlist Which is under ECO set_top("dpath"); # Set the top module that ECO is working on # Fix the modified module 'dpath' and its sub-modules fix_design; # Metal only ECO commands can be insert here report_eco(); # ECO report write_verilog("eco_dpath.v"); # Write out ECO result in Verilog
In post-mask ECO, only metal layers can be modified. Enough spare gates should be implemented to make metal only eco successful. The following lines are added in the above GofCall script to do metal only ECO
read_def("imp_fir.def"); # Read Design Exchange Format file, optional # Specify spare cell pattern and add freed gates in the current ECO into spare gate list get_spare_cells("u_spare*/*spare_gates*"); map_spare_cells;
The database has spare gate types, 'NOR', 'NAND', 'MUX' and invert. After mapping the 19 new gates into spare gate types, GOF uses 78 spare gates to implement the metal only ECO.
In this case, one coefficient has to increase width by one bit. The following figure shows coefficient C0 has bit width increased by one and rounding is added as the previous example. The change spots have been marked in 'red'.
Figure 2. Increase bit width of coefficient
The same GofCall script above can be used on this case. Input port C0 bit width will increase by one bit automatically after ECO.
The initial logic cone has 759 gates. GOF adds 120 gates into the logic to fix the bug.
Manual ECO is possible only in some special cases like fixed coefficients. For example, Figure 2, the FIR has fixed coefficients with value c0 = -2, c1 = 3, and c2 = 15.
Figure 3. Fixed coefficients FIR filter
Since
c0 + c1 + c2 = -2 + 3 + 15 = 16 So preadd0*c0 + preadd1*c1 + preadd2*c2 + 16 = (preadd0+2'sb1)*c0 + (preadd1+2'sb1)*c1 + (preadd2+2'sb1)*c2
So if the adders 'preadd0', 'preadd1' and 'preadd2' can be found and added carrier-in bit, a manual ECO is possible
... parameter WIDTH = 20; parameter WC = 5; always @(*) data_dly0 = i_data; always @(posedge clk) begin data_dly1 <= data_dly0; data_dly2 <= data_dly1; data_dly3 <= data_dly2; data_dly4 <= data_dly3; data_dly5 <= data_dly4; end wire signed [WIDTH:0] preadd0 = data_dly0 + data_dly5 + 2'sb1; wire signed [WIDTH:0] preadd1 = data_dly1 + data_dly4 + 2'sb1; wire signed [WIDTH:0] preadd2 = data_dly2 + data_dly3 + 2'sb1; wire signed [WIDTH+WC:0] m0 = preadd0 * c0; wire signed [WIDTH+WC:0] m1 = preadd1 * c1; wire signed [WIDTH+WC:0] m2 = preadd2 * c2; wire signed [WIDTH+WC+2:0] product = m0 + m1 + m2; wire [WIDTH+WC+2:0] rproduct = product; wire [WIDTH-3:0] sat_out; saturate #(.BW_IN(WIDTH+1), .BW_OUT(WIDTH-2)) u_saturate(.sat_in(rproduct[WIDTH+5:5]), .sat_out(sat_out[WIDTH-3:0])); reg [WIDTH-3:0] pout; always @(posedge clk) pout <= sat_out; ...
GofTrace schematic window can be enabled in command line, or use 'start_gui' to launch GUI window from the script.
Command line is:
gof -lib art.90nm.lib -imp imp_fir.v -ref ref_fir.v
Launch GUI window from the script
read_library("art.90nm.lib"); # Read in standard library read_design("-ref", "ref_fir.v"); # Read in the Reference Netlist read_design("-imp", "imp_fir.v"); # Read in the implementation Netlist Which is under ECO start_gui; # Enable GUI window
Find register data_dly*_reg[0] on GofTrace Schematic and trace back and forth by mouse-middle-button clicking on the gate pins
Figure 4. Three Half-Adders under ECO
The new value of 'S' and 'CO' become
new_S = A ^ B ^ 1 = !S
new_CO = A & B + A & 1 + B & 1 = A + B
So an inverter should be inserted to the 'S' path. And a new 'OR' gate with A/B driven by the Half-Adder inputs drives the original 'CO' fanouts
Trace the output pins of the Half-Adders as shown in Figure 5.
Figure 5. Trace output pins for ECO
The ECO steps for one Half-Adder (add_78_48_p3139D) are:
One Half-Adder after ECO fix is shown below. Do the same operations on the other two Half-Adders
Figure 6. Three Half Adders under ECO
Using 'change_pin' API in GofCall script is even more efficient
my @adders = qw(add_76_48_p2408D add_77_48_p3164A add_78_48_p3139D ); my $inv = "CKND1H"; my $or = "OR2D1H"; foreach my $add (@adders){ change_pin("$add/S", $inv, "", "-"); change_pin("$add/CO", $or, "", "$add/A,$add/B"); } write_verilog("man_eco_dpath_fc.vg");
The initial logic cone has 223 gates. Manual ECO only uses 6 new gates. Apply automatic GofCall ECO script listed above, 14 new gates are added
GOF adds 14 gates into the logic to fix the bug.
Datapath ECO is very complicated. Pure manual ECO is possible in some special cases, though it has better performance than automatic ECO. In most cases, datapath ECO has to be done by automatic way that Gates On the Fly provides.