YosysHQ / yosys

Yosys Open SYnthesis Suite
https://yosyshq.net/yosys/
ISC License
3.3k stars 860 forks source link

cellmatch: New pass for picking out standard cells automatically #4300

Closed povik closed 2 months ago

povik commented 3 months ago

    cellmatch -lib <design> [module selection]

This pass identifies functionally equivalent counterparts between each of the
selected modules and a module from the secondary design <design>. For every such
correspondence found, a techmap rule is generated for mapping instances of the
former to instances of the latter. This techmap rule is saved in yet another
design called '$cellmatch', which is created if non-existent.

This pass restricts itself to combinational modules. Modules are functionally
equivalent as long as their truth tables are identical upto a permutation of
inputs and outputs. The supported number of inputs is limited to 6.
QuantamHD commented 3 months ago

You're a machine @povik!

povik commented 3 months ago

This is useful for writing low-level structural Verilog with some degree of portability between cell libraries.

Say you write a Kogge-Stone carry lookahead unit out of AND, AOI2 gates with the expectation that the target cell library will contain cells resembling those.

module LCU(P, G, CI, CO);
    parameter WIDTH = 4;

    (* force_downto *)
    input [WIDTH-1:0] P, G;
    input CI;

    (* force_downto *)
    output [WIDTH-1:0] CO;

    localparam STAGES = $clog2(WIDTH);

    integer i, j;
    (* force_downto *)
    reg [WIDTH-1:0] p [STAGES:0], g [STAGES:0];

    assign p[0] = P;
    assign g[0] = G | (P[0] & CI);

    generate
        genvar i, j;

        for (i = 0; i < $clog2(WIDTH); i = i + 1) begin
            for (j = 0; j < 2**i; j = j + 1) begin
                assign g[i + 1][j] = g[i][j];
                assign p[i + 1][j] = p[i][j];
            end
            for (j = 2**i; j < WIDTH; j = j + 1) begin
                AOI2 aoi2(.A(g[i][j]), .B(p[i][j]), .C(g[i][j - 2**i]), .Y(g[i + 1][j]));
                AND and_(.A(p[i][j]), .B(p[i][j - 2**i]), .Y(p[i + 1][j]));
            end
        end
    endgenerate

    assign CO = g[STAGES];
endmodule

module AND(A, B, Y);
    input wire A;
    input wire B;
    output wire Y = A & B;
endmodule

module AOI2(A, B, C, Y);
    input wire A;
    input wire B;
    input wire C;
    output wire Y = A | B & C;
endmodule

You can map to those cells with the following script (here taking a SKY130 target as an example):

read_liberty -ignore_miss_func sky130_fd_sc_hd__tt_025C_1v80.lib
aigmap
design -save gatelib
design -reset

read_verilog design.v
prep
aigmap AND AOI2
cellmatch -lib gatelib AND AOI2
techmap -map %$cellmatch
dump
povik commented 3 months ago

@QuantamHD Hah, you are quick to notice the PR. :)

QuantamHD commented 3 months ago

I think this is super cool, and really helpful to users! Thanks for working on it

povik commented 3 months ago

This could use comb cell eval instead of limiting itself to AIGs, no?

Yes, but I leave dealing with the eval API for another day...

povik commented 2 months ago

This could use comb cell eval instead of limiting itself to AIGs, no?

I made this change, also I updated the quoted help message above to what it is now.

widlarizer commented 2 months ago

Please review and consider pulling in my comments https://github.com/widlarizer/yosys/commit/24bf8a5c1eb2171ee77917cb1c8fcd4ffc9f5b3f EDIT: instead, I created PR #4366